Search in sources :

Example 1 with ObjectSecurityConstraints

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

the class ModelInteractionServiceImpl method getAssignableRoleSpecification.

@Override
public <F extends FocusType> RoleSelectionSpecification getAssignableRoleSpecification(PrismObject<F> focus, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, ConfigurationException {
    OperationResult result = parentResult.createMinorSubresult(GET_ASSIGNABLE_ROLE_SPECIFICATION);
    RoleSelectionSpecification spec = new RoleSelectionSpecification();
    ObjectSecurityConstraints securityConstraints = securityEnforcer.compileSecurityConstraints(focus, null);
    if (securityConstraints == null) {
        return null;
    }
    AuthorizationDecisionType decision = securityConstraints.findItemDecision(new ItemPath(FocusType.F_ASSIGNMENT), ModelAuthorizationAction.MODIFY.getUrl(), AuthorizationPhaseType.REQUEST);
    if (decision == AuthorizationDecisionType.ALLOW) {
        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) {
        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, AbstractRoleType.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) {
            getAllRoleTypesSpec(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);
                    getAllRoleTypesSpec(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()) {
                getAllRoleTypesSpec(spec, result);
                result.recordSuccess();
                return spec;
            } else {
                addRoleTypeSpecEntries(spec, roleTypeDvals, result);
            }
        }
        result.recordSuccess();
        return spec;
    } catch (SchemaException | ConfigurationException | ObjectNotFoundException e) {
        result.recordFatalError(e);
        throw e;
    }
}
Also used : NoneFilter(com.evolveum.midpoint.prism.query.NoneFilter) SchemaException(com.evolveum.midpoint.util.exception.SchemaException) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) ObjectFilter(com.evolveum.midpoint.prism.query.ObjectFilter) OrFilter(com.evolveum.midpoint.prism.query.OrFilter) ObjectSecurityConstraints(com.evolveum.midpoint.security.api.ObjectSecurityConstraints) AllFilter(com.evolveum.midpoint.prism.query.AllFilter) ConfigurationException(com.evolveum.midpoint.util.exception.ConfigurationException) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Example 2 with ObjectSecurityConstraints

use of com.evolveum.midpoint.security.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 {
    OperationResult result = parentResult.createMinorSubresult(GET_EDIT_OBJECT_DEFINITION);
    PrismObjectDefinition<O> objectDefinition = object.getDefinition().deepClone(true);
    PrismObject<O> baseObject = object;
    if (object.getOid() != null) {
        // 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
        baseObject = cacheRepositoryService.getObject(object.getCompileTimeClass(), object.getOid(), null, result);
    }
    // TODO: maybe we need to expose owner resolver in the interface?
    ObjectSecurityConstraints securityConstraints = securityEnforcer.compileSecurityConstraints(baseObject, null);
    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("Security constrains for {}:\n{}", object, securityConstraints == null ? "null" : securityConstraints.debugDump());
    }
    if (securityConstraints == null) {
        // Nothing allowed => everything denied
        result.setStatus(OperationResultStatus.NOT_APPLICABLE);
        return null;
    }
    ObjectTemplateType objectTemplateType;
    try {
        objectTemplateType = schemaTransformer.determineObjectTemplate(object, phase, result);
    } catch (ConfigurationException | ObjectNotFoundException e) {
        result.recordFatalError(e);
        throw e;
    }
    schemaTransformer.applyObjectTemplateToDefinition(objectDefinition, objectTemplateType, result);
    schemaTransformer.applySecurityConstraints(objectDefinition, securityConstraints, phase);
    if (object.canRepresent(ShadowType.class)) {
        PrismObject<ShadowType> shadow = (PrismObject<ShadowType>) object;
        String resourceOid = ShadowUtil.getResourceOid(shadow);
        if (resourceOid != null) {
            Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(GetOperationOptions.createReadOnly());
            PrismObject<ResourceType> resource;
            try {
                resource = provisioning.getObject(ResourceType.class, resourceOid, options, task, result);
            } catch (CommunicationException | SecurityViolationException | ExpressionEvaluationException e) {
                throw new ConfigurationException(e.getMessage(), e);
            }
            RefinedObjectClassDefinition refinedObjectClassDefinition = getEditObjectClassDefinition(shadow, resource, phase);
            if (refinedObjectClassDefinition != null) {
                ((ComplexTypeDefinitionImpl) objectDefinition.getComplexTypeDefinition()).replaceDefinition(ShadowType.F_ATTRIBUTES, refinedObjectClassDefinition.toResourceAttributeContainerDefinition());
            }
        }
    }
    result.computeStatus();
    return objectDefinition;
}
Also used : ExpressionEvaluationException(com.evolveum.midpoint.util.exception.ExpressionEvaluationException) CommunicationException(com.evolveum.midpoint.util.exception.CommunicationException) SecurityViolationException(com.evolveum.midpoint.util.exception.SecurityViolationException) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) PolyString(com.evolveum.midpoint.prism.polystring.PolyString) ObjectSecurityConstraints(com.evolveum.midpoint.security.api.ObjectSecurityConstraints) ConfigurationException(com.evolveum.midpoint.util.exception.ConfigurationException) SelectorOptions(com.evolveum.midpoint.schema.SelectorOptions) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException)

