Search in sources :

Example 1 with AccessDecision

use of com.evolveum.midpoint.schema.AccessDecision in project midpoint by Evolveum.

the class ClockworkAuthorizationHelper method authorizeAssignmentRequest.

private <F extends ObjectType, O extends ObjectType> void authorizeAssignmentRequest(LensContext<F> context, String operationUrl, String assignActionUrl, ItemName assignmentElementQName, PrismObject<O> object, OwnerResolver ownerResolver, ObjectSecurityConstraints securityConstraints, PlusMinusZero plusMinusZero, boolean prohibitPolicies, Task task, OperationResult result) throws SecurityViolationException, SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException {
    // This is *request* authorization. Therefore we care only about primary delta.
    ObjectDelta<F> focusPrimaryDelta = context.getFocusContext().getPrimaryDelta();
    if (focusPrimaryDelta == null) {
        return;
    }
    ContainerDelta<AssignmentType> focusAssignmentDelta = focusPrimaryDelta.findContainerDelta(assignmentElementQName);
    if (focusAssignmentDelta == null) {
        return;
    }
    String operationDesc = assignActionUrl.substring(assignActionUrl.lastIndexOf('#') + 1);
    Collection<PrismContainerValue<AssignmentType>> changedAssignmentValues = determineChangedAssignmentValues(context.getFocusContext(), assignmentElementQName, focusAssignmentDelta, plusMinusZero);
    for (PrismContainerValue<AssignmentType> changedAssignmentValue : changedAssignmentValues) {
        AssignmentType changedAssignment = changedAssignmentValue.getRealValue();
        ObjectReferenceType targetRef = changedAssignment.getTargetRef();
        if (targetRef == null || targetRef.getOid() == null) {
            // This may still be allowed by #add and #modify authorizations. We have already checked these, but there may be combinations of
            // assignments, one of the assignments allowed by #assign, other allowed by #modify (e.g. MID-4517).
            // Therefore check the items again. This is not very efficient to check it twice. But this is not a common case
            // so there should not be any big harm in suffering this inefficiency.
            AccessDecision subitemDecision = securityEnforcer.determineSubitemDecision(securityConstraints, changedAssignmentValue, operationUrl, getRequestAuthorizationPhase(context), null, plusMinusZero, operationDesc);
            if (subitemDecision == AccessDecision.ALLOW) {
                LOGGER.debug("{} of policy {} to {} allowed with {} authorization", operationDesc, assignmentElementQName.getLocalPart(), object, operationUrl);
                continue;
            } else {
                LOGGER.debug("{} of non-target {} not allowed", operationDesc, assignmentElementQName.getLocalPart());
                if (LOGGER.isTraceEnabled()) {
                    LOGGER.trace("Denied request for object {}: {} of non-target {} not allowed", object, operationDesc, assignmentElementQName.getLocalPart());
                }
                securityEnforcer.failAuthorization(operationDesc, getRequestAuthorizationPhase(context), AuthorizationParameters.Builder.buildObject(object), result);
            }
        }
        PrismObject<ObjectType> target;
        try {
            // We do not worry about performance here too much. The target was already evaluated. This will be retrieved from repo cache anyway.
            target = objectResolver.resolve(targetRef.asReferenceValue(), "resolving " + assignmentElementQName.getLocalPart() + " target", task, result);
        } catch (ObjectNotFoundException e) {
            LOGGER.warn("Object {} referenced as {} target in {} was not found", targetRef.asReferenceValue().getOid(), assignmentElementQName.getLocalPart(), object);
            target = null;
        }
        ObjectDelta<O> assignmentObjectDelta = object.createModifyDelta();
        ContainerDelta<AssignmentType> assignmentDelta = assignmentObjectDelta.createContainerModification(assignmentElementQName);
        // We do not care if this is add or delete. All that matters for authorization is that it is in a delta.
        assignmentDelta.addValuesToAdd(changedAssignment.asPrismContainerValue().clone());
        QName relation = targetRef.getRelation();
        if (relation == null) {
            relation = prismContext.getDefaultRelation();
        }
        List<OrderConstraintsType> orderConstraints = determineOrderConstraints(assignmentElementQName, changedAssignment);
        AuthorizationParameters<O, ObjectType> autzParams = new AuthorizationParameters.Builder<O, ObjectType>().oldObject(object).delta(assignmentObjectDelta).target(target).relation(relation).orderConstraints(orderConstraints).build();
        if (prohibitPolicies) {
            if (changedAssignment.getPolicyRule() != null || !changedAssignment.getPolicyException().isEmpty() || !changedAssignment.getPolicySituation().isEmpty() || !changedAssignment.getTriggeredPolicyRule().isEmpty()) {
                // This may still be allowed by #add and #modify authorizations. We have already checked these, but there may be combinations of
                // assignments, one of the assignments allowed by #assign, other allowed by #modify (e.g. MID-4517).
                // Therefore check the items again. This is not very efficient to check it twice. But this is not a common case
                // so there should not be any big harm in suffering this inefficiency.
                AccessDecision subitemDecision = securityEnforcer.determineSubitemDecision(securityConstraints, changedAssignmentValue, operationUrl, getRequestAuthorizationPhase(context), null, plusMinusZero, operationDesc);
                if (subitemDecision == AccessDecision.ALLOW) {
                    LOGGER.debug("{} of policy assignment to {} allowed with {} authorization", operationDesc, object, operationUrl);
                    continue;
                } else {
                    securityEnforcer.failAuthorization("with assignment because of policies in the assignment", getRequestAuthorizationPhase(context), autzParams, result);
                }
            }
        }
        if (securityEnforcer.isAuthorized(assignActionUrl, getRequestAuthorizationPhase(context), autzParams, ownerResolver, task, result)) {
            LOGGER.debug("{} of target {} to {} allowed with {} authorization", operationDesc, target, object, assignActionUrl);
            continue;
        }
        if (relationRegistry.isDelegation(relation)) {
            if (securityEnforcer.isAuthorized(ModelAuthorizationAction.DELEGATE.getUrl(), getRequestAuthorizationPhase(context), autzParams, ownerResolver, task, result)) {
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("{} of target {} to {} allowed with {} authorization", operationDesc, target, object, ModelAuthorizationAction.DELEGATE.getUrl());
                }
                continue;
            }
        }
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("{} of target {} to {} denied", operationDesc, target, object);
        }
        securityEnforcer.failAuthorization("with " + assignmentElementQName.getLocalPart(), getRequestAuthorizationPhase(context), autzParams, result);
    }
}
Also used : PrismContainerValue(com.evolveum.midpoint.prism.PrismContainerValue) QName(javax.xml.namespace.QName) OrderConstraintsType(com.evolveum.midpoint.xml.ns._public.common.common_3.OrderConstraintsType) ObjectType(com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType) ObjectReferenceType(com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType) AssignmentType(com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType) AccessDecision(com.evolveum.midpoint.schema.AccessDecision) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException)

