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

madhan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/master by this push:
     new 405098b27 RANGER-4218: enable users to be designated as service admins 
via their groups
405098b27 is described below

commit 405098b27c5f2e52b9b5df6c2c307d9376815165
Author: Madhan Neethiraj <[email protected]>
AuthorDate: Fri Apr 28 13:44:03 2023 -0700

    RANGER-4218: enable users to be designated as service admins via their 
groups
---
 .../java/org/apache/ranger/biz/RangerBizUtil.java  | 28 ++++++++-
 .../java/org/apache/ranger/biz/ServiceDBStore.java | 32 ++++++++--
 .../org/apache/ranger/biz/TestServiceDBStore.java  | 71 ++++++++++++++++------
 3 files changed, 108 insertions(+), 23 deletions(-)

diff --git 
a/security-admin/src/main/java/org/apache/ranger/biz/RangerBizUtil.java 
b/security-admin/src/main/java/org/apache/ranger/biz/RangerBizUtil.java
index 155fa357d..7a7cc8137 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/RangerBizUtil.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/RangerBizUtil.java
@@ -1445,7 +1445,13 @@ public class RangerBizUtil {
        }
 
        public boolean isUserServiceAdmin(RangerService rangerService, String 
userName) {
-               return isUserInConfigParameter(rangerService, 
ServiceDBStore.SERVICE_ADMIN_USERS, userName);
+               boolean ret = isUserInConfigParameter(rangerService, 
ServiceDBStore.SERVICE_ADMIN_USERS, userName);
+
+               if (!ret && userMgr != null && userMgr.xUserMgr != null) {
+                       ret = isAnyGroupInConfigParameter(rangerService, 
ServiceDBStore.SERVICE_ADMIN_GROUPS, 
userMgr.xUserMgr.getGroupsForUser(userName));
+               }
+
+               return ret;
        }
 
        public boolean isUserInConfigParameter(RangerService rangerService, 
String configParamName, String userName) {
@@ -1465,6 +1471,26 @@ public class RangerBizUtil {
                return false;
        }
 
+       public boolean isAnyGroupInConfigParameter(RangerService rangerService, 
String configParamName, Set<String> groupNames) {
+               boolean             ret      = false;
+               Map<String, String> map      = rangerService.getConfigs();
+               String              cfgValue = map != null ? 
map.get(configParamName) : null;
+
+               if (StringUtils.isNotBlank(cfgValue) && 
CollectionUtils.isNotEmpty(groupNames)) {
+                       String[] svcCfgGroupNames = cfgValue.split(",");
+
+                       for (String svcCfgGroupName : svcCfgGroupNames) {
+                               if 
(RangerConstants.GROUP_PUBLIC.equals(svcCfgGroupName) || 
groupNames.contains(svcCfgGroupName)) {
+                                       ret = true;
+
+                                       break;
+                               }
+                       }
+               }
+
+               return ret;
+       }
+
         public void blockAuditorRoleUser() {
                 UserSessionBase session = ContextUtil.getCurrentUserSession();
                 if (session != null) {
diff --git 
a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java 
b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
index 60903cc97..04aee289e 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
@@ -237,6 +237,7 @@ public class ServiceDBStore extends AbstractServiceStore {
     private static final String SERVICE_CHECK_USER = "service.check.user";
     private static final String AMBARI_SERVICE_CHECK_USER = 
"ambari.service.check.user";
        public static final String SERVICE_ADMIN_USERS     = 
"service.admin.users";
+       public static final String SERVICE_ADMIN_GROUPS    = 
"service.admin.groups";
 
        private static boolean isRolesDownloadedByService = false;
 
@@ -1845,7 +1846,6 @@ public class ServiceDBStore extends AbstractServiceStore {
                                }
                        }
                }
-
        }
 
        private void validateUserAndProvideTabTagBasedPolicyPermission(String 
username){
@@ -5808,17 +5808,39 @@ public class ServiceDBStore extends 
AbstractServiceStore {
     }
 
     public boolean isServiceAdminUser(String serviceName, String userName) {
-               boolean ret=false;
-               XXServiceConfigMap cfgSvcAdminUsers = 
daoMgr.getXXServiceConfigMap().findByServiceNameAndConfigKey(serviceName, 
SERVICE_ADMIN_USERS);
-               String svcAdminUsers = cfgSvcAdminUsers != null ? 
cfgSvcAdminUsers.getConfigvalue() : null;
+               boolean               ret              = false;
+               XXServiceConfigMapDao svcCfgMapDao     = 
daoMgr.getXXServiceConfigMap();
+               XXServiceConfigMap    cfgSvcAdminUsers = 
svcCfgMapDao.findByServiceNameAndConfigKey(serviceName, SERVICE_ADMIN_USERS);
+               String                svcAdminUsers    = cfgSvcAdminUsers != 
null ? cfgSvcAdminUsers.getConfigvalue() : null;
+
                if (svcAdminUsers != null) {
                        for (String svcAdminUser : svcAdminUsers.split(",")) {
                                if (userName.equals(svcAdminUser)) {
-                                       ret=true;
+                                       ret = true;
                                        break;
                                }
                        }
                }
+
+               if (!ret) {
+                       XXServiceConfigMap cfgSvcAdminGroups = 
svcCfgMapDao.findByServiceNameAndConfigKey(serviceName, SERVICE_ADMIN_GROUPS);
+                       String             svcAdminGroups    = 
cfgSvcAdminGroups != null ? cfgSvcAdminGroups.getConfigvalue() : null;
+
+                       if (StringUtils.isNotBlank(svcAdminGroups)) {
+                               Set<String> userGroups = 
xUserMgr.getGroupsForUser(userName);
+
+                               if (CollectionUtils.isNotEmpty(userGroups)) {
+                                       for (String svcAdminGroup : 
svcAdminGroups.split(",")) {
+                                               if 
(RangerConstants.GROUP_PUBLIC.equals(svcAdminGroup) || 
userGroups.contains(svcAdminGroup)) {
+                                                       ret = true;
+
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+               }
+
                return ret;
        }
 
diff --git 
a/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java 
b/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java
index 691ab52b3..a468ed6f8 100644
--- a/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java
+++ b/security-admin/src/test/java/org/apache/ranger/biz/TestServiceDBStore.java
@@ -22,6 +22,7 @@ import static org.mockito.ArgumentMatchers.anyString;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 
@@ -89,6 +90,9 @@ import org.mockito.junit.MockitoJUnitRunner;
 public class TestServiceDBStore {
        private static Long Id = 8L;
 
+       private static final String CFG_SERVICE_ADMIN_USERS  = 
"service.admin.users";
+       private static final String CFG_SERVICE_ADMIN_GROUPS = 
"service.admin.groups";
+
        @InjectMocks
        ServiceDBStore serviceDBStore = new ServiceDBStore();
 
@@ -241,6 +245,7 @@ public class TestServiceDBStore {
                configs.put("hadoop.rpc.protection", "Privacy");
                configs.put("commonNameForCertificate", "");
                configs.put("service.admin.users", 
"testServiceAdminUser1,testServiceAdminUser2");
+               configs.put("service.admin.groups", 
"testServiceAdminGroup1,testServiceAdminGroup2");
 
                RangerService rangerService = new RangerService();
                rangerService.setId(Id);
@@ -2384,29 +2389,61 @@ public void test47getMetricByTypeDenyconditions() 
throws Exception {
     
serviceDBStore.getMetricByType(ServiceDBStore.METRIC_TYPE.getMetricTypeByName(type));
 }
 
-    @Test
-    public void test48IsServiceAdminUserTrue() throws Exception{
-       String configName = "service.admin.users";
-       boolean result=false;
-       RangerService rService= rangerService();
-       XXServiceConfigMapDao xxServiceConfigMapDao = 
Mockito.mock(XXServiceConfigMapDao.class);
-       XXServiceConfigMap xxServiceConfigMap = new XXServiceConfigMap();
-       xxServiceConfigMap.setConfigkey(configName);
-       
xxServiceConfigMap.setConfigvalue(rService.getConfigs().get(configName));
+       @Test
+       public void test48IsServiceAdminUserTrue() {
+               RangerService         rService              = rangerService();
+               XXServiceConfigMapDao xxServiceConfigMapDao = 
Mockito.mock(XXServiceConfigMapDao.class);
+               XXServiceConfigMap    svcAdminUserCfg       = new 
XXServiceConfigMap() {{ setConfigkey(CFG_SERVICE_ADMIN_USERS); 
setConfigvalue(rService.getConfigs().get(CFG_SERVICE_ADMIN_USERS)); }};
+               XXServiceConfigMap    svcAdminGroupCfg      = new 
XXServiceConfigMap() {{ setConfigkey(CFG_SERVICE_ADMIN_GROUPS); 
setConfigvalue(rService.getConfigs().get(CFG_SERVICE_ADMIN_GROUPS)); }};
 
-       
Mockito.when(daoManager.getXXServiceConfigMap()).thenReturn(xxServiceConfigMapDao);
-       
Mockito.when(xxServiceConfigMapDao.findByServiceNameAndConfigKey(rService.getName(),
 configName)).thenReturn(xxServiceConfigMap);
+               
Mockito.when(daoManager.getXXServiceConfigMap()).thenReturn(xxServiceConfigMapDao);
+               
Mockito.when(xxServiceConfigMapDao.findByServiceNameAndConfigKey(rService.getName(),
 CFG_SERVICE_ADMIN_USERS)).thenReturn(svcAdminUserCfg);
+               
Mockito.when(xxServiceConfigMapDao.findByServiceNameAndConfigKey(rService.getName(),
 CFG_SERVICE_ADMIN_GROUPS)).thenReturn(svcAdminGroupCfg);
 
-       result = 
serviceDBStore.isServiceAdminUser(rService.getName(),"testServiceAdminUser2");
+               boolean result = 
serviceDBStore.isServiceAdminUser(rService.getName(), "testServiceAdminUser1");
 
-       Assert.assertTrue(result);
-       Mockito.verify(daoManager).getXXServiceConfigMap();
-       
Mockito.verify(xxServiceConfigMapDao).findByServiceNameAndConfigKey(rService.getName(),
 configName);
-    }
+               Assert.assertTrue(result);
+               Mockito.verify(daoManager).getXXServiceConfigMap();
+               
Mockito.verify(xxServiceConfigMapDao).findByServiceNameAndConfigKey(rService.getName(),
 CFG_SERVICE_ADMIN_USERS);
+               Mockito.verify(xxServiceConfigMapDao, 
Mockito.never()).findByServiceNameAndConfigKey(rService.getName(), 
CFG_SERVICE_ADMIN_GROUPS);
+               Mockito.clearInvocations(daoManager);
+               Mockito.clearInvocations(xxServiceConfigMapDao);
+
+               result = serviceDBStore.isServiceAdminUser(rService.getName(), 
"testServiceAdminUser2");
+
+               Assert.assertTrue(result);
+               Mockito.verify(daoManager).getXXServiceConfigMap();
+               
Mockito.verify(xxServiceConfigMapDao).findByServiceNameAndConfigKey(rService.getName(),
 CFG_SERVICE_ADMIN_USERS);
+               Mockito.verify(xxServiceConfigMapDao, 
Mockito.never()).findByServiceNameAndConfigKey(rService.getName(), 
CFG_SERVICE_ADMIN_GROUPS);
+               Mockito.clearInvocations(daoManager);
+               Mockito.clearInvocations(xxServiceConfigMapDao);
+
+               
Mockito.when(serviceDBStore.xUserMgr.getGroupsForUser("testUser1")).thenReturn(new
 HashSet<String>() {{ add("testServiceAdminGroup1"); }});
+
+               result = serviceDBStore.isServiceAdminUser(rService.getName(), 
"testUser1");
+
+               Assert.assertTrue(result);
+               Mockito.verify(daoManager).getXXServiceConfigMap();
+               
Mockito.verify(xxServiceConfigMapDao).findByServiceNameAndConfigKey(rService.getName(),
 CFG_SERVICE_ADMIN_USERS);
+               
Mockito.verify(xxServiceConfigMapDao).findByServiceNameAndConfigKey(rService.getName(),
 CFG_SERVICE_ADMIN_GROUPS);
+               Mockito.clearInvocations(daoManager);
+               Mockito.clearInvocations(xxServiceConfigMapDao);
+
+               
Mockito.when(serviceDBStore.xUserMgr.getGroupsForUser("testUser2")).thenReturn(new
 HashSet<String>() {{ add("testServiceAdminGroup2"); }});
+
+               result = serviceDBStore.isServiceAdminUser(rService.getName(), 
"testUser1");
+
+               Assert.assertTrue(result);
+               Mockito.verify(daoManager).getXXServiceConfigMap();
+               
Mockito.verify(xxServiceConfigMapDao).findByServiceNameAndConfigKey(rService.getName(),
 CFG_SERVICE_ADMIN_USERS);
+               
Mockito.verify(xxServiceConfigMapDao).findByServiceNameAndConfigKey(rService.getName(),
 CFG_SERVICE_ADMIN_GROUPS);
+               Mockito.clearInvocations(daoManager);
+               Mockito.clearInvocations(xxServiceConfigMapDao);
+       }
 
     @Test
     public void test49IsServiceAdminUserFalse() throws Exception{
-       String configName = "service.admin.users";
+       String configName = CFG_SERVICE_ADMIN_USERS;
        boolean result=false;
        RangerService rService= rangerService();
        XXServiceConfigMapDao xxServiceConfigMapDao = 
Mockito.mock(XXServiceConfigMapDao.class);

Reply via email to