Example 3 with ObjectSecurityConstraints

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

the class ModelInteractionServiceImpl method getEditObjectClassDefinition.

@Override
public RefinedObjectClassDefinition getEditObjectClassDefinition(PrismObject<ShadowType> shadow, PrismObject<ResourceType> resource, AuthorizationPhaseType phase) throws SchemaException {
    Validate.notNull(resource, "Resource must not be null");
    RefinedResourceSchema refinedSchema = RefinedResourceSchemaImpl.getRefinedSchema(resource);
    CompositeRefinedObjectClassDefinition rocd = refinedSchema.determineCompositeObjectClassDefinition(shadow);
    if (rocd == null) {
        LOGGER.debug("No object class definition for shadow {}, returning null");
        return null;
    }
    LayerRefinedObjectClassDefinition layeredROCD = rocd.forLayer(LayerType.PRESENTATION);
    // TODO: maybe we need to expose owner resolver in the interface?
    ObjectSecurityConstraints securityConstraints = securityEnforcer.compileSecurityConstraints(shadow, null);
    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("Security constrains for {}:\n{}", shadow, securityConstraints == null ? "null" : securityConstraints.debugDump());
    }
    if (securityConstraints == null) {
        return null;
    }
    ItemPath attributesPath = new ItemPath(ShadowType.F_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(), securityConstraints.getActionDecision(ModelAuthorizationAction.ADD.getUrl(), phase), phase);
    AuthorizationDecisionType attributesModifyDecision = schemaTransformer.computeItemDecision(securityConstraints, attributesPath, ModelAuthorizationAction.MODIFY.getUrl(), securityConstraints.getActionDecision(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, although it is probably not strictly necessary.
         */
    layeredROCD = layeredROCD.clone();
    for (LayerRefinedAttributeDefinition rAttrDef : layeredROCD.getAttributeDefinitions()) {
        ItemPath attributePath = new ItemPath(ShadowType.F_ATTRIBUTES, rAttrDef.getName());
        AuthorizationDecisionType attributeReadDecision = schemaTransformer.computeItemDecision(securityConstraints, attributePath, ModelAuthorizationAction.READ.getUrl(), attributesReadDecision, phase);
        AuthorizationDecisionType attributeAddDecision = schemaTransformer.computeItemDecision(securityConstraints, attributePath, ModelAuthorizationAction.ADD.getUrl(), attributesAddDecision, phase);
        AuthorizationDecisionType attributeModifyDecision = schemaTransformer.computeItemDecision(securityConstraints, attributePath, ModelAuthorizationAction.MODIFY.getUrl(), attributesModifyDecision, phase);
        LOGGER.trace("Attribute {} access read:{}, add:{}, modify:{}", rAttrDef.getName(), attributeReadDecision, attributeAddDecision, attributeModifyDecision);
        if (attributeReadDecision != AuthorizationDecisionType.ALLOW) {
            ((LayerRefinedAttributeDefinitionImpl) rAttrDef).setOverrideCanRead(false);
        }
        if (attributeAddDecision != AuthorizationDecisionType.ALLOW) {
            ((LayerRefinedAttributeDefinitionImpl) rAttrDef).setOverrideCanAdd(false);
        }
        if (attributeModifyDecision != AuthorizationDecisionType.ALLOW) {
            ((LayerRefinedAttributeDefinitionImpl) rAttrDef).setOverrideCanModify(false);
        }
    }
    return layeredROCD;
}
Also used : ObjectSecurityConstraints(com.evolveum.midpoint.security.api.ObjectSecurityConstraints) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Example 4 with ObjectSecurityConstraints

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

the class Clockwork 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 {
    ObjectDelta<O> primaryDelta = elementContext.getPrimaryDelta();
    // If there is no delta then there is no request to authorize
    if (primaryDelta != null) {
        primaryDelta = primaryDelta.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 operationUrl = ModelUtils.getOperationUrlFromDelta(primaryDelta);
        ObjectSecurityConstraints securityConstraints = securityEnforcer.compileSecurityConstraints(object, ownerResolver);
        if (securityConstraints == null) {
            throw new AuthorizationException("Access denied");
        }
        if (isFocus) {
            // Process assignments first. If the assignments are allowed then we
            // have to ignore the assignment item in subsequent security checks
            ContainerDelta<Containerable> assignmentDelta = primaryDelta.findContainerDelta(FocusType.F_ASSIGNMENT);
            if (assignmentDelta != null) {
                AuthorizationDecisionType assignmentItemDecision = securityConstraints.findItemDecision(new ItemPath(FocusType.F_ASSIGNMENT), operationUrl, getRequestAuthorizationPhase(context));
                if (assignmentItemDecision == AuthorizationDecisionType.ALLOW) {
                // Nothing to do, operation is allowed for all values
                } else if (assignmentItemDecision == AuthorizationDecisionType.DENY) {
                    throw new AuthorizationException("Access denied");
                } else {
                    AuthorizationDecisionType actionDecision = securityConstraints.getActionDecision(operationUrl, getRequestAuthorizationPhase(context));
                    if (actionDecision == AuthorizationDecisionType.ALLOW) {
                    // Nothing to do, operation is allowed for all values
                    } else if (actionDecision == AuthorizationDecisionType.DENY) {
                        throw new AuthorizationException("Access denied");
                    } else {
                        // No explicit decision for assignment modification yet
                        // process each assignment individually
                        DeltaSetTriple<EvaluatedAssignmentImpl<?>> evaluatedAssignmentTriple = context.getEvaluatedAssignmentTriple();
                        authorizeAssignmentRequest(context, ModelAuthorizationAction.ASSIGN.getUrl(), object, ownerResolver, evaluatedAssignmentTriple.getPlusSet(), true, result);
                        // We want to allow unassignment even if there are policies. Otherwise we would not be able to get
                        // rid of that assignment
                        authorizeAssignmentRequest(context, ModelAuthorizationAction.UNASSIGN.getUrl(), object, ownerResolver, evaluatedAssignmentTriple.getMinusSet(), false, result);
                    }
                }
                // authorization
                if (primaryDelta.isAdd()) {
                    PrismObject<O> objectToAdd = primaryDelta.getObjectToAdd();
                    objectToAdd.removeContainer(FocusType.F_ASSIGNMENT);
                } else if (primaryDelta.isModify()) {
                    primaryDelta.removeContainerModification(FocusType.F_ASSIGNMENT);
                }
            }
        }
        if (!primaryDelta.isDelete()) {
            if (primaryDelta.isAdd()) {
                PrismObject<O> objectToAdd = primaryDelta.getObjectToAdd();
                PrismContainer<CredentialsType> credentialsContainer = objectToAdd.findContainer(UserType.F_CREDENTIALS);
                if (credentialsContainer != null) {
                    for (Item<?, ?> item : credentialsContainer.getValue().getItems()) {
                        ContainerDelta<?> cdelta = new ContainerDelta(item.getPath(), (PrismContainerDefinition) item.getDefinition(), prismContext);
                        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
                            objectToAdd.removeContainer(item.getPath());
                        } else if (cdecision == AuthorizationDecisionType.DENY) {
                            throw new AuthorizationException("Access denied");
                        } else {
                        // Do nothing. The access will be evaluated later in a normal way
                        }
                    }
                }
            } else {
                // modify
                Collection<? extends ItemDelta<?, ?>> credentialChanges = primaryDelta.findItemDeltasSubPath(new ItemPath(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
                        primaryDelta.removeModification(credentialChange);
                    } else if (cdecision == AuthorizationDecisionType.DENY) {
                        throw new AuthorizationException("Access denied");
                    } else {
                    // Do nothing. The access will be evaluated later in a normal way
                    }
                }
            }
        }
        if (primaryDelta != null && !primaryDelta.isEmpty()) {
            // TODO: optimize, avoid evaluating the constraints twice
            securityEnforcer.authorize(operationUrl, getRequestAuthorizationPhase(context), object, primaryDelta, null, ownerResolver, result);
        }
        return securityConstraints;
    } else {
        return null;
    }
}
Also used : AuthorizationException(com.evolveum.midpoint.util.exception.AuthorizationException) ObjectSecurityConstraints(com.evolveum.midpoint.security.api.ObjectSecurityConstraints) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Example 5 with ObjectSecurityConstraints

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

