From 81dca716ed647f1476d0a5599ce34f2daf1efd35 Mon Sep 17 00:00:00 2001 From: Pavol Mederly Date: Fri, 20 Feb 2015 12:39:50 +0100 Subject: [PATCH 1/2] Fixed MID-1700-related problems. New "assigned" and "actor" (MID-2011) variables. Enable/disableTimestamp and disableReason are updated only when the state really changes. --- .../web/component/prism/PrismValuePanel.java | 4 + .../schema/constants/ExpressionConstants.java | 4 +- .../public/model/context/model-context-3.xsd | 11 +- .../AbstractSearchExpressionEvaluator.java | 5 +- ...alueTransformationExpressionEvaluator.java | 46 +++++-- ...gnmentTargetSearchExpressionEvaluator.java | 5 +- ...argetSearchExpressionEvaluatorFactory.java | 7 +- ...iationTargetSearchExpressionEvaluator.java | 5 +- ...argetSearchExpressionEvaluatorFactory.java | 7 +- .../script/ScriptExpressionEvaluator.java | 5 +- .../ScriptExpressionEvaluatorFactory.java | 7 +- .../common/expression/ExpressionTestUtil.java | 5 +- .../common/expression/TestExpression.java | 2 +- .../common/mapping/MappingTestEvaluator.java | 2 +- .../impl/lens/LensProjectionContext.java | 22 +++- .../lens/projector/ActivationProcessor.java | 122 ++++++++++++------ .../lens/projector/AssignmentProcessor.java | 8 ++ .../src/main/resources/ctx-model.xml | 3 + 18 files changed, 200 insertions(+), 70 deletions(-) diff --git a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java index f8ecd3dc5b7..3e59093e03c 100644 --- a/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java +++ b/gui/admin-gui/src/main/java/com/evolveum/midpoint/web/component/prism/PrismValuePanel.java @@ -421,6 +421,10 @@ public void uploadFileFailed(AjaxRequestTarget target) { if (type != null && type.isPrimitive()) { type = ClassUtils.primitiveToWrapper(type); } +// // default QName validation is a bit weird, so let's treat QNames as strings [TODO finish this - at the parsing side] +// if (type == QName.class) { +// type = String.class; +// } panel = new TextPanel<>(id, new PropertyModel(model, baseExpression), type); } diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/ExpressionConstants.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/ExpressionConstants.java index 2da91f78958..a37d0120c69 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/ExpressionConstants.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/constants/ExpressionConstants.java @@ -42,8 +42,10 @@ public class ExpressionConstants { public static final QName VAR_MODEL_CONTEXT = new QName(SchemaConstants.NS_C, "modelContext"); public static final QName VAR_PRISM_CONTEXT = new QName(SchemaConstants.NS_C, "prismContext"); public static final QName VAR_CONFIGURATION = new QName(SchemaConstants.NS_C, "configuration"); - + public static final QName VAR_ACTOR = new QName(SchemaConstants.NS_C, "actor"); + public static final QName VAR_LEGAL = new QName(SchemaConstants.NS_C, "legal"); + public static final QName VAR_ASSIGNED = new QName(SchemaConstants.NS_C, "assigned"); public static final QName VAR_FOCUS_EXISTS = new QName(SchemaConstants.NS_C, "focusExists"); public static final QName VAR_ADMINISTRATIVE_STATUS = new QName(SchemaConstants.NS_C, "administrativeStatus"); diff --git a/infra/schema/src/main/resources/xml/ns/public/model/context/model-context-3.xsd b/infra/schema/src/main/resources/xml/ns/public/model/context/model-context-3.xsd index 9640aa13c98..f66e44b654a 100644 --- a/infra/schema/src/main/resources/xml/ns/public/model/context/model-context-3.xsd +++ b/infra/schema/src/main/resources/xml/ns/public/model/context/model-context-3.xsd @@ -368,6 +368,13 @@ + + + + "Old" version of isAssigned. + + + @@ -378,14 +385,14 @@ - True if there is a valid assignment for this projection and/or the policy allows such project to exist. + True if there is a valid assignment for this projection and/or the policy allows such projection to exist. - True if there is a valid assignment for this projection and/or the policy allows such project to exist. + True if there is a valid assignment for this projection and/or the policy allows such projection to exist. diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AbstractSearchExpressionEvaluator.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AbstractSearchExpressionEvaluator.java index 9a09b6006b8..7b5eb3760ed 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AbstractSearchExpressionEvaluator.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AbstractSearchExpressionEvaluator.java @@ -21,6 +21,7 @@ import javax.xml.namespace.QName; +import com.evolveum.midpoint.security.api.SecurityEnforcer; import com.evolveum.midpoint.util.QNameUtil; import com.evolveum.prism.xml.ns._public.types_3.ItemPathType; @@ -92,8 +93,8 @@ public abstract class AbstractSearchExpressionEvaluator protected AbstractSearchExpressionEvaluator(SearchObjectExpressionEvaluatorType expressionEvaluatorType, ItemDefinition outputDefinition, Protector protector, ObjectResolver objectResolver, - ModelService modelService, PrismContext prismContext) { - super(expressionEvaluatorType); + ModelService modelService, PrismContext prismContext, SecurityEnforcer securityEnforcer) { + super(expressionEvaluatorType, securityEnforcer); this.outputDefinition = outputDefinition; this.prismContext = prismContext; this.protector = protector; diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AbstractValueTransformationExpressionEvaluator.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AbstractValueTransformationExpressionEvaluator.java index b1d3c7d2f8f..df0ace9ac68 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AbstractValueTransformationExpressionEvaluator.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AbstractValueTransformationExpressionEvaluator.java @@ -41,6 +41,8 @@ import com.evolveum.midpoint.prism.xml.XsdTypeMapper; import com.evolveum.midpoint.schema.constants.ExpressionConstants; import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.security.api.MidPointPrincipal; +import com.evolveum.midpoint.security.api.SecurityEnforcer; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.MiscUtil; import com.evolveum.midpoint.util.PrettyPrinter; @@ -48,7 +50,10 @@ import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.SchemaException; +import com.evolveum.midpoint.util.exception.SecurityViolationException; +import com.evolveum.midpoint.util.exception.SystemException; import com.evolveum.midpoint.util.exception.TunnelException; +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.TransformExpressionEvaluatorType; @@ -57,6 +62,7 @@ import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; +import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import org.w3c.dom.Element; import java.util.ArrayList; @@ -74,12 +80,15 @@ public abstract class AbstractValueTransformationExpressionEvaluator implements ExpressionEvaluator { + private SecurityEnforcer securityEnforcer; + private E expressionEvaluatorType; private static final Trace LOGGER = TraceManager.getTrace(AbstractValueTransformationExpressionEvaluator.class); - protected AbstractValueTransformationExpressionEvaluator(E expressionEvaluatorType) { + protected AbstractValueTransformationExpressionEvaluator(E expressionEvaluatorType, SecurityEnforcer securityEnforcer) { this.expressionEvaluatorType = expressionEvaluatorType; + this.securityEnforcer = securityEnforcer; } public E getExpressionEvaluatorType() { @@ -91,10 +100,12 @@ public E getExpressionEvaluatorType() { */ @Override public PrismValueDeltaSetTriple evaluate(ExpressionEvaluationContext context) throws SchemaException, - ExpressionEvaluationException, ObjectNotFoundException { + ExpressionEvaluationException, ObjectNotFoundException { PrismValueDeltaSetTriple outputTriple = new PrismValueDeltaSetTriple(); - + + addActorVariable(context.getVariables()); + if (expressionEvaluatorType.getRelativityMode() == TransformExpressionRelativityModeType.ABSOLUTE) { outputTriple = evaluateAbsoluteExpression(context.getSources(), context.getVariables(), context, @@ -183,8 +194,8 @@ private List> processSources(Collection evaluateAbsoluteExpression(Collection> sources, - ExpressionVariables variables, ExpressionEvaluationContext params, String contextDescription, Task task, OperationResult result) - throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { + ExpressionVariables variables, ExpressionEvaluationContext params, String contextDescription, Task task, OperationResult result) + throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException { PrismValueDeltaSetTriple outputTriple; @@ -272,7 +283,7 @@ private Collection evaluateScriptExpression(Collection scriptResults = transformSingleValue(scriptVariables, null, useNew, params, (useNew ? "(new) " : "(old) " ) + contextDescription, task, result); @@ -303,8 +314,27 @@ private Collection evaluateScriptExpression(Collection transformSingleValue(ExpressionVariables variables, PlusMinusZero valueDestination, + + private void addActorVariable(ExpressionVariables scriptVariables) { + UserType actor = null; + try { + if (securityEnforcer != null) { + MidPointPrincipal principal = securityEnforcer.getPrincipal(); + if (principal != null) { + actor = principal.getUser(); + } + } + if (actor == null) { + LOGGER.error("Couldn't get principal information - the 'actor' variable is set to null"); + } + } catch (SecurityViolationException e) { + LoggingUtils.logUnexpectedException(LOGGER, "Couldn't get principal information - the 'actor' variable is set to null", e); + } + + scriptVariables.addVariableDefinition(ExpressionConstants.VAR_ACTOR, actor); + } + + protected abstract List transformSingleValue(ExpressionVariables variables, PlusMinusZero valueDestination, boolean useNew, ExpressionEvaluationContext params, String contextDescription, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException; diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssignmentTargetSearchExpressionEvaluator.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssignmentTargetSearchExpressionEvaluator.java index c23ae98a93c..889c752df6c 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssignmentTargetSearchExpressionEvaluator.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssignmentTargetSearchExpressionEvaluator.java @@ -26,6 +26,7 @@ import com.evolveum.midpoint.prism.crypto.Protector; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.schema.util.ObjectResolver; +import com.evolveum.midpoint.security.api.SecurityEnforcer; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SystemException; import com.evolveum.midpoint.util.logging.Trace; @@ -45,8 +46,8 @@ public class AssignmentTargetSearchExpressionEvaluator public AssignmentTargetSearchExpressionEvaluator(SearchObjectExpressionEvaluatorType expressionEvaluatorType, ItemDefinition outputDefinition, Protector protector, ObjectResolver objectResolver, - ModelService modelService, PrismContext prismContext) { - super(expressionEvaluatorType, outputDefinition, protector, objectResolver, modelService, prismContext); + ModelService modelService, PrismContext prismContext, SecurityEnforcer securityEnforcer) { + super(expressionEvaluatorType, outputDefinition, protector, objectResolver, modelService, prismContext, securityEnforcer); } protected PrismContainerValue createPrismValue(String oid, QName targetTypeQName, ExpressionEvaluationContext params) { diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssignmentTargetSearchExpressionEvaluatorFactory.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssignmentTargetSearchExpressionEvaluatorFactory.java index fbd533536c5..06cc3fa0b78 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssignmentTargetSearchExpressionEvaluatorFactory.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssignmentTargetSearchExpressionEvaluatorFactory.java @@ -30,6 +30,7 @@ import com.evolveum.midpoint.prism.crypto.Protector; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectResolver; +import com.evolveum.midpoint.security.api.SecurityEnforcer; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectFactory; import com.evolveum.midpoint.xml.ns._public.common.common_3.SearchObjectExpressionEvaluatorType; @@ -45,13 +46,15 @@ public class AssignmentTargetSearchExpressionEvaluatorFactory implements Express private Protector protector; private ObjectResolver objectResolver; private ModelService modelService; + private SecurityEnforcer securityEnforcer; - public AssignmentTargetSearchExpressionEvaluatorFactory(PrismContext prismContext, Protector protector, ObjectResolver objectResolver, ModelService modelService) { + public AssignmentTargetSearchExpressionEvaluatorFactory(PrismContext prismContext, Protector protector, ObjectResolver objectResolver, ModelService modelService, SecurityEnforcer securityEnforcer) { super(); this.prismContext = prismContext; this.protector = protector; this.objectResolver = objectResolver; this.modelService = modelService; + this.securityEnforcer = securityEnforcer; } /* (non-Javadoc) @@ -87,7 +90,7 @@ public ExpressionEvaluator createEvaluator(Collection< throw new SchemaException("assignment expression evaluator cannot handle elements of type " + evaluatorTypeObject.getClass().getName()+" in "+contextDescription); } AssignmentTargetSearchExpressionEvaluator expressionEvaluator = new AssignmentTargetSearchExpressionEvaluator((SearchObjectExpressionEvaluatorType)evaluatorTypeObject, - outputDefinition, protector, objectResolver, modelService, prismContext); + outputDefinition, protector, objectResolver, modelService, prismContext, securityEnforcer); return (ExpressionEvaluator) expressionEvaluator; } diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationTargetSearchExpressionEvaluator.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationTargetSearchExpressionEvaluator.java index 9016ba7a0e2..ac4a9508899 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationTargetSearchExpressionEvaluator.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationTargetSearchExpressionEvaluator.java @@ -33,6 +33,7 @@ import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.util.ObjectQueryUtil; import com.evolveum.midpoint.schema.util.ObjectResolver; +import com.evolveum.midpoint.security.api.SecurityEnforcer; import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.util.exception.SystemException; @@ -53,8 +54,8 @@ public class AssociationTargetSearchExpressionEvaluator public AssociationTargetSearchExpressionEvaluator(SearchObjectExpressionEvaluatorType expressionEvaluatorType, ItemDefinition outputDefinition, Protector protector, ObjectResolver objectResolver, - ModelService modelService, PrismContext prismContext) { - super(expressionEvaluatorType, outputDefinition, protector, objectResolver, modelService, prismContext); + ModelService modelService, PrismContext prismContext, SecurityEnforcer securityEnforcer) { + super(expressionEvaluatorType, outputDefinition, protector, objectResolver, modelService, prismContext, securityEnforcer); } @Override diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationTargetSearchExpressionEvaluatorFactory.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationTargetSearchExpressionEvaluatorFactory.java index 3f5db939313..e9c7ca96d01 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationTargetSearchExpressionEvaluatorFactory.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/evaluator/AssociationTargetSearchExpressionEvaluatorFactory.java @@ -29,6 +29,7 @@ import com.evolveum.midpoint.prism.crypto.Protector; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectResolver; +import com.evolveum.midpoint.security.api.SecurityEnforcer; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectFactory; import com.evolveum.midpoint.xml.ns._public.common.common_3.SearchObjectExpressionEvaluatorType; @@ -44,13 +45,15 @@ public class AssociationTargetSearchExpressionEvaluatorFactory implements Expres private Protector protector; private ObjectResolver objectResolver; private ModelService modelService; + private SecurityEnforcer securityEnforcer; - public AssociationTargetSearchExpressionEvaluatorFactory(PrismContext prismContext, Protector protector, ObjectResolver objectResolver, ModelService modelService) { + public AssociationTargetSearchExpressionEvaluatorFactory(PrismContext prismContext, Protector protector, ObjectResolver objectResolver, ModelService modelService, SecurityEnforcer securityEnforcer) { super(); this.prismContext = prismContext; this.protector = protector; this.objectResolver = objectResolver; this.modelService = modelService; + this.securityEnforcer = securityEnforcer; } /* (non-Javadoc) @@ -86,7 +89,7 @@ public ExpressionEvaluator createEvaluator(Collection< throw new SchemaException("Association expression evaluator cannot handle elements of type " + evaluatorTypeObject.getClass().getName()+" in "+contextDescription); } AssociationTargetSearchExpressionEvaluator evaluator = new AssociationTargetSearchExpressionEvaluator((SearchObjectExpressionEvaluatorType)evaluatorTypeObject, - outputDefinition, protector, objectResolver, modelService, prismContext); + outputDefinition, protector, objectResolver, modelService, prismContext, securityEnforcer); return (ExpressionEvaluator) evaluator; } diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/ScriptExpressionEvaluator.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/ScriptExpressionEvaluator.java index 5749fc6445d..14730e39b31 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/ScriptExpressionEvaluator.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/ScriptExpressionEvaluator.java @@ -23,6 +23,7 @@ import com.evolveum.midpoint.prism.PrismValue; import com.evolveum.midpoint.prism.delta.PlusMinusZero; import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.security.api.SecurityEnforcer; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.exception.ExpressionEvaluationException; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; @@ -42,8 +43,8 @@ public class ScriptExpressionEvaluator private static final Trace LOGGER = TraceManager.getTrace(ScriptExpressionEvaluator.class); - ScriptExpressionEvaluator(ScriptExpressionEvaluatorType scriptType, ScriptExpression scriptExpression) { - super(scriptType); + ScriptExpressionEvaluator(ScriptExpressionEvaluatorType scriptType, ScriptExpression scriptExpression, SecurityEnforcer securityEnforcer) { + super(scriptType, securityEnforcer); this.scriptExpression = scriptExpression; } diff --git a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/ScriptExpressionEvaluatorFactory.java b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/ScriptExpressionEvaluatorFactory.java index 9d493211f27..1002fa2cb07 100644 --- a/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/ScriptExpressionEvaluatorFactory.java +++ b/model/model-common/src/main/java/com/evolveum/midpoint/model/common/expression/script/ScriptExpressionEvaluatorFactory.java @@ -25,6 +25,7 @@ import com.evolveum.midpoint.prism.ItemDefinition; import com.evolveum.midpoint.prism.PrismValue; import com.evolveum.midpoint.schema.result.OperationResult; +import com.evolveum.midpoint.security.api.SecurityEnforcer; import com.evolveum.midpoint.util.exception.SchemaException; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectFactory; import com.evolveum.midpoint.xml.ns._public.common.common_3.ScriptExpressionEvaluatorType; @@ -36,9 +37,11 @@ public class ScriptExpressionEvaluatorFactory implements ExpressionEvaluatorFactory { private ScriptExpressionFactory scriptExpressionFactory; + private SecurityEnforcer securityEnforcer; - public ScriptExpressionEvaluatorFactory(ScriptExpressionFactory scriptExpressionFactory) { + public ScriptExpressionEvaluatorFactory(ScriptExpressionFactory scriptExpressionFactory, SecurityEnforcer securityEnforcer) { this.scriptExpressionFactory = scriptExpressionFactory; + this.securityEnforcer = securityEnforcer; } @Override @@ -66,7 +69,7 @@ public ExpressionEvaluator createEvaluator(Collection< ScriptExpression scriptExpression = scriptExpressionFactory.createScriptExpression(scriptType, outputDefinition, contextDescription); - return new ScriptExpressionEvaluator(scriptType, scriptExpression); + return new ScriptExpressionEvaluator(scriptType, scriptExpression, securityEnforcer); } diff --git a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/ExpressionTestUtil.java b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/ExpressionTestUtil.java index 63ca57f48ef..f901eeafc47 100644 --- a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/ExpressionTestUtil.java +++ b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/ExpressionTestUtil.java @@ -32,6 +32,7 @@ import com.evolveum.midpoint.prism.PrismContext; import com.evolveum.midpoint.prism.crypto.AESProtector; import com.evolveum.midpoint.schema.util.ObjectResolver; +import com.evolveum.midpoint.security.api.SecurityEnforcer; import com.evolveum.midpoint.test.util.MidPointTestConstants; /** @@ -49,7 +50,7 @@ public static AESProtector createInitializedProtector(PrismContext prismContext) return protector; } - public static ExpressionFactory createInitializedExpressionFactory(ObjectResolver resolver, AESProtector protector, PrismContext prismContext) { + public static ExpressionFactory createInitializedExpressionFactory(ObjectResolver resolver, AESProtector protector, PrismContext prismContext, SecurityEnforcer securityEnforcer) { ExpressionFactory expressionFactory = new ExpressionFactory(resolver, prismContext); // asIs @@ -79,7 +80,7 @@ public static ExpressionFactory createInitializedExpressionFactory(ObjectResolve scriptExpressionFactory.registerEvaluator(XPathScriptEvaluator.XPATH_LANGUAGE_URL, xpathEvaluator); Jsr223ScriptEvaluator groovyEvaluator = new Jsr223ScriptEvaluator("Groovy", prismContext, protector); scriptExpressionFactory.registerEvaluator(groovyEvaluator.getLanguageUrl(), groovyEvaluator); - ScriptExpressionEvaluatorFactory scriptExpressionEvaluatorFactory = new ScriptExpressionEvaluatorFactory(scriptExpressionFactory); + ScriptExpressionEvaluatorFactory scriptExpressionEvaluatorFactory = new ScriptExpressionEvaluatorFactory(scriptExpressionFactory, securityEnforcer); expressionFactory.addEvaluatorFactory(scriptExpressionEvaluatorFactory); return expressionFactory; diff --git a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/TestExpression.java b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/TestExpression.java index 29360cc44a0..1e3d71f1089 100644 --- a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/TestExpression.java +++ b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/expression/TestExpression.java @@ -72,7 +72,7 @@ public void setup() throws SchemaException, SAXException, IOException { prismContext = PrismTestUtil.createInitializedPrismContext(); ObjectResolver resolver = new DirectoryFileObjectResolver(MidPointTestConstants.OBJECTS_DIR); AESProtector protector = ExpressionTestUtil.createInitializedProtector(prismContext); - expressionFactory = ExpressionTestUtil.createInitializedExpressionFactory(resolver, protector, prismContext); + expressionFactory = ExpressionTestUtil.createInitializedExpressionFactory(resolver, protector, prismContext, null); } @Test diff --git a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/mapping/MappingTestEvaluator.java b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/mapping/MappingTestEvaluator.java index 9cf39f8618a..d994b6a19ff 100644 --- a/model/model-common/src/test/java/com/evolveum/midpoint/model/common/mapping/MappingTestEvaluator.java +++ b/model/model-common/src/test/java/com/evolveum/midpoint/model/common/mapping/MappingTestEvaluator.java @@ -98,7 +98,7 @@ public void init() throws SAXException, IOException, SchemaException { prismContext = PrismTestUtil.createInitializedPrismContext(); ObjectResolver resolver = new DirectoryFileObjectResolver(MidPointTestConstants.OBJECTS_DIR); protector = ExpressionTestUtil.createInitializedProtector(prismContext); - ExpressionFactory expressionFactory = ExpressionTestUtil.createInitializedExpressionFactory(resolver, protector, prismContext); + ExpressionFactory expressionFactory = ExpressionTestUtil.createInitializedExpressionFactory(resolver, protector, prismContext, null); mappingFactory = new MappingFactory(); mappingFactory.setExpressionFactory(expressionFactory); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java index 9e14f0a16c4..e36c1f608fb 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java @@ -103,11 +103,12 @@ public class LensProjectionContext extends LensElementContext implem private boolean fullShadow = false; /** - * True if the account is "legal" (assigned to the user). It may be false for accounts that are either + * True if the account is assigned to the user by a valid assignment. It may be false for accounts that are either * found to be illegal by live sync, were unassigned from user, etc. * If set to null the situation is not yet known. Null is a typical value when the context is constructed. */ private boolean isAssigned; + private boolean isAssignedOld; /** * True if the account should be part of the synchronization. E.g. outbound expression should be applied to it. @@ -115,7 +116,7 @@ public class LensProjectionContext extends LensElementContext implem private boolean isActive; /** - * True if there is a valid assignment for this projection and/or the policy allows such project to exist. + * True if there is a valid assignment for this projection and/or the policy allows such projection to exist. */ private Boolean isLegal = null; private Boolean isLegalOld = null; @@ -185,6 +186,7 @@ public class LensProjectionContext extends LensElementContext implem super(ShadowType.class, lensContext); this.resourceShadowDiscriminator = resourceAccountType; this.isAssigned = false; + this.isAssignedOld = false; } public ObjectDelta getSyncDelta() { @@ -344,6 +346,14 @@ public void setAssigned(boolean isAssigned) { this.isAssigned = isAssigned; } + public boolean isAssignedOld() { + return isAssignedOld; + } + + public void setAssignedOld(boolean isAssignedOld) { + this.isAssignedOld = isAssignedOld; + } + public boolean isActive() { return isActive; } @@ -783,6 +793,7 @@ public void cleanup() { // isLegal = null; // isLegalOld = null; isAssigned = false; + isAssignedOld = false; // ??? [med] isActive = false; } @@ -800,6 +811,7 @@ public void reset() { wave = -1; fullShadow = false; isAssigned = false; + isAssignedOld = false; isActive = false; synchronizationPolicyDecision = null; constructionDeltaSetTriple = null; @@ -832,6 +844,7 @@ protected void copyValues(LensProjectionContext clone, LensContext").append(isAssigned); sb.append(", active=").append(isActive); sb.append(", legal=").append(isLegalOld).append("->").append(isLegal); sb.append(", recon=").append(doReconciliation); @@ -1116,6 +1129,7 @@ public void addToPrismContainer(PrismContainer lensPr resourceShadowDiscriminator.toResourceShadowDiscriminatorType() : null); lensProjectionContextType.setFullShadow(fullShadow); lensProjectionContextType.setIsAssigned(isAssigned); + lensProjectionContextType.setIsAssignedOld(isAssignedOld); lensProjectionContextType.setIsActive(isActive); lensProjectionContextType.setIsLegal(isLegal); lensProjectionContextType.setIsLegalOld(isLegalOld); @@ -1147,8 +1161,10 @@ public static LensProjectionContext fromLensProjectionContextType(LensProjection projectionContext.wave = projectionContextType.getWave() != null ? projectionContextType.getWave() : 0; projectionContext.fullShadow = projectionContextType.isFullShadow() != null ? projectionContextType.isFullShadow() : false; projectionContext.isAssigned = projectionContextType.isIsAssigned() != null ? projectionContextType.isIsAssigned() : false; + projectionContext.isAssignedOld = projectionContextType.isIsAssignedOld() != null ? projectionContextType.isIsAssignedOld() : false; projectionContext.isActive = projectionContextType.isIsActive() != null ? projectionContextType.isIsActive() : false; projectionContext.isLegal = projectionContextType.isIsLegal(); + projectionContext.isLegalOld = projectionContextType.isIsLegalOld(); projectionContext.isExists = projectionContextType.isIsExists() != null ? projectionContextType.isIsExists() : false; projectionContext.synchronizationPolicyDecision = SynchronizationPolicyDecision.fromSynchronizationPolicyDecisionType(projectionContextType.getSynchronizationPolicyDecision()); projectionContext.doReconciliation = projectionContextType.isDoReconciliation() != null ? projectionContextType.isDoReconciliation() : false; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ActivationProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ActivationProcessor.java index 47b812ae5bf..1e4dbb1cae8 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ActivationProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/ActivationProcessor.java @@ -90,6 +90,7 @@ public class ActivationProcessor { private static final QName SHADOW_EXISTS_PROPERTY_NAME = new QName(SchemaConstants.NS_C, "shadowExists"); private static final QName LEGAL_PROPERTY_NAME = new QName(SchemaConstants.NS_C, "legal"); + private static final QName ASSIGNED_PROPERTY_NAME = new QName(SchemaConstants.NS_C, "assigned"); private static final QName FOCUS_EXISTS_PROPERTY_NAME = new QName(SchemaConstants.NS_C, "focusExists"); private PrismObjectDefinition userDefinition; @@ -309,36 +310,49 @@ public void processActivationMetadata(LensContext conte PropertyDelta statusDelta = projDelta.findPropertyDelta(SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS); if (statusDelta != null && !statusDelta.isDelete()) { - // timestamps - PrismProperty statusPropNew = (PrismProperty) statusDelta.getItemNewMatchingPath(null); - ActivationStatusType statusNew = statusPropNew.getRealValue(); - PropertyDelta timestampDelta = LensUtil.createActivationTimestampDelta(statusNew, - now, getActivationDefinition(), OriginType.OUTBOUND); - accCtx.swallowToSecondaryDelta(timestampDelta); - - // disableReason - if (statusNew == ActivationStatusType.DISABLED) { - PropertyDelta disableReasonDelta = projDelta.findPropertyDelta(SchemaConstants.PATH_ACTIVATION_DISABLE_REASON); - if (disableReasonDelta == null) { - String disableReason = null; - ObjectDelta projPrimaryDelta = accCtx.getPrimaryDelta(); - ObjectDelta projSecondaryDelta = accCtx.getSecondaryDelta(); - if (projPrimaryDelta != null - && projPrimaryDelta.findPropertyDelta(SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS) != null - && (projSecondaryDelta == null || projSecondaryDelta.findPropertyDelta(SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS) == null)) { - disableReason = SchemaConstants.MODEL_DISABLE_REASON_EXPLICIT; - } else if (accCtx.isLegal()) { - disableReason = SchemaConstants.MODEL_DISABLE_REASON_MAPPED; - } else { - disableReason = SchemaConstants.MODEL_DISABLE_REASON_DEPROVISION; - } - - PrismPropertyDefinition disableReasonDef = activationDefinition.findPropertyDefinition(ActivationType.F_DISABLE_REASON); - disableReasonDelta = disableReasonDef.createEmptyDelta(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_DISABLE_REASON)); - disableReasonDelta.setValueToReplace(new PrismPropertyValue(disableReason, OriginType.OUTBOUND, null)); - accCtx.swallowToSecondaryDelta(disableReasonDelta); - } - } + + // we have to determine if the status really changed + PrismObject oldShadow = accCtx.getObjectOld(); + ActivationStatusType statusOld = null; + if (oldShadow != null && oldShadow.asObjectable().getActivation() != null) { + statusOld = oldShadow.asObjectable().getActivation().getAdministrativeStatus(); + } + + PrismProperty statusPropNew = (PrismProperty) statusDelta.getItemNewMatchingPath(null); + ActivationStatusType statusNew = statusPropNew.getRealValue(); + + if (statusNew == statusOld) { + LOGGER.trace("Administrative status not changed ({}), timestamp and/or reason will be recorded", statusNew); + } else { + // timestamps + PropertyDelta timestampDelta = LensUtil.createActivationTimestampDelta(statusNew, + now, getActivationDefinition(), OriginType.OUTBOUND); + accCtx.swallowToSecondaryDelta(timestampDelta); + + // disableReason + if (statusNew == ActivationStatusType.DISABLED) { + PropertyDelta disableReasonDelta = projDelta.findPropertyDelta(SchemaConstants.PATH_ACTIVATION_DISABLE_REASON); + if (disableReasonDelta == null) { + String disableReason = null; + ObjectDelta projPrimaryDelta = accCtx.getPrimaryDelta(); + ObjectDelta projSecondaryDelta = accCtx.getSecondaryDelta(); + if (projPrimaryDelta != null + && projPrimaryDelta.findPropertyDelta(SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS) != null + && (projSecondaryDelta == null || projSecondaryDelta.findPropertyDelta(SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS) == null)) { + disableReason = SchemaConstants.MODEL_DISABLE_REASON_EXPLICIT; + } else if (accCtx.isLegal()) { + disableReason = SchemaConstants.MODEL_DISABLE_REASON_MAPPED; + } else { + disableReason = SchemaConstants.MODEL_DISABLE_REASON_DEPROVISION; + } + + PrismPropertyDefinition disableReasonDef = activationDefinition.findPropertyDefinition(ActivationType.F_DISABLE_REASON); + disableReasonDelta = disableReasonDef.createEmptyDelta(new ItemPath(FocusType.F_ACTIVATION, ActivationType.F_DISABLE_REASON)); + disableReasonDelta.setValueToReplace(new PrismPropertyValue(disableReason, OriginType.OUTBOUND, null)); + accCtx.swallowToSecondaryDelta(disableReasonDelta); + } + } + } } } @@ -444,7 +458,12 @@ public void initialize(Mapping> existenceMapping) th = new Source>(legalSourceIdi, ExpressionConstants.VAR_LEGAL); existenceMapping.setDefaultSource(legalSource); - // Source: focusExists + // Source: assigned + ItemDeltaItem> assignedIdi = getAssignedIdi(accCtx); + Source> assignedSource = new Source>(assignedIdi, ExpressionConstants.VAR_ASSIGNED); + existenceMapping.addSource(assignedSource); + + // Source: focusExists ItemDeltaItem> focusExistsSourceIdi = getFocusExistsIdi(context.getFocusContext()); Source> focusExistsSource = new Source>(focusExistsSourceIdi, ExpressionConstants.VAR_FOCUS_EXISTS); @@ -585,8 +604,13 @@ public void initialize(Mapping> mapping) throws SchemaExce ItemDeltaItem> legalIdi = getLegalIdi(projCtx); Source> legalSource = new Source>(legalIdi, ExpressionConstants.VAR_LEGAL); mapping.addSource(legalSource); - - // Source: focusExists + + // Source: assigned + ItemDeltaItem> assignedIdi = getAssignedIdi(projCtx); + Source> assignedSource = new Source>(assignedIdi, ExpressionConstants.VAR_ASSIGNED); + mapping.addSource(assignedSource); + + // Source: focusExists ItemDeltaItem> focusExistsSourceIdi = getFocusExistsIdi(context.getFocusContext()); Source> focusExistsSource = new Source>(focusExistsSourceIdi, ExpressionConstants.VAR_FOCUS_EXISTS); @@ -626,15 +650,15 @@ public void initialize(Mapping> mapping) throws SchemaExce private ItemDeltaItem> getLegalIdi(LensProjectionContext accCtx) throws SchemaException { Boolean legal = accCtx.isLegal(); Boolean legalOld = accCtx.isLegalOld(); - - PrismPropertyDefinition legalDef = new PrismPropertyDefinition(LEGAL_PROPERTY_NAME, + + PrismPropertyDefinition legalDef = new PrismPropertyDefinition(LEGAL_PROPERTY_NAME, DOMUtil.XSD_BOOLEAN, prismContext); legalDef.setMinOccurs(1); legalDef.setMaxOccurs(1); PrismProperty legalProp = legalDef.instantiate(); legalProp.add(new PrismPropertyValue(legal)); - - if (legal == legalOld) { + + if (legal == legalOld) { return new ItemDeltaItem>(legalProp); } else { PrismProperty legalPropOld = legalProp.clone(); @@ -645,7 +669,29 @@ private ItemDeltaItem> getLegalIdi(LensProjectionCon } } - private ItemDeltaItem> getFocusExistsIdi( + private ItemDeltaItem> getAssignedIdi(LensProjectionContext accCtx) throws SchemaException { + Boolean assigned = accCtx.isAssigned(); + Boolean assignedOld = accCtx.isAssignedOld(); + + PrismPropertyDefinition assignedDef = new PrismPropertyDefinition(ASSIGNED_PROPERTY_NAME, + DOMUtil.XSD_BOOLEAN, prismContext); + assignedDef.setMinOccurs(1); + assignedDef.setMaxOccurs(1); + PrismProperty assignedProp = assignedDef.instantiate(); + assignedProp.add(new PrismPropertyValue<>(assigned)); + + if (assigned == assignedOld) { + return new ItemDeltaItem<>(assignedProp); + } else { + PrismProperty assignedPropOld = assignedProp.clone(); + assignedPropOld.setRealValue(assignedOld); + PropertyDelta assignedDelta = assignedPropOld.createDelta(); + assignedDelta.setValuesToReplace(new PrismPropertyValue<>(assigned)); + return new ItemDeltaItem<>(assignedPropOld, assignedDelta, assignedProp); + } + } + + private ItemDeltaItem> getFocusExistsIdi( LensFocusContext lensFocusContext) throws SchemaException { Boolean existsOld = null; Boolean existsNew = null; diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentProcessor.java index 3b761a4c61a..31ffd3fcb7c 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentProcessor.java @@ -548,6 +548,7 @@ private void processAssignmentsProjectionsWithFocus(LensCo if (constructionPack.hasValidAssignment()) { LensProjectionContext projectionContext = LensUtil.getOrCreateProjectionContext(context, rat); projectionContext.setAssigned(true); + projectionContext.setAssignedOld(false); projectionContext.setLegalOld(false); AssignmentPolicyEnforcementType assignmentPolicyEnforcement = projectionContext.getAssignmentPolicyEnforcementType(); if (assignmentPolicyEnforcement != AssignmentPolicyEnforcementType.NONE) { @@ -576,6 +577,7 @@ private void processAssignmentsProjectionsWithFocus(LensCo projectionContext.setLegal(true); projectionContext.setLegalOld(true); projectionContext.setAssigned(true); + projectionContext.setAssignedOld(true); // SITUATION: The projection is both ASSIGNED and UNASSIGNED } else if (constructionMapTriple.getPlusMap().containsKey(rat) && constructionMapTriple.getMinusMap().containsKey(rat)) { @@ -600,6 +602,7 @@ private void processAssignmentsProjectionsWithFocus(LensCo } LOGGER.trace("Projection {} legal: both assigned and unassigned (valid)", desc); projectionContext.setAssigned(true); + projectionContext.setAssignedOld(true); projectionContext.setLegal(true); projectionContext.setLegalOld(true); @@ -617,6 +620,7 @@ private void processAssignmentsProjectionsWithFocus(LensCo projectionContext = LensUtil.getOrCreateProjectionContext(context, rat); } projectionContext.setAssigned(true); + projectionContext.setAssignedOld(false); projectionContext.setLegalOld(false); AssignmentPolicyEnforcementType assignmentPolicyEnforcement = projectionContext.getAssignmentPolicyEnforcementType(); if (assignmentPolicyEnforcement != AssignmentPolicyEnforcementType.NONE) { @@ -635,6 +639,7 @@ private void processAssignmentsProjectionsWithFocus(LensCo projectionContext = LensUtil.getOrCreateProjectionContext(context, rat); } projectionContext.setAssigned(false); + projectionContext.setAssignedOld(true); projectionContext.setLegalOld(true); AssignmentPolicyEnforcementType assignmentPolicyEnforcement = projectionContext.getAssignmentPolicyEnforcementType(); @@ -663,6 +668,7 @@ private void processAssignmentsProjectionsWithFocus(LensCo if (accountExists(context,rat)) { LensProjectionContext projectionContext = LensUtil.getOrCreateProjectionContext(context, rat); projectionContext.setAssigned(false); + projectionContext.setAssignedOld(true); projectionContext.setLegalOld(true); AssignmentPolicyEnforcementType assignmentPolicyEnforcement = projectionContext.getAssignmentPolicyEnforcementType(); @@ -698,6 +704,7 @@ private void processAssignmentsProjectionsWithFocus(LensCo projectionContext.setLegal(false); projectionContext.setLegalOld(false); projectionContext.setAssigned(false); + projectionContext.setAssignedOld(false); } else { throw new IllegalStateException("Projection " + desc + " went looney"); @@ -1021,6 +1028,7 @@ private void finishLegalDecisions(LensContext context) LOGGER.trace("Projection {} legal: legalized", desc); createAssignmentDelta(context, projectionContext); projectionContext.setAssigned(true); + projectionContext.setAssignedOld(false); projectionContext.setLegal(true); projectionContext.setLegalOld(false); } else { diff --git a/model/model-impl/src/main/resources/ctx-model.xml b/model/model-impl/src/main/resources/ctx-model.xml index 0085cf1c76d..28f7a9c1c3b 100644 --- a/model/model-impl/src/main/resources/ctx-model.xml +++ b/model/model-impl/src/main/resources/ctx-model.xml @@ -123,6 +123,7 @@ + + + Date: Fri, 20 Feb 2015 12:46:06 +0100 Subject: [PATCH 2/2] Yet another sample fix to make build work --- samples/demo/opendj.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/demo/opendj.xml b/samples/demo/opendj.xml index 84c151a7be0..11f9a319d64 100644 --- a/samples/demo/opendj.xml +++ b/samples/demo/opendj.xml @@ -482,11 +482,11 @@ + entitlement + group Group true ri:GroupObjectClass - entitlement - group