Skip to content

Commit

Permalink
Differentiating focus vs target policy rules
Browse files Browse the repository at this point in the history
  • Loading branch information
mederly committed Nov 29, 2016
1 parent d03667b commit 8ce165d
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 73 deletions.
Expand Up @@ -60,7 +60,7 @@ public interface EvaluatedAssignment<F extends FocusType> extends DebugDumpable
* The policy rules are compiled from all the applicable sources (target, meta-roles, etc.)
*/
@NotNull
Collection<EvaluatedPolicyRule> getPolicyRules();
Collection<EvaluatedPolicyRule> getFocusPolicyRules();

public Collection<String> getPolicySituations();

Expand Down
Expand Up @@ -42,7 +42,6 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyActionsType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyConstraintsType;

/**
* Hook used to enfore the policy rules that have the enforce action.
Expand Down Expand Up @@ -114,7 +113,7 @@ private <F extends FocusType> void evaluateAssignmentRules(ModelContext<F> conte
}

StringBuilder compositeMessageSb = new StringBuilder();
evaluatedAssignmentTriple.accept(assignment -> enforceRules(compositeMessageSb, assignment.getPolicyRules()));
evaluatedAssignmentTriple.accept(assignment -> enforceRules(compositeMessageSb, assignment.getFocusPolicyRules()));

if (compositeMessageSb.length() != 0) {
throw new PolicyViolationException(compositeMessageSb.toString());
Expand Down
Expand Up @@ -351,7 +351,12 @@ private <O extends ObjectType> void evaluateAssignmentWithResolvedTarget(Evaluat
} else if (assignmentType.getPolicyRule() != null) {

if (evaluateConstructions && assignmentPathSegment.isMatchingOrder()) {
evaluatePolicyRule(evalAssignment, assignmentPathSegment, evaluateOld, mode,
evaluatePolicyRule(evalAssignment, true, assignmentPathSegment, evaluateOld, mode,
isParentValid && isValid, source, sourceDescription,
assignmentPath, assignmentPathSegment.getOrderOneObject(), task, result);
}
if (evaluateConstructions && assignmentPathSegment.isMatchingOrderPlusOne()) {
evaluatePolicyRule(evalAssignment, false, assignmentPathSegment, evaluateOld, mode,
isParentValid && isValid, source, sourceDescription,
assignmentPath, assignmentPathSegment.getOrderOneObject(), task, result);
}
Expand Down Expand Up @@ -433,19 +438,25 @@ private void evaluateFocusMappings(EvaluatedAssignmentImpl<F> evaluatedAssignmen
}
}

private void evaluatePolicyRule(EvaluatedAssignmentImpl<F> evaluatedAssignment, AssignmentPathSegmentImpl assignmentPathSegment,
private void evaluatePolicyRule(EvaluatedAssignmentImpl<F> evaluatedAssignment, boolean focusRule,
AssignmentPathSegmentImpl assignmentPathSegment,
boolean evaluateOld, PlusMinusZero mode, boolean isValid, ObjectType source, String sourceDescription,
AssignmentPathImpl assignmentPath, ObjectType orderOneObject, Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException {
AssignmentPathImpl assignmentPath, ObjectType orderOneObject, Task task, OperationResult result)
throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException {
assertSource(source, evaluatedAssignment);

AssignmentType assignmentTypeNew = LensUtil.getAssignmentType(assignmentPathSegment.getAssignmentIdi(), evaluateOld);
PolicyRuleType policyRuleType = assignmentTypeNew.getPolicyRule();

LOGGER.trace("Evaluating policy rule '{}' in {}", policyRuleType.getName(), source);
LOGGER.trace("Evaluating {} policy rule '{}' in {}", focusRule ? "focus" : "target", policyRuleType.getName(), source);

EvaluatedPolicyRuleImpl policyRule = new EvaluatedPolicyRuleImpl(policyRuleType, assignmentPath.clone());

evaluatedAssignment.addPolicyRule(policyRule);
if (focusRule) {
evaluatedAssignment.addFocusPolicyRule(policyRule);
} else {
evaluatedAssignment.addTargetPolicyRule(policyRule);
}
}

private <O extends ObjectType> List<PrismObject<O>> resolveTargets(AssignmentType assignmentType, AssignmentPathSegment assignmentPathSegment, ObjectType source, String sourceDescription, AssignmentPathImpl assignmentPath, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException {
Expand Down Expand Up @@ -647,7 +658,7 @@ private boolean evaluateAssignmentTarget(EvaluatedAssignmentImpl<F> assignment,
subAssignmentPathSegment.setOrderOneObject(orderOneObject);
subAssignmentPathSegment.setProcessMembership(true);

if (subAssignmentPathSegment.isMatchingOrder()) {
//if (subAssignmentPathSegment.isMatchingOrder()) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("E({}): evaluate inducement({}) {} in {}",
evaluationOrder.shortDump(), FocusTypeUtil.dumpInducementConstraints(roleInducement),
Expand All @@ -656,13 +667,13 @@ private boolean evaluateAssignmentTarget(EvaluatedAssignmentImpl<F> assignment,
String subSourceDescription = targetType+" in "+sourceDescription;
evaluateAssignment(assignment, subAssignmentPathSegment, evaluateOld, mode, isValid, targetType, subSourceDescription, assignmentPath, task, result);

} else {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("E({}): NOT evaluate inducement({}) {} in {}",
evaluationOrder.shortDump(), FocusTypeUtil.dumpInducementConstraints(roleInducement),
FocusTypeUtil.dumpAssignment(roleInducement), targetType);
}
}
// } else {
// if (LOGGER.isTraceEnabled()) {
// LOGGER.trace("E({}): NOT evaluate inducement({}) {} in {}",
// evaluationOrder.shortDump(), FocusTypeUtil.dumpInducementConstraints(roleInducement),
// FocusTypeUtil.dumpAssignment(roleInducement), targetType);
// }
// }
}
}

Expand Down
Expand Up @@ -41,6 +41,7 @@ public class AssignmentPathSegmentImpl implements AssignmentPathSegment {
private EvaluationOrder evaluationOrder;
private ObjectType varThisObject;
private Boolean isMatchingOrder = null;
private Boolean isMatchingOrderPlusOne = null;
private boolean processMembership = false;

AssignmentPathSegmentImpl(ItemDeltaItem<PrismContainerValue<AssignmentType>,PrismContainerDefinition<AssignmentType>> assignmentIdi, ObjectType target) {
Expand Down Expand Up @@ -119,32 +120,39 @@ public void setProcessMembership(boolean processMembership) {

public boolean isMatchingOrder() {
if (isMatchingOrder == null) {
isMatchingOrder = computeMatchingOrder();
isMatchingOrder = computeMatchingOrder(0);
}
return isMatchingOrder;
}

private boolean computeMatchingOrder() {
public boolean isMatchingOrderPlusOne() {
if (isMatchingOrderPlusOne == null) {
isMatchingOrderPlusOne = computeMatchingOrder(1);
}
return isMatchingOrderPlusOne;
}

private boolean computeMatchingOrder(int offset) {
AssignmentType assignmentType = getAssignment();
if (assignmentType.getOrder() == null && assignmentType.getOrderConstraint().isEmpty()) {
// compatibility
return evaluationOrder.getSummaryOrder() == 1;
return evaluationOrder.getSummaryOrder() - offset == 1;
}
if (assignmentType.getOrder() != null) {
if (evaluationOrder.getSummaryOrder() != assignmentType.getOrder()) {
if (evaluationOrder.getSummaryOrder() - offset != assignmentType.getOrder()) {
return false;
}
}
for (OrderConstraintsType orderConstraint: assignmentType.getOrderConstraint()) {
if (!isMatchingConstraint(orderConstraint)) {
if (!isMatchingConstraint(orderConstraint, offset)) {
return false;
}
}
return true;
}

private boolean isMatchingConstraint(OrderConstraintsType orderConstraint) {
int evaluationOrderInt = evaluationOrder.getMatchingRelationOrder(orderConstraint.getRelation());
private boolean isMatchingConstraint(OrderConstraintsType orderConstraint, int offset) {
int evaluationOrderInt = evaluationOrder.getMatchingRelationOrder(orderConstraint.getRelation()) - offset;
if (orderConstraint.getOrder() != null) {
return orderConstraint.getOrder() == evaluationOrderInt;
} else {
Expand Down
Expand Up @@ -75,7 +75,8 @@ public class EvaluatedAssignmentImpl<F extends FocusType> implements EvaluatedAs
private Collection<Authorization> authorizations;
private Collection<Mapping<? extends PrismPropertyValue<?>,? extends PrismPropertyDefinition<?>>> focusMappings;
private Collection<AdminGuiConfigurationType> adminGuiConfigurations;
@NotNull private final Collection<EvaluatedPolicyRule> policyRules;
@NotNull private final Collection<EvaluatedPolicyRule> focusPolicyRules; // rules related to the focus itself
@NotNull private final Collection<EvaluatedPolicyRule> targetPolicyRules; // rules related to the target of this assignment
private PrismObject<?> target;
private boolean isValid;
private boolean forceRecon; // used also to force recomputation of parentOrgRefs
Expand All @@ -92,7 +93,8 @@ public EvaluatedAssignmentImpl() {
authorizations = new ArrayList<>();
focusMappings = new ArrayList<>();
adminGuiConfigurations = new ArrayList<>();
policyRules = new ArrayList<>();
focusPolicyRules = new ArrayList<>();
targetPolicyRules = new ArrayList<>();
}

public ItemDeltaItem<PrismContainerValue<AssignmentType>,PrismContainerDefinition<AssignmentType>> getAssignmentIdi() {
Expand Down Expand Up @@ -304,20 +306,28 @@ public boolean isPresentInOldObject() {
}

@NotNull
@Override
public Collection<EvaluatedPolicyRule> getPolicyRules() {
return policyRules;
public Collection<EvaluatedPolicyRule> getFocusPolicyRules() {
return focusPolicyRules;
}

public void addPolicyRule(EvaluatedPolicyRule policyRule) {
policyRules.add(policyRule);
public void addFocusPolicyRule(EvaluatedPolicyRule policyRule) {
focusPolicyRules.add(policyRule);
}


@NotNull
public Collection<EvaluatedPolicyRule> getTargetPolicyRules() {
return targetPolicyRules;
}

public void addTargetPolicyRule(EvaluatedPolicyRule policyRule) {
targetPolicyRules.add(policyRule);
}

public void addLegacyPolicyConstraints(PolicyConstraintsType constraints) {
PolicyRuleType policyRuleType = new PolicyRuleType();
policyRuleType.setPolicyConstraints(constraints);
EvaluatedPolicyRule policyRule = new EvaluatedPolicyRuleImpl(policyRuleType, null);
policyRules.add(policyRule);
focusPolicyRules.add(policyRule);
}

@Override
Expand Down Expand Up @@ -379,14 +389,16 @@ public String debugDump(int indent) {
DebugUtil.debugDumpWithLabel(sb, "Target", target.toString(), indent+1);
}
sb.append("\n");
DebugUtil.debugDumpWithLabelLn(sb, "policyRules", policyRules, indent+1);
DebugUtil.debugDumpWithLabelLn(sb, "focusPolicyRules", focusPolicyRules, indent+1);
DebugUtil.debugDumpWithLabelLn(sb, "targetPolicyRules", targetPolicyRules, indent+1);
DebugUtil.debugDumpWithLabelLn(sb, "Present in old object", isPresentInOldObject(), indent+1);
DebugUtil.debugDumpWithLabel(sb, "Present in current object", isPresentInCurrentObject(), indent+1);
return sb.toString();
}

@Override
public String toString() {
return "EvaluatedAssignment(constr=" + constructions + "; org="+orgRefVals+"; autz="+authorizations+"; "+focusMappings.size()+" focus mappings; "+policyRules.size()+" rules)";
return "EvaluatedAssignment(constr=" + constructions + "; org="+orgRefVals+"; autz="+authorizations+"; "+focusMappings.size()+" focus mappings; "+ focusPolicyRules
.size()+" rules)";
}
}
Expand Up @@ -901,25 +901,30 @@ private <F extends FocusType> void dumpEvaluatedAssignments(StringBuilder sb, St
sb.append("\n");
DebugUtil.indentDebugDump(sb, indent + 1);
sb.append(" -> " + assignment.getTarget());
sb.append(" [rules(").append(assignment.getPolicyRules().size()).append("): ");
boolean first = true;
for (EvaluatedPolicyRule rule : assignment.getPolicyRules()) {
if (first) {
first = false;
} else {
sb.append("; ");
}
sb.append(PolicyRuleTypeUtil.toShortString(rule.getPolicyConstraints()));
sb.append(" -> ");
sb.append(PolicyRuleTypeUtil.toShortString(rule.getActions()));
if (!rule.getTriggers().isEmpty()) {
sb.append(", T:");
rule.getTriggers()
.forEach(trigger -> sb.append(" ").append(PolicyRuleTypeUtil.toShortString(trigger.getConstraint())));
}
dumpRules(sb, "focus rules", assignment.getFocusPolicyRules());
dumpRules(sb, "target rules", assignment.getTargetPolicyRules());
}
}

private <F extends FocusType> void dumpRules(StringBuilder sb, String label, Collection<EvaluatedPolicyRule> policyRules) {
sb.append(" [").append(label).append("(").append(policyRules.size()).append("): ");
boolean first = true;
for (EvaluatedPolicyRule rule : policyRules) {
if (first) {
first = false;
} else {
sb.append("; ");
}
sb.append(PolicyRuleTypeUtil.toShortString(rule.getPolicyConstraints()));
sb.append(" -> ");
sb.append(PolicyRuleTypeUtil.toShortString(rule.getActions()));
if (!rule.getTriggers().isEmpty()) {
sb.append(", T:");
rule.getTriggers()
.forEach(trigger -> sb.append(" ").append(PolicyRuleTypeUtil.toShortString(trigger.getConstraint())));
}
sb.append("]");
}
sb.append("]");
}

public LensContextType toLensContextType() throws SchemaException {
Expand Down
Expand Up @@ -53,9 +53,6 @@
import com.evolveum.midpoint.model.impl.lens.LensFocusContext;
import com.evolveum.midpoint.model.impl.lens.LensProjectionContext;
import com.evolveum.midpoint.model.impl.lens.LensUtil;
import com.evolveum.midpoint.model.impl.lens.OperationalDataManager;
import com.evolveum.midpoint.prism.Containerable;
import com.evolveum.midpoint.prism.Item;
import com.evolveum.midpoint.prism.ItemDefinition;
import com.evolveum.midpoint.prism.Objectable;
import com.evolveum.midpoint.prism.PrismContainer;
Expand All @@ -80,12 +77,7 @@
import com.evolveum.midpoint.prism.path.IdItemPathSegment;
import com.evolveum.midpoint.prism.path.ItemPath;
import com.evolveum.midpoint.prism.path.NameItemPathSegment;
import com.evolveum.midpoint.prism.query.AndFilter;
import com.evolveum.midpoint.prism.query.InOidFilter;
import com.evolveum.midpoint.prism.query.NotFilter;
import com.evolveum.midpoint.prism.query.ObjectFilter;
import com.evolveum.midpoint.prism.query.ObjectQuery;
import com.evolveum.midpoint.prism.query.RefFilter;
import com.evolveum.midpoint.prism.xml.XsdTypeMapper;
import com.evolveum.midpoint.provisioning.api.ProvisioningService;
import com.evolveum.midpoint.repo.api.RepositoryService;
Expand Down Expand Up @@ -113,21 +105,17 @@
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentPolicyConstraintType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentPolicyEnforcementType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.AuthorizationPhaseType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ConstructionType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ExclusionPolicyConstraintType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.MultiplicityPolicyConstraintType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyConstraintEnforcementType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyConstraintKindType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.PolicyConstraintsType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType;
import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType;

/**
* Assignment processor is recomputing user assignments. It recomputes all the assignments whether they are direct
Expand Down Expand Up @@ -1558,7 +1546,7 @@ private <F extends FocusType> void checkAssigneeConstraints(LensContext<F> conte
if (target != null) {
Objectable targetType = target.asObjectable();
if (targetType instanceof AbstractRoleType) {
Collection<EvaluatedPolicyRule> policyRules = assignment.getPolicyRules();
Collection<EvaluatedPolicyRule> policyRules = assignment.getFocusPolicyRules();
for (EvaluatedPolicyRule policyRule: policyRules) {
PolicyConstraintsType policyConstraints = policyRule.getPolicyConstraints();
if (policyConstraints != null && (!policyConstraints.getMinAssignees().isEmpty() || !policyConstraints.getMaxAssignees().isEmpty())) {
Expand Down Expand Up @@ -1619,7 +1607,7 @@ private <F extends FocusType> void checkAssignmentRules(LensContext<F> context,
Collection<EvaluatedAssignmentImpl<F>> evaluatedAssignmentSet,
OperationResult result) throws PolicyViolationException, SchemaException {
for(EvaluatedAssignmentImpl<F> evaluatedAssignment: evaluatedAssignmentSet) {
Collection<EvaluatedPolicyRule> policyRules = evaluatedAssignment.getPolicyRules();
Collection<EvaluatedPolicyRule> policyRules = evaluatedAssignment.getFocusPolicyRules();
for (EvaluatedPolicyRule policyRule: policyRules) {
PolicyConstraintsType policyConstraints = policyRule.getPolicyConstraints();
if (policyConstraints == null) {
Expand Down
Expand Up @@ -377,7 +377,7 @@ private <F extends FocusType> void triggerAssignmentFocusPolicyRules(LensContext
return;
}
for (EvaluatedAssignmentImpl<F> evaluatedAssignment: evaluatedAssignmentTriple.getNonNegativeValues()) {
Collection<EvaluatedPolicyRule> policyRules = evaluatedAssignment.getPolicyRules();
Collection<EvaluatedPolicyRule> policyRules = evaluatedAssignment.getFocusPolicyRules();
for (EvaluatedPolicyRule policyRule: policyRules) {
triggerRule(focusContext, policyRule);
}
Expand Down
Expand Up @@ -689,9 +689,10 @@ public void test200AssignVisitor() throws Exception {
assertEquals("Wrong # of added assignments", 1, evaluatedAssignmentTriple.getPlusSet().size());

EvaluatedAssignmentImpl evaluatedAssignment = evaluatedAssignmentTriple.getPlusSet().iterator().next();
Collection<EvaluatedPolicyRule> policyRules = evaluatedAssignment.getPolicyRules();
assertEquals("Wrong # of policy rules", 1, policyRules.size());
EvaluatedPolicyRule policyRule = policyRules.iterator().next();
assertEquals("Wrong # of focus policy rules", 0, evaluatedAssignment.getFocusPolicyRules().size());
Collection<EvaluatedPolicyRule> targetPolicyRules = evaluatedAssignment.getTargetPolicyRules();
assertEquals("Wrong # of target policy rules", 1, targetPolicyRules.size());
EvaluatedPolicyRule policyRule = targetPolicyRules.iterator().next();
assertNotNull("Not an approval action: " + policyRule.getActions().asPrismContainerValue().debugDump(),
policyRule.getActions().getApproval());

Expand Down Expand Up @@ -749,7 +750,7 @@ public void test210AssignEngineer() throws Exception {
assertEquals("Wrong # of added assignments", 1, evaluatedAssignmentTriple.getPlusSet().size());

EvaluatedAssignmentImpl evaluatedAssignment = evaluatedAssignmentTriple.getPlusSet().iterator().next();
Collection<EvaluatedPolicyRule> policyRules = evaluatedAssignment.getPolicyRules();
Collection<EvaluatedPolicyRule> policyRules = evaluatedAssignment.getFocusPolicyRules();
assertEquals("Wrong # of policy rules", 2, policyRules.size());
Iterator<EvaluatedPolicyRule> iterator = policyRules.iterator();
EvaluatedPolicyRule policyRule1 = iterator.next();
Expand Down
Expand Up @@ -69,6 +69,5 @@ metaroles:
</approval>
</policyActions>
</policyRule>
<order>2</order>
</inducement>
</role>

0 comments on commit 8ce165d

Please sign in to comment.