added svcapi ui and camunda code
[it/otf.git] / otf-service-api / 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 groups that the user is in directly (non-child and non parents)****************\r
40     public static boolean hasPermissionTo (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     // create map that where key is the group id and value = users permission (string) that that group\r
79     private Map<String,Set<String>> mapGroupsToPermission(User user, GroupRepository groupRepository){\r
80         Map<String,Set<String>> groupAccessMap = new HashMap<>();\r
81         List<Group> enrolledGroups = groupRepository.findAllByMembersId(user.get_id());// enrolledGroups = groups that user is a member of\r
82         Map<String,Group> allGroupMap = groupListToMap(groupRepository.findAll());\r
83         // get all permission in the groups the user is ia member of\r
84         for(Group group: enrolledGroups) {\r
85             Set<String> permissions = getUserGroupPermissions(user,group);\r
86             groupAccessMap.put(group.get_id().toString(),convertPermissions(permissions));\r
87         }\r
88         //assign add read to all parent groups\r
89         Set<String> parentGroupsId = getParentGroups(enrolledGroups,allGroupMap);\r
90         for(String parentId : parentGroupsId)\r
91         {\r
92             // if parent access role already exist in\r
93             // group access map cause they are a member\r
94             if(groupAccessMap.get(parentId)!= null)\r
95                 groupAccessMap.get(parentId).add(UserPermission.Permission.READ);\r
96             else\r
97                 groupAccessMap.put(parentId,new HashSet<String>(Arrays.asList(UserPermission.Permission.READ)));\r
98         }\r
99         // if there is management role\r
100         // then assign read access to children\r
101         if(hasManagementRole(user,enrolledGroups)){\r
102 //            Set<String>childIds = getChildrenGroupsId(enrolledGroups,allGroupMap,user);\r
103             for(Group enrolledGroup : enrolledGroups) {\r
104                 // if enrolled groups is a management group\r
105                 if(hasPermissionTo(UserPermission.Permission.MANAGEMENT,user,enrolledGroup)){\r
106                     // if there is management role then get all the child of that group, do this for all management groups\r
107                     Set<String> childIds= getChildrenGroupsId(Arrays.asList(enrolledGroup),allGroupMap,user);\r
108                     Set<String> userGroupPermissions = convertPermissions(getUserGroupPermissions(user,enrolledGroup));\r
109                     for(String childId : childIds){\r
110                         if (groupAccessMap.get(childId) != null)\r
111                             groupAccessMap.get(childId).addAll(userGroupPermissions);\r
112                         else{\r
113                             groupAccessMap.put(childId,userGroupPermissions);\r
114                         }\r
115                     }\r
116                 }\r
117             }\r
118         }\r
119         return groupAccessMap;\r
120     }\r
121     // check is user have managementRole\r
122     private boolean hasManagementRole(User user, List<Group> enrolledGroups)\r
123     {\r
124         for(Group group: enrolledGroups){\r
125             if(hasPermissionTo(UserPermission.Permission.MANAGEMENT,user,group))\r
126             {\r
127                 return true;\r
128             }\r
129         }\r
130         return false;\r
131     }\r
132     // get the parent groups starting from the enrolled group of the user\r
133     private Set<String> getParentGroups(List<Group> enrolledGroup,Map<String,Group> groupMap )\r
134     {\r
135         Set<String> parentGroups = new HashSet<>();\r
136         return lookUp(enrolledGroup,groupMap,parentGroups);\r
137     }\r
138     //recursive lookup starting at the enrolled groups that the user is a member of\r
139     private Set<String> lookUp(List<Group> groupsToCheck, Map<String,Group> groupMap,Set<String> resultSet)\r
140     {\r
141         //base case: nothing to check anymore\r
142         if(groupsToCheck.isEmpty())\r
143             return resultSet;\r
144         //This is the parents directly above the current groups that are being checked\r
145         List<Group> currentParentGroups = new ArrayList<>();\r
146 \r
147         for(Group group : groupsToCheck)\r
148         {\r
149             if(group.getParentGroupId() != null) // if there is a parent\r
150             {\r
151                 String parentId = group.getParentGroupId().toString();\r
152                 Group parentGroup = groupMap.get(parentId);\r
153                 resultSet.add(parentId);\r
154                 currentParentGroups.add(parentGroup); // add to currentParentGroup so it can be used recursively check for more parents\r
155             }\r
156         }\r
157         return lookUp(currentParentGroups,groupMap,resultSet);\r
158     }\r
159     // convert a list of groups to a map of group ids to group\r
160     private Map<String,Group> groupListToMap(List<Group> allGroups)\r
161     {\r
162         Map<String,Group> groupMap = new HashMap<>();\r
163         allGroups.forEach(group -> groupMap.put(group.get_id().toString(),group));\r
164         return groupMap;\r
165     }\r
166     //get all the child group\r
167     private Set<String> getChildrenGroupsId(List<Group> enrolledGroup, Map<String,Group> allGroupsMap, User user)\r
168     {\r
169         Set<String> childrenGroups = new HashSet<>();\r
170         Set<String> managementGroupIds = getManagementGroupIds(enrolledGroup,user);\r
171         return  lookForChildren(managementGroupIds,allGroupsMap,childrenGroups);\r
172     }\r
173 \r
174     private Set<String> getManagementGroupIds(List<Group> enrolledGroups,User user)\r
175     {\r
176         Set<String> parentIds = new HashSet<>();\r
177         for(Group group: enrolledGroups)\r
178         {\r
179             if(hasPermissionTo(UserPermission.Permission.MANAGEMENT,user,group)) // has Management permission\r
180             {\r
181                 parentIds.add(group.get_id().toString());\r
182             }\r
183         }\r
184         return parentIds;\r
185     }\r
186     //recursive look down for childrens via breath first search\r
187     private Set<String> lookForChildren (Set<String> parentIds, Map<String,Group> allGroupsMap, Set<String> resultSet)\r
188     {\r
189         //base case = no groups to check anymore;\r
190         if (parentIds.isEmpty())\r
191             return resultSet;\r
192 \r
193         Set<String> currentChildrenIds = new HashSet<>();\r
194         for(String groupId : allGroupsMap.keySet())\r
195         {\r
196             Group possibleChildGroup = allGroupsMap.get(groupId);\r
197             if(isChildOf(parentIds,possibleChildGroup)) // if parent id is the same\r
198             {\r
199                 currentChildrenIds.add(groupId);\r
200                 resultSet.add(groupId);\r
201             }\r
202         }\r
203         return lookForChildren(currentChildrenIds,allGroupsMap,resultSet);\r
204     }\r
205     //check if a group is a child of a list of parent group ids\r
206     private boolean isChildOf(Set<String>parentGroupIds, Group childGroup){\r
207         for(String parentId: parentGroupIds)\r
208         {\r
209             if(isChildOf(parentId,childGroup))\r
210                 return true;\r
211         }\r
212         return false;\r
213     }\r
214     //check is group has parent that is specified by parentId\r
215     private boolean isChildOf(String parentId,Group childGroup) {\r
216         if(childGroup.getParentGroupId() == null)\r
217             return false;\r
218        return childGroup.getParentGroupId().toString().equals(parentId);\r
219     }\r
220 \r
221     private Set<String> convertPermissions (Set<String> permissions){\r
222         Set<String> result = new HashSet<>();\r
223         for (String permission: permissions){\r
224             if(permission.equalsIgnoreCase(UserPermission.Permission.READ))\r
225                 result.add(UserPermission.Permission.READ);\r
226             else if (permission.equalsIgnoreCase(UserPermission.Permission.WRITE))\r
227                 result.add(UserPermission.Permission.WRITE);\r
228             else if (permission.equalsIgnoreCase(UserPermission.Permission.DELETE))\r
229                 result.add(UserPermission.Permission.DELETE);\r
230             else if (permission.equalsIgnoreCase(UserPermission.Permission.EXECUTE))\r
231                 result.add(UserPermission.Permission.EXECUTE);\r
232             else if (permission.equalsIgnoreCase(UserPermission.Permission.MANAGEMENT))\r
233                 result.add(UserPermission.Permission.MANAGEMENT);\r
234         }\r
235             return result;\r
236     }\r
237 }\r