View Javadoc
1   package de.dlr.shepard.integrationtests;
2   
3   import static io.restassured.RestAssured.given;
4   import static org.assertj.core.api.Assertions.assertThat;
5   import static org.junit.jupiter.api.Assertions.assertEquals;
6   
7   import de.dlr.shepard.ErrorResponse;
8   import de.dlr.shepard.auth.permission.io.PermissionsIO;
9   import de.dlr.shepard.auth.permission.model.Roles;
10  import de.dlr.shepard.auth.users.io.UserGroupIO;
11  import de.dlr.shepard.common.util.Constants;
12  import de.dlr.shepard.common.util.PermissionType;
13  import de.dlr.shepard.context.collection.io.CollectionIO;
14  import io.quarkus.test.junit.QuarkusIntegrationTest;
15  import io.restassured.builder.RequestSpecBuilder;
16  import io.restassured.http.ContentType;
17  import io.restassured.specification.RequestSpecification;
18  import org.junit.jupiter.api.BeforeAll;
19  import org.junit.jupiter.api.MethodOrderer;
20  import org.junit.jupiter.api.Order;
21  import org.junit.jupiter.api.Test;
22  import org.junit.jupiter.api.TestMethodOrder;
23  
24  @QuarkusIntegrationTest
25  @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
26  public class PermissionsIT extends BaseTestCaseIT {
27  
28    private static CollectionIO collection;
29    private static CollectionIO collection1;
30    private static CollectionIO collection2;
31    private static CollectionIO collection3;
32    private static String collectionsURL;
33    private static String permissionsURL;
34    private static String userGroupURL;
35    private static RequestSpecification requestSpecification1;
36    private static RequestSpecification requestSpecification2;
37    private static RequestSpecification requestSpecification3;
38    private static RequestSpecification userGroupSpecification;
39    private static UserWithApiKey user1;
40    private static UserWithApiKey user2;
41    private static UserWithApiKey user3;
42    private static UserWithApiKey user4;
43    private static String jws1;
44    private static String jws2;
45    private static String jws3;
46  
47    @BeforeAll
48    public static void setUp() {
49      collectionsURL = "/" + Constants.COLLECTIONS;
50      collection = createCollection("PermissionsTestCollection");
51      permissionsURL = String.format("/%s/%d/%s", Constants.COLLECTIONS, collection.getId(), Constants.PERMISSIONS);
52      user1 = getNewUserWithApiKey("user1");
53      user2 = getNewUserWithApiKey("user2");
54      user3 = getNewUserWithApiKey("user3");
55      user4 = getNewUserWithApiKey("user4");
56      jws1 = user1.getApiKey().getJws();
57      jws2 = user2.getApiKey().getJws();
58      jws3 = user3.getApiKey().getJws();
59      requestSpecification1 = new RequestSpecBuilder()
60        .setContentType(ContentType.JSON)
61        .addHeader("X-API-KEY", jws1)
62        .build();
63      requestSpecification2 = new RequestSpecBuilder()
64        .setContentType(ContentType.JSON)
65        .addHeader("X-API-KEY", jws2)
66        .build();
67      requestSpecification3 = new RequestSpecBuilder()
68        .setContentType(ContentType.JSON)
69        .addHeader("X-API-KEY", jws3)
70        .build();
71      collection1 = createCollection("PermissionsTestCollection1", user1);
72      collection2 = createCollection("PermissionsTestCollection2", user2);
73      collection3 = createCollection("PermissionsTestCollection3", user1);
74      userGroupURL = "/" + Constants.USERGROUPS;
75    }
76  
77    @Test
78    @Order(1)
79    public void getPermissionsTest() {
80      var actual = given()
81        .spec(requestSpecOfDefaultUser)
82        .when()
83        .get(permissionsURL)
84        .then()
85        .statusCode(200)
86        .extract()
87        .as(PermissionsIO.class);
88  
89      assertThat(actual.getEntityId()).isEqualTo(collection.getId());
90      assertThat(actual.getOwner()).isEqualTo(nameOfDefaultUser);
91      assertThat(actual.getReader()).isEmpty();
92      assertThat(actual.getWriter()).isEmpty();
93      assertThat(actual.getManager()).isEmpty();
94    }
95  
96    @Test
97    @Order(2)
98    public void updatePermissionsTest() {
99      var permissions = new PermissionsIO() {
100       {
101         setReader(new String[] { nameOfDefaultUser });
102         setWriter(new String[] { nameOfDefaultUser });
103         setManager(new String[] { nameOfDefaultUser, "invalid" });
104       }
105     };
106 
107     var actual = given()
108       .spec(requestSpecOfDefaultUser)
109       .body(permissions)
110       .when()
111       .put(permissionsURL)
112       .then()
113       .statusCode(200)
114       .extract()
115       .as(PermissionsIO.class);
116     var expected = new PermissionsIO() {
117       {
118         setEntityId(collection.getId());
119         setOwner(defaultUser.getUser().getUsername());
120         setReader(new String[] { nameOfDefaultUser });
121         setWriter(new String[] { nameOfDefaultUser });
122         setReaderGroupIds(new long[] {});
123         setWriterGroupIds(new long[] {});
124         setManager(new String[] { nameOfDefaultUser });
125       }
126     };
127 
128     assertThat(actual).isEqualTo(expected);
129   }
130 
131   @Test
132   @Order(2)
133   public void updatePermissions_NonOwnerGetsManagerPermissions_success() {
134     var User2Username = user2.getUser().getUsername();
135     var permissions = new PermissionsIO() {
136       {
137         setReader(new String[] {});
138         setWriter(new String[] {});
139         setManager(new String[] { User2Username });
140       }
141     };
142 
143     var actual = given()
144       .spec(requestSpecification1)
145       .body(permissions)
146       .when()
147       .put(String.format("/%s/%d/%s", Constants.COLLECTIONS, collection3.getId(), Constants.PERMISSIONS))
148       .then()
149       .statusCode(200)
150       .extract()
151       .as(PermissionsIO.class);
152     var expected = new PermissionsIO() {
153       {
154         setEntityId(collection3.getId());
155         setOwner(user1.getUser().getUsername());
156         setReader(new String[] {});
157         setWriter(new String[] {});
158         setReaderGroupIds(new long[] {});
159         setWriterGroupIds(new long[] {});
160         setManager(new String[] { User2Username });
161       }
162     };
163 
164     assertThat(actual).isEqualTo(expected);
165   }
166 
167   @Test
168   @Order(3)
169   public void updatePermissions_NonOwnerChangesPermissionTypeWithOwnerInformation_success() {
170     // This tests the bug described in #591
171     var permissions = new PermissionsIO() {
172       {
173         setOwner(user1.getUser().getUsername());
174         setReader(new String[] {});
175         setWriter(new String[] {});
176         setManager(new String[] { user2.getUser().getUsername() });
177         setPermissionType(PermissionType.Public);
178       }
179     };
180 
181     var actual = given()
182       .spec(requestSpecification2)
183       .body(permissions)
184       .when()
185       .put(String.format("/%s/%d/%s", Constants.COLLECTIONS, collection3.getId(), Constants.PERMISSIONS))
186       .then()
187       .statusCode(200)
188       .extract()
189       .as(PermissionsIO.class);
190     var expected = new PermissionsIO() {
191       {
192         setEntityId(collection3.getId());
193         setOwner(user1.getUser().getUsername());
194         setReader(new String[] {});
195         setWriter(new String[] {});
196         setReaderGroupIds(new long[] {});
197         setWriterGroupIds(new long[] {});
198         setManager(new String[] { user2.getUser().getUsername() });
199         setPermissionType(PermissionType.Public);
200       }
201     };
202 
203     assertThat(actual).isEqualTo(expected);
204   }
205 
206   @Test
207   @Order(3)
208   public void updatePermissions_NonOwnerChangesPermissionTypeWithoutOwnerInformation_success() {
209     var permissions = new PermissionsIO() {
210       {
211         setReader(new String[] {});
212         setWriter(new String[] {});
213         setManager(new String[] { user2.getUser().getUsername() });
214         setPermissionType(PermissionType.PublicReadable);
215       }
216     };
217 
218     var actual = given()
219       .spec(requestSpecification2)
220       .body(permissions)
221       .when()
222       .put(String.format("/%s/%d/%s", Constants.COLLECTIONS, collection3.getId(), Constants.PERMISSIONS))
223       .then()
224       .statusCode(200)
225       .extract()
226       .as(PermissionsIO.class);
227     var expected = new PermissionsIO() {
228       {
229         setEntityId(collection3.getId());
230         setOwner(user1.getUser().getUsername());
231         setReader(new String[] {});
232         setWriter(new String[] {});
233         setReaderGroupIds(new long[] {});
234         setWriterGroupIds(new long[] {});
235         setManager(new String[] { user2.getUser().getUsername() });
236         setPermissionType(PermissionType.PublicReadable);
237       }
238     };
239 
240     assertThat(actual).isEqualTo(expected);
241   }
242 
243   @Test
244   @Order(3)
245   public void updatePermissions_NonOwnerWithManagerRoleTriesToChangeOwnership_forbid() {
246     var permissions = new PermissionsIO() {
247       {
248         setOwner(user2.getUser().getUsername());
249         setReader(new String[] {});
250         setWriter(new String[] {});
251         setManager(new String[] { user2.getUser().getUsername() });
252         setPermissionType(PermissionType.Private);
253       }
254     };
255 
256     var response = given()
257       .spec(requestSpecification2)
258       .body(permissions)
259       .when()
260       .put(String.format("/%s/%d/%s", Constants.COLLECTIONS, collection3.getId(), Constants.PERMISSIONS))
261       .then()
262       .statusCode(403)
263       .extract()
264       .as(ErrorResponse.class);
265     assertThat(response.getMessage()).isEqualTo("Action not allowed. Only Owners are allowed to change ownership.");
266   }
267 
268   @Test
269   @Order(3)
270   public void updatePermissions_OwnerTriesToChangeOwnership_success() {
271     var permissions = new PermissionsIO() {
272       {
273         setOwner(user2.getUser().getUsername());
274         setReader(new String[] {});
275         setWriter(new String[] {});
276         setManager(new String[] { user2.getUser().getUsername() });
277         setPermissionType(PermissionType.Private);
278       }
279     };
280 
281     var actual = given()
282       .spec(requestSpecification1)
283       .body(permissions)
284       .when()
285       .put(String.format("/%s/%d/%s", Constants.COLLECTIONS, collection3.getId(), Constants.PERMISSIONS))
286       .then()
287       .statusCode(200)
288       .extract()
289       .as(PermissionsIO.class);
290     var expected = new PermissionsIO() {
291       {
292         setEntityId(collection3.getId());
293         setOwner(user2.getUser().getUsername());
294         setReader(new String[] {});
295         setWriter(new String[] {});
296         setReaderGroupIds(new long[] {});
297         setWriterGroupIds(new long[] {});
298         setManager(new String[] { user2.getUser().getUsername() });
299         setPermissionType(PermissionType.Private);
300       }
301     };
302 
303     assertThat(actual).isEqualTo(expected);
304   }
305 
306   @Test
307   @Order(3)
308   public void permittedGet() {
309     var answer = given().spec(requestSpecification1).when().get(collectionsURL + "/" + collection1.getId());
310     assertEquals(200, answer.statusCode());
311   }
312 
313   @Test
314   @Order(4)
315   public void getRolesOwner() {
316     var actual = given()
317       .spec(requestSpecification1)
318       .when()
319       .get(collectionsURL + "/" + collection1.getId() + "/" + Constants.ROLES)
320       .as(Roles.class);
321     var expected = new Roles(true, false, false, false);
322     assertEquals(expected, actual);
323   }
324 
325   @Test
326   @Order(5)
327   public void notPermittedGet() {
328     var answer = given().spec(requestSpecification2).when().get(collectionsURL + "/" + collection1.getId());
329     assertEquals(403, answer.statusCode());
330   }
331 
332   @Test
333   @Order(6)
334   public void permittedGetViaPublicReadable() {
335     var permissions = new PermissionsIO() {
336       {
337         setOwner(user1.getUser().getUsername());
338         setReader(new String[] {});
339         setWriter(new String[] {});
340         setReaderGroupIds(new long[] {});
341         setWriterGroupIds(new long[] {});
342         setManager(new String[] {});
343         setPermissionType(PermissionType.PublicReadable);
344       }
345     };
346     permissionsURL = String.format("/%s/%d/%s", Constants.COLLECTIONS, collection1.getId(), Constants.PERMISSIONS);
347     given().spec(requestSpecification1).body(permissions).when().put(permissionsURL);
348     var answer = given().spec(requestSpecification2).when().get(collectionsURL + "/" + collection1.getId());
349     assertEquals(200, answer.statusCode());
350   }
351 
352   @Test
353   @Order(7)
354   public void getRolesReader() {
355     var actual = given()
356       .spec(requestSpecification2)
357       .when()
358       .get(collectionsURL + "/" + collection1.getId() + "/" + Constants.ROLES)
359       .as(Roles.class);
360     var expected = new Roles(false, false, false, true);
361     assertEquals(expected, actual);
362   }
363 
364   @Test
365   @Order(8)
366   public void notPermittedPutViaPublicReadable() {
367     var answer = given()
368       .spec(requestSpecification2)
369       .body(collection1)
370       .when()
371       .put(collectionsURL + "/" + collection1.getId());
372     assertEquals(403, answer.statusCode());
373   }
374 
375   @Test
376   @Order(9)
377   public void permittedPutViaPublic() {
378     var permissions = new PermissionsIO() {
379       {
380         setOwner(user1.getUser().getUsername());
381         setReader(new String[] {});
382         setWriter(new String[] {});
383         setReaderGroupIds(new long[] {});
384         setWriterGroupIds(new long[] {});
385         setManager(new String[] {});
386         setPermissionType(PermissionType.Public);
387       }
388     };
389     permissionsURL = String.format("/%s/%d/%s", Constants.COLLECTIONS, collection1.getId(), Constants.PERMISSIONS);
390     given().spec(requestSpecification1).body(permissions).when().put(permissionsURL).then().statusCode(200);
391     var answer = given()
392       .spec(requestSpecification2)
393       .body(collection1)
394       .when()
395       .put(collectionsURL + "/" + collection1.getId());
396     assertEquals(200, answer.statusCode());
397   }
398 
399   @Test
400   @Order(10)
401   public void getRolesReaderWriter() {
402     var actual = given()
403       .spec(requestSpecification2)
404       .when()
405       .get(collectionsURL + "/" + collection1.getId() + "/" + Constants.ROLES)
406       .as(Roles.class);
407     var expected = new Roles(false, false, true, true);
408     assertEquals(expected, actual);
409   }
410 
411   @Test
412   @Order(11)
413   public void permittedGetViaReadersList() {
414     var permissions = new PermissionsIO() {
415       {
416         setOwner(user2.getUser().getUsername());
417         setReader(new String[] { user1.getUser().getUsername() });
418         setWriter(new String[] {});
419         setReaderGroupIds(new long[] {});
420         setWriterGroupIds(new long[] {});
421         setManager(new String[] {});
422         setPermissionType(PermissionType.Private);
423       }
424     };
425     permissionsURL = String.format("/%s/%d/%s", Constants.COLLECTIONS, collection2.getId(), Constants.PERMISSIONS);
426     given().spec(requestSpecification2).body(permissions).when().put(permissionsURL);
427     var answer = given().spec(requestSpecification1).when().get(collectionsURL + "/" + collection2.getId());
428     assertEquals(200, answer.statusCode());
429   }
430 
431   @Test
432   @Order(12)
433   public void permittedPutViaWritersList() {
434     var permissions = new PermissionsIO() {
435       {
436         setOwner(user2.getUser().getUsername());
437         setReader(new String[] { "user1" });
438         setWriter(new String[] { "user1" });
439         setReaderGroupIds(new long[] {});
440         setWriterGroupIds(new long[] {});
441         setManager(new String[] {});
442         setPermissionType(PermissionType.Private);
443       }
444     };
445     permissionsURL = String.format("/%s/%d/%s", Constants.COLLECTIONS, collection2.getId(), Constants.PERMISSIONS);
446     given().spec(requestSpecification2).body(permissions).when().put(permissionsURL);
447     var answer = given()
448       .spec(requestSpecification1)
449       .body(collection2)
450       .when()
451       .put(collectionsURL + "/" + collection2.getId());
452     assertEquals(200, answer.statusCode());
453   }
454 
455   @Test
456   @Order(13)
457   public void notPermittedGetViaReadersGroup() {
458     UserGroupIO readersGroup = new UserGroupIO();
459     readersGroup.setName("readersGroup");
460     readersGroup.setUsernames(new String[] { user4.getUser().getUsername() });
461     userGroupSpecification = new RequestSpecBuilder()
462       .setContentType(ContentType.JSON)
463       .addHeader("X-API-KEY", jws2)
464       .build();
465     readersGroup = given()
466       .spec(userGroupSpecification)
467       .body(readersGroup)
468       .when()
469       .post(userGroupURL)
470       .then()
471       .statusCode(201)
472       .extract()
473       .as(UserGroupIO.class);
474     long[] readerGroupIds = { readersGroup.getId() };
475     var permissions = new PermissionsIO() {
476       {
477         setOwner(user2.getUser().getUsername());
478         setReader(new String[] {});
479         setWriter(new String[] {});
480         setReaderGroupIds(readerGroupIds);
481         setWriterGroupIds(new long[] {});
482         setManager(new String[] {});
483         setPermissionType(PermissionType.Private);
484       }
485     };
486     permissionsURL = String.format("/%s/%d/%s", Constants.COLLECTIONS, collection2.getId(), Constants.PERMISSIONS);
487     requestSpecification2 = new RequestSpecBuilder()
488       .setContentType(ContentType.JSON)
489       .addHeader("X-API-KEY", jws2)
490       .build();
491     given().spec(requestSpecification2).body(permissions).when().put(permissionsURL);
492 
493     var answer = given().spec(requestSpecification3).when().get(collectionsURL + "/" + collection2.getId());
494     assertEquals(403, answer.statusCode());
495   }
496 
497   @Test
498   @Order(14)
499   public void permittedGetViaReadersGroup() {
500     UserGroupIO readersGroup = new UserGroupIO();
501     readersGroup.setName("readersGroup1");
502     readersGroup.setUsernames(new String[] { "user3" });
503 
504     userGroupSpecification = new RequestSpecBuilder()
505       .setContentType(ContentType.JSON)
506       .addHeader("X-API-KEY", jws2)
507       .build();
508 
509     readersGroup = given()
510       .spec(userGroupSpecification)
511       .body(readersGroup)
512       .when()
513       .post(userGroupURL)
514       .then()
515       .statusCode(201)
516       .extract()
517       .as(UserGroupIO.class);
518     long[] readerGroupIds = { readersGroup.getId() };
519     var permissions = new PermissionsIO() {
520       {
521         setOwner(user2.getUser().getUsername());
522         setReader(new String[] {});
523         setWriter(new String[] {});
524         setReaderGroupIds(readerGroupIds);
525         setWriterGroupIds(new long[] {});
526         setManager(new String[] {});
527         setPermissionType(PermissionType.Private);
528       }
529     };
530 
531     permissionsURL = String.format("/%s/%d/%s", Constants.COLLECTIONS, collection2.getId(), Constants.PERMISSIONS);
532     given().spec(requestSpecification2).body(permissions).when().put(permissionsURL).then().statusCode(200);
533 
534     var answer = given().spec(requestSpecification3).when().get(collectionsURL + "/" + collection2.getId());
535     assertEquals(200, answer.statusCode());
536   }
537 
538   @Test
539   @Order(15)
540   public void notPermittedPutViaWritersGroup() {
541     UserGroupIO writersGroup = new UserGroupIO();
542     writersGroup.setName("writersGroup");
543     writersGroup.setUsernames(new String[] { user4.getUser().getUsername() });
544     userGroupSpecification = new RequestSpecBuilder()
545       .setContentType(ContentType.JSON)
546       .addHeader("X-API-KEY", jws2)
547       .build();
548     writersGroup = given()
549       .spec(userGroupSpecification)
550       .body(writersGroup)
551       .when()
552       .post(userGroupURL)
553       .then()
554       .statusCode(201)
555       .extract()
556       .as(UserGroupIO.class);
557     long[] writersGroupIds = { writersGroup.getId() };
558     var permissions = new PermissionsIO() {
559       {
560         setOwner(user2.getUser().getUsername());
561         setReader(new String[] {});
562         setWriter(new String[] {});
563         setReaderGroupIds(new long[] {});
564         setWriterGroupIds(writersGroupIds);
565         setManager(new String[] {});
566         setPermissionType(PermissionType.Private);
567       }
568     };
569     permissionsURL = String.format("/%s/%d/%s", Constants.COLLECTIONS, collection2.getId(), Constants.PERMISSIONS);
570     given().spec(requestSpecification2).body(permissions).when().put(permissionsURL);
571 
572     var answer = given()
573       .spec(requestSpecification3)
574       .body(collection2)
575       .when()
576       .put(collectionsURL + "/" + collection2.getId());
577     assertEquals(403, answer.statusCode());
578   }
579 
580   @Test
581   @Order(16)
582   public void permittedPutViaWritersGroup() {
583     UserGroupIO writersGroup = new UserGroupIO();
584     writersGroup.setName("writersGroup1");
585     writersGroup.setUsernames(new String[] { "user3" });
586     userGroupSpecification = new RequestSpecBuilder()
587       .setContentType(ContentType.JSON)
588       .addHeader("X-API-KEY", jws2)
589       .build();
590     writersGroup = given()
591       .spec(userGroupSpecification)
592       .body(writersGroup)
593       .when()
594       .post(userGroupURL)
595       .then()
596       .statusCode(201)
597       .extract()
598       .as(UserGroupIO.class);
599     long[] writersGroupIds = { writersGroup.getId() };
600     var permissions = new PermissionsIO() {
601       {
602         setOwner(user2.getUser().getUsername());
603         setReader(new String[] {});
604         setWriter(new String[] {});
605         setReaderGroupIds(writersGroupIds);
606         setWriterGroupIds(writersGroupIds);
607         setManager(new String[] {});
608         setPermissionType(PermissionType.Private);
609       }
610     };
611     permissionsURL = String.format("/%s/%d/%s", Constants.COLLECTIONS, collection2.getId(), Constants.PERMISSIONS);
612     given().spec(requestSpecification2).body(permissions).when().put(permissionsURL);
613 
614     var answer = given()
615       .spec(requestSpecification3)
616       .body(collection2)
617       .when()
618       .put(collectionsURL + "/" + collection2.getId());
619     assertEquals(200, answer.statusCode());
620   }
621 }