Search in sources :

Example 1 with ObjectSecurityConstraints

use of com.evolveum.midpoint.security.enforcer.api.ObjectSecurityConstraints in project midpoint by Evolveum.

the class SchemaTransformer method applySchemasAndSecurityElementContext.

private <F extends ObjectType, O extends ObjectType> ObjectSecurityConstraints applySchemasAndSecurityElementContext(LensContext<F> context, LensElementContext<O> elementContext, AuthorizationPhaseType phase, Task task, OperationResult result) throws SecurityViolationException, SchemaException, ConfigurationException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException {
    PrismObject<O> object = elementContext.getObjectAny();
    if (object == null) {
        if (elementContext.getSummaryDelta() == null) {
            // TODO check this
            return null;
        } else {
            throw new IllegalArgumentException("Cannot apply schema and security of null object");
        }
    }
    GetOperationOptions getOptions = ModelExecuteOptions.toGetOperationOptions(context.getOptions());
    authorizeOptions(getOptions, object, null, phase, task, result);
    ObjectSecurityConstraints securityConstraints = compileSecurityConstraints(object, task, result);
    AuthorizationDecisionType globalReadDecision = securityConstraints.findAllItemsDecision(ModelAuthorizationAction.AUTZ_ACTIONS_URLS_GET, phase);
    if (globalReadDecision == AuthorizationDecisionType.DENY) {
        // shortcut
        SecurityUtil.logSecurityDeny(object, "because the authorization denies access");
        throw new AuthorizationException("Access denied");
    }
    AuthorizationDecisionType globalAddDecision = securityConstraints.findAllItemsDecision(ModelAuthorizationAction.ADD.getUrl(), phase);
    AuthorizationDecisionType globalModifyDecision = securityConstraints.findAllItemsDecision(ModelAuthorizationAction.MODIFY.getUrl(), phase);
    elementContext.forEachObject(focusObject -> applySecurityConstraints(focusObject.getValue(), securityConstraints, phase, globalReadDecision, globalAddDecision, globalModifyDecision, false));
    elementContext.forEachDelta(focusDelta -> applySecurityConstraints(focusDelta, securityConstraints, phase, globalReadDecision, globalAddDecision, globalModifyDecision));
    return securityConstraints;
}
Also used : GetOperationOptions(com.evolveum.midpoint.schema.GetOperationOptions) ObjectSecurityConstraints(com.evolveum.midpoint.security.enforcer.api.ObjectSecurityConstraints)

Example 2 with ObjectSecurityConstraints

use of com.evolveum.midpoint.security.enforcer.api.ObjectSecurityConstraints in project midpoint by Evolveum.

the class ModelInteractionServiceImpl method getEditObjectDefinition.

@Override
public <O extends ObjectType> PrismObjectDefinition<O> getEditObjectDefinition(PrismObject<O> object, AuthorizationPhaseType phase, Task task, OperationResult parentResult) throws SchemaException, ConfigurationException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, SecurityViolationException {
    OperationResult result = parentResult.createMinorSubresult(GET_EDIT_OBJECT_DEFINITION);
    TransformableObjectDefinition<O> objectDefinition = schemaTransformer.transformableDefinition(object.getDefinition());
    try {
        // Re-read the object from the repository to make sure we have all the properties.
        // the object from method parameters may be already processed by the security code
        // and properties needed to evaluate authorizations may not be there
        // MID-3126, see also MID-3435
        PrismObject<O> fullObject = getFullObjectReadWrite(object, result);
        // TODO: maybe we need to expose owner resolver in the interface?
        ObjectSecurityConstraints securityConstraints = securityEnforcer.compileSecurityConstraints(fullObject, null, task, result);
        LOGGER.trace("Security constrains for {}:\n{}", object, DebugUtil.debugDumpLazily(securityConstraints));
        if (securityConstraints == null) {
            // Nothing allowed => everything denied
            result.recordNotApplicable();
            return null;
        } else {
            applyArchetypePolicy(objectDefinition, object, result);
            schemaTransformer.applySecurityConstraints(objectDefinition, securityConstraints, phase);
            if (object.canRepresent(ShadowType.class)) {
                applyObjectClassDefinition(objectDefinition, object, phase, task, result);
            }
            return objectDefinition;
        }
    } catch (ConfigurationException | ObjectNotFoundException | ExpressionEvaluationException | SchemaException e) {
        result.recordFatalError(e);
        throw e;
    } finally {
        result.computeStatusIfUnknown();
    }
}
Also used : OperationResult(com.evolveum.midpoint.schema.result.OperationResult) ObjectSecurityConstraints(com.evolveum.midpoint.security.enforcer.api.ObjectSecurityConstraints)

