X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?p=it%2Fotf.git;a=blobdiff_plain;f=otf-service-api%2Fsrc%2Fmain%2Fjava%2Forg%2Foran%2Fotf%2Fcommon%2Futility%2Fpermissions%2FPermissionUtil.java;fp=otf-service-api%2Fsrc%2Fmain%2Fjava%2Forg%2Foran%2Fotf%2Fcommon%2Futility%2Fpermissions%2FPermissionUtil.java;h=e8cdfea766da21a8e43ef0e63cf1e0f641df762f;hp=0000000000000000000000000000000000000000;hb=14f6f95c84a4a1fa8774190db4a03fd0214ec55f;hpb=f49bd1efeaaddd4891c1f329b18d8cfb28b3e75b diff --git a/otf-service-api/src/main/java/org/oran/otf/common/utility/permissions/PermissionUtil.java b/otf-service-api/src/main/java/org/oran/otf/common/utility/permissions/PermissionUtil.java new file mode 100644 index 0000000..e8cdfea --- /dev/null +++ b/otf-service-api/src/main/java/org/oran/otf/common/utility/permissions/PermissionUtil.java @@ -0,0 +1,237 @@ +/* Copyright (c) 2019 AT&T Intellectual Property. # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +##############################################################################*/ + + +package org.oran.otf.common.utility.permissions; + +import org.oran.otf.common.model.Group; +import org.oran.otf.common.model.GroupMember; +import org.oran.otf.common.model.Role; +import org.oran.otf.common.model.User; +import org.oran.otf.common.repository.GroupRepository; + +import java.util.*; + +public class PermissionUtil { + //build userPermission object which contains all access control information of the user + public UserPermission buildUserPermission(User user, GroupRepository groupRepository) { + UserPermission userPermission = new UserPermission(); + userPermission.setUser(user); + Map> userAccessMap; // map from group to permission that user have in that group + + userAccessMap = mapGroupsToPermission(user,groupRepository); + userPermission.setUserAccessMap(userAccessMap); + return userPermission; + } + // return if user have specified permission in a certain group + // ***********only use this groups that the user is in directly (non-child and non parents)**************** + public static boolean hasPermissionTo (String permission,User user, Group group) { + Set possiblePermissions= getUserGroupPermissions(user,group); + return possiblePermissions.stream().anyMatch(p-> p.equalsIgnoreCase(permission)); // + } + // Get all the permissions the user have in a certain group + public static Set getUserGroupPermissions(User user, Group group){ + Set permissionsAllowed = new HashSet<>(); + Set usersAssignedRoles = findUserRoles(user,group); + if(usersAssignedRoles.isEmpty()) // empty set permissions because the user have no roles in the group aka not a member + return permissionsAllowed; + //get every single permissions for each role that the user have. + for(String role : usersAssignedRoles){ + permissionsAllowed.addAll(getRolePermissions(role,group)); + } + return permissionsAllowed; + } + //get the permissions associated with the userRoleName in group + public static Set getRolePermissions(String userRoleName,Group group) + { + for(Role role : group.getRoles()) + { + if(role.getRoleName().equalsIgnoreCase(userRoleName)) + { + return new HashSet(role.getPermissions()); + } + } + return new HashSet(); // empty string set if the role name cant be found in the group + } + // find the user's role in the specified group + public static Set findUserRoles(User user,Group group){ + for(GroupMember member : group.getMembers()) + { + // if userId matches then get all the user's role in the group + if(member.getUserId().toString().equals(user.get_id().toString())) + return new HashSet(member.getRoles()); + } + return new HashSet(); //if user have no roles + } + // create map that where key is the group id and value = users permission (string) that that group + private Map> mapGroupsToPermission(User user, GroupRepository groupRepository){ + Map> groupAccessMap = new HashMap<>(); + List enrolledGroups = groupRepository.findAllByMembersId(user.get_id());// enrolledGroups = groups that user is a member of + Map allGroupMap = groupListToMap(groupRepository.findAll()); + // get all permission in the groups the user is ia member of + for(Group group: enrolledGroups) { + Set permissions = getUserGroupPermissions(user,group); + groupAccessMap.put(group.get_id().toString(),convertPermissions(permissions)); + } + //assign add read to all parent groups + Set parentGroupsId = getParentGroups(enrolledGroups,allGroupMap); + for(String parentId : parentGroupsId) + { + // if parent access role already exist in + // group access map cause they are a member + if(groupAccessMap.get(parentId)!= null) + groupAccessMap.get(parentId).add(UserPermission.Permission.READ); + else + groupAccessMap.put(parentId,new HashSet(Arrays.asList(UserPermission.Permission.READ))); + } + // if there is management role + // then assign read access to children + if(hasManagementRole(user,enrolledGroups)){ +// SetchildIds = getChildrenGroupsId(enrolledGroups,allGroupMap,user); + for(Group enrolledGroup : enrolledGroups) { + // if enrolled groups is a management group + if(hasPermissionTo(UserPermission.Permission.MANAGEMENT,user,enrolledGroup)){ + // if there is management role then get all the child of that group, do this for all management groups + Set childIds= getChildrenGroupsId(Arrays.asList(enrolledGroup),allGroupMap,user); + Set userGroupPermissions = convertPermissions(getUserGroupPermissions(user,enrolledGroup)); + for(String childId : childIds){ + if (groupAccessMap.get(childId) != null) + groupAccessMap.get(childId).addAll(userGroupPermissions); + else{ + groupAccessMap.put(childId,userGroupPermissions); + } + } + } + } + } + return groupAccessMap; + } + // check is user have managementRole + private boolean hasManagementRole(User user, List enrolledGroups) + { + for(Group group: enrolledGroups){ + if(hasPermissionTo(UserPermission.Permission.MANAGEMENT,user,group)) + { + return true; + } + } + return false; + } + // get the parent groups starting from the enrolled group of the user + private Set getParentGroups(List enrolledGroup,Map groupMap ) + { + Set parentGroups = new HashSet<>(); + return lookUp(enrolledGroup,groupMap,parentGroups); + } + //recursive lookup starting at the enrolled groups that the user is a member of + private Set lookUp(List groupsToCheck, Map groupMap,Set resultSet) + { + //base case: nothing to check anymore + if(groupsToCheck.isEmpty()) + return resultSet; + //This is the parents directly above the current groups that are being checked + List currentParentGroups = new ArrayList<>(); + + for(Group group : groupsToCheck) + { + if(group.getParentGroupId() != null) // if there is a parent + { + String parentId = group.getParentGroupId().toString(); + Group parentGroup = groupMap.get(parentId); + resultSet.add(parentId); + currentParentGroups.add(parentGroup); // add to currentParentGroup so it can be used recursively check for more parents + } + } + return lookUp(currentParentGroups,groupMap,resultSet); + } + // convert a list of groups to a map of group ids to group + private Map groupListToMap(List allGroups) + { + Map groupMap = new HashMap<>(); + allGroups.forEach(group -> groupMap.put(group.get_id().toString(),group)); + return groupMap; + } + //get all the child group + private Set getChildrenGroupsId(List enrolledGroup, Map allGroupsMap, User user) + { + Set childrenGroups = new HashSet<>(); + Set managementGroupIds = getManagementGroupIds(enrolledGroup,user); + return lookForChildren(managementGroupIds,allGroupsMap,childrenGroups); + } + + private Set getManagementGroupIds(List enrolledGroups,User user) + { + Set parentIds = new HashSet<>(); + for(Group group: enrolledGroups) + { + if(hasPermissionTo(UserPermission.Permission.MANAGEMENT,user,group)) // has Management permission + { + parentIds.add(group.get_id().toString()); + } + } + return parentIds; + } + //recursive look down for childrens via breath first search + private Set lookForChildren (Set parentIds, Map allGroupsMap, Set resultSet) + { + //base case = no groups to check anymore; + if (parentIds.isEmpty()) + return resultSet; + + Set currentChildrenIds = new HashSet<>(); + for(String groupId : allGroupsMap.keySet()) + { + Group possibleChildGroup = allGroupsMap.get(groupId); + if(isChildOf(parentIds,possibleChildGroup)) // if parent id is the same + { + currentChildrenIds.add(groupId); + resultSet.add(groupId); + } + } + return lookForChildren(currentChildrenIds,allGroupsMap,resultSet); + } + //check if a group is a child of a list of parent group ids + private boolean isChildOf(SetparentGroupIds, Group childGroup){ + for(String parentId: parentGroupIds) + { + if(isChildOf(parentId,childGroup)) + return true; + } + return false; + } + //check is group has parent that is specified by parentId + private boolean isChildOf(String parentId,Group childGroup) { + if(childGroup.getParentGroupId() == null) + return false; + return childGroup.getParentGroupId().toString().equals(parentId); + } + + private Set convertPermissions (Set permissions){ + Set result = new HashSet<>(); + for (String permission: permissions){ + if(permission.equalsIgnoreCase(UserPermission.Permission.READ)) + result.add(UserPermission.Permission.READ); + else if (permission.equalsIgnoreCase(UserPermission.Permission.WRITE)) + result.add(UserPermission.Permission.WRITE); + else if (permission.equalsIgnoreCase(UserPermission.Permission.DELETE)) + result.add(UserPermission.Permission.DELETE); + else if (permission.equalsIgnoreCase(UserPermission.Permission.EXECUTE)) + result.add(UserPermission.Permission.EXECUTE); + else if (permission.equalsIgnoreCase(UserPermission.Permission.MANAGEMENT)) + result.add(UserPermission.Permission.MANAGEMENT); + } + return result; + } +}