This is an automated email from the ASF dual-hosted git repository. spolavarapu 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 f279656 RANGER-3403: Incorporated review comments and fixed one regression case where order of roles is not applied properly f279656 is described below commit f279656bd01b9a3502ae243863060e1afa5442ef Author: Sailaja Polavarapu <spolavar...@cloudera.com> AuthorDate: Tue Feb 1 11:35:34 2022 -0800 RANGER-3403: Incorporated review comments and fixed one regression case where order of roles is not applied properly --- .../main/java/org/apache/ranger/biz/XUserMgr.java | 67 ++++++++++-- .../java/org/apache/ranger/db/XXPortalUserDao.java | 14 +++ .../main/resources/META-INF/jpa_named_queries.xml | 5 + .../java/org/apache/ranger/biz/TestXUserMgr.java | 2 + .../model/UsersGroupRoleAssignments.java | 30 ++++++ .../unixusersync/config/UserGroupSyncConfig.java | 16 ++- .../process/PolicyMgrUserGroupBuilder.java | 112 ++++++++++++++++----- 7 files changed, 214 insertions(+), 32 deletions(-) diff --git a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java index 1c2ef52..8109968 100755 --- a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java +++ b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java @@ -2819,8 +2819,17 @@ public class XUserMgr extends XUserMgrBase { @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public List<String> updateUserRoleAssignments(UsersGroupRoleAssignments ugRoleAssignments) { List<String> updatedUsers = new ArrayList<>(); + List<String> requestedUsers = ugRoleAssignments.getUsers(); + Map<String, String> userMap = ugRoleAssignments.getUserRoleAssignments(); + Map<String, String> groupMap = ugRoleAssignments.getGroupRoleAssignments(); + Map<String, String> whiteListUserMap = ugRoleAssignments.getWhiteListUserRoleAssignments(); + Map<String, String> whiteListGroupMap = ugRoleAssignments.getWhiteListGroupRoleAssignments(); + if (logger.isDebugEnabled()) { + logger.debug("Request users for role updates = " + requestedUsers); + } + // For each user get groups and compute roles based on group role assignments - for (String userName : ugRoleAssignments.getUsers()) { + for (String userName : requestedUsers) { VXPortalUser vXPortalUser = userMgr.getUserProfileByLoginId(userName); if (vXPortalUser == null) { logger.info(userName + " doesn't exist and hence ignoring role assignments"); @@ -2830,19 +2839,38 @@ public class XUserMgr extends XUserMgrBase { logger.info(userName + " is internal to ranger admin and hence ignoring role assignments"); continue; } + + if (logger.isDebugEnabled()) { + logger.debug("Computing role for " + userName); + } + + Set groupUsers = getGroupsForUser(userName); + String userRole = RangerConstants.ROLE_USER; - Map<String, String> userMap = ugRoleAssignments.getUserRoleAssignments(); - if (!userMap.isEmpty() && userMap.containsKey(userName)) { + if (MapUtils.isNotEmpty(userMap) && userMap.containsKey(userName)) { // Add the user role that is defined in user role assignments userRole = userMap.get(userName); - } else { - Map<String, String> groupMap = ugRoleAssignments.getGroupRoleAssignments(); - - if (!groupMap.isEmpty()) { - for (String group : getGroupsForUser(userName)) { + } else if (MapUtils.isNotEmpty(groupMap) && CollectionUtils.isNotEmpty(groupUsers)) { + for (String group : groupMap.keySet()) { + if (groupUsers.contains(group)) { String value = groupMap.get(group); if (value != null) { userRole = value; + break; + } + } + } + } + + if (MapUtils.isNotEmpty(whiteListUserMap) && whiteListUserMap.containsKey(userName)) { + userRole = whiteListUserMap.get(userName); + } else if (MapUtils.isNotEmpty(whiteListGroupMap) && CollectionUtils.isNotEmpty(groupUsers)) { + for (String group : whiteListGroupMap.keySet()) { + if (groupUsers.contains(group)) { + String value = whiteListGroupMap.get(group); + if (value != null) { + userRole = value; + break; } } } @@ -2850,12 +2878,35 @@ public class XUserMgr extends XUserMgrBase { if (!vXPortalUser.getUserRoleList().contains(userRole)) { //Update the role of the user only if newly computed role is different from the existing role. + if (logger.isDebugEnabled()) { + logger.debug("Updating role for " + userName + " to " + userRole); + } String updatedUser = setRolesByUserName(userName, Collections.singletonList(userRole)); if (updatedUser != null) { updatedUsers.add(updatedUser); } } } + + // Reset the role of any other users that are not part of the updated role assignments rules + if (ugRoleAssignments.isReset()) { + List<String> exitingNonUserRoleUsers = daoManager.getXXPortalUser().getNonUserRoleExternalUsers(); + if (logger.isDebugEnabled()) { + logger.debug("Existing non user role users = " + exitingNonUserRoleUsers); + } + for (String userName : exitingNonUserRoleUsers) { + if (!requestedUsers.contains(userName)) { + if (logger.isDebugEnabled()) { + logger.debug("Resetting to User role for " + userName); + } + String updatedUser = setRolesByUserName(userName, Collections.singletonList(RangerConstants.ROLE_USER)); + if (updatedUser != null) { + updatedUsers.add(updatedUser); + } + } + } + } + return updatedUsers; } diff --git a/security-admin/src/main/java/org/apache/ranger/db/XXPortalUserDao.java b/security-admin/src/main/java/org/apache/ranger/db/XXPortalUserDao.java index d383cf5..b4fdf02 100644 --- a/security-admin/src/main/java/org/apache/ranger/db/XXPortalUserDao.java +++ b/security-admin/src/main/java/org/apache/ranger/db/XXPortalUserDao.java @@ -23,6 +23,8 @@ import java.util.List; import javax.persistence.NoResultException; +import org.apache.ranger.common.RangerCommonEnums; +import org.apache.ranger.common.RangerConstants; import org.apache.ranger.common.db.BaseDao; import org.apache.ranger.entity.XXPortalUser; import org.springframework.stereotype.Service; @@ -103,4 +105,16 @@ public class XXPortalUserDao extends BaseDao<XXPortalUser> { } } + + @SuppressWarnings("unchecked") + public List<String> getNonUserRoleExternalUsers() { + try { + return getEntityManager().createNamedQuery("XXPortalUser.getNonUserRoleExternalUsers", String.class) + .setParameter("userRole", RangerConstants.ROLE_USER) + .setParameter("userSource", RangerCommonEnums.USER_EXTERNAL) + .getResultList(); + } catch (Exception e) { + return null; + } + } } diff --git a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml index d25fdc0..b56cd26 100755 --- a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml +++ b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml @@ -43,6 +43,11 @@ and role.userRole = :userRole</query> </named-query> + <named-query name="XXPortalUser.getNonUserRoleExternalUsers"> + <query>SELECT obj.loginId FROM XXPortalUser obj, XXPortalUserRole role WHERE obj.id = role.userId + and role.userRole != :userRole and obj.userSource = :userSource </query> + </named-query> + <named-query name="XXPortalUser.getUserAddedReport"> <query>SELECT count(obj), function('DATE',obj.createTime) as createDate FROM XXPortalUser obj GROUP BY createDate </query> diff --git a/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java b/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java index eb2d6b3..5273ad8 100644 --- a/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java +++ b/security-admin/src/test/java/org/apache/ranger/biz/TestXUserMgr.java @@ -4019,6 +4019,8 @@ public class TestXUserMgr { ugRoleAssignments.setUsers(allUsers); ugRoleAssignments.setGroupRoleAssignments(groupMap); ugRoleAssignments.setUserRoleAssignments(userMap); + ugRoleAssignments.setWhiteListUserRoleAssignments(new HashMap<>()); + ugRoleAssignments.setWhiteListGroupRoleAssignments(new HashMap<>()); VXUser vXUser = vxUser(); List<VXUser> vXUserList=new ArrayList<VXUser>(); vXUserList.add(vXUser); diff --git a/ugsync-util/src/main/java/org/apache/ranger/ugsyncutil/model/UsersGroupRoleAssignments.java b/ugsync-util/src/main/java/org/apache/ranger/ugsyncutil/model/UsersGroupRoleAssignments.java index ce0b9dd..a3e6c3e 100644 --- a/ugsync-util/src/main/java/org/apache/ranger/ugsyncutil/model/UsersGroupRoleAssignments.java +++ b/ugsync-util/src/main/java/org/apache/ranger/ugsyncutil/model/UsersGroupRoleAssignments.java @@ -41,6 +41,12 @@ public class UsersGroupRoleAssignments { Map<String, String> userRoleAssignments; + Map<String, String> whiteListGroupRoleAssignments; + + Map<String, String> whiteListUserRoleAssignments; + + boolean isReset = false; + public List<String> getUsers() { return users; } @@ -64,4 +70,28 @@ public class UsersGroupRoleAssignments { public void setUserRoleAssignments(Map<String, String> userRoleAssignments) { this.userRoleAssignments = userRoleAssignments; } + + public Map<String, String> getWhiteListGroupRoleAssignments() { + return whiteListGroupRoleAssignments; + } + + public void setWhiteListGroupRoleAssignments(Map<String, String> whiteListGroupRoleAssignments) { + this.whiteListGroupRoleAssignments = whiteListGroupRoleAssignments; + } + + public Map<String, String> getWhiteListUserRoleAssignments() { + return whiteListUserRoleAssignments; + } + + public void setWhiteListUserRoleAssignments(Map<String, String> whiteListUserRoleAssignments) { + this.whiteListUserRoleAssignments = whiteListUserRoleAssignments; + } + + public boolean isReset() { + return isReset; + } + + public void setReset(boolean reset) { + isReset = reset; + } } \ No newline at end of file diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java index 47beecf..5f30165 100644 --- a/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java +++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/config/UserGroupSyncConfig.java @@ -261,6 +261,9 @@ public class UserGroupSyncConfig { private static final String GROUP_BASED_ROLE_ASSIGNMENT_RULES = "ranger.usersync.group.based.role.assignment.rules"; + private static final String WHITELIST_USER_ROLE_ASSIGNMENT_RULES = "ranger.usersync.whitelist.users.role.assignment.rules"; + private static final String DEFAULT_WHITELIST_USER_ROLE_ASSIGNMENT_RULES = "&ROLE_SYS_ADMIN:u:admin,rangerusersync,rangertagsync&ROLE_KEY_ADMIN:u:keyadmin"; + private static final String USERSYNC_RANGER_COOKIE_ENABLED_PROP = "ranger.usersync.cookie.enabled"; private static final String RANGER_ADMIN_COOKIE_NAME_PROPS = "ranger.usersync.dest.ranger.session.cookie.name"; @@ -1034,13 +1037,24 @@ public class UserGroupSyncConfig { if (prop != null && prop.containsKey(GROUP_BASED_ROLE_ASSIGNMENT_RULES)) { String GroupRoleRules = prop .getProperty(GROUP_BASED_ROLE_ASSIGNMENT_RULES); - if (GroupRoleRules != null && !GroupRoleRules.isEmpty()) { + if (StringUtils.isNotBlank(GroupRoleRules)) { return GroupRoleRules.trim(); } } return null; } + public String getWhileListUserRoleRules() { + if (prop != null && prop.containsKey(WHITELIST_USER_ROLE_ASSIGNMENT_RULES)) { + String whiteListUserRoleRules = prop + .getProperty(WHITELIST_USER_ROLE_ASSIGNMENT_RULES); + if (StringUtils.isNotBlank(whiteListUserRoleRules) ) { + return whiteListUserRoleRules.trim(); + } + } + return DEFAULT_WHITELIST_USER_ROLE_ASSIGNMENT_RULES; + } + public String getUserGroupDelimiter() { if (prop != null && prop.containsKey(USERS_GROUPS_ASSIGNMENT_LIST_DELIMITER)) { diff --git a/ugsync/src/main/java/org/apache/ranger/unixusersync/process/PolicyMgrUserGroupBuilder.java b/ugsync/src/main/java/org/apache/ranger/unixusersync/process/PolicyMgrUserGroupBuilder.java index 693d908..654b832 100644 --- a/ugsync/src/main/java/org/apache/ranger/unixusersync/process/PolicyMgrUserGroupBuilder.java +++ b/ugsync/src/main/java/org/apache/ranger/unixusersync/process/PolicyMgrUserGroupBuilder.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.lang.reflect.Type; import java.net.UnknownHostException; import java.security.PrivilegedAction; +import java.util.Collections; import java.util.Map; import java.util.Set; import java.util.List; @@ -85,7 +86,6 @@ public class PolicyMgrUserGroupBuilder extends AbstractUserGroupSource implement private static final String PM_UPDATE_DELETED_GROUPS_URI = "/service/xusers/ugsync/groups/visibility"; // POST private static final String PM_UPDATE_DELETED_USERS_URI = "/service/xusers/ugsync/users/visibility"; // POST - private static final Pattern USER_OR_GROUP_NAME_VALIDATION_REGEX = Pattern.compile("^([A-Za-z0-9_]|[\u00C0-\u017F])([a-zA-Z0-9\\s,._\\-+/@= ]|[\u00C0-\u017F])+$", Pattern.CASE_INSENSITIVE); @@ -143,6 +143,8 @@ public class PolicyMgrUserGroupBuilder extends AbstractUserGroupSource implement String nameRules; Map<String, String> userMap = new LinkedHashMap<String, String>(); Map<String, String> groupMap = new LinkedHashMap<>(); + Map<String, String> whiteListUserMap = new LinkedHashMap<>(); + Map<String, String> whiteListGroupMap = new LinkedHashMap<>(); private boolean isRangerCookieEnabled; private String rangerCookieName; @@ -225,8 +227,22 @@ public class PolicyMgrUserGroupBuilder extends AbstractUserGroupSource implement String userGroupRoles = config.getGroupRoleRules(); if (userGroupRoles != null && !userGroupRoles.isEmpty()) { - getRoleForUserGroups(userGroupRoles); + getRoleForUserGroups(userGroupRoles, userMap, groupMap); + } + String whiteListUserRoles = config.getWhileListUserRoleRules(); + if (whiteListUserRoles != null && !whiteListUserRoles.isEmpty()) { + getRoleForUserGroups(whiteListUserRoles, whiteListUserMap, whiteListGroupMap); + } + String policyMgrUserRole = whiteListUserMap.get(policyMgrUserName); + if (!StringUtils.equalsIgnoreCase(policyMgrUserRole, "ROLE_SYS_ADMIN")) { + whiteListUserMap.put(policyMgrUserName, "ROLE_SYS_ADMIN"); } + + if (LOG.isDebugEnabled()) { + LOG.debug("Entries in group role assignments: " + groupMap); + LOG.debug("Entries in whitelist group role assignments: " + whiteListGroupMap); + } + buildUserGroupInfo(); if (LOG.isDebugEnabled()) { @@ -318,6 +334,29 @@ public class PolicyMgrUserGroupBuilder extends AbstractUserGroupSource implement if (isStartupFlag) { // This is to handle any config changes for role assignments that might impact existing users in ranger db + if (MapUtils.isNotEmpty(whiteListUserMap)) { + if (LOG.isDebugEnabled()) { + LOG.debug("adding " + whiteListUserMap.keySet() + " for computing roles during startup"); + } + computeRolesForUsers.addAll(whiteListUserMap.keySet()); // Add all the user defined in the whitelist role assignment rules + } + if (MapUtils.isNotEmpty(whiteListGroupMap)) { + for (String groupName : whiteListGroupMap.keySet()) { + Set<String> groupUsers = null; + if (CollectionUtils.isNotEmpty(groupUsersCache.get(groupName))) { + groupUsers = new HashSet<>(groupUsersCache.get(groupName)); + } else if (CollectionUtils.isNotEmpty(deltaGroupUsers.get(groupName))) { + groupUsers = new HashSet<>(deltaGroupUsers.get(groupName)); + } + if (groupUsers != null) { + if (LOG.isDebugEnabled()) { + LOG.debug("adding " + groupUsers + " from " + groupName + " for computing roles during startup"); + } + computeRolesForUsers.addAll(groupUsers); + } + } + } + if (MapUtils.isNotEmpty(userMap)) { if (LOG.isDebugEnabled()) { LOG.debug("adding " + userMap.keySet() + " for computing roles during startup"); @@ -580,18 +619,19 @@ public class PolicyMgrUserGroupBuilder extends AbstractUserGroupSource implement } private void updateUserRoles() throws Throwable { - if (MapUtils.isNotEmpty(groupMap) || MapUtils.isNotEmpty(userMap)) { - UsersGroupRoleAssignments ugRoleAssignments = new UsersGroupRoleAssignments(); - List<String> allUsers = new ArrayList<>(computeRolesForUsers); - - ugRoleAssignments.setUsers(allUsers); - ugRoleAssignments.setGroupRoleAssignments(groupMap); - ugRoleAssignments.setUserRoleAssignments(userMap); - if (updateRoles(ugRoleAssignments) == null) { - String msg = "Unable to update roles for " + allUsers; - LOG.error(msg); - throw new Exception(msg); - } + UsersGroupRoleAssignments ugRoleAssignments = new UsersGroupRoleAssignments(); + List<String> allUsers = new ArrayList<>(computeRolesForUsers); + + ugRoleAssignments.setUsers(allUsers); + ugRoleAssignments.setGroupRoleAssignments(groupMap); + ugRoleAssignments.setUserRoleAssignments(userMap); + ugRoleAssignments.setWhiteListUserRoleAssignments(whiteListUserMap); + ugRoleAssignments.setWhiteListGroupRoleAssignments(whiteListGroupMap); + ugRoleAssignments.setReset(isStartupFlag); + if (updateRoles(ugRoleAssignments) == null) { + String msg = "Unable to update roles for " + allUsers; + LOG.error(msg); + throw new Exception(msg); } } @@ -641,7 +681,8 @@ public class PolicyMgrUserGroupBuilder extends AbstractUserGroupSource implement continue; } - if (StringUtils.isEmpty(oldSyncSource) || (!StringUtils.equalsIgnoreCase(oldGroupAttrsStr, newGroupAttrsStr) && StringUtils.equalsIgnoreCase(oldSyncSource, newSyncSource))) { // update + if (StringUtils.isEmpty(oldSyncSource) || (!StringUtils.equalsIgnoreCase(oldGroupAttrsStr, newGroupAttrsStr) + && StringUtils.equalsIgnoreCase(oldSyncSource, newSyncSource))) { // update if (LOG.isDebugEnabled()) { if (StringUtils.isEmpty(oldSyncSource)) { LOG.debug("Sync Source has changed to " + newSyncSource); @@ -656,8 +697,13 @@ public class PolicyMgrUserGroupBuilder extends AbstractUserGroupSource implement deltaGroups.put(groupName, oldGroup); noOfModifiedGroups++; groupNameMap.put(groupDN, groupName); + } else if (LOG.isDebugEnabled()) { - LOG.debug("Skipping update for " + groupName + " as same group with different sync source already exists"); + if (!StringUtils.equalsIgnoreCase(oldSyncSource, newSyncSource)) { + LOG.debug("Skipping update for " + groupName + " as same group with different sync source already exists"); + } else { + LOG.debug("Skipping update for " + groupName + " as there is no change"); + } } if (StringUtils.equalsIgnoreCase(oldGroupAttrsStr, newGroupAttrsStr)) { @@ -724,7 +770,8 @@ public class PolicyMgrUserGroupBuilder extends AbstractUserGroupSource implement continue; } - if (StringUtils.isEmpty(oldSyncSource) || (!StringUtils.equalsIgnoreCase(oldUserAttrsStr, newUserAttrsStr) && StringUtils.equalsIgnoreCase(oldSyncSource, newSyncSource))) { // update + if (StringUtils.isEmpty(oldSyncSource) || (!StringUtils.equalsIgnoreCase(oldUserAttrsStr, newUserAttrsStr) + && StringUtils.equalsIgnoreCase(oldSyncSource, newSyncSource))) { // update if (LOG.isDebugEnabled()) { if (StringUtils.isEmpty(oldSyncSource)) { LOG.debug("Sync Source has changed to " + newSyncSource); @@ -741,7 +788,11 @@ public class PolicyMgrUserGroupBuilder extends AbstractUserGroupSource implement noOfModifiedUsers++; userNameMap.put(userDN, userName); } else if (LOG.isDebugEnabled()) { - LOG.debug("Skipping to update " + userName + " as same username with different sync source already exists"); + if (!StringUtils.equalsIgnoreCase(oldSyncSource, newSyncSource)) { + LOG.debug("Skipping to update " + userName + " as same username with different sync source already exists"); + } else { + LOG.debug("Skipping to update " + userName + " as there is no change"); + } } if (StringUtils.equalsIgnoreCase(oldUserAttrsStr, newUserAttrsStr)) { @@ -799,14 +850,14 @@ public class PolicyMgrUserGroupBuilder extends AbstractUserGroupSource implement groupUserInfo.setGroupName(groupName); if (CollectionUtils.isNotEmpty(addUsers)) { groupUserInfo.setAddUsers(addUsers); - if (groupMap.containsKey(groupName)) { + if (groupMap.containsKey(groupName) || whiteListGroupMap.containsKey(groupName)) { // Add users to the computeRole list only if there is a rule defined for the group. computeRolesForUsers.addAll(addUsers); } } if (CollectionUtils.isNotEmpty(delUsers)) { groupUserInfo.setDelUsers(delUsers); - if (groupMap.containsKey(groupName)) { + if (groupMap.containsKey(groupName)|| whiteListGroupMap.containsKey(groupName)) { // Add users to the computeRole list only if there is a rule defined for the group. computeRolesForUsers.addAll(delUsers); } @@ -1206,6 +1257,9 @@ public class PolicyMgrUserGroupBuilder extends AbstractUserGroupSource implement pagedUgRoleAssignmentsListLen > totalCount ? totalCount : pagedUgRoleAssignmentsListLen)); pagedUgRoleAssignmentsList.setGroupRoleAssignments(ugRoleAssignments.getGroupRoleAssignments()); pagedUgRoleAssignmentsList.setUserRoleAssignments(ugRoleAssignments.getUserRoleAssignments()); + pagedUgRoleAssignmentsList.setWhiteListGroupRoleAssignments(ugRoleAssignments.getWhiteListGroupRoleAssignments()); + pagedUgRoleAssignmentsList.setWhiteListUserRoleAssignments(ugRoleAssignments.getWhiteListUserRoleAssignments()); + pagedUgRoleAssignmentsList.setReset(ugRoleAssignments.isReset()); String response = null; ClientResponse clientRes = null; Gson gson = new GsonBuilder().create(); @@ -1549,7 +1603,11 @@ public class PolicyMgrUserGroupBuilder extends AbstractUserGroupSource implement return response; } - private void getRoleForUserGroups(String userGroupRolesData) { + private void getRoleForUserGroups(String userGroupRolesData, Map<String, String> userMap, Map<String, String> groupMap) { + if (LOG.isDebugEnabled()) { + LOG.debug("==>> getRoleForUserGroups(" + userGroupRolesData + ")"); + } + Map<String, String> reverseGroupMap = new LinkedHashMap<>(); String roleDelimiter = config.getRoleDelimiter(); String userGroupDelimiter = config.getUserGroupDelimiter(); String userNameDelimiter = config.getUserGroupNameDelimiter(); @@ -1599,7 +1657,7 @@ public class PolicyMgrUserGroupBuilder extends AbstractUserGroupSource implement if (userGroupCheck.trim().equalsIgnoreCase("u")) { userMap.put(userGroup.trim(), roleName.trim()); } else if (userGroupCheck.trim().equalsIgnoreCase("g")) { - groupMap.put(userGroup.trim(), + reverseGroupMap.put(userGroup.trim(), roleName.trim()); } } @@ -1608,7 +1666,7 @@ public class PolicyMgrUserGroupBuilder extends AbstractUserGroupSource implement break; default: userMap.clear(); - groupMap.clear(); + reverseGroupMap.clear(); break; } } @@ -1616,6 +1674,14 @@ public class PolicyMgrUserGroupBuilder extends AbstractUserGroupSource implement } } } + // Reversing the order of group keys so that the last role specified in the configuration rules is applied when a user belongs to multiple groups with different roles + if (MapUtils.isNotEmpty(reverseGroupMap)) { + List<String> groupNames = new ArrayList<>(reverseGroupMap.keySet()); + Collections.reverse(groupNames); + for (String group : groupNames) { + groupMap.put(group, reverseGroupMap.get(group)); + } + } } protected String userNameTransform(String userName) {