1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.security.authorization.cache.internal

File DefaultSecurityCacheTest.java

 

Code metrics

60
300
44
4
812
641
85
0.28
6.82
11
1.93

Classes

Class Line # Actions
DefaultSecurityCacheTest 77 297 0% 82 14
0.9648241496.5%
DefaultSecurityCacheTest.KeepEntries 349 0 - 0 0
-1.0 -
DefaultSecurityCacheTest.Keeper 356 3 0% 3 2
0.666666766.7%
DefaultSecurityCacheTest.Remover 404 0 - 0 0
-1.0 -
 

Contributing tests

This file is covered by 6 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.security.authorization.cache.internal;
21   
22    import java.util.ArrayList;
23    import java.util.Arrays;
24    import java.util.Collection;
25    import java.util.HashMap;
26    import java.util.Iterator;
27    import java.util.List;
28    import java.util.Map;
29   
30    import org.junit.Before;
31    import org.junit.Rule;
32    import org.junit.Test;
33    import org.xwiki.cache.CacheManager;
34    import org.xwiki.cache.config.CacheConfiguration;
35    import org.xwiki.model.EntityType;
36    import org.xwiki.model.internal.reference.DefaultStringEntityReferenceSerializer;
37    import org.xwiki.model.internal.reference.DefaultSymbolScheme;
38    import org.xwiki.model.reference.DocumentReference;
39    import org.xwiki.model.reference.EntityReferenceSerializer;
40    import org.xwiki.model.reference.SpaceReference;
41    import org.xwiki.model.reference.WikiReference;
42    import org.xwiki.security.AbstractSecurityTestCase;
43    import org.xwiki.security.DefaultSecurityReferenceFactory;
44    import org.xwiki.security.GroupSecurityReference;
45    import org.xwiki.security.SecurityReference;
46    import org.xwiki.security.SecurityReferenceFactory;
47    import org.xwiki.security.UserSecurityReference;
48    import org.xwiki.security.authorization.SecurityAccessEntry;
49    import org.xwiki.security.authorization.SecurityEntry;
50    import org.xwiki.security.authorization.SecurityRuleEntry;
51    import org.xwiki.security.authorization.cache.ConflictingInsertionException;
52    import org.xwiki.security.authorization.cache.ParentEntryEvictedException;
53    import org.xwiki.security.authorization.cache.SecurityShadowEntry;
54    import org.xwiki.security.internal.XWikiBridge;
55    import org.xwiki.test.LogRule;
56    import org.xwiki.test.annotation.ComponentList;
57    import org.xwiki.test.mockito.MockitoComponentMockingRule;
58   
59    import static org.hamcrest.CoreMatchers.is;
60    import static org.hamcrest.CoreMatchers.nullValue;
61    import static org.hamcrest.CoreMatchers.sameInstance;
62    import static org.junit.Assert.assertThat;
63    import static org.junit.Assert.fail;
64    import static org.mockito.Mockito.any;
65    import static org.mockito.Mockito.mock;
66    import static org.mockito.Mockito.when;
67   
68    /**
69    * Default security cache Unit Test.
70    *
71    * @version $Id: 6151557e95cdc28e46025fb7a7ad2891771a29ca $
72    */
73    @ComponentList({
74    DefaultStringEntityReferenceSerializer.class,
75    DefaultSymbolScheme.class
76    })
 
