use of com.evolveum.midpoint.model.api.context.EvaluatedExclusionTrigger in project midpoint by Evolveum.
the class PruningOperation method processPruneRuleExclusionTrigger.
private void processPruneRuleExclusionTrigger(EvaluatedAssignmentImpl<F> newAssignment, EvaluatedPolicyRuleImpl pruneRule, EvaluatedExclusionTrigger exclusionTrigger) {
EvaluatedAssignment<FocusType> conflictingAssignment = exclusionTrigger.getConflictingAssignment();
if (conflictingAssignment == null) {
throw new SystemException("Added assignment " + newAssignment + ", the exclusion prune rule was triggered but there is no conflicting assignment in the trigger");
}
LOGGER.debug("Pruning assignment {} because it conflicts with added assignment {}", conflictingAssignment, newAssignment);
if (conflictingAssignment.isPresentInOldObject()) {
// This is the usual (good) case. The conflicting assignment was present in the old object so we can remove it
// by means of secondary delta.
// noinspection unchecked
PrismContainerValue<AssignmentType> assignmentValueToRemove = conflictingAssignment.getAssignment().asPrismContainerValue().clone();
PrismObjectDefinition<F> focusDef = context.getFocusContext().getObjectDefinition();
ContainerDelta<AssignmentType> assignmentDelta = beans.prismContext.deltaFactory().container().createDelta(FocusType.F_ASSIGNMENT, focusDef);
// noinspection unchecked
assignmentDelta.addValuesToDelete(assignmentValueToRemove);
context.getFocusContext().swallowToSecondaryDeltaUnchecked(assignmentDelta);
prunedViaSecondaryDelta = true;
} else {
// Conflicting assignment was not present in old object i.e. it was added in the meanwhile into secondary delta.
// We create trigger for this with enforcementOverride = true, so it will be reported as policy violation
// even if not enforcement policy action is present. See also MID-4766.
SingleLocalizableMessage message = new LocalizableMessageBuilder().key("PolicyViolationException.message.prunedRolesAssigned").arg(ObjectTypeUtil.createDisplayInformation(newAssignment.getTarget(), false)).arg(ObjectTypeUtil.createDisplayInformation(conflictingAssignment.getTarget(), false)).build();
pruneRule.addTrigger(new EvaluatedExclusionTrigger(exclusionTrigger.getConstraint(), message, null, exclusionTrigger.getConflictingAssignment(), exclusionTrigger.getConflictingTarget(), exclusionTrigger.getConflictingPath(), true));
enforcementOverrideGenerated = true;
}
}
use of com.evolveum.midpoint.model.api.context.EvaluatedExclusionTrigger in project midpoint by Evolveum.
the class PruningOperation method pruneNewAssignment.
private void pruneNewAssignment(EvaluatedAssignmentImpl<F> newAssignment) {
LOGGER.trace("Checking for pruning of new assignment: {}", newAssignment);
for (EvaluatedPolicyRuleImpl newAssignmentRule : newAssignment.getAllTargetsPolicyRules()) {
if (newAssignmentRule.containsEnabledAction(PrunePolicyActionType.class)) {
Collection<EvaluatedExclusionTrigger> exclusionTriggers = newAssignmentRule.getAllTriggers(EvaluatedExclusionTrigger.class);
LOGGER.trace("Exclusion triggers: {}", exclusionTriggers);
for (EvaluatedExclusionTrigger exclusionTrigger : exclusionTriggers) {
processPruneRuleExclusionTrigger(newAssignment, newAssignmentRule, exclusionTrigger);
}
}
}
}
use of com.evolveum.midpoint.model.api.context.EvaluatedExclusionTrigger in project midpoint by Evolveum.
the class ExclusionConstraintEvaluator method evaluate.
@Override
public <AH extends AssignmentHolderType> EvaluatedExclusionTrigger evaluate(@NotNull JAXBElement<ExclusionPolicyConstraintType> constraint, @NotNull PolicyRuleEvaluationContext<AH> rctx, OperationResult parentResult) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException {
OperationResult result = parentResult.subresult(OP_EVALUATE).setMinor().build();
try {
LOGGER.trace("Evaluating exclusion constraint {} on {}", lazy(() -> PolicyRuleTypeUtil.toShortString(constraint)), rctx);
if (!(rctx instanceof AssignmentPolicyRuleEvaluationContext)) {
return null;
}
AssignmentPolicyRuleEvaluationContext<AH> ctx = (AssignmentPolicyRuleEvaluationContext<AH>) rctx;
if (!ctx.isAdded && !ctx.isKept) {
LOGGER.trace("Assignment not being added nor kept, skipping evaluation.");
return null;
}
if (sourceOrderConstraintsDoNotMatch(constraint, ctx)) {
// logged in the called method body
return null;
}
/*
* Now let us check the exclusions.
*
* Assignment A is the current evaluated assignment. It has directly or indirectly attached the exclusion policy rule.
* We now go through all other assignments B and check the exclusions.
*/
List<OrderConstraintsType> targetOrderConstraints = defaultIfEmpty(constraint.getValue().getTargetOrderConstraint());
List<EvaluatedAssignmentTargetImpl> nonNegativeTargetsA = ctx.evaluatedAssignment.getNonNegativeTargets();
ConstraintReferenceMatcher<AH> refMatcher = new ConstraintReferenceMatcher<>(ctx, constraint.getValue().getTargetRef(), expressionFactory, result, LOGGER);
for (EvaluatedAssignmentImpl<AH> assignmentB : ctx.evaluatedAssignmentTriple.getNonNegativeValues()) {
// MID-6403
if (assignmentB == ctx.evaluatedAssignment) {
// currently there is no other way of comparing the evaluated assignments
continue;
}
targetB: for (EvaluatedAssignmentTargetImpl targetB : assignmentB.getNonNegativeTargets()) {
if (!pathMatches(targetB.getAssignmentPath(), targetOrderConstraints)) {
LOGGER.trace("Skipping considering exclusion target {} because it does not match target path constraints." + " Path={}, constraints={}", targetB, targetB.getAssignmentPath(), targetOrderConstraints);
continue;
}
if (!refMatcher.refMatchesTarget(targetB.getTarget(), "exclusion constraint")) {
LOGGER.trace("Target {} OID does not match exclusion filter", targetB);
continue;
}
// To avoid false positives let us check if this target is not already covered by assignment being evaluated
for (EvaluatedAssignmentTargetImpl targetA : nonNegativeTargetsA) {
if (targetIsAlreadyCovered(targetB, targetA)) {
continue targetB;
}
}
EvaluatedExclusionTrigger rv = createTrigger(ctx.evaluatedAssignment, assignmentB, targetB, constraint, ctx.policyRule, ctx, result);
result.addReturn("trigger", rv.toDiagShortcut());
return rv;
}
}
return null;
} catch (Throwable t) {
result.recordFatalError(t.getMessage(), t);
throw t;
} finally {
result.computeStatusIfUnknown();
}
}
use of com.evolveum.midpoint.model.api.context.EvaluatedExclusionTrigger in project midpoint by Evolveum.
the class ExclusionConstraintEvaluator method createTrigger.
private <AH extends AssignmentHolderType> EvaluatedExclusionTrigger createTrigger(EvaluatedAssignmentImpl<AH> assignmentA, @NotNull EvaluatedAssignmentImpl<AH> assignmentB, EvaluatedAssignmentTargetImpl targetB, JAXBElement<ExclusionPolicyConstraintType> constraintElement, EvaluatedPolicyRule policyRule, AssignmentPolicyRuleEvaluationContext<AH> ctx, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException {
AssignmentPath pathA = policyRule.getAssignmentPath();
AssignmentPath pathB = targetB.getAssignmentPath();
LocalizableMessage infoA = createObjectInfo(pathA, assignmentA.getTarget(), true);
LocalizableMessage infoB = createObjectInfo(pathB, targetB.getTarget(), false);
ObjectType objectA = getConflictingObject(pathA, assignmentA.getTarget());
ObjectType objectB = getConflictingObject(pathB, targetB.getTarget());
LocalizableMessage message = createMessage(infoA, infoB, constraintElement, ctx, result);
LocalizableMessage shortMessage = createShortMessage(infoA, infoB, constraintElement, ctx, result);
return new EvaluatedExclusionTrigger(constraintElement.getValue(), message, shortMessage, assignmentB, objectA, objectB, pathA, pathB);
}
Aggregations