1 package de.dlr.shepard.security;
2
3 import de.dlr.shepard.labJournal.services.LabJournalEntryService;
4 import de.dlr.shepard.neo4Core.entities.Permissions;
5 import de.dlr.shepard.neo4Core.entities.User;
6 import de.dlr.shepard.neo4Core.entities.UserGroup;
7 import de.dlr.shepard.neo4Core.io.RolesIO;
8 import de.dlr.shepard.neo4Core.services.DataObjectService;
9 import de.dlr.shepard.neo4Core.services.PermissionsService;
10 import de.dlr.shepard.neo4Core.services.UserGroupService;
11 import de.dlr.shepard.util.AccessType;
12 import de.dlr.shepard.util.Constants;
13 import de.dlr.shepard.util.PermissionType;
14 import jakarta.enterprise.context.RequestScoped;
15 import jakarta.inject.Inject;
16 import jakarta.ws.rs.container.ContainerRequestContext;
17 import jakarta.ws.rs.core.PathSegment;
18 import java.util.HashSet;
19 import java.util.List;
20 import java.util.Set;
21 import org.apache.commons.lang3.StringUtils;
22
23 @RequestScoped
24 public class PermissionsUtil {
25
26 private PermissionsService permissionsService;
27 private UserGroupService userGroupService;
28 private LabJournalEntryService labJournalEntryService;
29 private DataObjectService dataObjectService;
30
31 PermissionsUtil() {}
32
33 @Inject
34 public PermissionsUtil(
35 PermissionsService permissionsService,
36 UserGroupService userGroupService,
37 LabJournalEntryService labJournalEntryService,
38 DataObjectService dataObjectService
39 ) {
40 this.permissionsService = permissionsService;
41 this.userGroupService = userGroupService;
42 this.labJournalEntryService = labJournalEntryService;
43 this.dataObjectService = dataObjectService;
44 }
45
46
47
48
49
50
51
52 public boolean isAllowed(ContainerRequestContext requestContext, AccessType accessType, String userName) {
53 List<PathSegment> pathSegments = requestContext.getUriInfo().getPathSegments();
54 var idSegment = pathSegments.size() > 1 ? pathSegments.get(1).getPath() : null;
55
56 if (pathSegments.get(0).getPath().equals(Constants.LAB_JOURNAL_ENTRIES)) {
57 return isAllowedLabJournalEntryRequest(requestContext, accessType, userName, idSegment);
58 }
59
60 if (idSegment == null || idSegment.isBlank()) {
61
62 return true;
63 } else if (!StringUtils.isNumeric(idSegment)) {
64
65 if (
66 pathSegments.get(0).getPath().equals(Constants.SEARCH) &&
67 List.of(Constants.USERS, Constants.CONTAINERS).contains(pathSegments.get(1).getPath()) &&
68 pathSegments.size() == 2
69 ) return true;
70
71 else if (pathSegments.get(0).getPath().equals(Constants.USERS)) {
72 if (pathSegments.size() <= 2 && AccessType.Read.equals(accessType)) return true;
73 else if (userName.equals(idSegment)) return true;
74 }
75 return false;
76 }
77
78 var entityId = Long.parseLong(idSegment);
79 return isAccessTypeAllowedForUser(entityId, accessType, userName);
80 }
81
82 private boolean isAllowedLabJournalEntryRequest(
83 ContainerRequestContext requestContext,
84 AccessType accessType,
85 String userName,
86 String idSegment
87 ) {
88 String dataObjectId = requestContext.getUriInfo().getQueryParameters().getFirst(Constants.DATA_OBJECT_ID);
89
90 if (dataObjectId != null && !dataObjectId.isEmpty() && StringUtils.isNumeric(dataObjectId)) {
91 Long collectionId = dataObjectService.getCollectionId(Long.parseLong(dataObjectId));
92 if (collectionId == null) return true;
93 return isAccessTypeAllowedForUser(collectionId, accessType, userName);
94 }
95 if (idSegment == null || idSegment.isBlank()) {
96 return true;
97 }
98 Long labJournalId = Long.parseLong(idSegment);
99 Long collectionId = labJournalEntryService.getCollectionId(labJournalId);
100 if (collectionId == null) return true;
101
102 return isAccessTypeAllowedForUser(collectionId, accessType, userName);
103 }
104
105
106
107
108
109
110
111
112
113 public boolean isAccessTypeAllowedForUser(long entityId, AccessType accessType, String username) {
114 var perms = permissionsService.getPermissionsByNeo4jId(entityId);
115 if (perms == null) return true;
116
117 if (isOwner(perms, username)) return true;
118
119 if (AccessType.Manage.equals(accessType)) {
120 return isManager(perms, username);
121 } else if (AccessType.Read.equals(accessType)) {
122 return isReader(perms, username);
123 } else if (AccessType.Write.equals(accessType)) {
124 return isWriter(perms, username);
125 }
126
127 return false;
128 }
129
130 private Set<String> fetchUserNames(List<UserGroup> userGroups) {
131 Set<String> ret = new HashSet<>();
132 for (UserGroup userGroup : userGroups) {
133 UserGroup fullUserGroup = userGroupService.getUserGroup(userGroup.getId());
134 for (User user : fullUserGroup.getUsers()) {
135 ret.add(user.getUsername());
136 }
137 }
138 return ret;
139 }
140
141 public RolesIO getRolesByNeo4jId(long id, String username) {
142 var perms = permissionsService.getPermissionsByNeo4jId(id);
143 return getRoles(perms, username);
144 }
145
146 public RolesIO getRolesByShepardId(long shepardId, String username) {
147 var perms = permissionsService.getPermissionsByShepardId(shepardId);
148 return getRoles(perms, username);
149 }
150
151 private RolesIO getRoles(Permissions perms, String username) {
152 if (perms == null) {
153
154 return new RolesIO(false, true, true, true);
155 }
156 var roles = new RolesIO(
157 isOwner(perms, username),
158 isManager(perms, username),
159 isWriter(perms, username),
160 isReader(perms, username)
161 );
162 return roles;
163 }
164
165 private boolean isOwner(Permissions perms, String username) {
166 return perms.getOwner() != null && username.equals(perms.getOwner().getUsername());
167 }
168
169 private boolean isManager(Permissions perms, String username) {
170 return perms.getManager().stream().anyMatch(u -> username.equals(u.getUsername()));
171 }
172
173 private boolean isReader(Permissions perms, String username) {
174 var pub = PermissionType.Public.equals(perms.getPermissionType());
175 var pubRead = PermissionType.PublicReadable.equals(perms.getPermissionType());
176 var reader = perms.getReader().stream().anyMatch(u -> username.equals(u.getUsername()));
177 var readerGroup = fetchUserNames(perms.getReaderGroups()).contains(username);
178 return pub || pubRead || reader || readerGroup;
179 }
180
181 private boolean isWriter(Permissions perms, String username) {
182 var pub = PermissionType.Public.equals(perms.getPermissionType());
183 var writer = perms.getWriter().stream().anyMatch(u -> username.equals(u.getUsername()));
184 var writerGroup = fetchUserNames(perms.getWriterGroups()).contains(username);
185 return pub || writer || writerGroup;
186 }
187 }