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.getPermissionsByNeo4jId(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 getRolesByNeo4jId(long id, String username) {
101 		var perms = permissionsService.getPermissionsByNeo4jId(id);
102 		return getRoles(perms, username);
103 	}
104 
105 	public RolesIO getRolesByShepardId(long shepardId, String username) {
106 		var perms = permissionsService.getPermissionsByShepardId(shepardId);
107 		return getRoles(perms, username);
108 	}
109 
110 	private RolesIO getRoles(Permissions perms, String username) {
111 		if (perms == null) {
112 			// Legacy entity without permissions
113 			return new RolesIO(false, true, true, true);
114 		}
115 		var roles = new RolesIO(isOwner(perms, username), isManager(perms, username), isWriter(perms, username),
116 				isReader(perms, username));
117 		return roles;
118 	}
119 
120 	private boolean isOwner(Permissions perms, String username) {
121 		return perms.getOwner() != null && username.equals(perms.getOwner().getUsername());
122 	}
123 
124 	private boolean isManager(Permissions perms, String username) {
125 		return perms.getManager().stream().anyMatch(u -> username.equals(u.getUsername()));
126 	}
127 
128 	private boolean isReader(Permissions perms, String username) {
129 		var pub = PermissionType.Public.equals(perms.getPermissionType());
130 		var pubRead = PermissionType.PublicReadable.equals(perms.getPermissionType());
131 		var reader = perms.getReader().stream().anyMatch(u -> username.equals(u.getUsername()));
132 		var readerGroup = fetchUserNames(perms.getReaderGroups()).contains(username);
133 		return pub || pubRead || reader || readerGroup;
134 	}
135 
136 	private boolean isWriter(Permissions perms, String username) {
137 		var pub = PermissionType.Public.equals(perms.getPermissionType());
138 		var writer = perms.getWriter().stream().anyMatch(u -> username.equals(u.getUsername()));
139 		var writerGroup = fetchUserNames(perms.getWriterGroups()).contains(username);
140 		return pub || writer || writerGroup;
141 	}
142 
143 }