Skip to content

Commit

Permalink
ModelInteractionService.getAssignableRoleSpecification(...) extended
Browse files Browse the repository at this point in the history
  • Loading branch information
semancik committed Mar 16, 2015
1 parent 22722eb commit 41924f9
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 19 deletions.
Expand Up @@ -122,8 +122,6 @@ <F extends ObjectType> ModelContext<F> previewChanges(

/**
* Returns an object that defines which roles can be assigned by the currently logged-in user.
* Returns null if there is no information about what a user can or cannot assign.
* Returns object with empty type list if the user is not authorized to assign anything.
*
* @param focus Object of the operation. The object (usually user) to whom the roles should be assigned.
*/
Expand Down
Expand Up @@ -18,6 +18,7 @@
import java.util.ArrayList;
import java.util.List;

import com.evolveum.midpoint.prism.query.ObjectFilter;
import com.evolveum.midpoint.util.DisplayableValue;

/**
Expand All @@ -26,19 +27,76 @@
*/
public class RoleSelectionSpecification {

private List<DisplayableValue<String>> roleTypes = new ArrayList<DisplayableValue<String>>();
private List<DisplayableValue<String>> roleTypes = null;
private ObjectFilter filter = null;

/**
* Returns null if there is no information about role types that can or cannot be assigned.
* Returns empty list list if the user is not authorized to assign anything.
*/
public List<DisplayableValue<String>> getRoleTypes() {
return roleTypes;
}

public void setNoRoleTypes() {
roleTypes = new ArrayList<DisplayableValue<String>>();
}

public void addRoleType(DisplayableValue<String> roleType) {
if (roleTypes == null) {
roleTypes = new ArrayList<DisplayableValue<String>>();
}
roleTypes.add(roleType);
}

/**
* Returns "additional filter" that should be used to search for assignible roles.
* This filter should be AND-ed with any application level filter.
* It can return null. The null filter means "ALL" (AllFilter).
* If this returns NoneFilter then no roles can be assigned to the user.
*/
public ObjectFilter getFilter() {
return filter;
}

public void setFilter(ObjectFilter filter) {
this.filter = filter;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((filter == null) ? 0 : filter.hashCode());
result = prime * result + ((roleTypes == null) ? 0 : roleTypes.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
RoleSelectionSpecification other = (RoleSelectionSpecification) obj;
if (filter == null) {
if (other.filter != null)
return false;
} else if (!filter.equals(other.filter))
return false;
if (roleTypes == null) {
if (other.roleTypes != null)
return false;
} else if (!roleTypes.equals(other.roleTypes))
return false;
return true;
}

@Override
public String toString() {
return "RoleSelectionSpecification(" + roleTypes + ")";
return "RoleSelectionSpecification(" + roleTypes + ": "+filter+")";
}


Expand Down
Expand Up @@ -1113,41 +1113,51 @@ public <F extends FocusType> RoleSelectionSpecification getAssignableRoleSpecifi
AuthorizationDecisionType decision = securityConstraints.findItemDecision(new ItemPath(FocusType.F_ASSIGNMENT),
ModelAuthorizationAction.MODIFY.getUrl(), AuthorizationPhaseType.REQUEST);
if (decision == AuthorizationDecisionType.ALLOW) {
spec = getAllRoleTypesSpec(result);
getAllRoleTypesSpec(spec, result);
result.recordSuccess();
return spec;
}
if (decision == AuthorizationDecisionType.DENY) {
result.recordSuccess();
spec.setNoRoleTypes();
spec.setFilter(NoneFilter.createNone());
return spec;
}
decision = securityConstraints.getActionDecision(ModelAuthorizationAction.MODIFY.getUrl(), AuthorizationPhaseType.REQUEST);
if (decision == AuthorizationDecisionType.ALLOW) {
spec = getAllRoleTypesSpec(result);
getAllRoleTypesSpec(spec, result);
result.recordSuccess();
return spec;
}
if (decision == AuthorizationDecisionType.DENY) {
result.recordSuccess();
spec.setNoRoleTypes();
spec.setFilter(NoneFilter.createNone());
return spec;
}

try {
ObjectFilter filter = securityEnforcer.preProcessObjectFilter(ModelAuthorizationAction.ASSIGN.getUrl(),
AuthorizationPhaseType.REQUEST, RoleType.class, focus, AllFilter.createAll());
LOGGER.trace("assignableRoleSpec filter: {}", filter);
spec.setFilter(filter);
if (filter instanceof NoneFilter) {
result.recordSuccess();
spec.setNoRoleTypes();
return spec;
} else if (filter == null || filter instanceof AllFilter) {
spec = getAllRoleTypesSpec(result);
getAllRoleTypesSpec(spec, result);
result.recordSuccess();
return spec;
} else if (filter instanceof OrFilter) {
for (ObjectFilter subfilter: ((OrFilter)filter).getConditions()) {
DisplayableValue<String> roleTypeDval = getRoleSelectionSpec(subfilter);
if (roleTypeDval == null) {
spec = getAllRoleTypesSpec(result);
// This branch of the OR clause does not have any constraint for roleType
// therefore all role types are possible (regardless of other branches, this is OR)
spec = new RoleSelectionSpecification();
spec.setFilter(filter);
getAllRoleTypesSpec(spec, result);
result.recordSuccess();
return spec;
} else {
Expand All @@ -1157,7 +1167,7 @@ public <F extends FocusType> RoleSelectionSpecification getAssignableRoleSpecifi
} else {
DisplayableValue<String> roleTypeDval = getRoleSelectionSpec(filter);
if (roleTypeDval == null) {
spec = getAllRoleTypesSpec(result);
getAllRoleTypesSpec(spec, result);
result.recordSuccess();
return spec;
} else {
Expand All @@ -1172,11 +1182,11 @@ public <F extends FocusType> RoleSelectionSpecification getAssignableRoleSpecifi
}
}

private RoleSelectionSpecification getAllRoleTypesSpec(OperationResult result)
private RoleSelectionSpecification getAllRoleTypesSpec(RoleSelectionSpecification spec, OperationResult result)
throws ObjectNotFoundException, SchemaException, ConfigurationException {
ObjectTemplateType objectTemplateType = determineObjectTemplate(RoleType.class, AuthorizationPhaseType.REQUEST, result);
if (objectTemplateType == null) {
return null;
return spec;
}
for(ObjectTemplateItemDefinitionType itemDef: objectTemplateType.getItem()) {
ItemPathType ref = itemDef.getRef();
Expand All @@ -1191,13 +1201,12 @@ private RoleSelectionSpecification getAllRoleTypesSpec(OperationResult result)
if (QNameUtil.match(RoleType.F_ROLE_TYPE, itemName)) {
ObjectReferenceType valueEnumerationRef = itemDef.getValueEnumerationRef();
if (valueEnumerationRef == null || valueEnumerationRef.getOid() == null) {
return null;
return spec;
}
Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(LookupTableType.F_TABLE,
GetOperationOptions.createRetrieve(RetrieveOption.INCLUDE));
PrismObject<LookupTableType> lookup = cacheRepositoryService.getObject(LookupTableType.class, valueEnumerationRef.getOid(),
options, result);
RoleSelectionSpecification spec = new RoleSelectionSpecification();
for (LookupTableTableType row: lookup.asObjectable().getTable()) {
PolyStringType polyLabel = row.getLabel();
String key = row.getKey();
Expand All @@ -1211,7 +1220,7 @@ private RoleSelectionSpecification getAllRoleTypesSpec(OperationResult result)
return spec;
}
}
return null;
return spec;
}

private DisplayableValue<String> getRoleSelectionSpec(ObjectFilter filter) throws SchemaException {
Expand Down
Expand Up @@ -16,6 +16,7 @@
package com.evolveum.midpoint.model.intest;

import static org.testng.AssertJUnit.assertNull;

import com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition;
import com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition;
import com.evolveum.midpoint.model.api.ModelAuthorizationAction;
Expand All @@ -29,7 +30,11 @@
import com.evolveum.midpoint.prism.PrismObjectDefinition;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.query.AndFilter;
import com.evolveum.midpoint.prism.query.NoneFilter;
import com.evolveum.midpoint.prism.query.ObjectFilter;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.prism.query.TypeFilter;
import com.evolveum.midpoint.prism.util.PrismAsserts;
import com.evolveum.midpoint.prism.util.PrismTestUtil;
import com.evolveum.midpoint.schema.GetOperationOptions;
Expand Down Expand Up @@ -540,7 +545,11 @@ public void test200AutzJackNoRole() throws Exception {
assertModifyDeny();
assertDeleteDeny();

assertRoleTypes(userJack);
RoleSelectionSpecification roleSpec = getAssignableRoleSpecification(userJack);
assertNotNull("Null role spec "+roleSpec, roleSpec);
assertRoleTypes(roleSpec);
assertFilter(roleSpec.getFilter(), NoneFilter.class);

}

@Test
Expand All @@ -559,9 +568,11 @@ public void test201AutzJackSuperuserRole() throws Exception {
assertDeleteAllow();

RoleSelectionSpecification roleSpec = getAssignableRoleSpecification(getUser(USER_JACK_OID));
assertNull("Non-null role spec "+roleSpec, roleSpec);
assertNotNull("Null role spec "+roleSpec, roleSpec);
assertNull("Non-null role types in spec "+roleSpec, roleSpec.getRoleTypes());
assertFilter(roleSpec.getFilter(), null);
}

@Test
public void test202AutzJackReadonlyRole() throws Exception {
final String TEST_NAME = "test202AutzJackReadonlyRole";
Expand Down Expand Up @@ -1269,7 +1280,9 @@ public void run(Task task, OperationResult result) throws Exception {
user = getUser(USER_JACK_OID);
assertAssignments(user, 2);

assertRoleTypes(getUser(USER_JACK_OID), "application");
RoleSelectionSpecification spec = getAssignableRoleSpecification(getUser(USER_JACK_OID));
assertRoleTypes(spec, "application");
assertFilter(spec.getFilter(), TypeFilter.class);
}

@Test
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2013 Evolveum
* Copyright (c) 2010-2015 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -44,6 +44,7 @@
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.query.AndFilter;
import com.evolveum.midpoint.prism.query.EqualFilter;
import com.evolveum.midpoint.prism.query.ObjectFilter;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.prism.query.RefFilter;
import com.evolveum.midpoint.prism.util.PrismAsserts;
Expand Down Expand Up @@ -888,5 +889,16 @@ protected void assertPassword(ShadowType shadow, String expectedPassword) throws
protector.decrypt(passwordValue);
assertEquals("Wrong password in "+shadow, expectedPassword, passwordValue.getClearValue());
}

protected void assertFilter(ObjectFilter filter, Class<? extends ObjectFilter> expectedClass) {
if (expectedClass == null) {
assertNull("Expected that filter is null, but it was "+filter, filter);
} else {
assertNotNull("Expected that filter is of class "+expectedClass.getName()+", but it was null", filter);
if (!(expectedClass.isAssignableFrom(filter.getClass()))) {
AssertJUnit.fail("Expected that filter is of class "+expectedClass.getName()+", but it was "+filter);
}
}
}

}

0 comments on commit 41924f9

Please sign in to comment.