77    public class DefaultSecurityCacheTest extends AbstractSecurityTestCase
78    {
79    @Rule
80    public final MockitoComponentMockingRule<SecurityCache> securityCacheMocker =
81    new MockitoComponentMockingRule<SecurityCache>(DefaultSecurityCache.class, SecurityCache.class,
82    Arrays.asList(EntityReferenceSerializer.class));
83   
84    @Rule
85    public final MockitoComponentMockingRule<SecurityReferenceFactory> securityReferenceFactoryMocker =
86    new MockitoComponentMockingRule<SecurityReferenceFactory>(DefaultSecurityReferenceFactory.class);
87   
88    @Rule
89    public LogRule logCapture = new LogRule();
90   
91    private SecurityCache securityCache;
92   
93    private SecurityReferenceFactory factory;
94   
95    private TestCache<Object> cache;
96   
97    private SecurityReference aMissingParentRef;
98    private SecurityReference aMissingEntityRef;
99   
100    private UserSecurityReference aMissingUserRef;
101    private GroupSecurityReference aMissingGroupRef;
102    private SecurityReference aMissingWikiRef;
103   
 
104  6 toggle @Before
105    public void configure() throws Exception
106    {
107  6 if (cache == null) {
108  6 cache = new TestCache<Object>();
109   
110  6 final CacheManager cacheManager = securityCacheMocker.getInstance(CacheManager.class);
111  6 when(cacheManager.createNewCache(any(CacheConfiguration.class))).thenReturn(cache);
112    }
113   
114  6 XWikiBridge xwikiBridge = securityReferenceFactoryMocker.getInstance(XWikiBridge.class);
115  6 when(xwikiBridge.getMainWikiReference()).thenReturn(new WikiReference("xwiki"));
116   
117  6 this.factory = securityReferenceFactoryMocker.getComponentUnderTest();
118  6 this.securityCache = securityCacheMocker.getComponentUnderTest();
119   
120  6 aMissingParentRef = factory.newEntityReference(new SpaceReference("space", new WikiReference("missing")));
121  6 aMissingEntityRef = factory.newEntityReference(new DocumentReference("missingPage",
122    xspaceRef.getOriginalSpaceReference()));
123   
124  6 aMissingUserRef = factory.newUserReference(new DocumentReference("missingUser",
125    xXWikiSpace.getOriginalSpaceReference()));
126  6 aMissingGroupRef = factory.newGroupReference(new DocumentReference("missingGroup",
127    xXWikiSpace.getOriginalSpaceReference()));
128  6 aMissingWikiRef = factory.newEntityReference(new WikiReference("missingWiki"));
129    }
130   
 
131  183 toggle private SecurityRuleEntry mockSecurityRuleEntry(final SecurityReference ref)
132    {
133  183 SecurityRuleEntry entry = mock(SecurityRuleEntry.class, "Rules for " + ref.toString());
134  183 when(entry.getReference()).thenReturn(ref);
135  183 return entry;
136    }
137   
 
138  72 toggle private SecurityShadowEntry mockSecurityShadowEntry(final UserSecurityReference user,
139    final SecurityReference wiki)
140    {
141  72 SecurityShadowEntry entry = mock(SecurityShadowEntry.class,
142    "Shadow for " + user.toString() + " on " + wiki.toString());
143  72 when(entry.getReference()).thenReturn(user);
144  72 when(entry.getWikiReference()).thenReturn(wiki);
145  72 return entry;
146    }
147   
 
148  651 toggle private SecurityAccessEntry mockSecurityAccessEntry(final SecurityReference ref,
149    final UserSecurityReference user)
150    {
151  651 SecurityAccessEntry entry = mock(SecurityAccessEntry.class,
152    "Access for " + user.toString() + " on " + ref.toString());
153  651 when(entry.getReference()).thenReturn(ref);
154  651 when(entry.getUserReference()).thenReturn(user);
155  651 return entry;
156    }
157   
 
158  653 toggle private String AddAccessEntry(final SecurityAccessEntry entry)
159    throws ParentEntryEvictedException, ConflictingInsertionException
160    {
161  653 WikiReference entityWiki =
162    (WikiReference) entry.getReference().getOriginalReference().extractReference(EntityType.WIKI);
163  653 WikiReference userWiki = entry.getUserReference().getOriginalReference().getWikiReference();
164  653 if (entityWiki != userWiki) {
165  384 if (entry.getUserReference().isGlobal()) {
166  180 securityCache.add(entry, factory.newEntityReference(entityWiki));
167  180 return cache.getLastInsertedKey();
168    } else {
169  204 return null;
170    }
171    } else {
172  269 securityCache.add(entry);
173  266 return cache.getLastInsertedKey();
174    }
175    }
176   
 
177  67 toggle private String AddUserEntry(SecurityRuleEntry entry, Collection<GroupSecurityReference> groups)
178    throws ParentEntryEvictedException, ConflictingInsertionException
179    {
180  67 securityCache.add(entry, groups);
181  66 return cache.getLastInsertedKey();
182    }
183   
 
184  184 toggle private String AddRuleEntry(SecurityRuleEntry entry)
185    throws ParentEntryEvictedException, ConflictingInsertionException
186    {
187  184 if (groupUserRefs.contains(entry.getReference())) {
188  36 final List<GroupSecurityReference> groups = new ArrayList<GroupSecurityReference>();
189  36 for (GroupSecurityReference group : groupRefs.keySet()) {
190  144 if (groupRefs.get(group).contains(entry.getReference())) {
191  72 if (group.getOriginalReference().getWikiReference().equals(
192    entry.getReference().getOriginalDocumentReference().getWikiReference())) {
193  48 groups.add(group);
194    }
195    }
196    }
197  36 AddUserEntry(entry, groups);
198  148 } else if (userRefs.contains(entry.getReference())) {
199  30 AddUserEntry(entry, null);
200    } else {
201  118 securityCache.add(entry);
202    }
203  182 return cache.getLastInsertedKey();
204    }
205   
 
206  73 toggle private String AddUserEntry(SecurityShadowEntry user)
207    throws ParentEntryEvictedException, ConflictingInsertionException
208    {
209  73 if (groupUserRefs.contains(user.getReference())) {
210  30 final List<GroupSecurityReference> groups = new ArrayList<GroupSecurityReference>();
211  30 for (GroupSecurityReference group : groupRefs.keySet()) {
212  120 if (groupRefs.get(group).contains(user.getReference())) {
213  80 if (group.getOriginalReference().getWikiReference().equals(
214    user.getWikiReference().getOriginalWikiReference())) {
215  20 groups.add(group);
216    }
217    }
218    }
219  30 securityCache.add(user, groups);
220    } else {
221  43 securityCache.add(user, null);
222    }
223  71 return cache.getLastInsertedKey();
224    }
225   
 
226  5 toggle private Map<String, SecurityEntry> InsertUsersWithouShadow()
227    throws ConflictingInsertionException, ParentEntryEvictedException
228    {
229  5 Map<String, SecurityEntry> entries = new HashMap<String, SecurityEntry>();
230   
231    // Add wikis
232  5 for (SecurityReference ref : wikiRefs) {
233  15 SecurityRuleEntry entry = mockSecurityRuleEntry(ref);
234  15 entries.put(AddRuleEntry(entry), entry);
235    }
236   
237    // XWiki spaces are required to load user entries
238  5 for (SecurityReference ref : xwikiSpaceRefs) {
239  15 SecurityRuleEntry entry = mockSecurityRuleEntry(ref);
240  15 entries.put(AddRuleEntry(entry), entry);
241    }
242   
243    // Insert some users
244  5 for (SecurityReference ref : userRefs) {
245  25 SecurityRuleEntry entry = mockSecurityRuleEntry(ref);
246  25 entries.put(AddRuleEntry(entry), entry);
247    }
248   
249    // Insert some groups
250  5 for (SecurityReference ref : groupRefs.keySet()) {
251  20 SecurityRuleEntry entry = mockSecurityRuleEntry(ref);
252  20 entries.put(AddRuleEntry(entry), entry);
253    }
254   
255    // Insert users in groups
256  5 for (SecurityReference ref : groupUserRefs) {
257  30 SecurityRuleEntry entry = mockSecurityRuleEntry(ref);
258  30 entries.put(AddRuleEntry(entry), entry);
259    }
260   
261  5 return entries;
262    }
263   
 
264  4 toggle private Map<String, SecurityEntry> InsertUsers()
265    throws ConflictingInsertionException, ParentEntryEvictedException
266    {
267  4 Map<String, SecurityEntry> entries = InsertUsersWithouShadow();
268   
269    // Check inserting shadow users
270  4 for (UserSecurityReference ref : userRefs) {
271  20 if (ref.isGlobal()) {
272  8 for(SecurityReference wiki : Arrays.asList(wikiRef, anotherWikiRef)) {
273  16 SecurityShadowEntry entry = mockSecurityShadowEntry(ref, wiki);
274  16 entries.put(AddUserEntry(entry), entry);
275    }
276    }
277    }
278   
279    // Insert some groups
280  4 for (GroupSecurityReference ref : groupRefs.keySet()) {
281  16 if (ref.isGlobal()) {
282  8 for(SecurityReference wiki : Arrays.asList(wikiRef, anotherWikiRef)) {
283  16 SecurityShadowEntry entry = mockSecurityShadowEntry(ref, wiki);
284  16 entries.put(AddUserEntry(entry), entry);
285    }
286    }
287    }
288   
289    // Insert shadow users in shadow groups
290  4 for (UserSecurityReference ref : groupUserRefs) {
291  24 if (ref.isGlobal()) {
292  12 for(SecurityReference wiki : Arrays.asList(wikiRef, anotherWikiRef)) {
293  24 SecurityShadowEntry entry = mockSecurityShadowEntry(ref, wiki);
294  24 entries.put(AddUserEntry(entry), entry);
295    }
296    }
297    }
298   
299  4 return entries;
300    }
301   
 
302  4 toggle private Map<String, SecurityEntry> InsertEntities()
303    throws ConflictingInsertionException, ParentEntryEvictedException
304    {
305  4 Map<String, SecurityEntry> entries = new HashMap<String, SecurityEntry>();
306   
307  4 for (SecurityReference ref : entityRefs) {
308  56 if (securityCache.get(ref) == null) {
309  44 SecurityRuleEntry entry = mockSecurityRuleEntry(ref);
310  44 entries.put(AddRuleEntry(entry), entry);
311    }
312    }
313   
314  4 return entries;
315    }
316   
 
317  3 toggle private Map<String, SecurityEntry> InsertAccess()
318    throws ConflictingInsertionException, ParentEntryEvictedException
319    {
320  3 Map<String, SecurityEntry> entries = new HashMap<String, SecurityEntry>();
321   
322    // Insert access for simple users
323  3 for (UserSecurityReference user : userRefs) {
324  15 for (SecurityReference ref : entityRefs) {
325  210 SecurityAccessEntry entry = mockSecurityAccessEntry(ref, user);
326  210 String key = AddAccessEntry(entry);
327  129 if (key != null) entries.put(key, entry);
328    }
329  15 SecurityAccessEntry entry = mockSecurityAccessEntry(user, user);
330  15 String key = AddAccessEntry(entry);
331  15 if (key != null) entries.put(key, entry);
332    }
333   
334    // Insert access for group users
335  3 for (UserSecurityReference user : groupUserRefs) {
336  18 for (SecurityReference ref : entityRefs) {
337  252 SecurityAccessEntry entry = mockSecurityAccessEntry(ref, user);
338  252 String key = AddAccessEntry(entry);
339  180 if (key != null) entries.put(key, entry);
340    }
341  18 SecurityAccessEntry entry = mockSecurityAccessEntry(user, user);
342  18 String key = AddAccessEntry(entry);
343  18 if (key != null) entries.put(key, entry);
344    }
345   
346  3 return entries;
347    }
348   
 
349    interface KeepEntries
350    {
351    boolean keepRule(SecurityRuleEntry entry);
352    boolean keepAccess(SecurityAccessEntry entry);
353    boolean keepShadow(SecurityShadowEntry entry);
354    }
355   
 
356    class Keeper implements KeepEntries
357    {
 
358  32 toggle public boolean keepRule(SecurityRuleEntry entry) {
359  32 return true;
360    }
 
361  0 toggle public boolean keepAccess(SecurityAccessEntry entry) {
362  0 return true;
363    }
 
364  90 toggle public boolean keepShadow(SecurityShadowEntry entry) {
365  90 return true;
366    }
367    }
368   
 
369  15 toggle private void checkEntries(Map<String, SecurityEntry> entries, KeepEntries keeper)
370    {
371  1827 for(Iterator<Map.Entry<String, SecurityEntry>> it = entries.entrySet().iterator(); it.hasNext(); ) {
372  1812 Map.Entry<String, SecurityEntry> entry = it.next();
373  1812 if (entry.getValue() instanceof SecurityRuleEntry) {
374  408 SecurityRuleEntry sentry = (SecurityRuleEntry) entry.getValue();
375  408 if (keeper.keepRule(sentry)) {
376  344 assertThat(((DefaultSecurityCache) securityCache).get(entry.getKey()),
377    sameInstance(entry.getValue()));
378    } else {
379  64 it.remove();
380  64 assertThat(((DefaultSecurityCache) securityCache).get(entry.getKey()), nullValue());
381    }
382  1404 } else if (entry.getValue() instanceof SecurityAccessEntry) {
383  1230 SecurityAccessEntry sentry = (SecurityAccessEntry) entry.getValue();
384  1230 if (keeper.keepAccess(sentry)) {
385  1001 assertThat(((DefaultSecurityCache) securityCache).get(entry.getKey()),
386    sameInstance(entry.getValue()));
387    } else {
388  229 it.remove();
389  229 assertThat(((DefaultSecurityCache) securityCache).get(entry.getKey()), nullValue());
390    }
391    } else {
392  174 SecurityShadowEntry sentry = (SecurityShadowEntry) entry.getValue();
393  174 if (keeper.keepShadow(sentry)) {
394  146 assertThat(((DefaultSecurityCache) securityCache).get(entry.getKey()),
395    sameInstance(entry.getValue()));
396    } else {
397  28 it.remove();
398  28 assertThat(((DefaultSecurityCache) securityCache).get(entry.getKey()), nullValue());
399    }
400    }
401    }
402    }
403   
 
404    interface Remover
405    {
406    void remove(SecurityReference ref);
407    }
408   
 
409  2 toggle private void removerTest(Map<String, SecurityEntry> entries, Remover remover) {
410   
411    // Remove an document entity
412  2 remover.remove(docRef);
413  2 checkEntries(entries, new Keeper() {
 
414  64 toggle public boolean keepRule(SecurityRuleEntry entry) {
415  64 return entry.getReference() != docRef;
416    }
 
417  228 toggle public boolean keepAccess(SecurityAccessEntry entry) {
418  228 return entry.getReference() != docRef;
419    }
420    });
421   
422    // Remove an user entity
423  2 remover.remove(anotherWikiUserRef);
424  2 checkEntries(entries, new Keeper() {
 
425  62 toggle public boolean keepRule(SecurityRuleEntry entry) {
426  62 return entry.getReference() != anotherWikiUserRef;
427    }
 
428  208 toggle public boolean keepAccess(SecurityAccessEntry entry) {
429  208 return entry.getUserReference() != anotherWikiUserRef;
430    }
431    });
432   
433    // Remove a global user entity with shadow entry
434  2 remover.remove(anotherGroupXUserRef);
435  2 checkEntries(entries, new Keeper() {
 
436  60 toggle public boolean keepRule(SecurityRuleEntry entry) {
437  60 return entry.getReference() != anotherGroupXUserRef;
438    }
 
439  200 toggle public boolean keepAccess(SecurityAccessEntry entry) {
440  200 return entry.getUserReference() != anotherGroupXUserRef;
441    }
 
442  28 toggle public boolean keepShadow(SecurityShadowEntry entry) {
443  28 return entry.getReference() != anotherGroupXUserRef;
444    }
445    });
446   
447    // Remove a group entity
448  2 remover.remove(groupRef);
449  2 checkEntries(entries, new Keeper() {
 
450  58 toggle public boolean keepRule(SecurityRuleEntry entry) {
451  58 return (entry.getReference() != groupRef
452    && (!groupRefs.get(groupRef).contains(entry.getReference())
453    || entry.getReference().getOriginalReference().extractReference(EntityType.WIKI)
454    != wikiRef.getOriginalWikiReference()));
455    }
 
456  172 toggle public boolean keepAccess(SecurityAccessEntry entry) {
457  172 return (!groupRefs.get(groupRef).contains(entry.getUserReference())
458    || entry.getReference().getOriginalReference().extractReference(EntityType.WIKI)
459    != wikiRef.getOriginalWikiReference());
460    }
 
461  24 toggle public boolean keepShadow(SecurityShadowEntry entry) {
462  24 return (!groupRefs.get(groupRef).contains(entry.getReference())
463    || entry.getWikiReference() != wikiRef);
464    }
465    });
466   
467    // Remove a space entry
468  2 remover.remove(spaceRef);
469  2 checkEntries(entries, new Keeper() {
 
470  52 toggle public boolean keepRule(SecurityRuleEntry entry) {
471  52 return (entry.getReference().getOriginalReference().extractReference(EntityType.SPACE)
472    != spaceRef.getOriginalSpaceReference());
473    }
 
474  128 toggle public boolean keepAccess(SecurityAccessEntry entry) {
475  128 return (entry.getReference().getOriginalReference().extractReference(EntityType.SPACE)
476    != spaceRef.getOriginalSpaceReference());
477    }
478    });
479   
480    // Remove an wiki entity
481  2 remover.remove(wikiRef);
482  2 checkEntries(entries, new Keeper() {
 
483  48 toggle public boolean keepRule(SecurityRuleEntry entry) {
484  48 return (entry.getReference().getOriginalReference().extractReference(EntityType.WIKI)
485    != wikiRef.getOriginalWikiReference());
486    }
 
487  108 toggle public boolean keepAccess(SecurityAccessEntry entry) {
488  108 return (entry.getReference().getOriginalReference().extractReference(EntityType.WIKI)
489    != wikiRef.getOriginalWikiReference());
490    }
 
491  20 toggle public boolean keepShadow(SecurityShadowEntry entry) {
492  20 return (entry.getWikiReference() != wikiRef);
493    }
494   
495    });
496   
497    // Remove the main wiki entry
498  2 remover.remove(xwikiRef);
499  2 checkEntries(entries, new Keeper() {
 
500  32 toggle public boolean keepRule(SecurityRuleEntry entry) {
501  32 return false;
502    }
 
503  72 toggle public boolean keepAccess(SecurityAccessEntry entry) {
504  72 return false;
505    }
 
506  12 toggle public boolean keepShadow(SecurityShadowEntry entry) {
507  12 return false;
508    }
509   
510    });
511    }
512   
 
513  1 toggle @Test
514    public void testAddSecurityRuleEntry() throws Exception
515    {
516  1 final List<SecurityRuleEntry> ruleEntries = new ArrayList<SecurityRuleEntry>();
517   
518    // Insert and check insertion individually
519  1 for (SecurityReference ref : entityRefs) {
520  14 assertThat(securityCache.get(ref), is(nullValue()));
521  14 SecurityRuleEntry entry = mockSecurityRuleEntry(ref);
522  14 AddRuleEntry(entry);
523  14 assertThat(securityCache.get(ref), sameInstance(entry));
524  14 ruleEntries.add(entry);
525    }
526   
527    // XWiki spaces are required to load user entries
528  1 for (SecurityReference ref : xwikiSpaceRefs) {
529  3 SecurityRuleEntry entry = mockSecurityRuleEntry(ref);
530  3 AddRuleEntry(entry);
531  3 assertThat(securityCache.get(ref), sameInstance(entry));
532  3 ruleEntries.add(entry);
533    }
534   
535    // Check inserting users
536  1 for (SecurityReference ref : userRefs) {
537  5 SecurityRuleEntry entry = mockSecurityRuleEntry(ref);
538  5 AddRuleEntry(entry);
539  5 assertThat(securityCache.get(ref), sameInstance(entry));
540  5 ruleEntries.add(entry);
541    }
542   
543    // Insert some groups
544  1 for (SecurityReference ref : groupRefs.keySet()) {
545  4 SecurityRuleEntry entry = mockSecurityRuleEntry(ref);
546  4 AddRuleEntry(entry);
547  4 assertThat(securityCache.get(ref), sameInstance(entry));
548  4 ruleEntries.add(entry);
549    }
550   
551    // Check inserting users in groups
552  1 for (SecurityReference ref : groupUserRefs) {
553  6 SecurityRuleEntry entry = mockSecurityRuleEntry(ref);
554  6 AddRuleEntry(entry);
555  6 assertThat(securityCache.get(ref), sameInstance(entry));
556  6 ruleEntries.add(entry);
557    }
558   
559    // Check all insertions
560  1 for (SecurityRuleEntry entry : ruleEntries) {
561  32 assertThat(securityCache.get(entry.getReference()), sameInstance(entry));
562    }
563   
564    // Check a non-conflicting duplicate insertion
565  1 try {
566  1 AddRuleEntry(ruleEntries.get(0));
567    } catch (ConflictingInsertionException e) {
568  0 fail("Inserting the same rule entry twice should NOT throw a ConflictingInsertionException.");
569    }
570   
571    // Check a conflicting duplicate insertion
572  1 try {
573  1 final SecurityReference ref = ruleEntries.get(0).getReference();
574  1 SecurityRuleEntry entry = mock(SecurityRuleEntry.class, "Another entry for "
575    + ruleEntries.get(0).getReference().toString());
576  1 when(entry.getReference()).thenReturn(ref);
577   
578  1 AddRuleEntry(entry);
579  0 fail("Inserting a different rule entry for the same reference should throw"
580    + " a ConflictingInsertionException.");
581    } catch (ConflictingInsertionException ignore) {
582    // Expected.
583    }
584   
585    // Check an insertion of an entry without inserting all its parents first
586  1 try {
587  1 AddRuleEntry(mockSecurityRuleEntry(aMissingParentRef));
588  0 fail("Inserting a rule entry without its parents should throw a ParentEntryEvictedException.");
589    } catch (ParentEntryEvictedException ignore) {
590    // Expected.
591    }
592   
593    // Check an insertion of a user without inserting all its groups first
594  1 try {
595  1 AddUserEntry(mockSecurityRuleEntry(aMissingUserRef), Arrays.asList(groupRef, aMissingGroupRef));
596  0 fail("Inserting a user entry without its parents should throw a ParentEntryEvictedException.");
597    } catch (ParentEntryEvictedException ignore) {
598    // Expected.
599    }
600    }
601   
 
602  1 toggle @Test
603    public void testAddSecurityShadowEntry() throws Exception
604    {
605  1 InsertUsersWithouShadow();
606   
607  1 final List<SecurityShadowEntry> allEntries = new ArrayList<SecurityShadowEntry>();
608   
609    // Check inserting shadow users
610  1 for (UserSecurityReference ref : userRefs) {
611  5 if (ref.isGlobal()) {
612  2 for(SecurityReference wiki : Arrays.asList(wikiRef, anotherWikiRef)) {
613  4 SecurityShadowEntry entry = mockSecurityShadowEntry(ref, wiki);
614  4 assertThat(((DefaultSecurityCache) securityCache).get(AddUserEntry(entry)),
615    sameInstance((SecurityEntry)entry));
616  4 allEntries.add(entry);
617    }
618    }
619    }
620   
621    // Check inserting some shadow groups
622  1 for (GroupSecurityReference ref : groupRefs.keySet()) {
623  4 if (ref.isGlobal()) {
624  2 for(SecurityReference wiki : Arrays.asList(wikiRef, anotherWikiRef)) {
625  4 SecurityShadowEntry entry = mockSecurityShadowEntry(ref, wiki);
626  4 assertThat(((DefaultSecurityCache) securityCache).get(AddUserEntry(entry)),
627    sameInstance((SecurityEntry)entry));
628  4 allEntries.add(entry);
629    }
630    }
631    }
632   
633    // Check inserting shadow users in shadow groups
634  1 for (UserSecurityReference ref : groupUserRefs) {
635  6 if (ref.isGlobal()) {
636  3 for(SecurityReference wiki : Arrays.asList(wikiRef, anotherWikiRef)) {
637  6 SecurityShadowEntry entry = mockSecurityShadowEntry(ref, wiki);
638  6 assertThat(((DefaultSecurityCache) securityCache).get(AddUserEntry(entry)),
639    sameInstance((SecurityEntry)entry));
640  6 allEntries.add(entry);
641    }
642    }
643    }
644   
645    // Check a duplicate insertion
646  1 try {
647  1 AddUserEntry(allEntries.get(0));
648    } catch (ConflictingInsertionException e) {
649  0 fail("Inserting the same shadow entry twice should NOT throw a ConflictingInsertionException.");
650    }
651   
652    // Check inserting a shadow for a missing user in an existing wiki
653  1 try {
654  1 AddUserEntry(mockSecurityShadowEntry(aMissingUserRef, wikiRef));
655  0 fail("Inserting a shadow entry without inserting its global user first should throw"
656    + " a ParentEntryEvictedException.");
657    } catch (ParentEntryEvictedException ignore) {
658    // Expected.
659    }
660   
661    // Check inserting a shadow for a existing user in a missing wiki
662  1 try {
663  1 AddUserEntry(mockSecurityShadowEntry(xuserRef, aMissingWikiRef));
664  0 fail("Inserting a shadow entry without inserting its wiki first should throw"
665    + " a ParentEntryEvictedException.");
666    } catch (ParentEntryEvictedException ignore) {
667    // Expected.
668    }
669    }
670   
671   
 
672  1 toggle @Test
673    public void testAddSecurityAccessEntry() throws Exception
674    {
675  1 InsertUsers();
676  1 InsertEntities();
677   
678  1 final List<SecurityAccessEntry> allEntries = new ArrayList<SecurityAccessEntry>();
679   
680    // Insert and check insertion individually for simple users
681  1 for (UserSecurityReference user : userRefs) {
682  5 for (SecurityReference ref : entityRefs) {
683  70 assertThat(securityCache.get(user, ref), is(nullValue()));
684  70 SecurityAccessEntry entry = mockSecurityAccessEntry(ref, user);
685  70 if (AddAccessEntry(entry) != null) {
686  43 assertThat(securityCache.get(user, ref), sameInstance(entry));
687  43 allEntries.add(entry);
688    }
689    }
690    }
691   
692    // Insert and check insertion individually for group users
693  1 for (UserSecurityReference user : groupUserRefs) {
694  6 for (SecurityReference ref : entityRefs) {
695  84 assertThat(securityCache.get(user, ref), is(nullValue()));
696  84 SecurityAccessEntry entry = mockSecurityAccessEntry(ref, user);
697  84 if (AddAccessEntry(entry) != null) {
698  60 assertThat(securityCache.get(user, ref), sameInstance(entry));
699  60 allEntries.add(entry);
700    }
701    }
702    }
703   
704    // Check all insertions
705  1 for (SecurityAccessEntry entry : allEntries) {
706  103 assertThat(securityCache.get(entry.getUserReference(), entry.getReference()), sameInstance(entry));
707    }
708   
709    // Check a non-conflicting duplicate insertion
710  1 try {
711  1 AddAccessEntry(allEntries.get(0));
712    } catch (ConflictingInsertionException e) {
713  0 fail("Inserting the same access entry twice should NOT throw a ConflictingInsertionException.");
714    }
715   
716    // Check a conflicting duplicate insertion
717  1 try {
718  1 final SecurityReference ref = allEntries.get(0).getReference();
719  1 final UserSecurityReference user = allEntries.get(0).getUserReference();
720  1 SecurityAccessEntry entry = mock(SecurityAccessEntry.class, "Another access for "
721    + allEntries.get(0).getUserReference().toString() + " on "
722    + allEntries.get(0).getReference().toString());
723  1 when(entry.getUserReference()).thenReturn(user);
724  1 when(entry.getReference()).thenReturn(ref);
725   
726  1 AddAccessEntry(entry);
727  0 fail("Inserting a different access entry for the same reference should throw"
728    + " a ConflictingInsertionException.");
729    } catch (ConflictingInsertionException ignore) {
730    // Expected.
731    }
732   
733    // Check insertion of entries without inserting either the entity or the user first
734  1 try {
735  1 AddAccessEntry(mockSecurityAccessEntry(aMissingEntityRef, xuserRef));
736  0 fail("Inserting a access entry without inserting its entity first should throw"
737    + " a ParentEntryEvictedException.");
738    } catch (ParentEntryEvictedException ignore) {
739    // Expected.
740    }
741   
742  1 try {
743  1 AddAccessEntry(mockSecurityAccessEntry(xdocRef, aMissingUserRef));
744  0 fail("Inserting a access entry without inserting its user first should throw"
745    + " a ParentEntryEvictedException.");
746    } catch (ParentEntryEvictedException ignore) {
747    // Expected.
748    }
749    }
750   
 
751  1 toggle @Test
752    public void testRemoveSecurityRuleEntry() throws Exception
753    {
754    // Fill the cache
755  1 Map<String, SecurityEntry> entries = InsertUsers();
756  1 entries.putAll(InsertEntities());
757  1 entries.putAll(InsertAccess());
758   
759  1 removerTest(entries, new Remover()
760    {
 
761  7 toggle @Override
762    public void remove(SecurityReference ref)
763    {
764  7 securityCache.remove(ref);
765    }
766    });
767    }
768   
 
769  1 toggle @Test
770    public void testCacheEvictedEntries() throws Exception
771    {
772    // Fill the cache
773  1 Map<String, SecurityEntry> entries = InsertUsers();
774  1 entries.putAll(InsertEntities());
775  1 entries.putAll(InsertAccess());
776   
777  1 final Map<SecurityReference, String> keys = new HashMap<SecurityReference, String>();
778   
779  1 for (Map.Entry<String, SecurityEntry> entry : entries.entrySet())
780    {
781  160 if (entry.getValue() instanceof SecurityRuleEntry) {
782  32 keys.put(entry.getValue().getReference(), entry.getKey());
783    }
784    }
785   
786  1 removerTest(entries, new Remover()
787    {
 
788  7 toggle @Override
789    public void remove(SecurityReference ref)
790    {
791  7 cache.remove(keys.get(ref));
792    }
793    });
794    }
795   
 
796  1 toggle @Test
797    public void testRemoveSecurityAccessEntry() throws Exception
798    {
799    // Fill the cache
800  1 Map<String, SecurityEntry> entries = InsertUsers();
801  1 entries.putAll(InsertEntities());
802  1 entries.putAll(InsertAccess());
803   
804    // Remove the access level for a user on a document
805  1 securityCache.remove(userRef, docRef);
806  1 checkEntries(entries, new Keeper() {
 
807  114 toggle public boolean keepAccess(SecurityAccessEntry entry) {
808  114 return entry.getReference() != docRef || entry.getUserReference() != userRef;
809    }
810    });
811    }
812    }