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 169f078af4..16b13b99d8 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 @@ -42,6 +42,7 @@ import org.apache.ranger.biz.ServiceDBStore.JSON_FILE_NAME_TYPE; import org.apache.ranger.biz.ServiceMgr; import org.apache.ranger.biz.TagDBStore; +import org.apache.ranger.biz.UserMgr; import org.apache.ranger.biz.XUserMgr; import org.apache.ranger.common.AppConstants; import org.apache.ranger.common.ContextUtil; @@ -150,6 +151,7 @@ import java.security.SecureRandom; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; @@ -262,6 +264,9 @@ public class ServiceREST { @Autowired RangerTransactionSynchronizationAdapter rangerTransactionSynchronizationAdapter; + @Autowired + UserMgr userMgrGrantor; + private RangerPolicyEngineOptions delegateAdminOptions; private RangerPolicyEngineOptions policySearchAdminOptions; private RangerPolicyEngineOptions defaultAdminOptions; @@ -1178,7 +1183,7 @@ public RESTResponse grantAccess(@PathParam("serviceName") String serviceName, Gr if (policyUpdated) { policy.setZoneName(zoneName); - ensureAdminAccess(policy); + ensureAdminAccess(policy, userName); svcStore.updatePolicy(policy); } else { @@ -1220,7 +1225,7 @@ public RESTResponse grantAccess(@PathParam("serviceName") String serviceName, Gr policy.addPolicyItem(policyItem); policy.setZoneName(zoneName); - ensureAdminAccess(policy); + ensureAdminAccess(policy, userName); svcStore.createPolicy(policy); } @@ -1295,7 +1300,7 @@ public RESTResponse secureGrantAccess(@PathParam("serviceName") String serviceNa if (policyUpdated) { policy.setZoneName(zoneName); - ensureAdminAccess(policy); + ensureAdminAccess(policy, userName); svcStore.updatePolicy(policy); } else { @@ -1337,7 +1342,7 @@ public RESTResponse secureGrantAccess(@PathParam("serviceName") String serviceNa policy.addPolicyItem(policyItem); policy.setZoneName(zoneName); - ensureAdminAccess(policy); + ensureAdminAccess(policy, userName); svcStore.createPolicy(policy); } @@ -1422,7 +1427,7 @@ public RESTResponse revokeAccess(@PathParam("serviceName") String serviceName, G if (policyUpdated) { policy.setZoneName(zoneName); - ensureAdminAccess(policy); + ensureAdminAccess(policy, userName); svcStore.updatePolicy(policy); } else { @@ -1501,7 +1506,7 @@ public RESTResponse secureRevokeAccess(@PathParam("serviceName") String serviceN if (policyUpdated) { policy.setZoneName(zoneName); - ensureAdminAccess(policy); + ensureAdminAccess(policy, userName); svcStore.updatePolicy(policy); } else { @@ -3205,11 +3210,27 @@ public RangerPolicy getPolicyByName(String serviceName, String policyName, Strin } void ensureAdminAccess(RangerPolicy policy) { + ensureAdminAccess(policy, null); + } + + void ensureAdminAccess(RangerPolicy policy, String grantor) { blockIfGdsService(policy.getService()); - boolean isAdmin = bizUtil.isAdmin(); - boolean isKeyAdmin = bizUtil.isKeyAdmin(); - String userName = bizUtil.getCurrentUserLoginId(); + final String userName; + final boolean isAdmin; + final boolean isKeyAdmin; + + if (StringUtils.isEmpty(grantor)) { + userName = bizUtil.getCurrentUserLoginId(); + isAdmin = bizUtil.isAdmin(); + isKeyAdmin = bizUtil.isKeyAdmin(); + } else { + Collection userRoles = userMgrGrantor.getRolesByLoginId(grantor); + + userName = grantor; + isAdmin = userRoles.contains(RangerConstants.ROLE_SYS_ADMIN); + isKeyAdmin = userRoles.contains(RangerConstants.ROLE_KEY_ADMIN); + } boolean isSvcAdmin = isAdmin || svcStore.isServiceAdminUser(policy.getService(), userName); if (!isAdmin && !isKeyAdmin && !isSvcAdmin) { 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 c3e3d6c338..c92c8d3e9e 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 @@ -30,6 +30,7 @@ import org.apache.ranger.biz.ServiceDBStore.JSON_FILE_NAME_TYPE; import org.apache.ranger.biz.ServiceMgr; import org.apache.ranger.biz.TagDBStore; +import org.apache.ranger.biz.UserMgr; import org.apache.ranger.biz.XUserMgr; import org.apache.ranger.common.ContextUtil; import org.apache.ranger.common.MessageEnums; @@ -227,6 +228,8 @@ public class TestServiceREST { RangerPolicyAdmin policyAdmin; @Mock RangerTransactionSynchronizationAdapter rangerTransactionSynchronizationAdapter; + @Mock + UserMgr userMgrGrantor; private String capabilityVector; public void setup() { @@ -2023,7 +2026,7 @@ public void test14bGrantAccess() throws Exception { Mockito.when(svcStore.getServiceByName(Mockito.anyString())).thenReturn(Mockito.mock(RangerService.class)); Mockito.when(daoManager.getXXServiceDef().findServiceDefTypeByServiceName(Mockito.anyString())).thenReturn("hdfs"); Mockito.when(bizUtil.isUserRangerAdmin(Mockito.anyString())).thenReturn(true); - Mockito.when(bizUtil.isAdmin()).thenReturn(true); + Mockito.when(userMgrGrantor.getRolesByLoginId(Mockito.anyString())).thenReturn(Arrays.asList("ROLE_SYS_ADMIN")); RESTResponse restResponse = serviceREST.grantAccess(serviceName, grantRequestObj, request); Mockito.verify(svcStore, Mockito.times(1)).createPolicy(Mockito.any(RangerPolicy.class)); Assertions.assertNotNull(restResponse); @@ -2046,6 +2049,7 @@ public void test64SecureGrantAccess() { mockValidateGrantRevokeRequest(); Mockito.when(bizUtil.isAdmin()).thenReturn(true); Mockito.when(bizUtil.isUserServiceAdmin(Mockito.any(RangerService.class), Mockito.anyString())).thenReturn(true); + Mockito.when(userMgrGrantor.getRolesByLoginId(Mockito.anyString())).thenReturn(Arrays.asList("ROLE_SYS_ADMIN")); RESTResponse restResponse; try { restResponse = serviceREST.secureGrantAccess(serviceName, grantRequestObj, request);