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