the class SchemaTransformer method applySchemasAndSecurity.

/**
	 * Validate the objects, apply security to the object definition, remove any non-visible properties (security),
	 * apply object template definitions and so on. This method is called for
	 * any object that is returned from the Model Service.  
	 */
public <O extends ObjectType> void applySchemasAndSecurity(PrismObject<O> object, GetOperationOptions rootOptions, AuthorizationPhaseType phase, Task task, OperationResult parentResult) throws SchemaException, SecurityViolationException, ConfigurationException, ObjectNotFoundException {
    OperationResult result = parentResult.createMinorSubresult(SchemaTransformer.class.getName() + ".applySchemasAndSecurity");
    validateObject(object, rootOptions, result);
    PrismObjectDefinition<O> objectDefinition = object.deepCloneDefinition(true);
    ObjectSecurityConstraints securityConstraints;
    try {
        securityConstraints = securityEnforcer.compileSecurityConstraints(object, null);
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Security constrains for {}:\n{}", object, securityConstraints == null ? "null" : securityConstraints.debugDump());
        }
        if (securityConstraints == null) {
            SecurityUtil.logSecurityDeny(object, "because no security constraints are defined (default deny)");
            throw new AuthorizationException("Access denied");
        }
    } catch (SecurityViolationException | SchemaException | RuntimeException e) {
        result.recordFatalError(e);
        throw e;
    }
    if (phase == null) {
        applySchemasAndSecurityPhase(object, securityConstraints, objectDefinition, rootOptions, AuthorizationPhaseType.REQUEST, task, result);
        applySchemasAndSecurityPhase(object, securityConstraints, objectDefinition, rootOptions, AuthorizationPhaseType.EXECUTION, task, result);
    } else {
        applySchemasAndSecurityPhase(object, securityConstraints, objectDefinition, rootOptions, phase, task, result);
    }
    ObjectTemplateType objectTemplateType;
    try {
        objectTemplateType = determineObjectTemplate(object, AuthorizationPhaseType.REQUEST, result);
    } catch (ConfigurationException | ObjectNotFoundException e) {
        result.recordFatalError(e);
        throw e;
    }
    applyObjectTemplateToObject(object, objectTemplateType, result);
    result.computeStatus();
    result.recordSuccessIfUnknown();
}
Also used : SchemaException(com.evolveum.midpoint.util.exception.SchemaException) SecurityViolationException(com.evolveum.midpoint.util.exception.SecurityViolationException) AuthorizationException(com.evolveum.midpoint.util.exception.AuthorizationException) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) ObjectSecurityConstraints(com.evolveum.midpoint.security.api.ObjectSecurityConstraints) ConfigurationException(com.evolveum.midpoint.util.exception.ConfigurationException) ObjectTemplateType(com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateType) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException)

