Skip to content

Commit

Permalink
Merge branch 'post-3.7-fixes' of https://github.com/Evolveum/midpoint
Browse files Browse the repository at this point in the history
…into post-3.7-fixes
  • Loading branch information
KaterynaHonchar committed Jan 16, 2018
2 parents 44fd386 + b30674c commit 27e077f
Show file tree
Hide file tree
Showing 21 changed files with 733 additions and 85 deletions.
Expand Up @@ -341,9 +341,9 @@ public HttpConnectionInformation getStoredConnectionInformation() {

@Override
public <O extends ObjectType> AccessDecision determineSubitemDecision(
ObjectSecurityConstraints securityConstraints, ObjectDelta<O> delta, String operationUrl,
ObjectSecurityConstraints securityConstraints, ObjectDelta<O> delta, PrismObject<O> currentObject, String operationUrl,
AuthorizationPhaseType phase, ItemPath subitemRootPath) {
return securityEnforcer.determineSubitemDecision(securityConstraints, delta, operationUrl, phase, subitemRootPath);
return securityEnforcer.determineSubitemDecision(securityConstraints, delta, currentObject, operationUrl, phase, subitemRootPath);
}

}
Expand Up @@ -1276,6 +1276,16 @@ public boolean isEmpty() {
}
return items.isEmpty();
}

public boolean isIdOnly() {
if (id == null) {
return false;
}
if (items == null || items.isEmpty()) {
return true;
}
return false;
}