Example 3 with ObjectSecurityConstraints

use of com.evolveum.midpoint.security.enforcer.api.ObjectSecurityConstraints in project midpoint by Evolveum.

the class ClockworkAuthorizationHelper method authorizeElementContext.

private <F extends ObjectType, O extends ObjectType> ObjectSecurityConstraints authorizeElementContext(LensContext<F> context, LensElementContext<O> elementContext, OwnerResolver ownerResolver, boolean isFocus, Task task, OperationResult result) throws SecurityViolationException, SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException {
    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("Authorizing request for element context {}", elementContext.getHumanReadableName());
    }
    ObjectDelta<O> origPrimaryDelta = elementContext.getPrimaryDelta();
    // If there is no delta then there is no request to authorize
    if (origPrimaryDelta != null) {
        ObjectDelta<O> primaryDeltaClone = origPrimaryDelta.clone();
        PrismObject<O> object = elementContext.getObjectCurrent();
        if (object == null) {
            // This may happen when object is being added.
            // But also in cases such as assignment of account and modification of
            // the same account in one operation
            object = elementContext.getObjectNew();
        }
        String deltaOperationUrl = ModelImplUtils.getOperationUrlFromDelta(primaryDeltaClone);
        ObjectSecurityConstraints securityConstraints = securityEnforcer.compileSecurityConstraints(object, ownerResolver, task, result);
        if (securityConstraints == null) {
            if (LOGGER.isTraceEnabled()) {
                LOGGER.trace("Denied request for element context {}: null security constraints", elementContext.getHumanReadableName());
            }
            throw new AuthorizationException("Access denied");
        }
        if (isFocus) {
            // have to ignore the assignment item in subsequent security checks
            if (object.canRepresent(AssignmentHolderType.class)) {
                processAssignment(context, elementContext, primaryDeltaClone, deltaOperationUrl, AssignmentHolderType.F_ASSIGNMENT, object, ownerResolver, securityConstraints, task, result);
            }
            if (object.canRepresent(AbstractRoleType.class)) {
                processAssignment(context, elementContext, primaryDeltaClone, deltaOperationUrl, AbstractRoleType.F_INDUCEMENT, object, ownerResolver, securityConstraints, task, result);
            }
        }
        if (!primaryDeltaClone.isDelete()) {
            if (primaryDeltaClone.isAdd()) {
                PrismObject<O> objectToAdd = primaryDeltaClone.getObjectToAdd();
                PrismContainer<CredentialsType> credentialsContainer = objectToAdd.findContainer(UserType.F_CREDENTIALS);
                if (credentialsContainer != null) {
                    List<ItemPath> pathsToRemove = new ArrayList<>();
                    for (Item<?, ?> item : credentialsContainer.getValue().getItems()) {
                        ContainerDelta<?> cdelta = prismContext.deltaFactory().container().create(item.getPath(), (PrismContainerDefinition) item.getDefinition());
                        cdelta.addValuesToAdd(((PrismContainer) item).getValue().clone());
                        AuthorizationDecisionType cdecision = evaluateCredentialDecision(context, securityConstraints, cdelta);
                        LOGGER.trace("AUTZ: credential add {} decision: {}", item.getPath(), cdecision);
                        if (cdecision == AuthorizationDecisionType.ALLOW) {
                            // Remove it from primary delta, so it will not be evaluated later
                            pathsToRemove.add(item.getPath());
                        } else if (cdecision == AuthorizationDecisionType.DENY) {
                            if (LOGGER.isTraceEnabled()) {
                                LOGGER.trace("Denied request for element context {}: explicit credentials deny", elementContext.getHumanReadableName());
                            }
                            throw new AuthorizationException("Access denied");
                        } else {
                        // Do nothing. The access will be evaluated later in a normal way
                        }
                    }
                    for (ItemPath pathToRemove : pathsToRemove) {
                        objectToAdd.removeContainer(pathToRemove);
                    }
                }
            } else {
                // modify
                Collection<? extends ItemDelta<?, ?>> credentialChanges = primaryDeltaClone.findItemDeltasSubPath(UserType.F_CREDENTIALS);
                for (ItemDelta<?, ?> credentialChange : credentialChanges) {
                    AuthorizationDecisionType cdecision = evaluateCredentialDecision(context, securityConstraints, credentialChange);
                    LOGGER.trace("AUTZ: credential delta {} decision: {}", credentialChange.getPath(), cdecision);
                    if (cdecision == AuthorizationDecisionType.ALLOW) {
                        // Remove it from primary delta, so it will not be evaluated later
                        primaryDeltaClone.removeModification(credentialChange);
                    } else if (cdecision == AuthorizationDecisionType.DENY) {
                        if (LOGGER.isTraceEnabled()) {
                            LOGGER.trace("Denied request for element context {}: explicit credentials deny", elementContext.getHumanReadableName());
                        }
                        throw new AuthorizationException("Access denied");
                    } else {
                    // Do nothing. The access will be evaluated later in a normal way
                    }
                }
            }
        }
        if (!primaryDeltaClone.isEmpty()) {
            // TODO: optimize, avoid evaluating the constraints twice
            securityEnforcer.authorize(deltaOperationUrl, getRequestAuthorizationPhase(context), AuthorizationParameters.Builder.buildObjectDelta(object, primaryDeltaClone), ownerResolver, task, result);
        }
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Authorized request for element context {}, constraints:\n{}", elementContext.getHumanReadableName(), securityConstraints.debugDump(1));
        }
        return securityConstraints;
    } else {
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Authorized request for element context {}, constraints=null", elementContext.getHumanReadableName());
        }
        return null;
    }
}
Also used : CredentialsType(com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsType) AuthorizationException(com.evolveum.midpoint.util.exception.AuthorizationException) ArrayList(java.util.ArrayList) ObjectSecurityConstraints(com.evolveum.midpoint.security.enforcer.api.ObjectSecurityConstraints) PrismContainer(com.evolveum.midpoint.prism.PrismContainer) AuthorizationDecisionType(com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationDecisionType) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Example 4 with ObjectSecurityConstraints

