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());
+ }
+ }
}