@Override
public void normalize() {
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2017 Evolveum
* Copyright (c) 2010-2018 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 @@ -58,6 +58,8 @@ public class InternalsConfig {
* use in testing.
*/
private static TestingPaths testingPaths = null;

private static boolean detailedAuhotizationLog = false;

public static boolean isPrismMonitoring() {
return prismMonitoring;
Expand Down Expand Up @@ -115,6 +117,14 @@ public static void setTestingPaths(TestingPaths testingPaths) {
InternalsConfig.testingPaths = testingPaths;
}

public static boolean isDetailedAuhotizationLog() {
return detailedAuhotizationLog;
}

public static void setDetailedAuhotizationLog(boolean detailedAuhotizationLog) {
InternalsConfig.detailedAuhotizationLog = detailedAuhotizationLog;
}

public static boolean isAllowClearDataLogging() {
return allowClearDataLogging;
}
Expand All @@ -135,6 +145,7 @@ public static void reset() {
avoidLoggingChange = false;
allowClearDataLogging = false;
testingPaths = null;
detailedAuhotizationLog = false;
}

public static void setDevelopmentMode() {
Expand Down
Expand Up @@ -51,6 +51,7 @@
import com.evolveum.midpoint.repo.common.expression.ItemDeltaItem;
import com.evolveum.midpoint.repo.common.expression.ObjectDeltaObject;
import com.evolveum.midpoint.schema.*;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
import com.evolveum.midpoint.security.api.*;
import com.evolveum.midpoint.security.enforcer.api.ObjectSecurityConstraints;
Expand Down Expand Up @@ -339,7 +340,7 @@ public RefinedObjectClassDefinition getEditObjectClassDefinition(PrismObject<Sha
return null;
}

ItemPath attributesPath = new ItemPath(ShadowType.F_ATTRIBUTES);
ItemPath attributesPath = SchemaConstants.PATH_ATTRIBUTES;
AuthorizationDecisionType attributesReadDecision = schemaTransformer.computeItemDecision(securityConstraints, attributesPath, ModelAuthorizationAction.READ.getUrl(),
securityConstraints.getActionDecision(ModelAuthorizationAction.READ.getUrl(), phase), phase);
AuthorizationDecisionType attributesAddDecision = schemaTransformer.computeItemDecision(securityConstraints, attributesPath, ModelAuthorizationAction.ADD.getUrl(),
Expand Down Expand Up @@ -403,7 +404,7 @@ public <F extends FocusType> RoleSelectionSpecification getAssignableRoleSpecifi
if (securityConstraints == null) {
return null;
}
AuthorizationDecisionType decision = securityConstraints.findItemDecision(new ItemPath(FocusType.F_ASSIGNMENT),
AuthorizationDecisionType decision = securityConstraints.findItemDecision(SchemaConstants.PATH_ASSIGNMENT,
ModelAuthorizationAction.MODIFY.getUrl(), AuthorizationPhaseType.REQUEST);
if (decision == AuthorizationDecisionType.ALLOW) {
getAllRoleTypesSpec(spec, result);
Expand Down
Expand Up @@ -291,9 +291,10 @@ public void applySecurityConstraints(List<Item<?,?>> items, ObjectSecurityConstr
LOGGER.trace("applySecurityConstraints(item): {}: skip (elaborate)", itemPath);
continue;
}
AuthorizationDecisionType itemReadDecision = computeItemDecision(securityConstraints, itemPath, ModelAuthorizationAction.READ.getUrl(), defaultReadDecision, phase);
AuthorizationDecisionType itemAddDecision = computeItemDecision(securityConstraints, itemPath, ModelAuthorizationAction.ADD.getUrl(), defaultReadDecision, phase);
AuthorizationDecisionType itemModifyDecision = computeItemDecision(securityConstraints, itemPath, ModelAuthorizationAction.MODIFY.getUrl(), defaultReadDecision, phase);
ItemPath nameOnlyItemPath = itemPath.namedSegmentsOnly();
AuthorizationDecisionType itemReadDecision = computeItemDecision(securityConstraints, nameOnlyItemPath, ModelAuthorizationAction.READ.getUrl(), defaultReadDecision, phase);
AuthorizationDecisionType itemAddDecision = computeItemDecision(securityConstraints, nameOnlyItemPath, ModelAuthorizationAction.ADD.getUrl(), defaultReadDecision, phase);
AuthorizationDecisionType itemModifyDecision = computeItemDecision(securityConstraints, nameOnlyItemPath, ModelAuthorizationAction.MODIFY.getUrl(), defaultReadDecision, phase);
LOGGER.trace("applySecurityConstraints(item): {}: decisions R={}, A={}, M={}",
itemPath, itemReadDecision, itemAddDecision, itemModifyDecision);
if (itemDef != null) {
Expand Down Expand Up @@ -368,16 +369,16 @@ private <D extends ItemDefinition> void applySecurityConstraintsPhase(D itemDefi

private <D extends ItemDefinition> void applySecurityConstraintsItemDef(D itemDefinition,
IdentityHashMap<ItemDefinition, Object> definitionsSeen,
ItemPath itemPath, ObjectSecurityConstraints securityConstraints, AuthorizationDecisionType defaultReadDecision,
ItemPath nameOnlyItemPath, ObjectSecurityConstraints securityConstraints, AuthorizationDecisionType defaultReadDecision,
AuthorizationDecisionType defaultAddDecision, AuthorizationDecisionType defaultModifyDecision,
AuthorizationPhaseType phase) {

boolean thisWasSeen = definitionsSeen.containsKey(itemDefinition);
definitionsSeen.put(itemDefinition, null);

AuthorizationDecisionType readDecision = computeItemDecision(securityConstraints, itemPath, ModelAuthorizationAction.READ.getUrl(), defaultReadDecision, phase);
AuthorizationDecisionType addDecision = computeItemDecision(securityConstraints, itemPath, ModelAuthorizationAction.ADD.getUrl(), defaultAddDecision, phase);
AuthorizationDecisionType modifyDecision = computeItemDecision(securityConstraints, itemPath, ModelAuthorizationAction.MODIFY.getUrl(), defaultModifyDecision, phase);
AuthorizationDecisionType readDecision = computeItemDecision(securityConstraints, nameOnlyItemPath, ModelAuthorizationAction.READ.getUrl(), defaultReadDecision, phase);
AuthorizationDecisionType addDecision = computeItemDecision(securityConstraints, nameOnlyItemPath, ModelAuthorizationAction.ADD.getUrl(), defaultAddDecision, phase);
AuthorizationDecisionType modifyDecision = computeItemDecision(securityConstraints, nameOnlyItemPath, ModelAuthorizationAction.MODIFY.getUrl(), defaultModifyDecision, phase);

boolean anySubElementRead = false;
boolean anySubElementAdd = false;
Expand All @@ -386,7 +387,7 @@ private <D extends ItemDefinition> void applySecurityConstraintsItemDef(D itemDe
PrismContainerDefinition<?> containerDefinition = (PrismContainerDefinition<?>)itemDefinition;
List<? extends ItemDefinition> subDefinitions = ((PrismContainerDefinition<?>)containerDefinition).getDefinitions();
for (ItemDefinition subDef: subDefinitions) {
ItemPath subPath = new ItemPath(itemPath, subDef.getName());
ItemPath subPath = new ItemPath(nameOnlyItemPath, subDef.getName());
if (subDef.isElaborate()) {
LOGGER.trace("applySecurityConstraints(itemDef): {}: skip (elaborate)", subPath);
continue;
Expand All @@ -408,7 +409,7 @@ private <D extends ItemDefinition> void applySecurityConstraintsItemDef(D itemDe
}

LOGGER.trace("applySecurityConstraints(itemDef): {}: decisions R={}, A={}, M={}; subelements R={}, A={}, M={}",
itemPath, readDecision, addDecision, modifyDecision, anySubElementRead, anySubElementAdd, anySubElementModify);
nameOnlyItemPath, readDecision, addDecision, modifyDecision, anySubElementRead, anySubElementAdd, anySubElementModify);

if (readDecision != AuthorizationDecisionType.ALLOW) {
((ItemDefinitionImpl) itemDefinition).setCanRead(false);
Expand All @@ -431,9 +432,9 @@ private <D extends ItemDefinition> void applySecurityConstraintsItemDef(D itemDe
}
}

public AuthorizationDecisionType computeItemDecision(ObjectSecurityConstraints securityConstraints, ItemPath itemPath, String actionUrl,
public AuthorizationDecisionType computeItemDecision(ObjectSecurityConstraints securityConstraints, ItemPath nameOnlyItemPath, String actionUrl,
AuthorizationDecisionType defaultDecision, AuthorizationPhaseType phase) {
AuthorizationDecisionType explicitDecision = securityConstraints.findItemDecision(itemPath, actionUrl, phase);
AuthorizationDecisionType explicitDecision = securityConstraints.findItemDecision(nameOnlyItemPath, actionUrl, phase);
// LOGGER.trace("Explicit decision for {}: {}", itemPath, explicitDecision);
if (explicitDecision != null) {
return explicitDecision;
Expand Down
Expand Up @@ -1346,11 +1346,14 @@ private <T extends ObjectType, F extends ObjectType> void executeModification(Ob
ConfigurationException, SecurityViolationException, ExpressionEvaluationException, PreconditionViolationException {
Class<T> objectTypeClass = delta.getObjectTypeClass();

PrismObject<T> objectNew = objectContext.getObjectNew();
// We need old object here. The old object is used to get data for id-only container delete deltas,
// replace deltas and so on. The authorization code can figure out new object if needed, but it needs
// old object to start from.
PrismObject<T> objectOld = objectContext.getObjectOld();
OwnerResolver ownerResolver = createOwnerResolver(context, task, result);
try {
securityEnforcer.authorize(ModelAuthorizationAction.MODIFY.getUrl(),
AuthorizationPhaseType.EXECUTION, AuthorizationParameters.Builder.buildObjectDelta(objectNew, delta), ownerResolver, task, result);
AuthorizationPhaseType.EXECUTION, AuthorizationParameters.Builder.buildObjectDelta(objectOld, delta), ownerResolver, task, result);

metadataManager.applyMetadataModify(delta, objectContext, objectTypeClass,
clock.currentTimeXMLGregorianCalendar(), task, context, result);
Expand Down Expand Up @@ -1387,10 +1390,10 @@ private <T extends ObjectType, F extends ObjectType> void executeModification(Ob
cacheRepositoryService.modifyObject(objectTypeClass, delta.getOid(),
delta.getModifications(), precondition, null, result);
}
task.recordObjectActionExecuted(objectNew, objectTypeClass, delta.getOid(), ChangeType.MODIFY,
task.recordObjectActionExecuted(objectOld, objectTypeClass, delta.getOid(), ChangeType.MODIFY,
context.getChannel(), null);
} catch (Throwable t) {
task.recordObjectActionExecuted(objectNew, objectTypeClass, delta.getOid(), ChangeType.MODIFY,
task.recordObjectActionExecuted(objectOld, objectTypeClass, delta.getOid(), ChangeType.MODIFY,
context.getChannel(), t);
throw t;
}
Expand Down
Expand Up @@ -1345,6 +1345,10 @@ private <F extends ObjectType, O extends ObjectType> ObjectSecurityConstraints a
ObjectDelta<O> primaryDelta = elementContext.getPrimaryDelta();
// If there is no delta then there is no request to authorize
if (primaryDelta != null) {
PrismObject<O> currentObject = elementContext.getObjectCurrent();
if (currentObject == null) {
currentObject = elementContext.getObjectOld();
}
primaryDelta = primaryDelta.clone();
PrismObject<O> object = elementContext.getObjectCurrent();
if (object == null) {
Expand All @@ -1363,7 +1367,7 @@ private <F extends ObjectType, O extends ObjectType> ObjectSecurityConstraints a
// Process assignments first. If the assignments are allowed then we
// have to ignore the assignment item in subsequent security checks
if (primaryDelta.hasItemOrSubitemDelta(SchemaConstants.PATH_ASSIGNMENT)) {
AccessDecision assignmentItemDecision = determineDecisionForAssignmentItems(securityConstraints, primaryDelta, operationUrl, getRequestAuthorizationPhase(context));
AccessDecision assignmentItemDecision = determineDecisionForAssignmentItems(securityConstraints, primaryDelta, currentObject, operationUrl, getRequestAuthorizationPhase(context));
LOGGER.trace("Security decision for assignment items: {}", assignmentItemDecision);
if (assignmentItemDecision == AccessDecision.ALLOW) {
// Nothing to do, operation is allowed for all values
Expand Down Expand Up @@ -1452,9 +1456,9 @@ private <F extends ObjectType, O extends ObjectType> ObjectSecurityConstraints a
}

private <O extends ObjectType> AccessDecision determineDecisionForAssignmentItems(
ObjectSecurityConstraints securityConstraints, ObjectDelta<O> primaryDelta, String operationUrl,
ObjectSecurityConstraints securityConstraints, ObjectDelta<O> primaryDelta, PrismObject<O> currentObject, String operationUrl,
AuthorizationPhaseType requestAuthorizationPhase) {
return securityEnforcer.determineSubitemDecision(securityConstraints, primaryDelta, operationUrl, requestAuthorizationPhase, SchemaConstants.PATH_ASSIGNMENT);
return securityEnforcer.determineSubitemDecision(securityConstraints, primaryDelta, currentObject, operationUrl, requestAuthorizationPhase, SchemaConstants.PATH_ASSIGNMENT);
}

private <F extends ObjectType> AuthorizationPhaseType getRequestAuthorizationPhase(LensContext<F> context) {
Expand All @@ -1466,7 +1470,7 @@ private <F extends ObjectType> AuthorizationPhaseType getRequestAuthorizationPha
}

private <F extends ObjectType> AuthorizationDecisionType evaluateCredentialDecision(LensContext<F> context, ObjectSecurityConstraints securityConstraints, ItemDelta credentialChange) {
return securityConstraints.findItemDecision(credentialChange.getPath(),
return securityConstraints.findItemDecision(credentialChange.getPath().namedSegmentsOnly(),
ModelAuthorizationAction.CHANGE_CREDENTIALS.getUrl(), getRequestAuthorizationPhase(context));
}

Expand Down
Expand Up @@ -68,6 +68,7 @@
import com.evolveum.midpoint.schema.ResultHandler;
import com.evolveum.midpoint.schema.SelectorOptions;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.internals.InternalsConfig;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.result.OperationResultStatus;
import com.evolveum.midpoint.schema.util.MiscSchemaUtil;
Expand Down Expand Up @@ -340,13 +341,7 @@ public abstract class AbstractSecurityTest extends AbstractInitializedModelInteg

protected static final File ROLE_ASSIGN_SELF_REQUESTABLE_ANY_APPROVER_FILE = new File(TEST_DIR, "role-assign-self-requestable-any-approver.xml");
protected static final String ROLE_ASSIGN_SELF_REQUESTABLE_ANY_APPROVER_OID = "d3e83cce-bb25-11e7-ae7c-b73d2208bf2a";

protected static final File ROLE_LIMITED_ROLE_ADMINISTRATOR_FILE = new File(TEST_DIR, "role-limited-role-administrator.xml");
protected static final String ROLE_LIMITED_ROLE_ADMINISTRATOR_OID = "ce67b472-e5a6-11e7-98c3-174355334559";

protected static final File ROLE_EXCLUSION_PIRATE_FILE = new File(TEST_DIR, "role-exclusion-pirate.xml");
protected static final String ROLE_EXCLUSION_PIRATE_OID = "cf60ec66-e5a8-11e7-a997-ab32b7ec5fdb";


protected static final File ORG_REQUESTABLE_FILE = new File(TEST_DIR,"org-requestable.xml");
protected static final String ORG_REQUESTABLE_OID = "8f2bd344-a46c-4c0b-aa34-db08b7d7f7f2";

Expand Down Expand Up @@ -385,7 +380,7 @@ public abstract class AbstractSecurityTest extends AbstractInitializedModelInteg
protected static final XMLGregorianCalendar JACK_VALID_FROM_LONG_AGO = XmlTypeConverter.createXMLGregorianCalendar(10000L);

protected static final int NUMBER_OF_ALL_USERS = 11;
protected static final int NUMBER_OF_IMPORTED_ROLES = 70;
protected static final int NUMBER_OF_IMPORTED_ROLES = 69;
protected static final int NUMBER_OF_ALL_ORGS = 11;

protected String userRumRogersOid;
Expand Down Expand Up @@ -469,7 +464,6 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti
repoAddObjectFromFile(ROLE_ATTORNEY_MANAGER_WORKITEMS_FILE, initResult);
repoAddObjectFromFile(ROLE_APPROVER_FILE, initResult);
repoAddObjectFromFile(ROLE_ASSIGN_SELF_REQUESTABLE_ANY_APPROVER_FILE, initResult);
repoAddObjectFromFile(ROLE_LIMITED_ROLE_ADMINISTRATOR_FILE, initResult);

repoAddObjectFromFile(ORG_REQUESTABLE_FILE, initResult);
repoAddObjectFromFile(ORG_INDIRECT_PIRATE_FILE, initResult);
Expand Down Expand Up @@ -498,6 +492,8 @@ public void initSystem(Task initTask, OperationResult initResult) throws Excepti
assignOrg(userCobbOid, ORG_SCUMM_BAR_OID, initTask, initResult);
assignRole(userCobbOid, ROLE_ORDINARY_OID, initTask, initResult);
assignRole(userCobbOid, ROLE_UNINTERESTING_OID, initTask, initResult);

InternalsConfig.setDetailedAuhotizationLog(true);
}

protected int getNumberOfRoles() {
Expand Down Expand Up @@ -646,6 +642,9 @@ protected void cleanupAutzTest(String userOid, int expectedAssignments) throws O
cleanupDelete(TaskType.class, TASK_T5_OID, task, result);
cleanupDelete(TaskType.class, TASK_T6_OID, task, result);

cleanupDelete(RoleType.class, ROLE_EMPTY_OID, task, result);
cleanupAdd(ROLE_EMPTY_FILE, task, result);

assumeAssignmentPolicy(AssignmentPolicyEnforcementType.RELATIVE);

PrismObject<UserType> user = getUser(userOid);
Expand Down

0 comments on commit 27e077f

Please sign in to comment.