Example 2 with AccessDecision

use of com.evolveum.midpoint.schema.AccessDecision in project midpoint by Evolveum.

the class SandboxTypeCheckingExtension method onMethodSelection.

@Override
public void onMethodSelection(final Expression expression, final MethodNode target) {
    ClassNode targetDeclaringClass = target.getDeclaringClass();
    AccessDecision decision = decideClass(targetDeclaringClass.getName(), target.getName());
    if (decision != AccessDecision.ALLOW) {
        StringBuilder sb = new StringBuilder(GroovyScriptEvaluator.SANDBOX_ERROR_PREFIX);
        sb.append("Access to Groovy method ");
        sb.append(targetDeclaringClass.getName()).append("#").append(target.getName()).append(" ");
        if (decision == AccessDecision.DENY) {
            sb.append("denied");
        } else {
            sb.append("not allowed");
        }
        if (getContext().getExpressionProfile() != null) {
            sb.append(" (applied expression profile '").append(getContext().getExpressionProfile().getIdentifier()).append("')");
        }
        addStaticTypeError(sb.toString(), expression);
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) AccessDecision(com.evolveum.midpoint.schema.AccessDecision)

Example 3 with AccessDecision

use of com.evolveum.midpoint.schema.AccessDecision in project midpoint by Evolveum.

the class SecurityEnforcerImpl method isAuthorizedPhase.

private <O extends ObjectType, T extends ObjectType> AccessDecision isAuthorizedPhase(MidPointPrincipal midPointPrincipal, String operationUrl, AuthorizationPhaseType phase, AuthorizationParameters<O, T> params, OwnerResolver ownerResolver, Consumer<Authorization> applicableAutzConsumer, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException {
    if (AuthorizationConstants.AUTZ_NO_ACCESS_URL.equals(operationUrl)) {
        return AccessDecision.DENY;
    }
    if (phase == null) {
        throw new IllegalArgumentException("No phase");
    }
    AccessDecision decision = AccessDecision.DEFAULT;
    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("AUTZ: evaluating authorization principal={}, op={}, phase={}, {}", getUsername(midPointPrincipal), operationUrl, phase, params.shortDump());
    }
    final AutzItemPaths allowedItems = new AutzItemPaths();
    Collection<Authorization> authorities = getAuthorities(midPointPrincipal);
    if (authorities != null) {
        for (GrantedAuthority authority : authorities) {
            if (authority instanceof Authorization) {
                Authorization autz = (Authorization) authority;
                String autzHumanReadableDesc = autz.getHumanReadableDesc();
                LOGGER.trace("  Evaluating {}", autzHumanReadableDesc);
                // action
                if (!autz.getAction().contains(operationUrl) && !autz.getAction().contains(AuthorizationConstants.AUTZ_ALL_URL)) {
                    LOGGER.trace("    {} not applicable for operation {}", autzHumanReadableDesc, operationUrl);
                    continue;
                }
                // phase
                if (autz.getPhase() == null) {
                    LOGGER.trace("    {} is applicable for all phases (continuing evaluation)", autzHumanReadableDesc);
                } else {
                    if (autz.getPhase() != phase) {
                        LOGGER.trace("    {} is not applicable for phases {} (breaking evaluation)", autzHumanReadableDesc, phase);
                        continue;
                    } else {
                        LOGGER.trace("    {} is applicable for phases {} (continuing evaluation)", autzHumanReadableDesc, phase);
                    }
                }
                // relation
                if (!isApplicableRelation(autz, params.getRelation())) {
                    LOGGER.trace("    {} not applicable for relation {}", autzHumanReadableDesc, params.getRelation());
                    continue;
                }
                // orderConstraints
                if (!isApplicableOrderConstraints(autz, params.getOrderConstraints())) {
                    if (LOGGER.isTraceEnabled()) {
                        LOGGER.trace("    {} not applicable for orderConstraints {}", autzHumanReadableDesc, SchemaDebugUtil.shortDumpOrderConstraintsList(params.getOrderConstraints()));
                    }
                    continue;
                }
                // object
                if (isApplicableObject(autz, params.getOdo(), midPointPrincipal, ownerResolver, autzHumanReadableDesc, task, result)) {
                    LOGGER.trace("    {} applicable for object {} (continuing evaluation)", autzHumanReadableDesc, params.getAnyObject());
                } else {
                    LOGGER.trace("    {} not applicable for object {}, none of the object specifications match (breaking evaluation)", autzHumanReadableDesc, params.getAnyObject());
                    continue;
                }
                // target
                if (isApplicable(autz.getTarget(), params.getTarget(), midPointPrincipal, ownerResolver, "target", autzHumanReadableDesc, task, result)) {
                    LOGGER.trace("    {} applicable for target {} (continuing evaluation)", autzHumanReadableDesc, params.getAnyObject());
                } else {
                    LOGGER.trace("    {} not applicable for target {}, none of the target specifications match (breaking evaluation)", autzHumanReadableDesc, params.getAnyObject());
                    continue;
                }
                if (applicableAutzConsumer != null) {
                    applicableAutzConsumer.accept(autz);
                }
                // authority is applicable to this situation. now we can process the decision.
                AuthorizationDecisionType autzDecision = autz.getDecision();
                if (autzDecision == null || autzDecision.equals(AuthorizationDecisionType.ALLOW)) {
                    allowedItems.collectItems(autz);
                    LOGGER.trace("    {}: ALLOW operation {} (but continue evaluation)", autzHumanReadableDesc, operationUrl);
                    decision = AccessDecision.ALLOW;
                // Do NOT break here. Other authorization statements may still deny the operation
                } else {
                    // item
                    if (isApplicableItem(autz, params.getOldObject(), params.getDelta())) {
                        LOGGER.trace("    {}: Deny authorization applicable for items (continuing evaluation)", autzHumanReadableDesc);
                    } else {
                        LOGGER.trace("    {} not applicable for items (breaking evaluation)", autzHumanReadableDesc);
                        continue;
                    }
                    LOGGER.trace("    {}: DENY operation {}", autzHumanReadableDesc, operationUrl);
                    decision = AccessDecision.DENY;
                    // Break right here. Deny cannot be overridden by allow. This decision cannot be changed.
                    break;
                }
            } else {
                LOGGER.warn("Unknown authority type {} in user {}", authority.getClass(), getUsername(midPointPrincipal));
            }
        }
    }
    if (decision == AccessDecision.ALLOW) {
        // Still check allowedItems. We may still deny the operation.
        if (allowedItems.isAllItems()) {
            // This means all items are allowed. No need to check anything
            LOGGER.trace("  Empty list of allowed items, operation allowed");
        } else {
            // all items in the object and delta must be allowed
            LOGGER.trace("  Checking for allowed items: {}", allowedItems);
            ItemDecisionFunction itemDecisionFunction = (itemPath, removingContainer) -> decideAllowedItems(itemPath, allowedItems, phase, removingContainer);
            AccessDecision itemsDecision = null;
            if (params.hasDelta()) {
                // Behave as if this is execution phase for delete delta authorizations. We do not want to avoid deleting objects just because there
                // are automatic/operational items that were generated by midPoint. Otherwise we won't be really able to delete any object.
                ItemDecisionFunction itemDecisionFunctionDelete = (itemPath, removingContainer) -> decideAllowedItems(itemPath, allowedItems, AuthorizationPhaseType.EXECUTION, removingContainer);
                itemsDecision = determineDeltaDecision(params.getDelta(), params.getOldObject(), itemDecisionFunction, itemDecisionFunctionDelete);
            } else if (params.hasObject()) {
                itemsDecision = determineObjectDecision(params.getAnyObject(), itemDecisionFunction);
            }
            if (itemsDecision != AccessDecision.ALLOW) {
                LOGGER.trace("    NOT ALLOWED operation because the item decision is {}", itemsDecision);
                decision = AccessDecision.DEFAULT;
            }
        }
    }
    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("AUTZ result: principal={}, operation={}: {}", getUsername(midPointPrincipal), prettyActionUrl(operationUrl), decision);
    }
    return decision;
}
Also used : com.evolveum.midpoint.prism.query(com.evolveum.midpoint.prism.query) Autowired(org.springframework.beans.factory.annotation.Autowired) ConfigurationException(com.evolveum.midpoint.util.exception.ConfigurationException) SchemaException(com.evolveum.midpoint.util.exception.SchemaException) InternalsConfig(com.evolveum.midpoint.schema.internals.InternalsConfig) ExpressionConstants(com.evolveum.midpoint.schema.constants.ExpressionConstants) AuthorizationException(com.evolveum.midpoint.util.exception.AuthorizationException) BooleanUtils(org.apache.commons.lang.BooleanUtils) QNameUtil(com.evolveum.midpoint.util.QNameUtil) AccessDecision(com.evolveum.midpoint.schema.AccessDecision) SecurityContextHolder(org.springframework.security.core.context.SecurityContextHolder) com.evolveum.midpoint.prism(com.evolveum.midpoint.prism) ObjectDelta(com.evolveum.midpoint.prism.delta.ObjectDelta) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException) Collection(java.util.Collection) Task(com.evolveum.midpoint.task.api.Task) GrantedAuthority(org.springframework.security.core.GrantedAuthority) PlusMinusZero(com.evolveum.midpoint.prism.delta.PlusMinusZero) List(java.util.List) ExpressionFactory(com.evolveum.midpoint.repo.common.expression.ExpressionFactory) ExpressionUtil(com.evolveum.midpoint.repo.common.expression.ExpressionUtil) XsdTypeMapper(com.evolveum.midpoint.prism.xml.XsdTypeMapper) CommunicationException(com.evolveum.midpoint.util.exception.CommunicationException) QName(javax.xml.namespace.QName) NotNull(org.jetbrains.annotations.NotNull) Authentication(org.springframework.security.core.Authentication) PrismObjectValue.asObjectable(com.evolveum.midpoint.prism.PrismObjectValue.asObjectable) CaseTypeUtil(com.evolveum.midpoint.schema.util.cases.CaseTypeUtil) com.evolveum.midpoint.xml.ns._public.common.common_3(com.evolveum.midpoint.xml.ns._public.common.common_3) ObjectFilterExpressionEvaluator(com.evolveum.midpoint.repo.api.query.ObjectFilterExpressionEvaluator) ObjectDeltaObject(com.evolveum.midpoint.prism.util.ObjectDeltaObject) SchemaConstants(com.evolveum.midpoint.schema.constants.SchemaConstants) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) Trace(com.evolveum.midpoint.util.logging.Trace) TaskManager(com.evolveum.midpoint.task.api.TaskManager) DebugUtil(com.evolveum.midpoint.util.DebugUtil) ExpressionEvaluationException(com.evolveum.midpoint.util.exception.ExpressionEvaluationException) CollectionUtils(org.apache.commons.collections4.CollectionUtils) ArrayList(java.util.ArrayList) ItemDelta(com.evolveum.midpoint.prism.delta.ItemDelta) HashSet(java.util.HashSet) SecurityViolationException(com.evolveum.midpoint.util.exception.SecurityViolationException) RelationRegistry(com.evolveum.midpoint.schema.RelationRegistry) Qualifier(org.springframework.beans.factory.annotation.Qualifier) VariablesMap(com.evolveum.midpoint.schema.expression.VariablesMap) com.evolveum.midpoint.security.api(com.evolveum.midpoint.security.api) RepositoryService(com.evolveum.midpoint.repo.api.RepositoryService) DebugDumpable(com.evolveum.midpoint.util.DebugDumpable) ContainerDelta(com.evolveum.midpoint.prism.delta.ContainerDelta) Collections.emptySet(java.util.Collections.emptySet) S_AtomicFilterExit(com.evolveum.midpoint.prism.query.builder.S_AtomicFilterExit) ItemPath(com.evolveum.midpoint.prism.path.ItemPath) LoggingUtils(com.evolveum.midpoint.util.logging.LoggingUtils) Consumer(java.util.function.Consumer) Component(org.springframework.stereotype.Component) ItemName(com.evolveum.midpoint.prism.path.ItemName) com.evolveum.midpoint.security.enforcer.api(com.evolveum.midpoint.security.enforcer.api) SearchFilterType(com.evolveum.prism.xml.ns._public.query_3.SearchFilterType) S_FilterEntryOrEmpty(com.evolveum.midpoint.prism.query.builder.S_FilterEntryOrEmpty) TraceManager(com.evolveum.midpoint.util.logging.TraceManager) com.evolveum.midpoint.schema.util(com.evolveum.midpoint.schema.util) ItemPathType(com.evolveum.prism.xml.ns._public.types_3.ItemPathType) AccessDecision(com.evolveum.midpoint.schema.AccessDecision) GrantedAuthority(org.springframework.security.core.GrantedAuthority)

