added svcapi ui and camunda code
[it/otf.git] / otf-service-api / src / main / java / org / oran / otf / common / utility / permissions / PermissionUtil.java
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 (file)
index 0000000..e8cdfea
--- /dev/null
@@ -0,0 +1,237 @@
+/*  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 groups that the user is in directly (non-child and non parents)****************\r
+    public static boolean hasPermissionTo (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
+    // 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(hasPermissionTo(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(hasPermissionTo(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(hasPermissionTo(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