use of org.xwiki.security.SecurityReference in project xwiki-platform by xwiki.
the class PrioritizingAuthorizationSettler method settle.
@Override
protected XWikiSecurityAccess settle(UserSecurityReference user, Collection<GroupSecurityReference> groups, SecurityRuleEntry entry, Policies policies) {
XWikiSecurityAccess access = new XWikiSecurityAccess();
Map<Right, Integer> priorities = new RightMap<Integer>();
SecurityReference reference = entry.getReference();
Set<Right> enabledRights = Right.getEnabledRights(reference.getSecurityType());
// Evaluate rules from current level
for (Right right : enabledRights) {
for (SecurityRule obj : entry.getRules()) {
if (obj.match(right)) {
resolveLevel(right, user, groups, obj, access, policies, priorities);
if (access.get(right) == ALLOW) {
implyRights(right, access, reference, policies, priorities);
}
}
}
}
return access;
}
use of org.xwiki.security.SecurityReference in project xwiki-platform by xwiki.
the class DefaultAuthorizationManager method getAccess.
/**
* Obtain the access for the user on the given entity and load it into the cache if unavailable.
*
* @param user The user identity.
* @param entity The entity. May be of type DOCUMENT, WIKI, or SPACE.
* @return the cached access entry.
* @exception org.xwiki.security.authorization.AuthorizationException if an error occurs
*/
private SecurityAccess getAccess(UserSecurityReference user, SecurityReference entity) throws AuthorizationException {
for (SecurityReference ref = entity; ref != null; ref = ref.getParentSecurityReference()) {
if (Right.getEnabledRights(ref.getSecurityType()).isEmpty()) {
// Skip search on entity types that will obviously have empty/useless list of rules.
continue;
}
SecurityRuleEntry entry = securityCache.get(ref);
if (entry == null) {
SecurityAccess access = securityCacheLoader.load(user, entity).getAccess();
this.logger.debug("1. Loaded a new entry for user {} on {} into cache: [{}]", user, entity, access);
return access;
}
if (!entry.isEmpty()) {
SecurityAccessEntry accessEntry = securityCache.get(user, ref);
if (accessEntry == null) {
SecurityAccess access = securityCacheLoader.load(user, entity).getAccess();
logger.debug("2. Loaded a new entry for user {} on {} into cache: [{}]", user, entity, access);
return access;
} else {
SecurityAccess access = accessEntry.getAccess();
logger.debug("3. Got entry for user {} on {} from cache: [{}]", user, entity, access);
return access;
}
}
}
SecurityAccess access = securityCacheLoader.load(user, entity).getAccess();
logger.debug("4. Loaded a new default entry for user {} on {} into cache: [{}]", user, entity, access);
return access;
}
use of org.xwiki.security.SecurityReference in project xwiki-platform by xwiki.
the class DefaultAuthorizationManagerIntegrationTest method initialiseWikiMock.
@Override
public TestDefinition initialiseWikiMock(String filename) throws Exception {
super.initialiseWikiMock(filename);
when(xWikiBridge.getMainWikiReference()).thenReturn(testDefinition.getMainWiki().getWikiReference());
when(xWikiBridge.isWikiReadOnly()).thenReturn(false);
when(userBridge.getAllGroupsFor(any(UserSecurityReference.class), any(WikiReference.class))).thenAnswer(new Answer<Collection<GroupSecurityReference>>() {
@Override
public Collection<GroupSecurityReference> answer(InvocationOnMock invocationOnMock) throws Throwable {
UserSecurityReference userReference = (UserSecurityReference) invocationOnMock.getArguments()[0];
WikiReference wikiReference = (WikiReference) invocationOnMock.getArguments()[1];
if (userReference.getOriginalReference() == null) {
// Public users (not logged in) may not appears in any group
return Collections.emptyList();
}
TestWiki wiki = testDefinition.getWiki(userReference.getOriginalReference().getWikiReference());
if (wiki == null) {
throw new AuthorizationException(String.format("Failed to get groups for user or group [%s] in wiki [%s]. Unknown wiki.", userReference, wikiReference), null);
}
TestUserDocument user = wiki.getUser(userReference.getName());
if (user == null) {
return Collections.emptyList();
}
Collection<GroupSecurityReference> groups = new ArrayList<GroupSecurityReference>();
for (TestGroup group : user.getGroups()) {
// Ensure we return only group of the requested wiki
if (group.getGroupReference().getWikiReference().equals(wikiReference)) {
groups.add(securityReferenceFactory.newGroupReference(group.getGroupReference()));
}
}
return groups;
}
});
when(securityEntryReader.read(any(SecurityReference.class))).thenAnswer(new Answer<SecurityRuleEntry>() {
@Override
public SecurityRuleEntry answer(InvocationOnMock invocationOnMock) throws Throwable {
final SecurityReference reference = (SecurityReference) invocationOnMock.getArguments()[0];
TestEntity entity = testDefinition.searchEntity(reference);
Collection<TestAccessRule> rules = (entity != null && entity instanceof SecureTestEntity) ? ((SecureTestEntity) entity).getAccessRules() : Collections.<TestAccessRule>emptyList();
final Collection<SecurityRule> mockedRules = new ArrayList<SecurityRule>();
for (final TestAccessRule rule : rules) {
mockedRules.add(mockSecurityRule(reference, rule.getRight(), rule.getState(), rule.getUser(), rule.isUser()));
}
if (entity instanceof TestWiki) {
TestWiki wiki = (TestWiki) entity;
if (wiki.getOwner() != null) {
mockedRules.add(mockSecurityRule(reference, Right.ADMIN, RuleState.ALLOW, wiki.getOwner(), true));
}
}
if (entity instanceof TestDocument) {
TestDocument document = (TestDocument) entity;
if (document.getCreator() != null) {
mockedRules.add(mockSecurityRule(reference, Right.CREATOR, RuleState.ALLOW, document.getCreator(), true));
}
}
return new AbstractSecurityRuleEntry() {
@Override
public Collection<SecurityRule> getRules() {
return mockedRules;
}
@Override
public SecurityReference getReference() {
return reference;
}
@Override
public String toString() {
return String.format("Rule entry for %s containing %d rules", reference.toString(), mockedRules.size());
}
@Override
public boolean equals(Object object) {
if (object == this) {
return true;
}
if (!(object instanceof SecurityRuleEntry)) {
return false;
}
SecurityRuleEntry other = (SecurityRuleEntry) object;
return compareReferenceNullSafe(other.getReference(), reference) && other.getRules().size() == mockedRules.size();
}
};
}
});
return testDefinition;
}
use of org.xwiki.security.SecurityReference in project xwiki-platform by xwiki.
the class DefaultSecurityCacheLoaderTest method loadWithConflictingInsertionException.
@Test
public void loadWithConflictingInsertionException() throws Exception {
DocumentReference userReference = new DocumentReference("wiki", "Users", "mflorea");
UserSecurityReference user = securityReferenceFactory.newUserReference(userReference);
DocumentReference documentReference = new DocumentReference("wiki", "Space", "Document");
SecurityReference entity = securityReferenceFactory.newEntityReference(documentReference);
SecurityRuleEntry documentEntry = mock(SecurityRuleEntry.class, "document");
when(documentEntry.getReference()).thenReturn(entity);
when(documentEntry.isEmpty()).thenReturn(true);
SecurityRuleEntry spaceEntry = mock(SecurityRuleEntry.class, "space");
when(spaceEntry.getReference()).thenReturn(entity.getParentSecurityReference());
when(spaceEntry.isEmpty()).thenReturn(true);
SecurityRuleEntry wikiEntry = mock(SecurityRuleEntry.class, "wiki");
when(wikiEntry.getReference()).thenReturn(entity.getParentSecurityReference().getParentSecurityReference());
when(wikiEntry.isEmpty()).thenReturn(true);
SecurityCache securityCache = mocker.getInstance(SecurityCache.class);
when(securityCache.get(entity)).thenReturn(documentEntry);
when(securityCache.get(entity.getParentSecurityReference())).thenReturn(spaceEntry);
when(securityCache.get(entity.getParentSecurityReference().getParentSecurityReference())).thenReturn(wikiEntry);
when(securityCache.getGroupsFor(user, null)).thenReturn(null);
UserBridge userBridge = mocker.getInstance(UserBridge.class);
DocumentReference groupReference = new DocumentReference("wiki", "Groups", "AllGroup");
Set<GroupSecurityReference> groups = Collections.singleton(securityReferenceFactory.newGroupReference(groupReference));
when(userBridge.getAllGroupsFor(user, userReference.getWikiReference())).thenReturn(groups);
SecurityAccessEntry securityAccessEntry = mock(SecurityAccessEntry.class);
AuthorizationSettler authorizationSettler = mocker.getInstance(AuthorizationSettler.class);
Deque<SecurityRuleEntry> securityRuleEntries = new LinkedList<SecurityRuleEntry>(Arrays.asList(documentEntry, spaceEntry, wikiEntry));
when(authorizationSettler.settle(user, groups, securityRuleEntries)).thenReturn(securityAccessEntry);
doThrow(ConflictingInsertionException.class).when(securityCache).add(securityAccessEntry);
doThrow(ConflictingInsertionException.class).when(securityCache).add(securityAccessEntry, null);
try {
securityCacheLoader.load(user, entity);
fail();
} catch (AuthorizationException e) {
assertEquals("Failed to load the cache in 5 attempts. Giving up. when checking " + "access to [wiki:Space.Document] for user [wiki:Users.mflorea]", e.getMessage());
assertTrue(ExceptionUtils.getRootCauseMessage(e).contains("ConflictingInsertionException"));
}
// Assert that we've also emitted a log
assertEquals(1, this.logRule.size());
assertEquals("Failed to load the cache in 5 attempts. Giving up.", this.logRule.getMessage(0));
}
use of org.xwiki.security.SecurityReference 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