Example 4 with AccessDecision

use of com.evolveum.midpoint.schema.AccessDecision in project midpoint by Evolveum.

the class ClockworkAuthorizationHelper method processAssignment.

private <F extends ObjectType, O extends ObjectType> void processAssignment(LensContext<F> context, LensElementContext<O> elementContext, ObjectDelta<O> primaryDeltaClone, String deltaOperationUrl, ItemName assignmentElementQName, PrismObject<O> object, OwnerResolver ownerResolver, ObjectSecurityConstraints securityConstraints, Task task, OperationResult result) throws SecurityViolationException, SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException {
    PrismObject<O> currentObject = elementContext.getObjectCurrent();
    if (currentObject == null) {
        currentObject = elementContext.getObjectOld();
    }
    if (primaryDeltaClone.hasItemOrSubitemDelta(assignmentElementQName)) {
        AccessDecision assignmentItemDecision = determineDecisionForAssignmentItems(securityConstraints, primaryDeltaClone, currentObject, deltaOperationUrl, assignmentElementQName, getRequestAuthorizationPhase(context));
        LOGGER.trace("Security decision for {} items: {}", assignmentElementQName.getLocalPart(), assignmentItemDecision);
        if (assignmentItemDecision == AccessDecision.ALLOW) {
            // Nothing to do, operation is allowed for all values
            LOGGER.debug("Allow assignment/unassignment to {} because access to {} container/properties is explicitly allowed", assignmentElementQName.getLocalPart(), object);
        } else if (assignmentItemDecision == AccessDecision.DENY) {
            LOGGER.debug("Deny assignment/unassignment to {} because access to {} container/properties is explicitly denied", assignmentElementQName.getLocalPart(), object);
            if (LOGGER.isTraceEnabled()) {
                LOGGER.trace("Denied request for element context {}: access to {} container/properties is explicitly denied", elementContext.getHumanReadableName(), assignmentElementQName.getLocalPart());
            }
            throw new AuthorizationException("Access denied");
        } else {
            AuthorizationDecisionType allItemsDecision = securityConstraints.findAllItemsDecision(deltaOperationUrl, getRequestAuthorizationPhase(context));
            if (allItemsDecision == AuthorizationDecisionType.ALLOW) {
            // Nothing to do, operation is allowed for all values
            } else if (allItemsDecision == AuthorizationDecisionType.DENY) {
                if (LOGGER.isTraceEnabled()) {
                    LOGGER.trace("Denied request for element context {}: access to {} items is explicitly denied", elementContext.getHumanReadableName(), assignmentElementQName.getLocalPart());
                }
                throw new AuthorizationException("Access denied");
            } else {
                // No blank decision for assignment modification yet
                // process each assignment individually
                authorizeAssignmentRequest(context, deltaOperationUrl, ModelAuthorizationAction.ASSIGN.getUrl(), assignmentElementQName, object, ownerResolver, securityConstraints, PlusMinusZero.PLUS, true, task, result);
                if (!primaryDeltaClone.isAdd()) {
                    // We want to allow unassignment even if there are policies. Otherwise we would not be able to get
                    // rid of that assignment
                    authorizeAssignmentRequest(context, deltaOperationUrl, ModelAuthorizationAction.UNASSIGN.getUrl(), assignmentElementQName, object, ownerResolver, securityConstraints, PlusMinusZero.MINUS, false, task, result);
                }
            }
        }
        // authorization
        if (primaryDeltaClone.isAdd()) {
            PrismObject<O> objectToAdd = primaryDeltaClone.getObjectToAdd();
            objectToAdd.removeContainer(assignmentElementQName);
        } else if (primaryDeltaClone.isModify()) {
            primaryDeltaClone.removeContainerModification(ItemName.fromQName(assignmentElementQName));
        }
    }
}
Also used : AuthorizationException(com.evolveum.midpoint.util.exception.AuthorizationException) AccessDecision(com.evolveum.midpoint.schema.AccessDecision) AuthorizationDecisionType(com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationDecisionType)

