From 31edd89e34ebe7d182b9e4c472b5279a6acb6f35 Mon Sep 17 00:00:00 2001 From: abhiishek26 Date: Wed, 27 May 2026 19:43:51 +0530 Subject: [PATCH] updated updateService in ServiceREST to aviod id mismatch issue --- .../org/apache/ranger/rest/ServiceREST.java | 20 ++++++++ .../apache/ranger/rest/TestServiceREST.java | 51 +++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java index 74468691c1..32ef6261fe 100644 --- a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java +++ b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java @@ -734,6 +734,26 @@ public RangerService createService(RangerService service) { @PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.UPDATE_SERVICE + "\")") public RangerService updateService(RangerService service, @Context HttpServletRequest request) { LOG.debug("==> ServiceREST.updateService(): {}", service); + // if service.id and param 'id' are specified, service.id should be same as the param 'id' + // if service.id is null, then set param 'id' into service Object + if (request != null) { + String requestURI = request.getRequestURI(); + if (requestURI != null) { + String[] parts = requestURI.split("/"); + try { + Long id = Long.parseLong(parts[parts.length - 1]); + if (service.getId() == null) { + service.setId(id); + } else if (StringUtils.isBlank(service.getName()) || !service.getId().equals(id)) { + throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST, "serviceDef Id mismatch or service name not provided", true); + } + } catch (NumberFormatException e) { + LOG.warn("Could not parse service id from request URI: {}", requestURI); + } + } + } else { + LOG.debug("HttpServletRequest is null, skipping URI-based ID validation"); + } RangerService ret; RangerPerfTracer perf = null; diff --git a/security-admin/src/test/java/org/apache/ranger/rest/TestServiceREST.java b/security-admin/src/test/java/org/apache/ranger/rest/TestServiceREST.java index 91c5e34263..2bece73467 100644 --- a/security-admin/src/test/java/org/apache/ranger/rest/TestServiceREST.java +++ b/security-admin/src/test/java/org/apache/ranger/rest/TestServiceREST.java @@ -4505,4 +4505,55 @@ public void testValidateGrantRevokeRequest_InvalidOwnerForNonAdmin() throws Exce } }); } + + @Test + public void testUpdateService_IdMismatchBetweenPayloadAndURL() throws Exception { + // service has id=8 in payload, but URL has id=99 — should trigger BAD_REQUEST + RangerService service = rangerService(); + service.setId(8L); + service.setName("test-service"); + + HttpServletRequest request = Mockito.mock(HttpServletRequest.class); + Mockito.when(request.getRequestURI()).thenReturn("/ranger/plugins/services/99"); + + WebApplicationException expectedException = new WebApplicationException(HttpServletResponse.SC_BAD_REQUEST); + Mockito.when(restErrorUtil.createRESTException( + HttpServletResponse.SC_BAD_REQUEST, + "serviceDef Id mismatch or service name not provided", + true)).thenReturn(expectedException); + + Assertions.assertThrows(WebApplicationException.class, () -> + serviceREST.updateService(service, request)); + + Mockito.verify(restErrorUtil).createRESTException( + HttpServletResponse.SC_BAD_REQUEST, + "serviceDef Id mismatch or service name not provided", + true); + } + + @Test + public void testUpdateService_BlankNameWithIdInPayload() throws Exception { + // service has id set but name is blank — should trigger BAD_REQUEST + RangerService service = rangerService(); + service.setId(8L); + service.setName(""); // blank name + + HttpServletRequest request = Mockito.mock(HttpServletRequest.class); + Mockito.when(request.getRequestURI()).thenReturn("/ranger/plugins/services/8"); + + WebApplicationException expectedException = new WebApplicationException(HttpServletResponse.SC_BAD_REQUEST); + Mockito.when(restErrorUtil.createRESTException( + HttpServletResponse.SC_BAD_REQUEST, + "serviceDef Id mismatch or service name not provided", + true)) + .thenReturn(expectedException); + + Assertions.assertThrows(WebApplicationException.class, () -> + serviceREST.updateService(service, request)); + + Mockito.verify(restErrorUtil).createRESTException( + HttpServletResponse.SC_BAD_REQUEST, + "serviceDef Id mismatch or service name not provided", + true); + } }