View Javadoc
1   package de.dlr.shepard.security;
2   
3   import java.util.HashSet;
4   import java.util.List;
5   import java.util.Set;
6   
7   import org.apache.commons.lang3.StringUtils;
8   
9   import de.dlr.shepard.neo4Core.entities.Permissions;
10  import de.dlr.shepard.neo4Core.entities.User;
11  import de.dlr.shepard.neo4Core.entities.UserGroup;
12  import de.dlr.shepard.neo4Core.io.RolesIO;
13  import de.dlr.shepard.neo4Core.services.PermissionsService;
14  import de.dlr.shepard.neo4Core.services.UserGroupService;
15  import de.dlr.shepard.util.AccessType;
16  import de.dlr.shepard.util.Constants;
17  import de.dlr.shepard.util.PermissionType;
18  import jakarta.ws.rs.core.PathSegment;
19  
20  public class PermissionsUtil {
21  
22  	private PermissionsService permissionsService = new PermissionsService();
23  	private UserGroupService userGroupService = new UserGroupService();
24  
25  	/**
26  	 * Check whether a request is allowed or not
27  	 *
28  	 * @param pathSegments the path segments of the request uri
29  	 * @param accessType   the access type (read, write, manage)
30  	 * @param username     the user that wants access
31  	 * @return whether the request is allowed or not
32  	 */
33  	public boolean isAllowed(List<PathSegment> pathSegments, AccessType accessType, String username) {
34  		var idSegment = pathSegments.size() > 1 ? pathSegments.get(1).getPath() : null;
35  		if (idSegment == null || idSegment.isBlank()) {
36  			// No id in path
37  			return true;
38  		} else if (!StringUtils.isNumeric(idSegment)) {
39  			// usersearch and containersearch
40  			if (pathSegments.get(0).getPath().equals(Constants.SEARCH)
41  					&& List.of(Constants.USERS, Constants.CONTAINERS).contains(pathSegments.get(1).getPath())
42  					&& pathSegments.size() == 2)
43  				return true;
44  			// non-numeric id
45  			else if (pathSegments.get(0).getPath().equals(Constants.USERS)) {
46  				if (pathSegments.size() <= 2 && AccessType.Read.equals(accessType))
47  					// it is allowed to read all users
48  					return true;
49  				else if (username.equals(idSegment))
50  					// it is allowed to access yourself
51  					return true;
52  			}
53  			return false;
54  		}
55  
56  		var entityId = Long.parseLong(idSegment);
57  		return isAllowed(entityId, accessType, username);
58  	}
59  
60  	/**
61  	 * Check whether a request is allowed or not
62  	 *
63  	 * @param entityId   the entity that is to be accessed
64  	 * @param accessType the access type (read, write, manage)
65  	 * @param username   the user that wants access
66  	 * @return whether the access is allowed or not
67  	 */
68  	public boolean isAllowed(long entityId, AccessType accessType, String username) {
69  		var perms = permissionsService.getPermissionsByEntity(entityId);
70  		if (perms == null)
71  			// No permissions
72  			return true;
73  
74  		if (isOwner(perms, username))
75  			// Is owner
76  			return true;
77  
78  		if (AccessType.Manage.equals(accessType)) {
79  			return isManager(perms, username);
80  		} else if (AccessType.Read.equals(accessType)) {
81  			return isReader(perms, username);
82  		} else if (AccessType.Write.equals(accessType)) {
83  			return isWriter(perms, username);
84  		}
85  
86  		return false;
87  	}
88  
89  	private Set<String> fetchUserNames(List<UserGroup> userGroups) {
90  		Set<String> ret = new HashSet<>();
91  		for (UserGroup userGroup : userGroups) {
92  			UserGroup fullUserGroup = userGroupService.getUserGroup(userGroup.getId());
93  			for (User user : fullUserGroup.getUsers()) {
94  				ret.add(user.getUsername());
95  			}
96  		}
97  		return ret;
98  	}
99  
100 	public RolesIO getRoles(long entityId, String username) {
101 		var perms = permissionsService.getPermissionsByEntity(entityId);
102 		if (perms == null) {
103 			// Legacy entity without permissions
104 			return new RolesIO(false, true, true, true);
105 		}
106 		var roles = new RolesIO(isOwner(perms, username), isManager(perms, username), isWriter(perms, username),
107 				isReader(perms, username));
108 		return roles;
109 	}
110 
111 	private boolean isOwner(Permissions perms, String username) {
112 		return perms.getOwner() != null && username.equals(perms.getOwner().getUsername());
113 	}
114 
115 	private boolean isManager(Permissions perms, String username) {
116 		return perms.getManager().stream().anyMatch(u -> username.equals(u.getUsername()));
117 	}
118 
119 	private boolean isReader(Permissions perms, String username) {
120 		var pub = PermissionType.Public.equals(perms.getPermissionType());
121 		var pubRead = PermissionType.PublicReadable.equals(perms.getPermissionType());
122 		var reader = perms.getReader().stream().anyMatch(u -> username.equals(u.getUsername()));
123 		var readerGroup = fetchUserNames(perms.getReaderGroups()).contains(username);
124 		return pub || pubRead || reader || readerGroup;
125 	}
126 
127 	private boolean isWriter(Permissions perms, String username) {
128 		var pub = PermissionType.Public.equals(perms.getPermissionType());
129 		var writer = perms.getWriter().stream().anyMatch(u -> username.equals(u.getUsername()));
130 		var writerGroup = fetchUserNames(perms.getWriterGroups()).contains(username);
131 		return pub || writer || writerGroup;
132 	}
133 
134 }