Skip to content

Commit

Permalink
Fix for authorization search filter computation (MID-4931)
Browse files Browse the repository at this point in the history
  • Loading branch information
semancik committed Nov 12, 2018
1 parent ff7986b commit 4c9e098
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 22 deletions.
Expand Up @@ -3187,21 +3187,34 @@ public void test340AutzJackSuperUserAndExecRead() throws Exception {

assignRole(USER_JACK_OID, ROLE_SUPERUSER_OID);
assignRole(USER_JACK_OID, ROLE_READ_ORG_EXEC_OID);


// preconditions
assertSearch(UserType.class, createOrgSubtreeQuery(ORG_MINISTRY_OF_OFFENSE_OID), USER_LECHUCK_OID, USER_GUYBRUSH_OID, userCobbOid, USER_ESTEVAN_OID);
assertSearch(UserType.class, createOrgSubtreeAndNameQuery(ORG_MINISTRY_OF_OFFENSE_OID, USER_GUYBRUSH_USERNAME), USER_GUYBRUSH_OID);
assertSearch(ObjectType.class, createOrgSubtreeAndNameQuery(ORG_MINISTRY_OF_OFFENSE_OID, USER_GUYBRUSH_USERNAME), USER_GUYBRUSH_OID);

login(USER_JACK_USERNAME);

// WHEN
displayWhen(TEST_NAME);

assertSearch(UserType.class, createOrgSubtreeQuery(ORG_MINISTRY_OF_OFFENSE_OID), USER_LECHUCK_OID, USER_GUYBRUSH_OID, userCobbOid, USER_ESTEVAN_OID);
assertSearch(UserType.class, createOrgSubtreeAndNameQuery(ORG_MINISTRY_OF_OFFENSE_OID, USER_GUYBRUSH_USERNAME), USER_GUYBRUSH_OID);
assertSearch(ObjectType.class, createOrgSubtreeAndNameQuery(ORG_MINISTRY_OF_OFFENSE_OID, USER_GUYBRUSH_USERNAME), USER_GUYBRUSH_OID);

assertSuperuserAccess(NUMBER_OF_ALL_USERS);

assertGlobalStateUntouched();
}

private ObjectQuery createOrgSubtreeAndNameQuery(String orgOid, String name) {
return queryFor(ObjectType.class)
.isChildOf(orgOid)
.and()
.item(ObjectType.F_NAME).eqPoly(name)
.build();
}

