Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/Evolveum/midpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Feb 10, 2015
2 parents 8acdbe3 + a3b297a commit 73d25dd
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 67 deletions.
Expand Up @@ -6,6 +6,9 @@
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.PrismObjectDefinition;
import com.evolveum.midpoint.prism.PrismReference;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.util.exception.ConfigurationException;
import com.evolveum.midpoint.util.exception.ObjectNotFoundException;
import com.evolveum.midpoint.util.exception.SchemaException;
import com.evolveum.midpoint.util.exception.SystemException;
import com.evolveum.midpoint.web.component.prism.ContainerStatus;
Expand All @@ -26,7 +29,8 @@ public static <O extends ObjectType> ObjectWrapper createObjectWrapper(String di
public static <O extends ObjectType> ObjectWrapper createObjectWrapper(String displayName, String description, PrismObject<O> object, ContainerStatus status, boolean delayContainerCreation, PageBase pageBase) {
try {

PrismContainerDefinition objectDefinitionForEditing = pageBase.getModelInteractionService().getEditObjectDefinition(object, AuthorizationPhaseType.REQUEST);
OperationResult result = new OperationResult(ObjectWrapperUtil.class+".createObjectWrapper");
PrismContainerDefinition objectDefinitionForEditing = pageBase.getModelInteractionService().getEditObjectDefinition(object, AuthorizationPhaseType.REQUEST, result);
RefinedObjectClassDefinition objectClassDefinitionForEditing = null;
if (isShadow(object)) {
PrismReference resourceRef = object.findReference(ShadowType.F_RESOURCE_REF);
Expand All @@ -36,7 +40,7 @@ public static <O extends ObjectType> ObjectWrapper createObjectWrapper(String di

ObjectWrapper wrapper = new ObjectWrapper(displayName, description, object, objectDefinitionForEditing, objectClassDefinitionForEditing, status, delayContainerCreation, pageBase);
return wrapper;
} catch (SchemaException ex){
} catch (SchemaException | ConfigurationException | ObjectNotFoundException ex){
throw new SystemException(ex);
}
}
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2013 Evolveum
* Copyright (c) 2010-2015 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -271,6 +271,15 @@ public ComplexTypeDefinition clone() {
return clone;
}

public ComplexTypeDefinition deepClone() {
ComplexTypeDefinition clone = clone();
clone.itemDefinitions.clear();
for (ItemDefinition itemDef: this.itemDefinitions) {
clone.itemDefinitions.add(itemDef.deepClone());
}
return clone;
}

protected void copyDefinitionData(ComplexTypeDefinition clone) {
super.copyDefinitionData(clone);
clone.superType = this.superType;
Expand Down
Expand Up @@ -315,6 +315,10 @@ protected void copyDefinitionData(ItemDefinition clone) {
clone.operational = this.operational;
}

public ItemDefinition deepClone() {
return clone();
}

@Override
public void revive(PrismContext prismContext) {
if (this.prismContext != null) {
Expand Down
Expand Up @@ -356,7 +356,18 @@ protected void copyDefinitionData(PrismContainerDefinition<V> clone) {
clone.compileTimeClass = this.compileTimeClass;
}

public PrismContainerDefinition<V> cloneWithReplacedDefinition(QName itemName, ItemDefinition newDefinition) {
@Override
public ItemDefinition deepClone() {
PrismContainerDefinition<V> clone = clone();
ComplexTypeDefinition ctd = getComplexTypeDefinition();
if (ctd != null) {
ctd = ctd.deepClone();
clone.setComplexTypeDefinition(ctd);
}
return clone;
}

public PrismContainerDefinition<V> cloneWithReplacedDefinition(QName itemName, ItemDefinition newDefinition) {
PrismContainerDefinition<V> clone = clone();
ComplexTypeDefinition originalComplexTypeDefinition = getComplexTypeDefinition();
ComplexTypeDefinition cloneComplexTypeDefinition = originalComplexTypeDefinition.clone();
Expand Down
Expand Up @@ -62,6 +62,11 @@ public PrismObjectDefinition<O> clone() {
return clone;
}

@Override
public PrismObjectDefinition<O> deepClone() {
return (PrismObjectDefinition<O>) super.deepClone();
}

public PrismObjectDefinition<O> cloneWithReplacedDefinition(QName itemName, ItemDefinition newDefinition) {
return (PrismObjectDefinition<O>) super.cloneWithReplacedDefinition(itemName, newDefinition);
}
Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2013 Evolveum
* Copyright (c) 2010-2015 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -15,7 +15,10 @@
*/
package com.evolveum.midpoint.prism.util;

import com.evolveum.midpoint.prism.ComplexTypeDefinition;
import com.evolveum.midpoint.prism.ItemDefinition;
import com.evolveum.midpoint.prism.PrismConstants;
import com.evolveum.midpoint.prism.PrismContainerDefinition;
import com.evolveum.midpoint.prism.PrismContext;
import com.evolveum.midpoint.prism.PrismProperty;
import com.evolveum.midpoint.prism.PrismPropertyDefinition;
Expand Down Expand Up @@ -188,5 +191,5 @@ public static <T,X> PrismProperty<X> convertProperty(PrismProperty<T> srcProp, P
return targetProp;
}
}

}
Expand Up @@ -53,8 +53,9 @@
*/
public interface ModelInteractionService {

String CLASS_NAME_WITH_DOT = ModelInteractionService.class.getName() + ".";
String PREVIEW_CHANGES = CLASS_NAME_WITH_DOT + "previewChanges";
static final String CLASS_NAME_WITH_DOT = ModelInteractionService.class.getName() + ".";
static final String PREVIEW_CHANGES = CLASS_NAME_WITH_DOT + "previewChanges";
static final String GET_EDIT_OBJECT_DEFINITION = CLASS_NAME_WITH_DOT + "getEditObjectDefinition";

/**
* Computes the most likely changes triggered by the provided delta. The delta may be any change of any object, e.g.
Expand Down Expand Up @@ -100,7 +101,7 @@ <F extends ObjectType> ModelContext<F> previewChanges(
* @return schema with correctly set constraint parts or null
* @throws SchemaException
*/
<O extends ObjectType> PrismObjectDefinition<O> getEditObjectDefinition(PrismObject<O> object, AuthorizationPhaseType phase) throws SchemaException;
<O extends ObjectType> PrismObjectDefinition<O> getEditObjectDefinition(PrismObject<O> object, AuthorizationPhaseType phase, OperationResult result) throws SchemaException, ConfigurationException, ObjectNotFoundException;

RefinedObjectClassDefinition getEditObjectClassDefinition(PrismObject<ShadowType> shadow, PrismObject<ResourceType> resource, AuthorizationPhaseType phase) throws SchemaException;

Expand Down
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2014 Evolveum
* Copyright (c) 2010-2015 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -140,8 +140,10 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorHostType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.LayerType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectPolicyConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectSynchronizationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultStatusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType;
Expand Down Expand Up @@ -817,34 +819,43 @@ public <F extends ObjectType> ModelContext<F> previewChanges(
}

@Override
public <O extends ObjectType> PrismObjectDefinition<O> getEditObjectDefinition(PrismObject<O> object, AuthorizationPhaseType phase) throws SchemaException {
PrismObjectDefinition<O> origDefinition = object.getDefinition();
public <O extends ObjectType> PrismObjectDefinition<O> getEditObjectDefinition(PrismObject<O> object, AuthorizationPhaseType phase, OperationResult parentResult) throws SchemaException, ConfigurationException, ObjectNotFoundException {
OperationResult result = parentResult.createMinorSubresult(GET_EDIT_OBJECT_DEFINITION);
PrismObjectDefinition<O> objectDefinition = object.getDefinition().deepClone();
// TODO: maybe we need to expose owner resolver in the interface?
ObjectSecurityConstraints securityConstraints = securityEnforcer.compileSecurityConstraints(object, 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;
}
PrismObjectDefinition<O> finalDefinition = applySecurityContraints(origDefinition, new ItemPath(), securityConstraints,

ObjectTemplateType objectTemplateType;
try {
objectTemplateType = determineObjectTemplate(object, phase, result);
} catch (ConfigurationException | ObjectNotFoundException e) {
result.recordFatalError(e);
throw e;
}
if (objectTemplateType != null) {
// TODO
}

applySecurityContraints(objectDefinition, new ItemPath(), securityConstraints,
securityConstraints.getActionDecision(ModelAuthorizationAction.READ.getUrl(), phase),
securityConstraints.getActionDecision(ModelAuthorizationAction.ADD.getUrl(), phase),
securityConstraints.getActionDecision(ModelAuthorizationAction.MODIFY.getUrl(), phase), phase);
return finalDefinition;

result.computeStatus();
return objectDefinition;
}

private <D extends ItemDefinition> D applySecurityContraints(D origItemDefinition, ItemPath itemPath, ObjectSecurityConstraints securityConstraints,
private <D extends ItemDefinition> void applySecurityContraints(D itemDefinition, ItemPath itemPath, ObjectSecurityConstraints securityConstraints,
AuthorizationDecisionType defaultReadDecition, AuthorizationDecisionType defaultAddDecition, AuthorizationDecisionType defaultModifyDecition,
AuthorizationPhaseType phase) {
D itemDefinition = (D) origItemDefinition.clone();
// We need to make a super-deep clone here. Even make sure that the complex types inside are cloned.
// Otherwise permissions from one part of the definition tree may be incorrectly propagated to another part
if (itemDefinition instanceof PrismContainerDefinition<?>) {
PrismContainerDefinition<?> containerDefinition = (PrismContainerDefinition<?>)itemDefinition;
ComplexTypeDefinition origCtd = containerDefinition.getComplexTypeDefinition();
containerDefinition.setComplexTypeDefinition(origCtd.clone());
}
AuthorizationDecisionType readDecision = computeItemDecision(securityConstraints, itemPath, ModelAuthorizationAction.READ.getUrl(), defaultReadDecition, phase);
AuthorizationDecisionType addDecision = computeItemDecision(securityConstraints, itemPath, ModelAuthorizationAction.ADD.getUrl(), defaultAddDecition, phase);
AuthorizationDecisionType modifyDecision = computeItemDecision(securityConstraints, itemPath, ModelAuthorizationAction.MODIFY.getUrl(), defaultModifyDecition, phase);
Expand All @@ -862,19 +873,16 @@ private <D extends ItemDefinition> D applySecurityContraints(D origItemDefinitio
if (itemDefinition instanceof PrismContainerDefinition<?>) {
PrismContainerDefinition<?> containerDefinition = (PrismContainerDefinition<?>)itemDefinition;
// The items are still shallow-clonned, we need to deep-clone them
List<? extends ItemDefinition> origSubDefinitions = ((PrismContainerDefinition<?>)origItemDefinition).getDefinitions();
containerDefinition.getDefinitions().clear();
List<? extends ItemDefinition> origSubDefinitions = ((PrismContainerDefinition<?>)containerDefinition).getDefinitions();
for (ItemDefinition subDef: origSubDefinitions) {
// TODO fix this brutal hack - it is necessary to avoid endless recursion in the style of "Decision for authorization/object/owner/owner/......../owner/special: ALLOW"
// it's too late to come up with a serious solution
if (!(itemPath.lastNamed() != null && ObjectSpecificationType.F_OWNER.equals(itemPath.lastNamed().getName()) && ObjectSpecificationType.F_OWNER.equals(subDef.getName()))) {
ItemDefinition newDef = applySecurityContraints(subDef, new ItemPath(itemPath, subDef.getName()), securityConstraints,
applySecurityContraints(subDef, new ItemPath(itemPath, subDef.getName()), securityConstraints,
readDecision, addDecision, modifyDecision, phase);
containerDefinition.getComplexTypeDefinition().add(newDef);
}
}
}
return itemDefinition;
}

private AuthorizationDecisionType computeItemDecision(ObjectSecurityConstraints securityConstraints, ItemPath itemPath, String actionUrl,
Expand All @@ -888,6 +896,23 @@ private AuthorizationDecisionType computeItemDecision(ObjectSecurityConstraints
}
}

public <O extends ObjectType> ObjectTemplateType determineObjectTemplate(PrismObject<O> object, AuthorizationPhaseType phase, OperationResult result) throws SchemaException, ConfigurationException, ObjectNotFoundException {
PrismObject<SystemConfigurationType> systemConfiguration = Utils.getSystemConfiguration(cacheRepositoryService, result);
if (systemConfiguration == null) {
return null;
}
ObjectPolicyConfigurationType objectPolicyConfiguration = ModelUtils.determineObjectPolicyConfiguration(object.getCompileTimeClass(), systemConfiguration.asObjectable());
if (objectPolicyConfiguration == null) {
return null;
}
ObjectReferenceType objectTemplateRef = objectPolicyConfiguration.getObjectTemplateRef();
if (objectTemplateRef == null) {
return null;
}
PrismObject<ObjectTemplateType> template = cacheRepositoryService.getObject(ObjectTemplateType.class, objectTemplateRef.getOid(), null, result);
return template.asObjectable();
}

@Override
public RefinedObjectClassDefinition getEditObjectClassDefinition(PrismObject<ShadowType> shadow, PrismObject<ResourceType> resource, AuthorizationPhaseType phase)
throws SchemaException {
Expand Down
Expand Up @@ -15,14 +15,24 @@
*/
package com.evolveum.midpoint.model.impl.controller;

import javax.xml.namespace.QName;

import com.evolveum.midpoint.model.api.ModelAuthorizationAction;
import com.evolveum.midpoint.prism.PrismObject;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.query.ObjectPaging;
import com.evolveum.midpoint.schema.constants.ObjectTypes;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.util.exception.ConfigurationException;
import com.evolveum.midpoint.util.logging.LoggingUtils;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectPolicyConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectTemplateType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;

/**
*
Expand Down Expand Up @@ -87,5 +97,40 @@ public static <O extends ObjectType> String getOperationUrlFromDelta(ObjectDelta
}
throw new IllegalArgumentException("Unknown delta type "+delta);
}

public static <O extends ObjectType> ObjectPolicyConfigurationType determineObjectPolicyConfiguration(Class<O> objectClass, SystemConfigurationType systemConfigurationType) throws ConfigurationException {
for (ObjectPolicyConfigurationType aPolicyConfigurationType: systemConfigurationType.getDefaultObjectPolicyConfiguration()) {
QName typeQName = aPolicyConfigurationType.getType();
ObjectTypes objectType = ObjectTypes.getObjectTypeFromTypeQName(typeQName);
if (objectType == null) {
throw new ConfigurationException("Unknown type "+typeQName+" in default object policy definition in system configuration");
}
if (objectType.getClassDefinition() == objectClass) {
return aPolicyConfigurationType;
}
}

// Deprecated
for (ObjectPolicyConfigurationType aPolicyConfigurationType: systemConfigurationType.getObjectTemplate()) {
QName typeQName = aPolicyConfigurationType.getType();
ObjectTypes objectType = ObjectTypes.getObjectTypeFromTypeQName(typeQName);
if (objectType == null) {
throw new ConfigurationException("Unknown type "+typeQName+" in object template definition in system configuration");
}
if (objectType.getClassDefinition() == objectClass) {
return aPolicyConfigurationType;
}
}

// Deprecated method to specify user template. For compatibility only
if (objectClass == UserType.class) {
ObjectReferenceType templateRef = systemConfigurationType.getDefaultUserTemplateRef();
ObjectPolicyConfigurationType policy = new ObjectPolicyConfigurationType();
policy.setObjectTemplateRef(templateRef.clone());
return policy;
}

return null;
}

}

0 comments on commit 73d25dd

Please sign in to comment.