Skip to content

Commit

Permalink
Adjustements and test for policy rules.
Browse files Browse the repository at this point in the history
  • Loading branch information
semancik committed Nov 14, 2016
1 parent 9fc834e commit 201d5db
Show file tree
Hide file tree
Showing 17 changed files with 490 additions and 78 deletions.
Expand Up @@ -61,6 +61,5 @@ public interface EvaluatedAssignment<F extends FocusType> extends DebugDumpable
*/
Collection<EvaluatedPolicyRule> getPolicyRules();

void triggerConstraint(EvaluatedPolicyRule rule, AbstractPolicyConstraintType constraint,
PolicyConstraintKind constraintKind, String message) throws PolicyViolationException;
void triggerConstraint(EvaluatedPolicyRule rule, EvaluatedPolicyRuleTrigger trigger) throws PolicyViolationException;
}
Expand Up @@ -28,13 +28,13 @@
*
*/
public interface EvaluatedPolicyRule extends DebugDumpable, Serializable {

Collection<EvaluatedPolicyRuleTrigger> getTriggers();

String getName();

PolicyConstraintsType getPolicyConstraints();

Collection<PolicyConstraintKind> getTriggeredConstraintKinds();

String getPolicySituation();

PolicyActionsType getActions();
Expand Down
@@ -0,0 +1,109 @@
/**
* Copyright (c) 2016 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.evolveum.midpoint.model.api.context;

import com.evolveum.midpoint.xml.ns._public.common.common_3.AbstractPolicyConstraintType;

/**
* Description of a situation that caused a trigger of the policy rule.
*
* @author semancik
*/
public class EvaluatedPolicyRuleTrigger {

PolicyConstraintKind constraintKind;
AbstractPolicyConstraintType constraint;
String message;

public EvaluatedPolicyRuleTrigger(PolicyConstraintKind constraintKind, AbstractPolicyConstraintType constraint, String message) {
super();
this.constraintKind = constraintKind;
this.constraint = constraint;
this.message = message;
}

/**
* The kind of constraint that caused the trigger.
* @return
*/
PolicyConstraintKind getConstraintKind() {
return constraintKind;
}

public AbstractPolicyConstraintType getConstraint() {
return constraint;
}

/**
* Human-readable message associated with this trigger. The message
* explain why the rule was triggered. It can be used
* in the logs, as an error message, in the audit trail
* and so on.
*/
public String getMessage() {
return message;
}



@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((constraint == null) ? 0 : constraint.hashCode());
result = prime * result + ((constraintKind == null) ? 0 : constraintKind.hashCode());
result = prime * result + ((message == null) ? 0 : message.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
EvaluatedPolicyRuleTrigger other = (EvaluatedPolicyRuleTrigger) obj;
if (constraint == null) {
if (other.constraint != null) {
return false;
}
} else if (!constraint.equals(other.constraint)) {
return false;
}
if (constraintKind != other.constraintKind) {
return false;
}
if (message == null) {
if (other.message != null) {
return false;
}
} else if (!message.equals(other.message)) {
return false;
}
return true;
}

@Override
public String toString() {
return "EvaluatedPolicyRuleTrigger(" + constraintKind + ": " + message + ")";
}

}
Expand Up @@ -15,6 +15,7 @@
*/
package com.evolveum.midpoint.model.api.hooks;

import com.evolveum.midpoint.model.api.PolicyViolationException;
import com.evolveum.midpoint.model.api.context.ModelContext;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
Expand Down Expand Up @@ -48,7 +49,7 @@ public interface ChangeHook {
* - ERROR, if the hook encountered an error which prevents model operation from continuing
* (this case is currently not defined very well)
*/
<O extends ObjectType> HookOperationMode invoke(ModelContext<O> context, Task task, OperationResult result);
<O extends ObjectType> HookOperationMode invoke(ModelContext<O> context, Task task, OperationResult result) throws PolicyViolationException;

/**
* This method is invoked by the clockwork when an exception occurs.
Expand Down
@@ -0,0 +1,144 @@
/**
* Copyright (c) 2016 Evolveum
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.evolveum.midpoint.model.impl.hooks;

import java.util.Collection;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.evolveum.midpoint.model.api.PolicyViolationException;
import com.evolveum.midpoint.model.api.context.EvaluatedAssignment;
import com.evolveum.midpoint.model.api.context.EvaluatedPolicyRule;
import com.evolveum.midpoint.model.api.context.EvaluatedPolicyRuleTrigger;
import com.evolveum.midpoint.model.api.context.ModelContext;
import com.evolveum.midpoint.model.api.context.ModelElementContext;
import com.evolveum.midpoint.model.api.context.ModelState;
import com.evolveum.midpoint.model.api.hooks.ChangeHook;
import com.evolveum.midpoint.model.api.hooks.HookOperationMode;
import com.evolveum.midpoint.model.api.hooks.HookRegistry;
import com.evolveum.midpoint.prism.delta.DeltaSetTriple;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.logging.Trace;
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.EnforcementPolicyActionType;
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.
*
* @author semancik
*
*/
@Component
public class PolicyRuleEnforcerHook implements ChangeHook {

private static final Trace LOGGER = TraceManager.getTrace(PolicyRuleEnforcerHook.class);

public static final String HOOK_URI = SchemaConstants.NS_MODEL + "/policy-rule-enforcer-hook-3";

@Autowired(required = true)
private HookRegistry hookRegistry;

@PostConstruct
public void init() {
hookRegistry.registerChangeHook(HOOK_URI, this);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("PolicyRuleEnforcerHook registered.");
}
}

/* (non-Javadoc)
* @see com.evolveum.midpoint.model.api.hooks.ChangeHook#invoke(com.evolveum.midpoint.model.api.context.ModelContext, com.evolveum.midpoint.task.api.Task, com.evolveum.midpoint.schema.result.OperationResult)
*/
@Override
public <O extends ObjectType> HookOperationMode invoke(ModelContext<O> context, Task task,
OperationResult result) throws PolicyViolationException {

if (context.getState() != ModelState.PRIMARY) {
return HookOperationMode.FOREGROUND;
}

DeltaSetTriple<? extends EvaluatedAssignment> evaluatedAssignmentTriple = context.getEvaluatedAssignmentTriple();
if (evaluatedAssignmentTriple == null) {
return HookOperationMode.FOREGROUND;
}

StringBuilder compositeMessageSb = new StringBuilder();
evaluatedAssignmentTriple.accept(assignment -> enforceAssignmentRules(compositeMessageSb, assignment));

if (compositeMessageSb.length() != 0) {
throw new PolicyViolationException(compositeMessageSb.toString());
}

return HookOperationMode.FOREGROUND;
}

private <F extends FocusType> void enforceAssignmentRules(StringBuilder compositeMessageSb, EvaluatedAssignment<F> assignment) {
for (EvaluatedPolicyRule policyRule: assignment.getPolicyRules()) {

Collection<EvaluatedPolicyRuleTrigger> triggers = policyRule.getTriggers();
if (triggers.isEmpty()) {
continue;
}

if (!isEnforce(policyRule)) {
continue;
}

for (EvaluatedPolicyRuleTrigger trigger: triggers) {
if (trigger.getMessage() != null) {
if (compositeMessageSb.length() != 0) {
compositeMessageSb.append("; ");
}
compositeMessageSb.append(trigger.getMessage());
}
}
}
}

private boolean isEnforce(EvaluatedPolicyRule policyRule) {
PolicyActionsType actions = policyRule.getActions();

if (actions == null) {
// enforce is the default (this also covers legacy configuration)
return true;
}

EnforcementPolicyActionType enforcement = actions.getEnforcement();
if (enforcement == null) {
return false;
}
return true;
}

/* (non-Javadoc)
* @see com.evolveum.midpoint.model.api.hooks.ChangeHook#invokeOnException(com.evolveum.midpoint.model.api.context.ModelContext, java.lang.Throwable, com.evolveum.midpoint.task.api.Task, com.evolveum.midpoint.schema.result.OperationResult)
*/
@Override
public void invokeOnException(ModelContext context, Throwable throwable, Task task,
OperationResult result) {
// Nothing to do
}

}
Expand Up @@ -389,7 +389,7 @@ public <F extends ObjectType> HookOperationMode click(LensContext<F> context, Ta
* - BACKGROUND, if any hook reported switching to background; otherwise
* - FOREGROUND (if all hooks reported finishing on foreground)
*/
private HookOperationMode invokeHooks(LensContext context, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException {
private HookOperationMode invokeHooks(LensContext context, Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, PolicyViolationException {
// TODO: following two parts should be merged together in later versions

// Execute configured scripting hooks
Expand Down
Expand Up @@ -24,6 +24,7 @@
import com.evolveum.midpoint.model.api.context.EvaluatedAssignment;
import com.evolveum.midpoint.model.api.context.EvaluatedConstruction;
import com.evolveum.midpoint.model.api.context.EvaluatedPolicyRule;
import com.evolveum.midpoint.model.api.context.EvaluatedPolicyRuleTrigger;
import com.evolveum.midpoint.model.api.context.PolicyConstraintKind;
import com.evolveum.midpoint.model.common.expression.ItemDeltaItem;
import com.evolveum.midpoint.model.common.expression.ObjectDeltaObject;
Expand Down Expand Up @@ -310,12 +311,22 @@ public void addLegacyPolicyConstraints(PolicyConstraintsType constraints) {
}

@Override
public void triggerConstraint(EvaluatedPolicyRule rule, AbstractPolicyConstraintType constraint,
PolicyConstraintKind constraintKind, String message) throws PolicyViolationException {
// legacy functionality
if (constraint.getEnforcement() == null || constraint.getEnforcement() == PolicyConstraintEnforcementType.ENFORCE) {
throw new PolicyViolationException(message);
public void triggerConstraint(EvaluatedPolicyRule rule, EvaluatedPolicyRuleTrigger trigger) throws PolicyViolationException {

LOGGER.debug("Policy rule {} triggered: ", rule==null?null:rule.getName(), trigger);

if (rule == null) {
// legacy functionality
if (trigger.getConstraint().getEnforcement() == null || trigger.getConstraint().getEnforcement() == PolicyConstraintEnforcementType.ENFORCE) {
throw new PolicyViolationException(trigger.getMessage());
}

} else {

((EvaluatedPolicyRuleImpl)rule).addTrigger(trigger);

}

}

@Override
Expand Down

0 comments on commit 201d5db

Please sign in to comment.