Aggregations

ObjectSecurityConstraints (com.evolveum.midpoint.security.api.ObjectSecurityConstraints)5 ItemPath (com.evolveum.midpoint.prism.path.ItemPath)3 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)3 ConfigurationException (com.evolveum.midpoint.util.exception.ConfigurationException)3 ObjectNotFoundException (com.evolveum.midpoint.util.exception.ObjectNotFoundException)3 AuthorizationException (com.evolveum.midpoint.util.exception.AuthorizationException)2 SchemaException (com.evolveum.midpoint.util.exception.SchemaException)2 SecurityViolationException (com.evolveum.midpoint.util.exception.SecurityViolationException)2 PolyString (com.evolveum.midpoint.prism.polystring.PolyString)1 AllFilter (com.evolveum.midpoint.prism.query.AllFilter)1 NoneFilter (com.evolveum.midpoint.prism.query.NoneFilter)1 ObjectFilter (com.evolveum.midpoint.prism.query.ObjectFilter)1 OrFilter (com.evolveum.midpoint.prism.query.OrFilter)1 SelectorOptions (com.evolveum.midpoint.schema.SelectorOptions)1 CommunicationException (com.evolveum.midpoint.util.exception.CommunicationException)1 ExpressionEvaluationException (com.evolveum.midpoint.util.exception.ExpressionEvaluationException)1 ObjectTemplateType (com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateType)1