use of com.evolveum.midpoint.security.enforcer.api.ObjectSecurityConstraints in project midpoint by Evolveum.

the class ModelInteractionServiceImpl method getAssignableRoleSpecification.

@Override
public <H extends AssignmentHolderType, R extends AbstractRoleType> RoleSelectionSpecification getAssignableRoleSpecification(PrismObject<H> focus, Class<R> targetType, int assignmentOrder, Task task, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, ConfigurationException, ExpressionEvaluationException, CommunicationException, SecurityViolationException {
    OperationResult result = parentResult.createMinorSubresult(GET_ASSIGNABLE_ROLE_SPECIFICATION);
    ObjectSecurityConstraints securityConstraints;
    try {
        securityConstraints = securityEnforcer.compileSecurityConstraints(focus, null, task, result);
    } catch (ExpressionEvaluationException | ObjectNotFoundException | SchemaException | CommunicationException | SecurityViolationException e) {
        result.recordFatalError(e);
        throw e;
    }
    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("Security constrains for getAssignableRoleSpecification on {}:\n{}", focus, securityConstraints == null ? null : securityConstraints.debugDump(1));
    }
    if (securityConstraints == null) {
        return null;
    }
    // Global decisions: processing #modify authorizations: allow/deny for all items or allow/deny for assignment/inducement item.
    ItemPath assignmentPath;
    if (assignmentOrder == 0) {
        assignmentPath = SchemaConstants.PATH_ASSIGNMENT;
    } else {
        assignmentPath = SchemaConstants.PATH_INDUCEMENT;
    }
    AuthorizationDecisionType assignmentItemDecision = securityConstraints.findItemDecision(assignmentPath, ModelAuthorizationAction.MODIFY.getUrl(), AuthorizationPhaseType.REQUEST);
    LOGGER.trace("getAssignableRoleSpecification decision for {}:{}", assignmentPath, assignmentItemDecision);
    if (assignmentItemDecision == AuthorizationDecisionType.ALLOW) {
        RoleSelectionSpecification spec = new RoleSelectionSpecification();
        spec.setGlobalFilter(prismContext.queryFactory().createAll());
        result.recordSuccess();
        return spec;
    }
    if (assignmentItemDecision == AuthorizationDecisionType.DENY) {
        result.recordSuccess();
        RoleSelectionSpecification spec = new RoleSelectionSpecification();
        spec.setGlobalFilter(prismContext.queryFactory().createNone());
        return spec;
    }
    AuthorizationDecisionType allItemsDecision = securityConstraints.findAllItemsDecision(ModelAuthorizationAction.MODIFY.getUrl(), AuthorizationPhaseType.REQUEST);
    if (allItemsDecision == AuthorizationDecisionType.ALLOW) {
        RoleSelectionSpecification spec = new RoleSelectionSpecification();
        spec.setGlobalFilter(prismContext.queryFactory().createAll());
        result.recordSuccess();
        return spec;
    }
    if (allItemsDecision == AuthorizationDecisionType.DENY) {
        result.recordSuccess();
        RoleSelectionSpecification spec = new RoleSelectionSpecification();
        spec.setGlobalFilter(prismContext.queryFactory().createNone());
        return spec;
    }
    // Assignment decisions: processing #assign authorizations
    MidPointPrincipal principal = securityEnforcer.getMidPointPrincipal();
    OrderConstraintsType orderConstraints = new OrderConstraintsType();
    orderConstraints.setOrder(assignmentOrder);
    List<OrderConstraintsType> orderConstraintsList = new ArrayList<>(1);
    orderConstraintsList.add(orderConstraints);
    FilterGizmo<RoleSelectionSpecification> gizmo = new FilterGizmoAssignableRoles(prismContext);
    try {
        RoleSelectionSpecification spec = securityEnforcer.computeSecurityFilter(principal, ModelAuthorizationAction.AUTZ_ACTIONS_URLS_ASSIGN, AuthorizationPhaseType.REQUEST, targetType, focus, prismContext.queryFactory().createAll(), null, orderConstraintsList, gizmo, task, result);
        result.recordSuccess();
        return spec;
    } catch (SchemaException | ConfigurationException | ObjectNotFoundException | ExpressionEvaluationException e) {
        result.recordFatalError(e);
        throw e;
    }
// 
// // Assignment decisions: processing #assign authorizations
// OrderConstraintsType orderConstraints = new OrderConstraintsType();
// orderConstraints.setOrder(assignmentOrder);
// List<OrderConstraintsType> orderConstraintsList = new ArrayList<>(1);
// orderConstraintsList.add(orderConstraints);
// try {
// ObjectFilter filter = securityEnforcer.preProcessObjectFilter(ModelAuthorizationAction.AUTZ_ACTIONS_URLS_ASSIGN,
// AuthorizationPhaseType.REQUEST, targetType, focus, FilterCreationUtil.createAll(prismContext), null, orderConstraintsList, task, result);
// 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) {
// getGlobalAssignableRoleSpecification(spec, result);
// result.recordSuccess();
// return spec;
// } else if (filter instanceof OrFilter) {
// Collection<RoleSelectionSpecEntry> allRoleTypeDvals = new ArrayList<>();
// for (ObjectFilter subfilter: ((OrFilter)filter).getConditions()) {
// Collection<RoleSelectionSpecEntry> roleTypeDvals =  getRoleSelectionSpecEntries(subfilter);
// if (roleTypeDvals == null || roleTypeDvals.isEmpty()) {
// // 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);
// getGlobalAssignableRoleSpecification(spec, result);
// result.recordSuccess();
// return spec;
// } else {
// allRoleTypeDvals.addAll(roleTypeDvals);
// }
// }
// addRoleTypeSpecEntries(spec, allRoleTypeDvals, result);
// } else {
// Collection<RoleSelectionSpecEntry> roleTypeDvals = getRoleSelectionSpecEntries(filter);
// if (roleTypeDvals == null || roleTypeDvals.isEmpty()) {
// getGlobalAssignableRoleSpecification(spec, result);
// result.recordSuccess();
// return spec;
// } else {
// addRoleTypeSpecEntries(spec, roleTypeDvals, result);
// }
// }
// result.recordSuccess();
// return spec;
// } catch (SchemaException | ConfigurationException | ObjectNotFoundException | ExpressionEvaluationException e) {
// result.recordFatalError(e);
// throw e;
// }
}
Also used : OperationResult(com.evolveum.midpoint.schema.result.OperationResult) ObjectSecurityConstraints(com.evolveum.midpoint.security.enforcer.api.ObjectSecurityConstraints) ItemPath(com.evolveum.midpoint.prism.path.ItemPath) MidPointPrincipal(com.evolveum.midpoint.security.api.MidPointPrincipal)