Example 5 with AccessDecision

use of com.evolveum.midpoint.schema.AccessDecision in project midpoint by Evolveum.

the class SecurityEnforcerImpl method determineContainerDecision.

private AccessDecision determineContainerDecision(PrismContainerValue<?> cval, ItemDecisionFunction itemDecisionFunction, boolean removingContainer, String decisionContextDesc) {
    Collection<Item<?, ?>> items = cval.getItems();
    // Note: cval.isEmpty() will also check for id. We do not care about that.
    if (items.isEmpty()) {
        // TODO: problem with empty containers such as
        // orderConstraint in assignment. Skip all
        // empty items ... for now.
        logSubitemContainerDecision(null, decisionContextDesc, cval);
        return null;
    }
    AccessDecision decision = null;
    for (Item<?, ?> item : items) {
        ItemPath itemPath = item.getPath();
        AccessDecision itemDecision = itemDecisionFunction.decide(itemPath.namedSegmentsOnly(), removingContainer);
        logSubitemDecision(itemDecision, decisionContextDesc, itemPath);
        if (itemDecision == null) {
            // null decision means: skip this
            continue;
        }
        if (itemDecision == AccessDecision.DEFAULT && item instanceof PrismContainer<?>) {
            // No decision for entire container. Subitems will dictate the decision.
            @SuppressWarnings("unchecked") List<PrismContainerValue<?>> subValues = (List) ((PrismContainer<?>) item).getValues();
            AccessDecision containerDecision = null;
            for (PrismContainerValue<?> subValue : subValues) {
                AccessDecision subdecision = determineContainerDecision(subValue, itemDecisionFunction, removingContainer, decisionContextDesc);
                containerDecision = AccessDecision.combine(containerDecision, subdecision);
            // We do not want to break the loop immediately here. We want all the denied items to get logged
            }
            if (containerDecision == null) {
                // noinspection UnnecessaryContinue : explicit continue here makes the code more readable
                continue;
            } else {
                decision = AccessDecision.combine(decision, containerDecision);
            }
        } else {
            if (itemDecision == AccessDecision.DENY) {
                LOGGER.trace("  DENY operation because item {} in the object is not allowed", itemPath);
            // We do not want to break the loop immediately here. We want all the denied items to get logged
            }
            decision = AccessDecision.combine(decision, itemDecision);
        }
    }
    logSubitemContainerDecision(decision, decisionContextDesc, cval);
    return decision;
}
Also used : AccessDecision(com.evolveum.midpoint.schema.AccessDecision) List(java.util.List) ArrayList(java.util.ArrayList) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Aggregations

