1 package de.dlr.shepard.auth.permission.services;
2
3 import static org.junit.jupiter.api.Assertions.assertEquals;
4 import static org.junit.jupiter.api.Assertions.assertThrows;
5 import static org.mockito.ArgumentMatchers.anyString;
6 import static org.mockito.Mockito.verify;
7 import static org.mockito.Mockito.when;
8
9 import de.dlr.shepard.BaseTestCase;
10 import de.dlr.shepard.auth.permission.daos.PermissionsDAO;
11 import de.dlr.shepard.auth.permission.io.PermissionsIO;
12 import de.dlr.shepard.auth.permission.model.Permissions;
13 import de.dlr.shepard.auth.security.PermissionLastSeenCache;
14 import de.dlr.shepard.auth.users.entities.User;
15 import de.dlr.shepard.auth.users.entities.UserGroup;
16 import de.dlr.shepard.auth.users.services.UserGroupService;
17 import de.dlr.shepard.auth.users.services.UserService;
18 import de.dlr.shepard.common.exceptions.InvalidAuthException;
19 import de.dlr.shepard.common.exceptions.ShepardProcessingException;
20 import de.dlr.shepard.common.neo4j.entities.BasicEntity;
21 import de.dlr.shepard.common.util.PermissionType;
22 import de.dlr.shepard.context.collection.entities.Collection;
23 import de.dlr.shepard.data.file.entities.FileContainer;
24 import jakarta.ws.rs.NotFoundException;
25 import java.util.ArrayList;
26 import java.util.Collections;
27 import java.util.List;
28 import java.util.Optional;
29 import org.junit.jupiter.api.Assertions;
30 import org.junit.jupiter.api.Test;
31 import org.mockito.InjectMocks;
32 import org.mockito.Mock;
33
34 public class PermissionsServiceTest extends BaseTestCase {
35
36 private final User user = new User("testuser");
37
38 @Mock
39 private UserService userService;
40
41 @Mock
42 private UserGroupService userGroupService;
43
44 @Mock
45 private PermissionsDAO dao;
46
47 @Mock
48 private PermissionLastSeenCache lastSeenCache;
49
50 @InjectMocks
51 private PermissionsService service;
52
53 @Test
54 public void createPermissions_callsDAO() {
55 var entity = new BasicEntity(2L);
56 var user = new User("name");
57 var permissionType = PermissionType.Private;
58 service.createPermissions(entity, user, permissionType);
59 verify(dao).createOrUpdate(new Permissions(entity, user, permissionType));
60 }
61
62 @Test
63 public void getPermissionsByNeo4jIdTest() {
64 var con = new FileContainer(2L);
65 ArrayList<BasicEntity> conList = new ArrayList<BasicEntity>();
66 conList.add(con);
67 var perms = new Permissions();
68 perms.setEntities(conList);
69
70 when(dao.findByEntityNeo4jId(2L)).thenReturn(perms);
71 when(userService.getCurrentUser()).thenReturn(user);
72 when(lastSeenCache.isKeyCached(anyString())).thenReturn(false);
73 var actual = service.getPermissionsOfEntity(2L);
74 assertEquals(perms, actual);
75 }
76
77 @Test
78 public void getPermissionsByNeo4jIdTest_notFound() {
79 when(dao.findByEntityNeo4jId(2L)).thenReturn(null);
80 when(userService.getCurrentUser()).thenReturn(user);
81 when(lastSeenCache.isKeyCached(anyString())).thenReturn(false);
82
83 var ex = assertThrows(NotFoundException.class, () -> service.getPermissionsOfEntity(2L));
84 assertEquals("Permissions with entity 2 is null", ex.getMessage());
85 }
86
87 @Test
88 public void updatePermissionsByNeo4jIdTest() {
89 var owner = new User("owner");
90 var reader = new User("reader");
91 var writer = new User("writer");
92 var manager = new User("manager");
93 List<User> writerGroupList = List.of(new User("groupwriter"));
94 UserGroup writerGroup = new UserGroup(12L);
95 writerGroup.setName("writerGroup");
96 writerGroup.setUsers(writerGroupList);
97 List<UserGroup> writerGroupsList = List.of(writerGroup);
98
99 var con = new FileContainer(2L);
100
101 ArrayList<BasicEntity> conList = new ArrayList<BasicEntity>();
102 conList.add(con);
103
104 var existing = new Permissions(1L);
105 existing.setEntities(conList);
106 existing.setOwner(owner);
107 con.setPermissions(existing);
108
109 var perms = new PermissionsIO() {
110 {
111 setOwner(owner.getUsername());
112 setReader(new String[] { "reader", "false" });
113 setWriter(new String[] { "writer" });
114 setWriterGroupIds(new long[] { 12L, -1L });
115 setManager(new String[] { "manager" });
116 }
117 };
118
119 var updated = new Permissions() {
120 {
121 setId(1L);
122 setEntities(conList);
123 setOwner(owner);
124 setReader(List.of(reader));
125 setWriter(List.of(writer));
126 setWriterGroups(writerGroupsList);
127 setManager(List.of(manager));
128 }
129 };
130
131 when(userService.getCurrentUser()).thenReturn(owner);
132 when(userService.getUserOptional("owner")).thenReturn(Optional.of(owner));
133 when(userService.getUserOptional("reader")).thenReturn(Optional.of(reader));
134 when(userService.getUserOptional("writer")).thenReturn(Optional.of(writer));
135 when(userService.getUserOptional("manager")).thenReturn(Optional.of(manager));
136 when(userGroupService.getUserGroupOptional(12L)).thenReturn(Optional.of(writerGroup));
137 when(dao.findByEntityNeo4jId(2L)).thenReturn(existing);
138 when(dao.createOrUpdate(updated)).thenReturn(updated);
139
140 var actual = service.updatePermissionsByNeo4jId(perms, 2L);
141 assertEquals(updated, actual);
142 }
143
144 @Test
145 public void updatePermissionsByNeo4jIdTest_oldIsNull() {
146 var owner = new User("owner");
147 var reader = new User("reader");
148 var writer = new User("writer");
149 var manager = new User("manager");
150
151 var con = new FileContainer(2L);
152 ArrayList<BasicEntity> conList = new ArrayList<BasicEntity>();
153 conList.add(con);
154 var perms = new PermissionsIO() {
155 {
156 setOwner("owner");
157 setReader(new String[] { "reader" });
158 setWriter(new String[] { "writer" });
159 setReaderGroupIds(new long[] {});
160 setManager(new String[] { "manager" });
161 }
162 };
163
164 var toCreate = new Permissions() {
165 {
166 setEntities(conList);
167 setOwner(owner);
168 setReader(List.of(reader));
169 setWriter(List.of(writer));
170 setReaderGroups(Collections.emptyList());
171 setWriterGroups(Collections.emptyList());
172 setManager(List.of(manager));
173 }
174 };
175
176 var updated = new Permissions() {
177 {
178 setId(1L);
179 setEntities(conList);
180 setOwner(owner);
181 setReader(List.of(reader));
182 setWriter(List.of(writer));
183 setReaderGroups(Collections.emptyList());
184 setWriterGroups(Collections.emptyList());
185 setManager(List.of(manager));
186 }
187 };
188
189 when(userService.getUserOptional("owner")).thenReturn(Optional.of(owner));
190 when(userService.getUserOptional("reader")).thenReturn(Optional.of(reader));
191 when(userService.getUserOptional("writer")).thenReturn(Optional.of(writer));
192 when(userService.getUserOptional("manager")).thenReturn(Optional.of(manager));
193 when(dao.findByEntityNeo4jId(2L)).thenReturn(null);
194 when(dao.createOrUpdate(toCreate)).thenReturn(updated);
195
196 Assertions.assertThrowsExactly(ShepardProcessingException.class, () -> service.updatePermissionsByNeo4jId(perms, 2L)
197 );
198 }
199
200 @Test
201 public void updatePermissionsByNeo4jIdTest_userIsNull() {
202 var reader = new User("reader");
203 var writer = new User("writer");
204 var manager = new User("manager");
205
206 var con = new FileContainer(2L);
207 ArrayList<BasicEntity> conList = new ArrayList<BasicEntity>();
208 conList.add(con);
209 var existing = new Permissions(1L);
210 existing.setEntities(conList);
211
212 var perms = new PermissionsIO() {
213 {
214 setReader(new String[] { "reader", "not_existing" });
215 setWriter(new String[] { "writer", null });
216 setReaderGroupIds(new long[] {});
217 setWriterGroupIds(new long[] {});
218 setManager(new String[0]);
219 }
220 };
221
222 var updated = new Permissions() {
223 {
224 setId(1L);
225 setEntities(conList);
226 setReader(List.of(reader));
227 setWriter(List.of(writer));
228 setReaderGroups(Collections.emptyList());
229 setWriterGroups(Collections.emptyList());
230 }
231 };
232
233 when(userService.getUserOptional("reader")).thenReturn(Optional.of(reader));
234 when(userService.getUserOptional("writer")).thenReturn(Optional.of(writer));
235 when(userService.getUserOptional("manager")).thenReturn(Optional.of(manager));
236 when(dao.findByEntityNeo4jId(2L)).thenReturn(existing);
237 when(dao.createOrUpdate(updated)).thenReturn(updated);
238
239 var actual = service.updatePermissionsByNeo4jId(perms, 2L);
240 assertEquals(updated, actual);
241 }
242
243 @Test
244 public void updatePermissionsByShepardIdTest_userIsNull() {
245 var reader = new User("reader");
246 var writer = new User("writer");
247 var manager = new User("manager");
248
249 var col = new Collection(2L);
250 col.setShepardId(4L);
251 ArrayList<BasicEntity> colList = new ArrayList<BasicEntity>();
252 colList.add(col);
253 var existing = new Permissions(1L);
254 existing.setEntities(colList);
255
256 var perms = new PermissionsIO() {
257 {
258 setReader(new String[] { "reader", "not_existing" });
259 setWriter(new String[] { "writer", null });
260 setReaderGroupIds(new long[] {});
261 setWriterGroupIds(new long[] {});
262 setManager(new String[0]);
263 }
264 };
265
266 var updated = new Permissions() {
267 {
268 setId(1L);
269 setEntities(colList);
270 setReader(List.of(reader));
271 setWriter(List.of(writer));
272 setReaderGroups(Collections.emptyList());
273 setWriterGroups(Collections.emptyList());
274 }
275 };
276
277 when(userService.getUserOptional("reader")).thenReturn(Optional.of(reader));
278 when(userService.getUserOptional("writer")).thenReturn(Optional.of(writer));
279 when(userService.getUserOptional("manager")).thenReturn(Optional.of(manager));
280 when(dao.findByEntityNeo4jId(col.getShepardId())).thenReturn(existing);
281 when(dao.createOrUpdate(updated)).thenReturn(updated);
282
283 var actual = service.updatePermissionsByNeo4jId(perms, col.getShepardId());
284 assertEquals(updated, actual);
285 }
286
287 @Test
288 public void deletePermissions_callsDAO() {
289 var permissions = new Permissions(2L);
290 service.deletePermissions(permissions);
291 verify(dao).deleteByNeo4jId(2L);
292 }
293
294 @Test
295 public void updatePermissionsByNeo4jId_changeOwnerUserIsOwner_success() {
296 var currentOwner = new User("OwnerOld");
297 var futureOwner = new User("OwnerNew");
298 var col = new Collection(2L);
299 col.setShepardId(4L);
300
301 ArrayList<BasicEntity> colList = new ArrayList<BasicEntity>();
302 colList.add(col);
303
304 var existing = new Permissions(1L);
305 existing.setEntities(colList);
306 existing.setOwner(currentOwner);
307
308 var perms = new PermissionsIO() {
309 {
310 setOwner(futureOwner.getUsername());
311 setReader(new String[] {});
312 setWriter(new String[] {});
313 setReaderGroupIds(new long[] {});
314 setWriterGroupIds(new long[] {});
315 setManager(new String[0]);
316 }
317 };
318
319 var updated = new Permissions() {
320 {
321 setId(1L);
322 setEntities(colList);
323 setOwner(futureOwner);
324 }
325 };
326
327 when(userService.getUserOptional("OwnerOld")).thenReturn(Optional.of(currentOwner));
328 when(userService.getUserOptional("OwnerNew")).thenReturn(Optional.of(futureOwner));
329 when(dao.findByEntityNeo4jId(col.getShepardId())).thenReturn(existing);
330 when(dao.createOrUpdate(updated)).thenReturn(updated);
331 when(userService.getCurrentUser()).thenReturn(currentOwner);
332
333 var actual = service.updatePermissionsByNeo4jId(perms, col.getShepardId());
334 assertEquals(updated, actual);
335 }
336
337 @Test
338 public void updatePermissionsByNeo4jId_changeOwnerUserIsNotOwner_throwException() {
339
340 var currentOwner = new User("Owner");
341 var otherUser = new User("OtherUser");
342
343 var col = new Collection(2L);
344 col.setShepardId(4L);
345
346 ArrayList<BasicEntity> colList = new ArrayList<BasicEntity>();
347 colList.add(col);
348
349 var existing = new Permissions(1L);
350 existing.setEntities(colList);
351 existing.setOwner(currentOwner);
352
353 var perms = new PermissionsIO() {
354 {
355 setOwner(otherUser.getUsername());
356 setReader(new String[] {});
357 setWriter(new String[] {});
358 setReaderGroupIds(new long[] {});
359 setWriterGroupIds(new long[] {});
360 setManager(new String[0]);
361 }
362 };
363
364 when(userService.getUserOptional("Owner")).thenReturn(Optional.of(currentOwner));
365 when(userService.getUserOptional("OtherUser")).thenReturn(Optional.of(otherUser));
366 when(dao.findByEntityNeo4jId(col.getShepardId())).thenReturn(existing);
367 when(userService.getCurrentUser()).thenReturn(otherUser);
368
369 var ex = assertThrows(InvalidAuthException.class, () ->
370 service.updatePermissionsByNeo4jId(perms, col.getShepardId())
371 );
372 assertEquals("Action not allowed. Only Owners are allowed to change ownership.", ex.getMessage());
373 }
374 }