Example 5 with ObjectSecurityConstraints

use of com.evolveum.midpoint.security.enforcer.api.ObjectSecurityConstraints in project midpoint by Evolveum.

the class ModelInteractionServiceImpl method getEditObjectClassDefinition.

@Override
public ResourceObjectDefinition getEditObjectClassDefinition(PrismObject<ShadowType> shadow, PrismObject<ResourceType> resource, AuthorizationPhaseType phase, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException, ConfigurationException, SecurityViolationException {
    Validate.notNull(resource, "Resource must not be null");
    ResourceSchema resourceSchema = ResourceSchemaFactory.getCompleteSchema(resource);
    ResourceObjectDefinition rocd = ResourceObjectDefinitionResolver.getDefinitionForShadow(resourceSchema, shadow);
    if (rocd == null) {
        LOGGER.debug("No object class definition for shadow {}, returning null", shadow.getOid());
        return null;
    }
    ResourceObjectDefinition objectDefinition = rocd.forLayer(LayerType.PRESENTATION);
    // TODO: maybe we need to expose owner resolver in the interface?
    ObjectSecurityConstraints securityConstraints = securityEnforcer.compileSecurityConstraints(shadow, null, task, result);
    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("Security constrains for {}:\n{}", shadow, securityConstraints == null ? "null" : securityConstraints.debugDump());
    }
    if (securityConstraints == null) {
        return null;
    }
    ItemPath attributesPath = SchemaConstants.PATH_ATTRIBUTES;
    AuthorizationDecisionType attributesReadDecision = schemaTransformer.computeItemDecision(securityConstraints, attributesPath, ModelAuthorizationAction.AUTZ_ACTIONS_URLS_GET, securityConstraints.findAllItemsDecision(ModelAuthorizationAction.AUTZ_ACTIONS_URLS_GET, phase), phase);
    AuthorizationDecisionType attributesAddDecision = schemaTransformer.computeItemDecision(securityConstraints, attributesPath, ModelAuthorizationAction.AUTZ_ACTIONS_URLS_ADD, securityConstraints.findAllItemsDecision(ModelAuthorizationAction.ADD.getUrl(), phase), phase);
    AuthorizationDecisionType attributesModifyDecision = schemaTransformer.computeItemDecision(securityConstraints, attributesPath, ModelAuthorizationAction.AUTZ_ACTIONS_URLS_MODIFY, securityConstraints.findAllItemsDecision(ModelAuthorizationAction.MODIFY.getUrl(), phase), phase);
    LOGGER.trace("Attributes container access read:{}, add:{}, modify:{}", attributesReadDecision, attributesAddDecision, attributesModifyDecision);
    /*
         *  We are going to modify attribute definitions list.
         *  So let's make a (shallow) clone here.
         */
    objectDefinition = objectDefinition.clone();
    // Let's work on the copied list, as we modify (replace = delete+add) the definitions in the object definition.
    List<? extends ResourceAttributeDefinition<?>> definitionsCopy = new ArrayList<>(objectDefinition.getAttributeDefinitions());
    for (ResourceAttributeDefinition<?> rAttrDef : definitionsCopy) {
        ItemPath attributePath = ItemPath.create(ShadowType.F_ATTRIBUTES, rAttrDef.getItemName());
        AuthorizationDecisionType attributeReadDecision = schemaTransformer.computeItemDecision(securityConstraints, attributePath, ModelAuthorizationAction.AUTZ_ACTIONS_URLS_GET, attributesReadDecision, phase);
        AuthorizationDecisionType attributeAddDecision = schemaTransformer.computeItemDecision(securityConstraints, attributePath, ModelAuthorizationAction.AUTZ_ACTIONS_URLS_ADD, attributesAddDecision, phase);
        AuthorizationDecisionType attributeModifyDecision = schemaTransformer.computeItemDecision(securityConstraints, attributePath, ModelAuthorizationAction.AUTZ_ACTIONS_URLS_MODIFY, attributesModifyDecision, phase);
        LOGGER.trace("Attribute {} access read:{}, add:{}, modify:{}", rAttrDef.getItemName(), attributeReadDecision, attributeAddDecision, attributeModifyDecision);
        if (attributeReadDecision != AuthorizationDecisionType.ALLOW || attributeAddDecision != AuthorizationDecisionType.ALLOW || attributeModifyDecision != AuthorizationDecisionType.ALLOW) {
            // This opens up flag overriding
            ResourceAttributeDefinition<?> attrDefClone = rAttrDef.clone();
            if (attributeReadDecision != AuthorizationDecisionType.ALLOW) {
                attrDefClone.setOverrideCanRead(false);
            }
            if (attributeAddDecision != AuthorizationDecisionType.ALLOW) {
                attrDefClone.setOverrideCanAdd(false);
            }
            if (attributeModifyDecision != AuthorizationDecisionType.ALLOW) {
                attrDefClone.setOverrideCanModify(false);
            }
            objectDefinition.replaceDefinition(rAttrDef.getItemName(), attrDefClone);
        }
    }
    return objectDefinition;
}
Also used : ObjectSecurityConstraints(com.evolveum.midpoint.security.enforcer.api.ObjectSecurityConstraints) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Aggregations

ObjectSecurityConstraints (com.evolveum.midpoint.security.enforcer.api.ObjectSecurityConstraints)7 ItemPath (com.evolveum.midpoint.prism.path.ItemPath)3 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)3 DefinitionsToTransformable (com.evolveum.midpoint.model.impl.schema.transform.DefinitionsToTransformable)1 PrismContainer (com.evolveum.midpoint.prism.PrismContainer)1 UniformItemPath (com.evolveum.midpoint.prism.path.UniformItemPath)1 DefinitionProcessingOption (com.evolveum.midpoint.schema.DefinitionProcessingOption)1 GetOperationOptions (com.evolveum.midpoint.schema.GetOperationOptions)1 GetOperationOptions.createReadOnlyCollection (com.evolveum.midpoint.schema.GetOperationOptions.createReadOnlyCollection)1 MidPointPrincipal (com.evolveum.midpoint.security.api.MidPointPrincipal)1 AuthorizationException (com.evolveum.midpoint.util.exception.AuthorizationException)1 AuthorizationDecisionType (com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationDecisionType)1 CredentialsType (com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsType)1 ArrayList (java.util.ArrayList)1