KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > outerj > daisy > repository > test > AbstractAclTest


1 /*
2  * Copyright 2004 Outerthought bvba and Schaubroeck nv
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.outerj.daisy.repository.test;
17
18 import org.outerj.daisy.repository.*;
19 import org.outerj.daisy.repository.comment.CommentVisibility;
20 import org.outerj.daisy.repository.testsupport.AbstractDaisyTestCase;
21 import org.outerj.daisy.repository.user.UserManager;
22 import org.outerj.daisy.repository.user.Role;
23 import org.outerj.daisy.repository.user.User;
24 import org.outerj.daisy.repository.acl.*;
25 import org.outerj.daisy.repository.schema.DocumentType;
26 import org.outerj.daisy.repository.schema.RepositorySchema;
27 import org.outerj.daisy.repository.schema.FieldType;
28 import org.outerj.daisy.repository.schema.PartType;
29
30 /**
31  * Tests for the AccessManager.
32  */

33 public abstract class AbstractAclTest extends AbstractDaisyTestCase {
34     protected boolean resetDataStores() {
35         return true;
36     }
37
38     protected abstract RepositoryManager getRepositoryManager() throws Exception JavaDoc;
39
40     public void testAcl() throws Exception JavaDoc {
41         RepositoryManager repositoryManager = getRepositoryManager();
42
43         Repository testuserRepository = repositoryManager.getRepository(new Credentials("testuser", "testuser"));
44         testuserRepository.switchRole(Role.ADMINISTRATOR);
45
46         // Create a document type
47
RepositorySchema schema = testuserRepository.getRepositorySchema();
48
49         FieldType stringField = schema.createFieldType("StringField", ValueType.STRING);
50         stringField.setAclAllowed(true);
51         stringField.save();
52         FieldType longField = schema.createFieldType("LongField", ValueType.LONG);
53         longField.save();
54
55         PartType partType = schema.createPartType("TestPart", "");
56         partType.save();
57
58         DocumentType documentType = schema.createDocumentType("acltesttype");
59         documentType.addFieldType(stringField, false);
60         documentType.addFieldType(longField, false);
61         documentType.addPartType(partType, false);
62         documentType.save();
63
64         // Create users
65
UserManager userManager = testuserRepository.getUserManager();
66         Role userRole = userManager.getRole("user", false);
67
68         User user1 = userManager.createUser("user1");
69         user1.setPassword("user1");
70         user1.addToRole(userRole);
71         user1.setDefaultRole(userRole);
72         user1.save();
73         Repository user1Repository = repositoryManager.getRepository(new Credentials("user1", "user1"));
74
75         User user2 = userManager.createUser("user2");
76         user2.setPassword("user2");
77         user2.addToRole(userRole);
78         user2.setDefaultRole(userRole);
79         user2.save();
80         Repository user2Repository = repositoryManager.getRepository(new Credentials("user2", "user2"));
81
82         // Create documents
83
Document document1 = testuserRepository.createDocument("Document1", documentType.getId());
84         document1.setField(stringField.getId(), "hello");
85         document1.setField(longField.getId(), new Long JavaDoc(55));
86         document1.setPart(partType.getId(), "text/plain", "Once upon a time.".getBytes());
87         document1.save();
88
89         //
90
// First do some tests regarding ACL manipulation
91
//
92

93         AccessManager accessManager = testuserRepository.getAccessManager();
94         Acl acl = accessManager.getStagingAcl();
95         AclObject aclObject = acl.createNewObject("true");
96         acl.add(aclObject);
97         acl.save();
98
99         Acl aclParallel = accessManager.getStagingAcl();
100         aclParallel.save();
101         try {
102             acl.save();
103             fail("Saving ACL should have given concurrent modification exception.");
104         } catch (Exception JavaDoc e) {}
105
106         accessManager.copyStagingToLive();
107         Acl liveAcl = accessManager.getLiveAcl();
108
109         try {
110             liveAcl.save();
111             fail("Saving the live ACL should not be possible.");
112         } catch (Exception JavaDoc e) {}
113
114         assertEquals(1, liveAcl.size());
115
116         acl = accessManager.getStagingAcl();
117         aclObject = acl.get(0);
118
119         try {
120             aclObject.createNewEntry(AclSubjectType.EVERYONE, 5);
121             fail("For subject type EVERYONE, -1 is required as subject value.");
122         } catch (Exception JavaDoc e) {}
123
124         try {
125             aclObject.createNewEntry(AclSubjectType.USER, -1);
126             fail("For subject type USER, -1 is not allowed as subject value.");
127         } catch (Exception JavaDoc e) {}
128
129         try {
130             aclObject.createNewEntry(AclSubjectType.ROLE, -1);
131             fail("For subject type USER, -1 is not allowed as subject value.");
132         } catch (Exception JavaDoc e) {}
133
134         try {
135             AclEntry aclEntry = aclObject.createNewEntry(AclSubjectType.EVERYONE, -1);
136             aclEntry.setSubjectValue(5);
137             fail("For subject type EVERYONE, 5 is not allowed as subject value.");
138         } catch (Exception JavaDoc e) {}
139
140         AclEntry aclEntry = aclObject.createNewEntry(AclSubjectType.EVERYONE, -1);
141         aclEntry.set(AclPermission.READ_LIVE, AclActionType.GRANT);
142         aclEntry.set(AclPermission.READ, AclActionType.GRANT);
143         assertEquals(AclActionType.DO_NOTHING, aclEntry.get(AclPermission.WRITE));
144         assertEquals(AclActionType.DO_NOTHING, aclEntry.get(AclPermission.PUBLISH));
145         aclEntry.set(AclPermission.PUBLISH, AclActionType.GRANT);
146         assertEquals(AclActionType.GRANT, aclEntry.get(AclPermission.PUBLISH));
147         aclEntry.set(AclPermission.DELETE, AclActionType.GRANT);
148         assertEquals(AclActionType.GRANT, aclEntry.get(AclPermission.DELETE));
149         aclObject.add(aclEntry);
150
151         acl.save();
152
153         // Check that saving staging ACL didn't influence live ACL
154
liveAcl = accessManager.getLiveAcl();
155         assertEquals(0, liveAcl.get(0).size());
156
157         // check that copying live back to staging works
158
accessManager.copyLiveToStaging();
159         acl = accessManager.getStagingAcl();
160         assertEquals(0, acl.get(0).size());
161
162         // Test object expressions don't work on fields that are not ACL allowed
163
aclObject = acl.createNewObject("$LongField = 55");
164         acl.add(aclObject);
165         acl.save();
166         try {
167             accessManager.getAclInfoOnStaging(-1, new long[] {-1}, document1.getId());
168             fail("Evaluating an ACL containg a check on a non-ACL allowed field should have failed.");
169         } catch (RepositoryException e) {}
170
171         // Overview of the ACL created below:
172
// READ_LIVE READ WRITE PUBLISH DELETE
173
// true
174
// role=user G G G G G
175
// documentType='acltesttype' and $StringField='ciao'
176
// user=user1 G G D D D
177
// documentType='acltesttype' and $StringField='hello'
178
// everyone G G D D D
179
// documentType='acltesttype'
180
// user=user2 D D G G G
181
// $StringField='ta'
182
// user=user2 G G G D D
183
// user=user1 G G G G G
184
// $StringField='tata'
185
// user=user2 G D D D D
186
// user=user1 G G G G G
187

188         acl = accessManager.getStagingAcl();
189         acl.clear();
190
191         AclObject object = acl.createNewObject("true");
192         acl.add(object);
193         AclEntry entry = object.createNewEntry(AclSubjectType.ROLE, userRole.getId());
194         object.add(entry);
195         entry.set(AclPermission.READ_LIVE, AclActionType.GRANT);
196         entry.set(AclPermission.READ, AclActionType.GRANT);
197         entry.set(AclPermission.WRITE, AclActionType.GRANT);
198         entry.set(AclPermission.PUBLISH, AclActionType.GRANT);
199         entry.set(AclPermission.DELETE, AclActionType.GRANT);
200
201         object = acl.createNewObject("documentType = 'acltesttype' and $StringField='ciao'");
202         acl.add(object);
203         entry = object.createNewEntry(AclSubjectType.USER, user1.getId());
204         object.add(entry);
205         entry.set(AclPermission.READ_LIVE, AclActionType.GRANT);
206         entry.set(AclPermission.READ, AclActionType.GRANT);
207         entry.set(AclPermission.WRITE, AclActionType.DENY);
208         entry.set(AclPermission.PUBLISH, AclActionType.DENY);
209         entry.set(AclPermission.DELETE, AclActionType.DENY);
210
211         object = acl.createNewObject("documentType = 'acltesttype' and $StringField='hello'");
212         acl.add(object);
213         entry = object.createNewEntry(AclSubjectType.EVERYONE, -1);
214         object.add(entry);
215         entry.set(AclPermission.READ_LIVE, AclActionType.GRANT);
216         entry.set(AclPermission.READ, AclActionType.GRANT);
217         entry.set(AclPermission.WRITE, AclActionType.DENY);
218         entry.set(AclPermission.PUBLISH, AclActionType.DENY);
219         entry.set(AclPermission.DELETE, AclActionType.DENY);
220
221         object = acl.createNewObject("documentType = 'acltesttype'");
222         acl.add(object);
223         entry = object.createNewEntry(AclSubjectType.USER, user2.getId());
224         object.add(entry);
225         entry.set(AclPermission.READ_LIVE, AclActionType.DENY);
226         entry.set(AclPermission.READ, AclActionType.DENY);
227         entry.set(AclPermission.WRITE, AclActionType.GRANT);
228         entry.set(AclPermission.PUBLISH, AclActionType.DENY);
229         entry.set(AclPermission.DELETE, AclActionType.DENY);
230
231         object = acl.createNewObject("$StringField = 'ta'");
232         acl.add(object);
233         entry = object.createNewEntry(AclSubjectType.USER, user2.getId());
234         object.add(entry);
235         entry.set(AclPermission.READ_LIVE, AclActionType.GRANT);
236         entry.set(AclPermission.READ, AclActionType.GRANT);
237         entry.set(AclPermission.WRITE, AclActionType.GRANT);
238         entry.set(AclPermission.PUBLISH, AclActionType.DENY);
239         entry.set(AclPermission.DELETE, AclActionType.DENY);
240         entry = object.createNewEntry(AclSubjectType.USER, user1.getId());
241         object.add(entry);
242         entry.set(AclPermission.READ_LIVE, AclActionType.GRANT);
243         entry.set(AclPermission.READ, AclActionType.GRANT);
244         entry.set(AclPermission.WRITE, AclActionType.GRANT);
245         entry.set(AclPermission.PUBLISH, AclActionType.GRANT);
246         entry.set(AclPermission.DELETE, AclActionType.GRANT);
247
248         object = acl.createNewObject("$StringField = 'tata'");
249         acl.add(object);
250         entry = object.createNewEntry(AclSubjectType.USER, user2.getId());
251         object.add(entry);
252         entry.set(AclPermission.READ_LIVE, AclActionType.GRANT);
253         entry.set(AclPermission.READ, AclActionType.DENY);
254         entry.set(AclPermission.WRITE, AclActionType.DENY);
255         entry.set(AclPermission.PUBLISH, AclActionType.DENY);
256         entry.set(AclPermission.DELETE, AclActionType.DENY);
257         entry = object.createNewEntry(AclSubjectType.USER, user1.getId());
258         object.add(entry);
259         entry.set(AclPermission.READ_LIVE, AclActionType.GRANT);
260         entry.set(AclPermission.READ, AclActionType.GRANT);
261         entry.set(AclPermission.WRITE, AclActionType.GRANT);
262         entry.set(AclPermission.PUBLISH, AclActionType.GRANT);
263         entry.set(AclPermission.DELETE, AclActionType.GRANT);
264
265         acl.save();
266         accessManager.copyStagingToLive();
267
268         // owner of the document should have all permissions
269
AclResultInfo result = accessManager.getAclInfoOnLive(testuserRepository.getUserId(), new long[] {-1}, document1.getId());
270         assertEquals("owner should have read access", result.isAllowed(AclPermission.READ), true);
271         assertEquals("owner should have write access", result.isAllowed(AclPermission.WRITE), true);
272
273         // everyone should have read access on the document, but not write access
274
result = accessManager.getAclInfoOnLive(-1, new long[] {-1}, document1.getId());
275         assertEquals(result.isAllowed(AclPermission.READ), true);
276         assertEquals(result.isAllowed(AclPermission.WRITE), false);
277
278         // everyone should have read access on the document, but not write access
279
result = accessManager.getAclInfoOnLive(user2.getId(), new long[] {userRole.getId()}, document1.getId());
280         assertEquals(result.isAllowed(AclPermission.READ), false);
281         assertEquals(result.isAllowed(AclPermission.WRITE), false); // Note that even though write access is granted
282
// in the ACL, write rights can never be more
283
// liberal then read rights.
284

285         // Document owner should be able to retrieve the document
286
testuserRepository.getDocument(document1.getId(), true);
287
288         // Test that user2 should not have read access
289
try {
290             user2Repository.getDocument(document1.getId(), true);
291             fail("user 'user2' should not be able to access Document1");
292         } catch (RepositoryException e) {}
293
294         // and verify this is also the case if user2 tries to directly access part data
295
try {
296             user2Repository.getPartData(document1.getId(), 1, partType.getId());
297         } catch (RepositoryException e) {}
298
299         Document document2 = user1Repository.createDocument("Document2", documentType.getId());
300         document2.setField(stringField.getId(), "hi");
301         document2.setField(longField.getId(), new Long JavaDoc(55));
302         document2.save();
303
304         // User 'user1' should be able to save a document having $StringField='ciao' IF HE IS THE OWNER
305
document2 = user1Repository.getDocument(document2.getId(), true);
306         document2.setField("StringField", "ciao");
307         document2.save();
308
309         // User 'user1' should not be able to save a document having $StringField='ciao'
310
Document document3 = testuserRepository.createDocument("Document3", documentType.getId());
311         document3.save();
312         document3 = user1Repository.getDocument(document3.getId(), true);
313         document3.save(); // verifies that saving under normal conditions would work
314
try {
315             document3.setField("StringField", "ciao");
316             document3.save();
317             fail("Saving document3 by user 'user1' should have failed.");
318         } catch (RepositoryException e) {}
319
320         // test that a new document cannot be created if the user himself would not have
321
// access to it (even if he is the owner, and would thus never be able to loose
322
// these rights, we don't let him create new documents this way)
323
Document document4 = user1Repository.createDocument("Document4", documentType.getId());
324         try {
325             document4.setField("StringField", "ciao");
326             document4.save();
327             fail("Saving a new document (document4) to which the user would not have access (if he/she were not owner) should fail.");
328         } catch (RepositoryException e) {}
329
330
331         // Adding comments only works if you have read access
332
try {
333             user2Repository.getCommentManager().addComment(document1.getId(), CommentVisibility.PUBLIC, "hello");
334             fail("Adding a comment should have failed because user2 does not have read access.");
335         } catch (Exception JavaDoc e) {}
336
337         user1Repository.getCommentManager().addComment(document1.getId(), CommentVisibility.PUBLIC, "hello");
338
339
340         // Test private flag
341
Document document5 = user1Repository.createDocument("Document5", documentType.getId());
342         document5.setPrivate(true);
343         document5.save();
344
345         // owner should be able to access private document
346
user1Repository.getDocument(document5.getId(), true);
347         // admin should be able to access private document
348
testuserRepository.getDocument(document5.getId(), true);
349
350         Document document6 = testuserRepository.createDocument("Document6", documentType.getId());
351         document6.setPrivate(true);
352         document6.save();
353         try {
354             user1Repository.getDocument(document6.getId(), true);
355             fail("user1 should not have access to a private document of someone else.");
356         } catch (Exception JavaDoc e) {}
357
358         Document document7 = user2Repository.createDocument("Document7", documentType.getId());
359         document7.setOwner(user1.getId()); // otherwise user will always have publish right since he is owner
360
document7.setField("StringField", "ta");
361         document7.setNewVersionState(VersionState.PUBLISH);
362         document7.save();
363         document7 = user2Repository.getDocument(document7.getId(), true);
364         assertTrue("user2 can't put publish document", document7.getLastVersion().getState() == VersionState.DRAFT);
365
366         AclResultInfo info = testuserRepository.getAccessManager().getAclInfoOnLive(user2Repository.getUserId(), user2Repository.getActiveRoleIds(), document7.getId());
367         info.dump();
368
369         try {
370             document7.getLastVersion().setState(VersionState.PUBLISH);
371             fail("Setting state to publish should have failed.");
372         } catch (Exception JavaDoc e) {}
373
374         Document document7user1 = user1Repository.getDocument(document7.getId(), true);
375         try {
376             document7user1.getLastVersion().setState(VersionState.PUBLISH);
377         } catch (Exception JavaDoc e) {}
378
379         assertTrue(user2Repository.getAccessManager().getAclInfoOnLive(user2.getId(), user2Repository.getActiveRoleIds(), document7.getId()).getActionType(AclPermission.DELETE) == AclActionType.DENY);
380         try {
381             user2Repository.deleteDocument(document7.getId());
382             fail("user2 shouldn't be able to delete document.");
383         } catch (AccessException e) {}
384
385         assertTrue(user1Repository.getAccessManager().getAclInfoOnLive(user1.getId(), user1Repository.getActiveRoleIds(), document7.getId()).getActionType(AclPermission.DELETE) == AclActionType.GRANT);
386         user1Repository.deleteDocument(document7.getId());
387
388         // test read live access
389
Document document8 = user1Repository.createDocument("Document8", documentType.getId());
390         document8.setField("StringField", "tata");
391         document8.save();
392         document8.setName("Document8 - 2");
393         document8.setNewVersionState(VersionState.DRAFT);
394         document8.save();
395
396         testuserRepository.getAccessManager().getAclInfoOnLive(user2.getId(), user2.getAllRoleIds(), document8.getVariantKey()).dump();
397
398         document8 = user2Repository.getDocument(document8.getId(), false);
399         callDisallowedVersionMethods(document8);
400         document8 = user2Repository.getDocument(document8.getId(), true);
401         callDisallowedVersionMethods(document8);
402
403         document8 = user1Repository.getDocument(document8.getId(), true);
404         document8.setRetired(true);
405         document8.save();
406
407         try {
408             document8 = user2Repository.getDocument(document8.getId(), false);
409             fail("Getting live version of retired document should fail if user has only read live permission");
410         } catch (DocumentReadDeniedException e) {}
411
412         try {
413             document8 = user2Repository.getDocument(document8.getId(), true);
414             fail("Getting live version of retired document should fail if user has only read live permission");
415         } catch (DocumentReadDeniedException e) {}
416
417         //
418
// Test filtering of document types
419
//
420

421         // start by creating some document types
422
DocumentType documentTypeA = schema.createDocumentType("A");
423         documentTypeA.save();
424         DocumentType documentTypeB = schema.createDocumentType("B");
425         documentTypeB.save();
426         DocumentType documentTypeC = schema.createDocumentType("C");
427         documentTypeC.save();
428
429         // Create an acl
430
acl = accessManager.getStagingAcl();
431         acl.clear();
432
433         aclObject = acl.createNewObject("documentType = 'A'");
434         aclEntry = aclObject.createNewEntry(AclSubjectType.EVERYONE, -1);
435         aclEntry.set(AclPermission.READ, AclActionType.GRANT);
436         aclEntry.set(AclPermission.WRITE, AclActionType.GRANT);
437         aclObject.add(aclEntry);
438         acl.add(aclObject);
439
440         aclObject = acl.createNewObject("documentType = 'B' and $StringField = 'hello'");
441         aclEntry = aclObject.createNewEntry(AclSubjectType.EVERYONE, -1);
442         aclEntry.set(AclPermission.READ, AclActionType.GRANT);
443         aclEntry.set(AclPermission.WRITE, AclActionType.GRANT);
444         aclObject.add(aclEntry);
445         acl.add(aclObject);
446
447         aclObject = acl.createNewObject("documentType = 'C'");
448         aclEntry = aclObject.createNewEntry(AclSubjectType.EVERYONE, -1);
449         aclEntry.set(AclPermission.READ, AclActionType.DENY);
450         aclEntry.set(AclPermission.WRITE, AclActionType.DENY);
451         aclObject.add(aclEntry);
452         acl.add(aclObject);
453
454         acl.save();
455         accessManager.copyStagingToLive();
456
457         long[] filteredDocTypes = user1Repository.getAccessManager().filterDocumentTypes(new long[] {documentTypeA.getId(), documentTypeB.getId(), documentTypeC.getId()}, -1);
458         assertEquals(2, filteredDocTypes.length);
459         assertEquals(documentTypeA.getId(), filteredDocTypes[0]);
460         assertEquals(documentTypeB.getId(), filteredDocTypes[1]);
461
462         // TODO: also test this with relation to collections
463

464
465         // Note: the QueryTest implicitely also contains some ACL testing due
466
// to the ACL-based filtering of resultsets, which is there tested.
467
}
468
469     private void callDisallowedVersionMethods(Document document) throws Exception JavaDoc {
470         document.getLiveVersion();
471
472         try {
473             document.getVersions();
474             fail("Getting non-live version data should fail.");
475         } catch (RuntimeException JavaDoc e) {}
476
477         try {
478             document.getLastVersion();
479             fail("Getting non-live version data should fail.");
480         } catch (RuntimeException JavaDoc e) {}
481
482         try {
483             document.getXml();
484             fail("Getting non-live version data should fail.");
485         } catch (RuntimeException JavaDoc e) {}
486
487         try {
488             document.getXml(2);
489             fail("Getting non-live version data should fail.");
490         } catch (RuntimeException JavaDoc e) {}
491
492         try {
493             document.getName();
494             fail("Getting non-live version data should fail.");
495         } catch (RuntimeException JavaDoc e) {}
496
497         try {
498             document.getField("whatever");
499             fail("Getting non-live version data should fail.");
500         } catch (RuntimeException JavaDoc e) {}
501     }
502 }
503
Popular Tags