private void modifyJackValidTo() throws ObjectNotFoundException, SchemaException, ExpressionEvaluationException, CommunicationException, ConfigurationException, ObjectAlreadyExistsException, PolicyViolationException, SecurityViolationException {
Task task = createTask("modifyJackValidTo");
OperationResult result = task.getResult();
Expand Down
Expand Up @@ -1097,9 +1097,9 @@ public <T extends ObjectType, O extends ObjectType> ObjectFilter preProcessObjec
if (origFilter == null) {
origFilter = AllFilter.createAll();
}
ObjectFilter finalFilter;
ObjectFilter securityFilter;
if (phase != null) {
finalFilter = preProcessObjectFilterInternal(principal, operationUrls, phase,
securityFilter = preProcessObjectFilterInternal(principal, operationUrls, phase,
true, searchResultType, object, true, origFilter, limitAuthorizationAction, "search pre-process", task, result);
} else {
ObjectFilter filterBoth = preProcessObjectFilterInternal(principal, operationUrls, null,
Expand All @@ -1108,8 +1108,9 @@ public <T extends ObjectType, O extends ObjectType> ObjectFilter preProcessObjec
false, searchResultType, object, true, origFilter, limitAuthorizationAction, "search pre-process", task, result);
ObjectFilter filterExecution = preProcessObjectFilterInternal(principal, operationUrls, AuthorizationPhaseType.EXECUTION,
false, searchResultType, object, true, origFilter, limitAuthorizationAction, "search pre-process", task, result);
finalFilter = ObjectQueryUtil.filterOr(filterBoth, ObjectQueryUtil.filterAnd(filterRequest, filterExecution));
securityFilter = ObjectQueryUtil.filterOr(filterBoth, ObjectQueryUtil.filterAnd(filterRequest, filterExecution));
}
ObjectFilter finalFilter = ObjectQueryUtil.filterAnd(origFilter, securityFilter);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("AUTZ: evaluated search pre-process principal={}, objectType={}: {}",
getUsername(principal), getObjectType(searchResultType), finalFilter);
Expand All @@ -1126,29 +1127,30 @@ public <T extends ObjectType, O extends ObjectType> ObjectFilter preProcessObjec
*/
@Override
public <T extends ObjectType, O extends ObjectType> boolean canSearch(String[] operationUrls,
AuthorizationPhaseType phase, Class<T> searchResultType, PrismObject<O> object, boolean includeSpecial, ObjectFilter filter, Task task, OperationResult result)
AuthorizationPhaseType phase, Class<T> searchResultType, PrismObject<O> object, boolean includeSpecial, ObjectFilter origFilter, Task task, OperationResult result)
throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException {
MidPointPrincipal principal = getMidPointPrincipal();
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("AUTZ: evaluating search permission principal={}, searchResultType={}, object={}: filter {}",
getUsername(principal), searchResultType, object, filter);
getUsername(principal), searchResultType, object, origFilter);
}
if (filter == null) {
if (origFilter == null) {
return true;
}
ObjectFilter finalFilter;
ObjectFilter securityFilter;
if (phase != null) {
finalFilter = preProcessObjectFilterInternal(principal, operationUrls, phase,
true, searchResultType, object, includeSpecial, filter, null, "search permission", task, result);
securityFilter = preProcessObjectFilterInternal(principal, operationUrls, phase,
true, searchResultType, object, includeSpecial, origFilter, null, "search permission", task, result);
} else {
ObjectFilter filterBoth = preProcessObjectFilterInternal(principal, operationUrls, null,
false, searchResultType, object, includeSpecial, filter, null, "search permission", task, result);
false, searchResultType, object, includeSpecial, origFilter, null, "search permission", task, result);
ObjectFilter filterRequest = preProcessObjectFilterInternal(principal, operationUrls, AuthorizationPhaseType.REQUEST,
false, searchResultType, object, includeSpecial, filter, null, "search permission", task, result);
false, searchResultType, object, includeSpecial, origFilter, null, "search permission", task, result);
ObjectFilter filterExecution = preProcessObjectFilterInternal(principal, operationUrls, AuthorizationPhaseType.EXECUTION,
false, searchResultType, object, includeSpecial, filter, null, "search permission", task, result);
finalFilter = ObjectQueryUtil.filterOr(filterBoth, ObjectQueryUtil.filterAnd(filterRequest, filterExecution));
false, searchResultType, object, includeSpecial, origFilter, null, "search permission", task, result);
securityFilter = ObjectQueryUtil.filterOr(filterBoth, ObjectQueryUtil.filterAnd(filterRequest, filterExecution));
}
ObjectFilter finalFilter = ObjectQueryUtil.filterAnd(origFilter, securityFilter);
finalFilter = ObjectQueryUtil.simplify(finalFilter);
boolean decision = !(finalFilter instanceof NoneFilter);
if (LOGGER.isTraceEnabled()) {
Expand All @@ -1158,6 +1160,9 @@ public <T extends ObjectType, O extends ObjectType> boolean canSearch(String[] o
return decision;
}

/**
* @return additional security filter. This filter is supposed to be added (operation "AND") to the original filter.
*/
private <T extends ObjectType, O extends ObjectType> ObjectFilter preProcessObjectFilterInternal(MidPointPrincipal principal, String[] operationUrls,
AuthorizationPhaseType phase, boolean includeNullPhase,
Class<T> objectType, PrismObject<O> object, boolean includeSpecial, ObjectFilter origFilter, String limitAuthorizationAction, String desc, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException {
Expand Down Expand Up @@ -1492,9 +1497,8 @@ private <T extends ObjectType, O extends ObjectType> ObjectFilter preProcessObje
return secFilter;
}

ObjectFilter origWithAllowFilter;
if (hasAllowAll) {
origWithAllowFilter = origFilter;
securityFilterAllow = AllFilter.createAll();
} else if (securityFilterAllow == null) {
// Nothing has been allowed. This means default deny.
if (LOGGER.isTraceEnabled()) {
Expand All @@ -1504,20 +1508,18 @@ private <T extends ObjectType, O extends ObjectType> ObjectFilter preProcessObje
NoneFilter secFilter = NoneFilter.createNone();
traceFilter("secFilter", null, secFilter);
return secFilter;
} else {
origWithAllowFilter = ObjectQueryUtil.filterAnd(origFilter, securityFilterAllow);
}

if (securityFilterDeny == null) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(" phase={} done: principal={}, operation={}, {}: allow\n Filter:\n{}",
phase, getUsername(principal), prettyActionUrl(operationUrls), desc,
origWithAllowFilter==null?"null":origWithAllowFilter.debugDump(2));
securityFilterAllow==null?"null":securityFilterAllow.debugDump(2));
}
traceFilter("origWithAllowFilter", null, origWithAllowFilter);
return origWithAllowFilter;
traceFilter("securityFilterAllow", null, securityFilterAllow);
return securityFilterAllow;
} else {
ObjectFilter secFilter = ObjectQueryUtil.filterAnd(origWithAllowFilter, NotFilter.createNot(securityFilterDeny));
ObjectFilter secFilter = ObjectQueryUtil.filterAnd(securityFilterAllow, NotFilter.createNot(securityFilterDeny));
if (LOGGER.isTraceEnabled()) {
LOGGER.trace(" phase={} done: principal={}, operation={}, {}: allow (with deny clauses)\n Filter:\n{}",
phase, getUsername(principal), prettyActionUrl(operationUrls), desc,
Expand Down

0 comments on commit 4c9e098

Please sign in to comment.