AccessDecision (com.evolveum.midpoint.schema.AccessDecision)10 ItemPath (com.evolveum.midpoint.prism.path.ItemPath)3 AuthorizationException (com.evolveum.midpoint.util.exception.AuthorizationException)2 ObjectNotFoundException (com.evolveum.midpoint.util.exception.ObjectNotFoundException)2 QName (javax.xml.namespace.QName)2 com.evolveum.midpoint.prism (com.evolveum.midpoint.prism)1 PrismContainerValue (com.evolveum.midpoint.prism.PrismContainerValue)1 PrismObjectValue.asObjectable (com.evolveum.midpoint.prism.PrismObjectValue.asObjectable)1 ContainerDelta (com.evolveum.midpoint.prism.delta.ContainerDelta)1 ItemDelta (com.evolveum.midpoint.prism.delta.ItemDelta)1 ObjectDelta (com.evolveum.midpoint.prism.delta.ObjectDelta)1 PlusMinusZero (com.evolveum.midpoint.prism.delta.PlusMinusZero)1 ItemName (com.evolveum.midpoint.prism.path.ItemName)1 com.evolveum.midpoint.prism.query (com.evolveum.midpoint.prism.query)1 S_AtomicFilterExit (com.evolveum.midpoint.prism.query.builder.S_AtomicFilterExit)1 S_FilterEntryOrEmpty (com.evolveum.midpoint.prism.query.builder.S_FilterEntryOrEmpty)1 ObjectDeltaObject (com.evolveum.midpoint.prism.util.ObjectDeltaObject)1 XsdTypeMapper (com.evolveum.midpoint.prism.xml.XsdTypeMapper)1 RepositoryService (com.evolveum.midpoint.repo.api.RepositoryService)1 ObjectFilterExpressionEvaluator (com.evolveum.midpoint.repo.api.query.ObjectFilterExpressionEvaluator)1