This is an automated email from the ASF dual-hosted git repository.

dhavalshah9131 pushed a commit to branch ranger-2.10
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/ranger-2.10 by this push:
     new 314dafaef RANGER-5787 : Refactoring the security zone API (#1252)
314dafaef is described below

commit 314dafaef734754786b2d6f6f6a6c2e25864496a
Author: dhavalshah9131 <[email protected]>
AuthorDate: Wed Sep 23 20:46:20 2026 +0530

    RANGER-5787 : Refactoring the security zone API (#1252)
    
    Co-authored-by: Dhaval Shah <dhavalshah9131@@gmail.com>
---
 .../org/apache/ranger/rest/SecurityZoneREST.java   |  54 ++++--
 .../apache/ranger/rest/TestSecurityZoneREST.java   | 183 +++++++++++++++++----
 2 files changed, 196 insertions(+), 41 deletions(-)

diff --git 
a/security-admin/src/main/java/org/apache/ranger/rest/SecurityZoneREST.java 
b/security-admin/src/main/java/org/apache/ranger/rest/SecurityZoneREST.java
index a999b0843..e700d9cf2 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/SecurityZoneREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/SecurityZoneREST.java
@@ -58,8 +58,6 @@
 import org.apache.ranger.common.RangerSearchUtil;
 import org.apache.ranger.common.RangerValidatorFactory;
 import org.apache.ranger.db.RangerDaoManager;
-import org.apache.ranger.entity.XXService;
-import org.apache.ranger.entity.XXServiceDef;
 import org.apache.ranger.plugin.model.RangerSecurityZone;
 import org.apache.ranger.plugin.model.RangerSecurityZoneHeaderInfo;
 import org.apache.ranger.plugin.model.RangerSecurityZoneV2;
@@ -186,6 +184,7 @@ public RangerSecurityZone 
updateSecurityZone(@PathParam("id") Long zoneId,
         } else {
             securityZone.setId(zoneId);
         }
+        blockAdminFromKMSServiceOnUpdate(securityZone);
         RangerSecurityZone ret;
         try {
             RangerSecurityZoneValidator validator = 
validatorFactory.getSecurityZoneValidator(svcStore, securityZoneStore);
@@ -216,6 +215,9 @@ public void deleteSecurityZone(@PathParam("name") String 
zoneName) {
         }
         try {
                ensureAdminAccess();
+
+            blockAdminFromKMSServiceOnDelete(zoneName, null);
+
             RangerSecurityZoneValidator validator = 
validatorFactory.getSecurityZoneValidator(svcStore, securityZoneStore);
             validator.validate(zoneName, RangerValidator.Action.DELETE);
             securityZoneStore.deleteSecurityZoneByName(zoneName);
@@ -246,6 +248,9 @@ public void deleteSecurityZone(@PathParam("id") Long 
zoneId) {
         }
         try {
                ensureAdminAccess();
+
+            blockAdminFromKMSServiceOnDelete(null, zoneId);
+
             RangerSecurityZoneValidator validator = 
validatorFactory.getSecurityZoneValidator(svcStore, securityZoneStore);
             validator.validate(zoneId, RangerValidator.Action.DELETE);
             securityZoneStore.deleteSecurityZoneById(zoneId);
@@ -739,24 +744,51 @@ private void ensureAdminAccess(RangerSecurityZone 
securityZone) {
        }
 
        private void blockAdminFromKMSService(RangerSecurityZone securityZone) {
-               if(securityZone != null) {
+               if (securityZone != null) {
                        Map<String, RangerSecurityZoneService> serviceMap = 
securityZone.getServices();
+
                        if (serviceMap != null) {
                                for (String serviceName : serviceMap.keySet()) {
-                                       XXService xService = 
daoManager.getXXService().findByName(serviceName);
-                                       if (xService != null) {
-                                               XXServiceDef xServiceDef = 
daoManager.getXXServiceDef().getById(xService.getType());
-                                               if 
(EmbeddedServiceDefsUtil.KMS_IMPL_CLASS_NAME.equals(xServiceDef.getImplclassname()))
 {
-                                                       throw 
restErrorUtil.createRESTException(
-                                                                       "KMS 
Services/Service-Defs are not accessible for Zone operations",
-                                                                       
MessageEnums.OPER_NOT_ALLOWED_FOR_ENTITY);
-                                               }
+                                       String serviceType = 
daoManager.getXXServiceDef().findServiceDefTypeByServiceName(serviceName);
+
+                                       if 
(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_KMS_NAME.equals(serviceType)) {
+                                               throw 
restErrorUtil.createRESTException(
+                                                               "KMS 
Services/Service-Defs are not accessible for Zone operations",
+                                                               
MessageEnums.OPER_NOT_ALLOWED_FOR_ENTITY);
                                        }
                                }
                        }
                }
        }
 
+       private void blockAdminFromKMSServiceOnUpdate(RangerSecurityZone 
submittedZone) {
+               if (bizUtil.isAdmin()) {
+                       blockAdminFromKMSService(submittedZone);
+               }
+       }
+
+       private void blockAdminFromKMSServiceOnDelete(String zoneName, Long 
zoneId) {
+               if (bizUtil.isAdmin()) {
+                       RangerSecurityZone existingZone = null;
+
+                       try {
+                               if (zoneId != null) {
+                                       existingZone = 
securityZoneStore.getSecurityZone(zoneId);
+                               } else if (zoneName != null) {
+                                       existingZone = 
securityZoneStore.getSecurityZoneByName(zoneName);
+                               }
+                       } catch (WebApplicationException excp) {
+                               throw excp;
+                       } catch (Exception ex) {
+                               LOG.error("Unable to get Security Zone with id 
: {}, name : {}", zoneId, zoneName, ex);
+
+                               throw 
restErrorUtil.createRESTException(ex.getMessage());
+                       }
+
+                       blockAdminFromKMSService(existingZone);
+               }
+       }
+
        private void removeEmptyEntries(RangerSecurityZone securityZone) {
                 bizUtil.removeEmptyStrings(securityZone.getTagServices());
                bizUtil.removeEmptyStrings(securityZone.getAdminUsers());
diff --git 
a/security-admin/src/test/java/org/apache/ranger/rest/TestSecurityZoneREST.java 
b/security-admin/src/test/java/org/apache/ranger/rest/TestSecurityZoneREST.java
index cc530c60d..c383c74b9 100644
--- 
a/security-admin/src/test/java/org/apache/ranger/rest/TestSecurityZoneREST.java
+++ 
b/security-admin/src/test/java/org/apache/ranger/rest/TestSecurityZoneREST.java
@@ -18,7 +18,14 @@
 package org.apache.ranger.rest;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.lenient;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -35,18 +42,17 @@
 import org.apache.ranger.biz.RangerBizUtil;
 import org.apache.ranger.biz.SecurityZoneDBStore;
 import org.apache.ranger.biz.ServiceDBStore;
+import org.apache.ranger.common.MessageEnums;
 import org.apache.ranger.common.RESTErrorUtil;
 import org.apache.ranger.common.RangerSearchUtil;
 import org.apache.ranger.common.RangerValidatorFactory;
 import org.apache.ranger.db.RangerDaoManager;
-import org.apache.ranger.db.XXServiceDao;
 import org.apache.ranger.db.XXServiceDefDao;
-import org.apache.ranger.entity.XXService;
-import org.apache.ranger.entity.XXServiceDef;
 import org.apache.ranger.plugin.model.RangerSecurityZone;
 import 
org.apache.ranger.plugin.model.RangerSecurityZone.RangerSecurityZoneService;
 import org.apache.ranger.plugin.model.validation.RangerSecurityZoneValidator;
 import org.apache.ranger.plugin.model.validation.RangerValidator;
+import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
 import org.apache.ranger.plugin.util.SearchFilter;
 import org.apache.ranger.service.RangerSecurityZoneServiceService;
 import org.apache.ranger.view.RangerSecurityZoneList;
@@ -82,11 +88,49 @@ public class TestSecurityZoneREST {
        @Mock
        RangerDaoManager daoManager;
        @Mock
-       XXServiceDef xServiceDef;
+       XXServiceDefDao xxServiceDefDao;
 
        @Rule
        public ExpectedException thrown = ExpectedException.none();
 
+       private RangerSecurityZone 
createRangerSecurityZoneWithKmsService(String kmsServiceName) {
+               RangerSecurityZone zone = createRangerSecurityZone();
+
+               zone.getServices().put(kmsServiceName, new 
RangerSecurityZoneService());
+
+               return zone;
+       }
+
+       private void mockNonKmsServiceLookupForZoneCheck() {
+               when(daoManager.getXXServiceDef()).thenReturn(xxServiceDefDao);
+               
when(xxServiceDefDao.findServiceDefTypeByServiceName("test_service_1")).thenReturn("hdfs");
+       }
+
+       private void mockKmsServiceLookupForZoneCheck(String kmsServiceName) {
+               when(daoManager.getXXServiceDef()).thenReturn(xxServiceDefDao);
+               
when(xxServiceDefDao.findServiceDefTypeByServiceName(kmsServiceName))
+                               
.thenReturn(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_KMS_NAME);
+               when(restErrorUtil.createRESTException(
+                               eq("KMS Services/Service-Defs are not 
accessible for Zone operations"),
+                               
eq(MessageEnums.OPER_NOT_ALLOWED_FOR_ENTITY))).thenReturn(new 
WebApplicationException());
+       }
+
+       private void mockMixedKmsAndNonKmsServiceLookupForZoneCheck(String 
kmsServiceName) {
+               when(daoManager.getXXServiceDef()).thenReturn(xxServiceDefDao);
+               
lenient().when(xxServiceDefDao.findServiceDefTypeByServiceName("test_service_1")).thenReturn("hdfs");
+               
when(xxServiceDefDao.findServiceDefTypeByServiceName(kmsServiceName))
+                               
.thenReturn(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_KMS_NAME);
+               when(restErrorUtil.createRESTException(
+                               eq("KMS Services/Service-Defs are not 
accessible for Zone operations"),
+                               
eq(MessageEnums.OPER_NOT_ALLOWED_FOR_ENTITY))).thenReturn(new 
WebApplicationException());
+       }
+
+       private void mockServiceDefTypeLookup(String serviceName1, String 
serviceType1, String serviceName2, String serviceType2) {
+               when(daoManager.getXXServiceDef()).thenReturn(xxServiceDefDao);
+               
when(xxServiceDefDao.findServiceDefTypeByServiceName(serviceName1)).thenReturn(serviceType1);
+               
when(xxServiceDefDao.findServiceDefTypeByServiceName(serviceName2)).thenReturn(serviceType2);
+       }
+
        private RangerSecurityZone createRangerSecurityZone() {
                String testZone1 = "testzone1";
                List<String> testZone1ResoursesList = new 
ArrayList(Arrays.asList("/path/to/resource1", "/path/to/resource2"));
@@ -115,15 +159,8 @@ private RangerSecurityZone createRangerSecurityZone() {
        @Test
        public void testCreateSecurityZone() throws Exception {
                RangerSecurityZone rangerSecurityZone = 
createRangerSecurityZone();
-               XXServiceDao xServiceDao = Mockito.mock(XXServiceDao.class);
-               XXService xService = Mockito.mock(XXService.class);
-               XXServiceDefDao xServiceDefDao = 
Mockito.mock(XXServiceDefDao.class);
                when(rangerBizUtil.isAdmin()).thenReturn(true);
-               when(daoManager.getXXService()).thenReturn(xServiceDao);
-               
when(xServiceDao.findByName("test_service_1")).thenReturn(xService);
-
-               when(daoManager.getXXServiceDef()).thenReturn(xServiceDefDao);
-               
when(xServiceDefDao.getById(xService.getType())).thenReturn(xServiceDef);
+               mockNonKmsServiceLookupForZoneCheck();
 
                when(validatorFactory.getSecurityZoneValidator(svcStore, 
securityZoneStore)).thenReturn(validator);
                doNothing().when(validator).validate(rangerSecurityZone, 
RangerValidator.Action.CREATE);
@@ -133,23 +170,49 @@ public void testCreateSecurityZone() throws Exception {
                verify(validator, times(1)).validate(rangerSecurityZone, 
RangerValidator.Action.CREATE);
        }
 
+       @Test
+       public void testCreateSecurityZone_AdminBlockedFromKMSService() throws 
Exception {
+               String kmsServiceName = "dev_kms";
+               RangerSecurityZone zone = 
createRangerSecurityZoneWithKmsService(kmsServiceName);
+
+               when(rangerBizUtil.isAdmin()).thenReturn(true);
+               mockMixedKmsAndNonKmsServiceLookupForZoneCheck(kmsServiceName);
+
+               try {
+                       securityZoneREST.createSecurityZone(zone);
+                       fail("Expected WebApplicationException");
+               } catch (WebApplicationException expected) {
+                       verify(validator, 
never()).validate(any(RangerSecurityZone.class), any());
+                       verify(securityZoneStore, 
never()).createSecurityZone(any(RangerSecurityZone.class));
+               }
+       }
+
+       @Test
+       public void testCreateSecurityZone_AllowedForCustomNamedKMSServiceDef() 
throws Exception {
+               String customKmsServiceName = "my_kms_instance";
+               RangerSecurityZone zone = 
createRangerSecurityZoneWithKmsService(customKmsServiceName);
+
+               when(rangerBizUtil.isAdmin()).thenReturn(true);
+               mockServiceDefTypeLookup("test_service_1", "hdfs", 
customKmsServiceName, "my-kms");
+
+               when(validatorFactory.getSecurityZoneValidator(svcStore, 
securityZoneStore)).thenReturn(validator);
+               
doNothing().when(validator).validate(any(RangerSecurityZone.class), 
eq(RangerValidator.Action.CREATE));
+               
when(securityZoneStore.createSecurityZone(any(RangerSecurityZone.class))).thenReturn(zone);
+
+               securityZoneREST.createSecurityZone(zone);
+
+               verify(securityZoneStore, 
times(1)).createSecurityZone(any(RangerSecurityZone.class));
+       }
+
        @Test
        public void testUpdateSecurityZone() throws Exception {
                RangerSecurityZone rangerSecurityZoneToUpdate = 
createRangerSecurityZone();
                Long securityZoneId = 2L;
-               XXServiceDao xServiceDao = Mockito.mock(XXServiceDao.class);
-               XXService xService = Mockito.mock(XXService.class);
-               XXServiceDefDao xServiceDefDao = 
Mockito.mock(XXServiceDefDao.class);
                rangerSecurityZoneToUpdate.setId(securityZoneId);
                when(rangerBizUtil.isAdmin()).thenReturn(true);
+               mockNonKmsServiceLookupForZoneCheck();
                when(validatorFactory.getSecurityZoneValidator(svcStore, 
securityZoneStore)).thenReturn(validator);
 
-               when(daoManager.getXXService()).thenReturn(xServiceDao);
-               
when(xServiceDao.findByName("test_service_1")).thenReturn(xService);
-
-               when(daoManager.getXXServiceDef()).thenReturn(xServiceDefDao);
-               
when(xServiceDefDao.getById(xService.getType())).thenReturn(xServiceDef);
-
                
doNothing().when(validator).validate(rangerSecurityZoneToUpdate, 
RangerValidator.Action.UPDATE);
                
when(securityZoneStore.updateSecurityZoneById(rangerSecurityZoneToUpdate))
                                .thenReturn(rangerSecurityZoneToUpdate);
@@ -159,22 +222,35 @@ public void testUpdateSecurityZone() throws Exception {
                verify(validator, 
times(1)).validate(rangerSecurityZoneToUpdate, RangerValidator.Action.UPDATE);
        }
 
+       @Test
+       public void testUpdateSecurityZone_AdminBlockedFromKMSService() throws 
Exception {
+               Long securityZoneId = 2L;
+               RangerSecurityZone zone = createRangerSecurityZone();
+               zone.setId(securityZoneId);
+
+               Map<String, RangerSecurityZoneService> services = new 
HashMap<>();
+               services.put("dev_kms", new RangerSecurityZoneService());
+               zone.setServices(services);
+
+               when(rangerBizUtil.isAdmin()).thenReturn(true);
+               mockKmsServiceLookupForZoneCheck("dev_kms");
+
+               try {
+                       securityZoneREST.updateSecurityZone(securityZoneId, 
zone);
+                       fail("Expected WebApplicationException");
+               } catch (WebApplicationException expected) {
+                       verify(securityZoneStore, 
never()).updateSecurityZoneById(any(RangerSecurityZone.class));
+               }
+       }
+
        @Test
        public void testUpdateSecurityZoneWithMisMatchId() throws Exception {
                RangerSecurityZone rangerSecurityZoneToUpdate = 
createRangerSecurityZone();
                Long securityZoneId = 2L;
-               XXServiceDefDao xServiceDefDao = 
Mockito.mock(XXServiceDefDao.class);
-               XXServiceDao xServiceDao = Mockito.mock(XXServiceDao.class);
-               XXService xService = Mockito.mock(XXService.class);
 
                rangerSecurityZoneToUpdate.setId(securityZoneId);
                when(rangerBizUtil.isAdmin()).thenReturn(true);
-
-               when(daoManager.getXXService()).thenReturn(xServiceDao);
-               
when(xServiceDao.findByName("test_service_1")).thenReturn(xService);
-
-               when(daoManager.getXXServiceDef()).thenReturn(xServiceDefDao);
-               
when(xServiceDefDao.getById(xService.getType())).thenReturn(xServiceDef);
+               mockNonKmsServiceLookupForZoneCheck();
 
                when(validatorFactory.getSecurityZoneValidator(svcStore, 
securityZoneStore)).thenReturn(validator);
                
doNothing().when(validator).validate(rangerSecurityZoneToUpdate, 
RangerValidator.Action.UPDATE);
@@ -260,6 +336,8 @@ public void testDeleteSecurityZoneById() throws Exception {
                Long securityZoneId = 2L;
                securityZone.setId(securityZoneId);
                when(rangerBizUtil.isAdmin()).thenReturn(true);
+               mockNonKmsServiceLookupForZoneCheck();
+               
when(securityZoneStore.getSecurityZone(securityZoneId)).thenReturn(securityZone);
                when(validatorFactory.getSecurityZoneValidator(svcStore, 
securityZoneStore)).thenReturn(validator);
                doNothing().when(validator).validate(securityZoneId, 
RangerValidator.Action.DELETE);
                securityZoneREST.deleteSecurityZone(securityZoneId);
@@ -267,6 +345,28 @@ public void testDeleteSecurityZoneById() throws Exception {
 
        }
 
+       @Test
+       public void 
testDeleteSecurityZoneById_AdminBlockedWhenZoneContainsKMSService() throws 
Exception {
+               Long securityZoneId = 2L;
+               RangerSecurityZone zone = createRangerSecurityZone();
+               zone.setId(securityZoneId);
+
+               Map<String, RangerSecurityZoneService> services = new 
HashMap<>();
+               services.put("dev_kms", new RangerSecurityZoneService());
+               zone.setServices(services);
+
+               when(rangerBizUtil.isAdmin()).thenReturn(true);
+               mockKmsServiceLookupForZoneCheck("dev_kms");
+               
when(securityZoneStore.getSecurityZone(securityZoneId)).thenReturn(zone);
+
+               try {
+                       securityZoneREST.deleteSecurityZone(securityZoneId);
+                       fail("Expected WebApplicationException");
+               } catch (WebApplicationException expected) {
+                       verify(securityZoneStore, 
never()).deleteSecurityZoneById(anyLong());
+               }
+       }
+
        @Test
        public void testDeleteSecurityZoneByName() throws Exception {
                RangerSecurityZone securityZone = createRangerSecurityZone();
@@ -274,10 +374,33 @@ public void testDeleteSecurityZoneByName() throws 
Exception {
                securityZone.setId(securityZoneId);
                String securityZoneName = securityZone.getName();
                when(rangerBizUtil.isAdmin()).thenReturn(true);
+               mockNonKmsServiceLookupForZoneCheck();
+               
when(securityZoneStore.getSecurityZoneByName(securityZoneName)).thenReturn(securityZone);
                when(validatorFactory.getSecurityZoneValidator(svcStore, 
securityZoneStore)).thenReturn(validator);
                doNothing().when(validator).validate(securityZoneName, 
RangerValidator.Action.DELETE);
                securityZoneREST.deleteSecurityZone(securityZoneName);
                verify(securityZoneStore, 
times(1)).deleteSecurityZoneByName(securityZoneName);
 
        }
+
+       @Test
+       public void 
testDeleteSecurityZoneByName_AdminBlockedWhenZoneContainsKMSService() throws 
Exception {
+               RangerSecurityZone zone = createRangerSecurityZone();
+               String zoneName = zone.getName();
+
+               Map<String, RangerSecurityZoneService> services = new 
HashMap<>();
+               services.put("dev_kms", new RangerSecurityZoneService());
+               zone.setServices(services);
+
+               when(rangerBizUtil.isAdmin()).thenReturn(true);
+               mockKmsServiceLookupForZoneCheck("dev_kms");
+               
when(securityZoneStore.getSecurityZoneByName(zoneName)).thenReturn(zone);
+
+               try {
+                       securityZoneREST.deleteSecurityZone(zoneName);
+                       fail("Expected WebApplicationException");
+               } catch (WebApplicationException expected) {
+                       verify(securityZoneStore, 
never()).deleteSecurityZoneByName(anyString());
+               }
+       }
 }

Reply via email to