Skip to content

Commit

Permalink
Role conditions almost done, assignment conditions almost almost done…
Browse files Browse the repository at this point in the history
… (untested).
  • Loading branch information
semancik committed Jul 31, 2014
1 parent a33a8ab commit 1c57aa0
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 52 deletions.
Expand Up @@ -155,6 +155,10 @@ public PolyString getAt(int index) {
public int length() {
return orig.length();
}

public PolyString trim() {
return new PolyString(orig.trim(), norm.trim());
}

@Override
public int hashCode() {
Expand Down
Expand Up @@ -81,9 +81,15 @@ public static <T> T convert(Class<T> expectedType, Object rawValue) {
if (expectedType == Boolean.class && rawValue instanceof String) {
return (T) (Boolean)Boolean.parseBoolean(((String)rawValue));
}
if (expectedType == Boolean.class && rawValue instanceof PolyString) {
return (T) (Boolean)Boolean.parseBoolean(((PolyString)rawValue).toString());
}
if (expectedType == boolean.class && rawValue instanceof String) {
return (T) (Boolean)Boolean.parseBoolean(((String)rawValue));
}
if (expectedType == boolean.class && rawValue instanceof PolyString) {
return (T) (Boolean)Boolean.parseBoolean(((PolyString)rawValue).toString());
}
if (expectedType == String.class && rawValue instanceof Boolean) {
return (T) rawValue.toString();
}
Expand Down
1 change: 1 addition & 0 deletions infra/schema/.gitignore
Expand Up @@ -16,3 +16,4 @@
/target
/target
/target
/target
Expand Up @@ -54,6 +54,7 @@
import com.evolveum.midpoint.prism.crypto.EncryptionException;
import com.evolveum.midpoint.prism.crypto.Protector;
import com.evolveum.midpoint.prism.delta.ItemDelta;
import com.evolveum.midpoint.prism.delta.PlusMinusZero;
import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.path.ItemPathSegment;
Expand Down Expand Up @@ -552,5 +553,42 @@ public static boolean hasExplicitTarget(List<MappingType> mappingTypes) {
private static boolean hasExplicitTarget(MappingType mappingType) {
return mappingType.getTarget() != null;
}

public static boolean computeConditionResult(Collection<PrismPropertyValue<Boolean>> booleanPropertyValues) {
if (booleanPropertyValues == null || booleanPropertyValues.isEmpty()) {
// No value means false
return false;
}
boolean hasFalse = false;
for (PrismPropertyValue<Boolean> pval: booleanPropertyValues) {
Boolean value = pval.getValue();
if (Boolean.TRUE.equals(value)) {
return true;
}
if (Boolean.FALSE.equals(value)) {
hasFalse = true;
}
}
if (hasFalse) {
return false;
}
// No value or all values null. Return default.
return true;
}

public static PlusMinusZero computeConditionResultMode(boolean condOld, boolean condNew) {
if (condOld && condNew) {
return PlusMinusZero.ZERO;
}
if (!condOld && !condNew) {
return null;
}
if (condOld && !condNew) {
return PlusMinusZero.MINUS;
}
if (!condOld && condNew) {
return PlusMinusZero.PLUS;
}
throw new IllegalStateException("notreached");
}
}
Expand Up @@ -647,25 +647,7 @@ private boolean computeConditionResult(Collection<PrismPropertyValue<Boolean>> b
// If condition is not present at all consider it to be true
return true;
}
if (booleanPropertyValues == null || booleanPropertyValues.isEmpty()) {
// No value means false
return false;
}
boolean hasFalse = false;
for (PrismPropertyValue<Boolean> pval: booleanPropertyValues) {
Boolean value = pval.getValue();
if (Boolean.TRUE.equals(value)) {
return true;
}
if (Boolean.FALSE.equals(value)) {
hasFalse = true;
}
}
if (hasFalse) {
return false;
}
// No value or all values null. Return default.
return true;
return ExpressionUtil.computeConditionResult(booleanPropertyValues);
}

public Boolean evaluateTimeConstraintValid(OperationResult result) throws SchemaException, ObjectNotFoundException {
Expand Down
Expand Up @@ -24,6 +24,7 @@

import com.evolveum.midpoint.common.ActivationComputer;
import com.evolveum.midpoint.model.api.PolicyViolationException;
import com.evolveum.midpoint.model.common.expression.ExpressionUtil;
import com.evolveum.midpoint.model.common.expression.ItemDeltaItem;
import com.evolveum.midpoint.model.common.expression.ObjectDeltaObject;
import com.evolveum.midpoint.model.common.mapping.Mapping;
Expand All @@ -44,6 +45,7 @@
import com.evolveum.midpoint.prism.delta.DeltaSetTriple;
import com.evolveum.midpoint.prism.delta.ItemDelta;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.delta.PlusMinusZero;
import com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple;
import com.evolveum.midpoint.repo.api.RepositoryService;
import com.evolveum.midpoint.schema.constants.ExpressionConstants;
Expand Down Expand Up @@ -208,7 +210,7 @@ public EvaluatedAssignment<F> evaluate(ItemDeltaItem<PrismContainerValue<Assignm
assignmentPathSegment.setEvaluateConstructions(true);
assignmentPathSegment.setValidityOverride(true);

evaluateAssignment(evalAssignment, assignmentPathSegment, evaluateOld, source, sourceDescription, assignmentPath, task, result);
evaluateAssignment(evalAssignment, assignmentPathSegment, evaluateOld, PlusMinusZero.ZERO, source, sourceDescription, assignmentPath, task, result);

if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Assignment evaluation finished:\n{}", evalAssignment.debugDump());
Expand All @@ -218,11 +220,12 @@ public EvaluatedAssignment<F> evaluate(ItemDeltaItem<PrismContainerValue<Assignm
}

private void evaluateAssignment(EvaluatedAssignment<F> evalAssignment, AssignmentPathSegment assignmentPathSegment,
boolean evaluateOld, ObjectType source, String sourceDescription,
boolean evaluateOld, PlusMinusZero mode, ObjectType source, String sourceDescription,
AssignmentPath assignmentPath, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, PolicyViolationException {
assertSource(source, evalAssignment);

LOGGER.trace("Evaluate assignment {} (eval constr: {})", assignmentPath, assignmentPathSegment.isEvaluateConstructions());
LOGGER.trace("Evaluate assignment {} (eval constr: {}, mode: {})", new Object[]{
assignmentPath, assignmentPathSegment.isEvaluateConstructions(), mode});

ItemDeltaItem<PrismContainerValue<AssignmentType>> assignmentIdi = assignmentPathSegment.getAssignmentIdi();
AssignmentType assignmentType = LensUtil.getAssignmentType(assignmentIdi, evaluateOld);
Expand Down Expand Up @@ -250,13 +253,28 @@ private void evaluateAssignment(EvaluatedAssignment<F> evalAssignment, Assignmen

assignmentPath.add(assignmentPathSegment);

MappingType conditionType = assignmentType.getCondition();
if (conditionType != null) {
PrismValueDeltaSetTriple<PrismPropertyValue<Boolean>> conditionTriple = evaluateMappingAsCondition(conditionType, source, task, result);
boolean condOld = ExpressionUtil.computeConditionResult(conditionTriple.getNonPositiveValues());
boolean condNew = ExpressionUtil.computeConditionResult(conditionTriple.getNonNegativeValues());
PlusMinusZero condMode = ExpressionUtil.computeConditionResultMode(condOld, condNew);
if (condMode == null || (condMode == PlusMinusZero.ZERO && !condNew)) {
LOGGER.trace("Skipping evaluation of "+assignmentType+" because of condition result");
assignmentPath.remove(assignmentPathSegment);
evalAssignment.setValid(false);
return;
}
mode = PlusMinusZero.compute(mode, condMode);
}

boolean isValid = LensUtil.isValid(assignmentType, now, activationComputer);
if (isValid || assignmentPathSegment.isValidityOverride()) {

if (assignmentType.getConstruction() != null) {

if (evaluateConstructions && assignmentPathSegment.isEvaluateConstructions()) {
prepareConstructionEvaluation(evalAssignment, assignmentPathSegment, evaluateOld, source, sourceDescription,
prepareConstructionEvaluation(evalAssignment, assignmentPathSegment, evaluateOld, mode, source, sourceDescription,
assignmentPath, assignmentPathSegment.getOrderOneObject(), task, result);
}

Expand All @@ -269,7 +287,7 @@ private void evaluateAssignment(EvaluatedAssignment<F> evalAssignment, Assignmen

} else if (target != null) {

evaluateTarget(evalAssignment, assignmentPathSegment, evaluateOld, target, source, assignmentType.getTargetRef().getRelation(), sourceDescription,
evaluateTarget(evalAssignment, assignmentPathSegment, evaluateOld, mode, target, source, assignmentType.getTargetRef().getRelation(), sourceDescription,
assignmentPath, task, result);

} else {
Expand All @@ -288,7 +306,7 @@ private void evaluateAssignment(EvaluatedAssignment<F> evalAssignment, Assignmen
}

private void prepareConstructionEvaluation(EvaluatedAssignment<F> evaluatedAssignment, AssignmentPathSegment assignmentPathSegment,
boolean evaluateOld, ObjectType source, String sourceDescription,
boolean evaluateOld, PlusMinusZero mode, ObjectType source, String sourceDescription,
AssignmentPath assignmentPath, ObjectType orderOneObject, Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException {
assertSource(source, evaluatedAssignment);

Expand All @@ -310,8 +328,17 @@ private void prepareConstructionEvaluation(EvaluatedAssignment<F> evaluatedAssig
construction.setOrderOneObject(orderOneObject);

// Do not evaluate the construction here. We will do it in the second pass. Just prepare everything to be evaluated.

evaluatedAssignment.addConstructionZero(construction);
switch (mode) {
case PLUS:
evaluatedAssignment.addConstructionPlus(construction);
break;
case ZERO:
evaluatedAssignment.addConstructionZero(construction);
break;
case MINUS:
evaluatedAssignment.addConstructionMinus(construction);
break;
}
}

private void evaluateFocusMappings(EvaluatedAssignment<F> evaluatedAssignment, AssignmentPathSegment assignmentPathSegment,
Expand Down Expand Up @@ -373,15 +400,15 @@ private PrismObject<?> resolveTarget(AssignmentType assignmentType, ObjectType s


private void evaluateTarget(EvaluatedAssignment<F> assignment, AssignmentPathSegment assignmentPathSegment,
boolean evaluateOld, PrismObject<?> target, ObjectType source, QName relation, String sourceDescription,
boolean evaluateOld, PlusMinusZero mode, PrismObject<?> target, ObjectType source, QName relation, String sourceDescription,
AssignmentPath assignmentPath, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, PolicyViolationException {
assertSource(source, assignment);
ObjectType targetType = (ObjectType) target.asObjectable();
assignmentPathSegment.setTarget(targetType);
if (targetType instanceof AbstractRoleType) {
evaluateAbstractRole(assignment, assignmentPathSegment, evaluateOld, (AbstractRoleType)targetType, source, sourceDescription,
boolean roleConditionTrue = evaluateAbstractRole(assignment, assignmentPathSegment, evaluateOld, mode, (AbstractRoleType)targetType, source, sourceDescription,
assignmentPath, task, result);
if (targetType instanceof OrgType && assignmentPath.getEvaluationOrder() == 1) {
if (roleConditionTrue && mode != PlusMinusZero.MINUS && targetType instanceof OrgType && assignmentPath.getEvaluationOrder() == 1) {
PrismReferenceValue refVal = new PrismReferenceValue();
refVal.setObject(targetType.asPrismObject());
refVal.setRelation(relation);
Expand All @@ -393,18 +420,21 @@ private void evaluateTarget(EvaluatedAssignment<F> assignment, AssignmentPathSeg
}

private boolean evaluateAbstractRole(EvaluatedAssignment<F> assignment, AssignmentPathSegment assignmentPathSegment,
boolean evaluateOld, AbstractRoleType roleType, ObjectType source, String sourceDescription,
boolean evaluateOld, PlusMinusZero mode, AbstractRoleType roleType, ObjectType source, String sourceDescription,
AssignmentPath assignmentPath, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, PolicyViolationException {
assertSource(source, assignment);

MappingType conditionType = roleType.getCondition();
if (conditionType != null) {
DeltaSetTriple<Boolean> conditionTriple = evaluateMappingAsCondition(conditionType, source, task, result);
if (conditionTriple != null) {
// TODO


PrismValueDeltaSetTriple<PrismPropertyValue<Boolean>> conditionTriple = evaluateMappingAsCondition(conditionType, source, task, result);
boolean condOld = ExpressionUtil.computeConditionResult(conditionTriple.getNonPositiveValues());
boolean condNew = ExpressionUtil.computeConditionResult(conditionTriple.getNonNegativeValues());
PlusMinusZero condMode = ExpressionUtil.computeConditionResultMode(condOld, condNew);
if (condMode == null || (condMode == PlusMinusZero.ZERO && !condNew)) {
LOGGER.trace("Skipping evaluation of "+roleType+" because of condition result");
return false;
}
mode = PlusMinusZero.compute(mode, condMode);
}

int evaluationOrder = assignmentPath.getEvaluationOrder();
Expand Down Expand Up @@ -438,7 +468,7 @@ private boolean evaluateAbstractRole(EvaluatedAssignment<F> assignment, Assignme
roleAssignmentPathSegment.setEvaluateConstructions(true);
roleAssignmentPathSegment.setEvaluationOrder(evaluationOrder);
roleAssignmentPathSegment.setOrderOneObject(orderOneObject);
evaluateAssignment(assignment, roleAssignmentPathSegment, evaluateOld, roleType, subSourceDescription, assignmentPath, task, result);
evaluateAssignment(assignment, roleAssignmentPathSegment, evaluateOld, mode, roleType, subSourceDescription, assignmentPath, task, result);
// } else if (inducementOrder < assignmentPath.getEvaluationOrder()) {
// LOGGER.trace("Follow({}) inducement({}) in role {}",
// new Object[]{evaluationOrder, inducementOrder, source});
Expand Down Expand Up @@ -466,14 +496,14 @@ private boolean evaluateAbstractRole(EvaluatedAssignment<F> assignment, Assignme
roleAssignmentPathSegment.setEvaluateConstructions(false);
roleAssignmentPathSegment.setEvaluationOrder(evaluationOrder+1);
roleAssignmentPathSegment.setOrderOneObject(orderOneObject);
evaluateAssignment(assignment, roleAssignmentPathSegment, evaluateOld, roleType, subSourceDescription, assignmentPath, task, result);
evaluateAssignment(assignment, roleAssignmentPathSegment, evaluateOld, mode, roleType, subSourceDescription, assignmentPath, task, result);
}
for(AuthorizationType authorizationType: roleType.getAuthorization()) {
Authorization authorization = createAuthorization(authorizationType);
assignment.addAuthorization(authorization);
}

return true;
return mode != PlusMinusZero.MINUS;
}

public static String dumpAssignment(AssignmentType assignmentType) {
Expand Down Expand Up @@ -530,7 +560,7 @@ private void checkSchema(AssignmentType assignmentType, String sourceDescription
}
}

public DeltaSetTriple<Boolean> evaluateMappingAsCondition(MappingType conditionType, ObjectType source, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException {
public PrismValueDeltaSetTriple<PrismPropertyValue<Boolean>> evaluateMappingAsCondition(MappingType conditionType, ObjectType source, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException {
Mapping<? extends PrismPropertyValue<Boolean>> mapping = mappingFactory.createMapping(conditionType,
"condition in " + source);

Expand All @@ -549,16 +579,7 @@ public DeltaSetTriple<Boolean> evaluateMappingAsCondition(MappingType conditionT

LensUtil.evaluateMapping(mapping, lensContext, task, result);

PrismValueDeltaSetTriple<? extends PrismPropertyValue<Boolean>> mappingOutputTriple = mapping.getOutputTriple();
DeltaSetTriple<Boolean> outputTriple = new DeltaSetTriple<>();
Transformer<PrismPropertyValue<Boolean>, Boolean> transformer = new Transformer<PrismPropertyValue<Boolean>, Boolean>() {
@Override
public Boolean transform(PrismPropertyValue<Boolean> in) {
return in.getValue();
}
};
mappingOutputTriple.transform(outputTriple, transformer);
return outputTriple;
return (PrismValueDeltaSetTriple<PrismPropertyValue<Boolean>>) mapping.getOutputTriple();
}


Expand Down
Expand Up @@ -87,6 +87,14 @@ public void addConstructionZero(Construction<F> contruction) {
constructions.addToZeroSet(contruction);
}

public void addConstructionPlus(Construction<F> contruction) {
constructions.addToPlusSet(contruction);
}

public void addConstructionMinus(Construction<F> contruction) {
constructions.addToMinusSet(contruction);
}

public Collection<PrismReferenceValue> getOrgRefVals() {
return orgRefVals;
}
Expand Down
4 changes: 2 additions & 2 deletions model/model-intest/src/test/resources/rbac/role-wannabe.xml
Expand Up @@ -49,7 +49,7 @@
</source>
<expression>
<script>
<code>honorificPrefix?.trim()</code>
<code>(Boolean)honorificPrefix?.trim()</code>
</script>
</expression>
</condition>
Expand All @@ -63,7 +63,7 @@
</source>
<expression>
<script>
<code>honorificSuffix?.trim()</code>
<code>(Boolean)honorificSuffix?.trim()</code>
</script>
</expression>
</condition>
Expand Down

0 comments on commit 1c57aa0

Please sign in to comment.