use of org.xwiki.security.authorization.cache.ConflictingInsertionException in project xwiki-platform by xwiki.
the class DefaultSecurityCacheTest method testAddSecurityAccessEntry.
@Test
public void testAddSecurityAccessEntry() throws Exception {
InsertUsers();
InsertEntities();
final List<SecurityAccessEntry> allEntries = new ArrayList<SecurityAccessEntry>();
// Insert and check insertion individually for simple users
for (UserSecurityReference user : userRefs) {
for (SecurityReference ref : entityRefs) {
assertThat(securityCache.get(user, ref), is(nullValue()));
SecurityAccessEntry entry = mockSecurityAccessEntry(ref, user);
if (AddAccessEntry(entry) != null) {
assertThat(securityCache.get(user, ref), sameInstance(entry));
allEntries.add(entry);
}
}
}
// Insert and check insertion individually for group users
for (UserSecurityReference user : groupUserRefs) {
for (SecurityReference ref : entityRefs) {
assertThat(securityCache.get(user, ref), is(nullValue()));
SecurityAccessEntry entry = mockSecurityAccessEntry(ref, user);
if (AddAccessEntry(entry) != null) {
assertThat(securityCache.get(user, ref), sameInstance(entry));
allEntries.add(entry);
}
}
}
// Check all insertions
for (SecurityAccessEntry entry : allEntries) {
assertThat(securityCache.get(entry.getUserReference(), entry.getReference()), sameInstance(entry));
}
// Check a non-conflicting duplicate insertion
try {
AddAccessEntry(allEntries.get(0));
} catch (ConflictingInsertionException e) {
fail("Inserting the same access entry twice should NOT throw a ConflictingInsertionException.");
}
// Check a conflicting duplicate insertion
try {
final SecurityReference ref = allEntries.get(0).getReference();
final UserSecurityReference user = allEntries.get(0).getUserReference();
SecurityAccessEntry entry = mock(SecurityAccessEntry.class, "Another access for " + allEntries.get(0).getUserReference().toString() + " on " + allEntries.get(0).getReference().toString());
when(entry.getUserReference()).thenReturn(user);
when(entry.getReference()).thenReturn(ref);
AddAccessEntry(entry);
fail("Inserting a different access entry for the same reference should throw" + " a ConflictingInsertionException.");
} catch (ConflictingInsertionException ignore) {
// Expected.
}
// Check insertion of entries without inserting either the entity or the user first
try {
AddAccessEntry(mockSecurityAccessEntry(aMissingEntityRef, xuserRef));
fail("Inserting a access entry without inserting its entity first should throw" + " a ParentEntryEvictedException.");
} catch (ParentEntryEvictedException ignore) {
// Expected.
}
try {
AddAccessEntry(mockSecurityAccessEntry(xdocRef, aMissingUserRef));
fail("Inserting a access entry without inserting its user first should throw" + " a ParentEntryEvictedException.");
} catch (ParentEntryEvictedException ignore) {
// Expected.
}
}
use of org.xwiki.security.authorization.cache.ConflictingInsertionException in project xwiki-platform by xwiki.
the class DefaultSecurityCacheTest method testAddSecurityShadowEntry.
@Test
public void testAddSecurityShadowEntry() throws Exception {
InsertUsersWithouShadow();
final List<SecurityShadowEntry> allEntries = new ArrayList<SecurityShadowEntry>();
// Check inserting shadow users
for (UserSecurityReference ref : userRefs) {
if (ref.isGlobal()) {
for (SecurityReference wiki : Arrays.asList(wikiRef, anotherWikiRef)) {
SecurityShadowEntry entry = mockSecurityShadowEntry(ref, wiki);
assertThat(((DefaultSecurityCache) securityCache).get(AddUserEntry(entry)), sameInstance((SecurityEntry) entry));
allEntries.add(entry);
}
}
}
// Check inserting some shadow groups
for (GroupSecurityReference ref : groupRefs.keySet()) {
if (ref.isGlobal()) {
for (SecurityReference wiki : Arrays.asList(wikiRef, anotherWikiRef)) {
SecurityShadowEntry entry = mockSecurityShadowEntry(ref, wiki);
assertThat(((DefaultSecurityCache) securityCache).get(AddUserEntry(entry)), sameInstance((SecurityEntry) entry));
allEntries.add(entry);
}
}
}
// Check inserting shadow users in shadow groups
for (UserSecurityReference ref : groupUserRefs) {
if (ref.isGlobal()) {
for (SecurityReference wiki : Arrays.asList(wikiRef, anotherWikiRef)) {
SecurityShadowEntry entry = mockSecurityShadowEntry(ref, wiki);
assertThat(((DefaultSecurityCache) securityCache).get(AddUserEntry(entry)), sameInstance((SecurityEntry) entry));
allEntries.add(entry);
}
}
}
// Check a duplicate insertion
try {
AddUserEntry(allEntries.get(0));
} catch (ConflictingInsertionException e) {
fail("Inserting the same shadow entry twice should NOT throw a ConflictingInsertionException.");
}
// Check inserting a shadow for a missing user in an existing wiki
try {
AddUserEntry(mockSecurityShadowEntry(aMissingUserRef, wikiRef));
fail("Inserting a shadow entry without inserting its global user first should throw" + " a ParentEntryEvictedException.");
} catch (ParentEntryEvictedException ignore) {
// Expected.
}
// Check inserting a shadow for a existing user in a missing wiki
try {
AddUserEntry(mockSecurityShadowEntry(xuserRef, aMissingWikiRef));
fail("Inserting a shadow entry without inserting its wiki first should throw" + " a ParentEntryEvictedException.");
} catch (ParentEntryEvictedException ignore) {
// Expected.
}
}
use of org.xwiki.security.authorization.cache.ConflictingInsertionException in project xwiki-platform by xwiki.
the class DefaultSecurityCacheLoader method load.
@Override
public SecurityAccessEntry load(UserSecurityReference user, SecurityReference entity) throws AuthorizationException {
int retries = 0;
Exception lastException;
while (true) {
rulesInvalidator.suspend();
try {
retries++;
return loadRequiredEntries(user, entity);
} catch (ParentEntryEvictedException e) {
lastException = e;
if (retries < MAX_RETRIES) {
this.logger.debug("The parent entry was evicted. Have tried {} times. Trying again...", retries);
continue;
}
} catch (ConflictingInsertionException e) {
lastException = e;
if (retries < MAX_RETRIES) {
this.logger.debug("There were conflicting insertions. Have tried {} times. Retrying...", retries);
continue;
}
} finally {
rulesInvalidator.resume();
}
String message = String.format("Failed to load the cache in %d attempts. Giving up.", retries);
this.logger.error(message);
throw new AuthorizationException(user.getOriginalDocumentReference(), entity.getOriginalReference(), message, lastException);
}
}
use of org.xwiki.security.authorization.cache.ConflictingInsertionException in project xwiki-platform by xwiki.
the class DefaultSecurityCacheTest method testAddSecurityRuleEntry.
@Test
public void testAddSecurityRuleEntry() throws Exception {
final List<SecurityRuleEntry> ruleEntries = new ArrayList<SecurityRuleEntry>();
// Insert and check insertion individually
for (SecurityReference ref : entityRefs) {
assertThat(securityCache.get(ref), is(nullValue()));
SecurityRuleEntry entry = mockSecurityRuleEntry(ref);
AddRuleEntry(entry);
assertThat(securityCache.get(ref), sameInstance(entry));
ruleEntries.add(entry);
}
// XWiki spaces are required to load user entries
for (SecurityReference ref : xwikiSpaceRefs) {
SecurityRuleEntry entry = mockSecurityRuleEntry(ref);
AddRuleEntry(entry);
assertThat(securityCache.get(ref), sameInstance(entry));
ruleEntries.add(entry);
}
// Check inserting users
for (SecurityReference ref : userRefs) {
SecurityRuleEntry entry = mockSecurityRuleEntry(ref);
AddRuleEntry(entry);
assertThat(securityCache.get(ref), sameInstance(entry));
ruleEntries.add(entry);
}
// Insert some groups
for (SecurityReference ref : groupRefs.keySet()) {
SecurityRuleEntry entry = mockSecurityRuleEntry(ref);
AddRuleEntry(entry);
assertThat(securityCache.get(ref), sameInstance(entry));
ruleEntries.add(entry);
}
// Check inserting users in groups
for (SecurityReference ref : groupUserRefs) {
SecurityRuleEntry entry = mockSecurityRuleEntry(ref);
AddRuleEntry(entry);
assertThat(securityCache.get(ref), sameInstance(entry));
ruleEntries.add(entry);
}
// Check all insertions
for (SecurityRuleEntry entry : ruleEntries) {
assertThat(securityCache.get(entry.getReference()), sameInstance(entry));
}
// Check a non-conflicting duplicate insertion
try {
AddRuleEntry(ruleEntries.get(0));
} catch (ConflictingInsertionException e) {
fail("Inserting the same rule entry twice should NOT throw a ConflictingInsertionException.");
}
// Check a conflicting duplicate insertion
try {
final SecurityReference ref = ruleEntries.get(0).getReference();
SecurityRuleEntry entry = mock(SecurityRuleEntry.class, "Another entry for " + ruleEntries.get(0).getReference().toString());
when(entry.getReference()).thenReturn(ref);
AddRuleEntry(entry);
fail("Inserting a different rule entry for the same reference should throw" + " a ConflictingInsertionException.");
} catch (ConflictingInsertionException ignore) {
// Expected.
}
// Check an insertion of an entry without inserting all its parents first
try {
AddRuleEntry(mockSecurityRuleEntry(aMissingParentRef));
fail("Inserting a rule entry without its parents should throw a ParentEntryEvictedException.");
} catch (ParentEntryEvictedException ignore) {
// Expected.
}
// Check an insertion of a user without inserting all its groups first
try {
AddUserEntry(mockSecurityRuleEntry(aMissingUserRef), Arrays.asList(groupRef, aMissingGroupRef));
fail("Inserting a user entry without its parents should throw a ParentEntryEvictedException.");
} catch (ParentEntryEvictedException ignore) {
// Expected.
}
}
Aggregations