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;
}
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();
}
}
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;
}
}
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;
// }
}
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;
}
Aggregations