added svcapi ui and camunda code
[it/otf.git] / otf-camunda / src / main / java / org / oran / otf / common / utility / permissions / PermissionUtil.java
1 /*  Copyright (c) 2019 AT&T Intellectual Property.                             #\r
2 #                                                                              #\r
3 #   Licensed under the Apache License, Version 2.0 (the "License");            #\r
4 #   you may not use this file except in compliance with the License.           #\r
5 #   You may obtain a copy of the License at                                    #\r
6 #                                                                              #\r
7 #       http://www.apache.org/licenses/LICENSE-2.0                             #\r
8 #                                                                              #\r
9 #   Unless required by applicable law or agreed to in writing, software        #\r
10 #   distributed under the License is distributed on an "AS IS" BASIS,          #\r
11 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #\r
12 #   See the License for the specific language governing permissions and        #\r
13 #   limitations under the License.                                             #\r
14 ##############################################################################*/\r
15 \r
16 \r
17 package org.oran.otf.common.utility.permissions;\r
18 \r
19 import org.oran.otf.common.model.Group;\r
20 import org.oran.otf.common.model.GroupMember;\r
21 import org.oran.otf.common.model.Role;\r
22 import org.oran.otf.common.model.User;\r
23 import org.oran.otf.common.repository.GroupRepository;\r
24 \r
25 import java.util.*;\r
26 \r
27 public class PermissionUtil {\r
28     //build userPermission object which contains all access control information of the user\r
29     public UserPermission buildUserPermission(User user, GroupRepository groupRepository) {\r
30         UserPermission userPermission = new UserPermission();\r
31         userPermission.setUser(user);\r
32         Map<String,Set<String>> userAccessMap; // map from group to permission that user have in that group\r
33 \r
34         userAccessMap = mapGroupsToPermission(user,groupRepository);\r
35         userPermission.setUserAccessMap(userAccessMap);\r
36         return userPermission;\r
37     }\r
38     // return if user have specified permission in a certain group\r
39     // ***********only use this on groups that the user is in directly (non-child and non parents)****************\r
40     public static boolean hasDirectPermissionTo(String permission, User user, Group group) {\r
41         Set<String> possiblePermissions= getUserGroupPermissions(user,group);\r
42         return possiblePermissions.stream().anyMatch(p-> p.equalsIgnoreCase(permission)); //\r
43     }\r
44     // Get all the permissions the user have in a certain group\r
45     public static Set<String> getUserGroupPermissions(User user, Group group){\r
46         Set<String> permissionsAllowed = new HashSet<>();\r
47         Set<String> usersAssignedRoles = findUserRoles(user,group);\r
48         if(usersAssignedRoles.isEmpty()) // empty set permissions because the user have no roles in the group aka not a member\r
49             return permissionsAllowed;\r
50         //get every single permissions for each role that the user have.\r
51         for(String role : usersAssignedRoles){\r
52              permissionsAllowed.addAll(getRolePermissions(role,group));\r
53         }\r
54         return permissionsAllowed;\r
55     }\r
56     //get the permissions associated with the userRoleName in group\r
57     public static Set<String> getRolePermissions(String userRoleName, Group group)\r
58     {\r
59         for(Role role : group.getRoles())\r
60         {\r
61             if(role.getRoleName().equalsIgnoreCase(userRoleName))\r
62             {\r
63                 return new HashSet<String>(role.getPermissions());\r
64             }\r
65         }\r
66         return new HashSet<String>(); // empty string set if the role name cant be found in the group\r
67     }\r
68     // find the user's role in the specified group\r
69     public static Set<String> findUserRoles(User user, Group group){\r
70         for(GroupMember member : group.getMembers())\r
71         {\r
72             // if userId matches then get all the user's role in the group\r
73             if(member.getUserId().toString().equals(user.get_id().toString()))\r
74                 return new HashSet<String>(member.getRoles());\r
75         }\r
76         return new HashSet<String>(); //if user have no roles\r
77     }\r
78 \r
79     // create map that where key is the group id and value = users permission (string) that that group\r
80     private Map<String,Set<String>> mapGroupsToPermission(User user, GroupRepository groupRepository){\r
81         Map<String,Set<String>> groupAccessMap = new HashMap<>();\r
82         List<Group> enrolledGroups = groupRepository.findAllByMembersId(user.get_id());// enrolledGroups = groups that user is a member of\r
83         Map<String, Group> allGroupMap = groupListToMap(groupRepository.findAll());\r
84         // get all permission in the groups the user is ia member of\r
85         for(Group group: enrolledGroups) {\r
86             Set<String> permissions = getUserGroupPermissions(user,group);\r
87             groupAccessMap.put(group.get_id().toString(),convertPermissions(permissions));\r
88         }\r
89         //assign add read to all parent groups\r
90         Set<String> parentGroupsId = getParentGroups(enrolledGroups,allGroupMap);\r
91         for(String parentId : parentGroupsId)\r
92         {\r
93             // if parent access role already exist in\r
94             // group access map cause they are a member\r
95             if(groupAccessMap.get(parentId)!= null)\r
96                 groupAccessMap.get(parentId).add(UserPermission.Permission.READ);\r
97             else\r
98                 groupAccessMap.put(parentId,new HashSet<String>(Arrays.asList(UserPermission.Permission.READ)));\r
99         }\r
100         // if there is management role\r
101         // then assign read access to children\r
102         if(hasManagementRole(user,enrolledGroups)){\r
103 //            Set<String>childIds = getChildrenGroupsId(enrolledGroups,allGroupMap,user);\r
104             for(Group enrolledGroup : enrolledGroups) {\r
105                 // if enrolled groups is a management group\r
106                 if(hasDirectPermissionTo(UserPermission.Permission.MANAGEMENT,user,enrolledGroup)){\r
107                     // if there is management role then get all the child of that group, do this for all management groups\r
108                     Set<String> childIds= getChildrenGroupsId(Arrays.asList(enrolledGroup),allGroupMap,user);\r
109                     Set<String> userGroupPermissions = convertPermissions(getUserGroupPermissions(user,enrolledGroup));\r
110                     for(String childId : childIds){\r
111                         if (groupAccessMap.get(childId) != null)\r
112                             groupAccessMap.get(childId).addAll(userGroupPermissions);\r
113                         else{\r
114                             groupAccessMap.put(childId,userGroupPermissions);\r
115                         }\r
116                     }\r
117                 }\r
118             }\r
119         }\r
120         return groupAccessMap;\r
121     }\r
122     // check is user have managementRole\r
123     private boolean hasManagementRole(User user, List<Group> enrolledGroups)\r
124     {\r
125         for(Group group: enrolledGroups){\r
126             if(hasDirectPermissionTo(UserPermission.Permission.MANAGEMENT,user,group))\r
127             {\r
128                 return true;\r
129             }\r
130         }\r
131         return false;\r
132     }\r
133     // get the parent groups starting from the enrolled group of the user\r
134     private Set<String> getParentGroups(List<Group> enrolledGroup, Map<String, Group> groupMap )\r
135     {\r
136         Set<String> parentGroups = new HashSet<>();\r
137         return lookUp(enrolledGroup,groupMap,parentGroups);\r
138     }\r
139     //recursive lookup starting at the enrolled groups that the user is a member of\r
140     private Set<String> lookUp(List<Group> groupsToCheck, Map<String, Group> groupMap, Set<String> resultSet)\r
141     {\r
142         //base case: nothing to check anymore\r
143         if(groupsToCheck.isEmpty())\r
144             return resultSet;\r
145         //This is the parents directly above the current groups that are being checked\r
146         List<Group> currentParentGroups = new ArrayList<>();\r
147 \r
148         for(Group group : groupsToCheck)\r
149         {\r
150             if(group.getParentGroupId() != null) // if there is a parent\r
151             {\r
152                 String parentId = group.getParentGroupId().toString();\r
153                 Group parentGroup = groupMap.get(parentId);\r
154                 resultSet.add(parentId);\r
155                 currentParentGroups.add(parentGroup); // add to currentParentGroup so it can be used recursively check for more parents\r
156             }\r
157         }\r
158         return lookUp(currentParentGroups,groupMap,resultSet);\r
159     }\r
160     // convert a list of groups to a map of group ids to group\r
161     private Map<String, Group> groupListToMap(List<Group> allGroups)\r
162     {\r
163         Map<String, Group> groupMap = new HashMap<>();\r
164         allGroups.forEach(group -> groupMap.put(group.get_id().toString(),group));\r
165         return groupMap;\r
166     }\r
167     //get all the child group\r
168     private Set<String> getChildrenGroupsId(List<Group> enrolledGroup, Map<String, Group> allGroupsMap, User user)\r
169     {\r
170         Set<String> childrenGroups = new HashSet<>();\r
171         Set<String> managementGroupIds = getManagementGroupIds(enrolledGroup,user);\r
172         return  lookForChildren(managementGroupIds,allGroupsMap,childrenGroups);\r
173     }\r
174 \r
175     private Set<String> getManagementGroupIds(List<Group> enrolledGroups, User user)\r
176     {\r
177         Set<String> parentIds = new HashSet<>();\r
178         for(Group group: enrolledGroups)\r
179         {\r
180             if(hasDirectPermissionTo(UserPermission.Permission.MANAGEMENT,user,group)) // has Management permission\r
181             {\r
182                 parentIds.add(group.get_id().toString());\r
183             }\r
184         }\r
185         return parentIds;\r
186     }\r
187     //recursive look down for childrens via breath first search\r
188     private Set<String> lookForChildren (Set<String> parentIds, Map<String, Group> allGroupsMap, Set<String> resultSet)\r
189     {\r
190         //base case = no groups to check anymore;\r
191         if (parentIds.isEmpty())\r
192             return resultSet;\r
193 \r
194         Set<String> currentChildrenIds = new HashSet<>();\r
195         for(String groupId : allGroupsMap.keySet())\r
196         {\r
197             Group possibleChildGroup = allGroupsMap.get(groupId);\r
198             if(isChildOf(parentIds,possibleChildGroup)) // if parent id is the same\r
199             {\r
200                 currentChildrenIds.add(groupId);\r
201                 resultSet.add(groupId);\r
202             }\r
203         }\r
204         return lookForChildren(currentChildrenIds,allGroupsMap,resultSet);\r
205     }\r
206     //check if a group is a child of a list of parent group ids\r
207     private boolean isChildOf(Set<String>parentGroupIds, Group childGroup){\r
208         for(String parentId: parentGroupIds)\r
209         {\r
210             if(isChildOf(parentId,childGroup))\r
211                 return true;\r
212         }\r
213         return false;\r
214     }\r
215     //check is group has parent that is specified by parentId\r
216     private boolean isChildOf(String parentId, Group childGroup) {\r
217         if(childGroup.getParentGroupId() == null)\r
218             return false;\r
219        return childGroup.getParentGroupId().toString().equals(parentId);\r
220     }\r
221 \r
222     private Set<String> convertPermissions (Set<String> permissions){\r
223         Set<String> result = new HashSet<>();\r
224         for (String permission: permissions){\r
225             if(permission.equalsIgnoreCase(UserPermission.Permission.READ))\r
226                 result.add(UserPermission.Permission.READ);\r
227             else if (permission.equalsIgnoreCase(UserPermission.Permission.WRITE))\r
228                 result.add(UserPermission.Permission.WRITE);\r
229             else if (permission.equalsIgnoreCase(UserPermission.Permission.DELETE))\r
230                 result.add(UserPermission.Permission.DELETE);\r
231             else if (permission.equalsIgnoreCase(UserPermission.Permission.EXECUTE))\r
232                 result.add(UserPermission.Permission.EXECUTE);\r
233             else if (permission.equalsIgnoreCase(UserPermission.Permission.MANAGEMENT))\r
234                 result.add(UserPermission.Permission.MANAGEMENT);\r
235         }\r
236             return result;\r
237     }\r
238 }\r