Commit 1e078482 authored by cdanger's avatar cdanger

- StandardEnvironmentAttributeSource (REQUEST_ELSE_PDP, REQUEST_ONLY,

PDP_ONLY) feature support to select where current date/time come from
- Renamed BaseDecisionResult into MutableDecisionResult
parent 2ec4593e
......@@ -18,6 +18,7 @@
*/
package org.ow2.authzforce.core.pdp.impl;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -30,7 +31,7 @@ import org.ow2.authzforce.core.pdp.api.EvaluationContext;
import org.ow2.authzforce.core.pdp.api.IndividualDecisionRequest;
import org.ow2.authzforce.core.pdp.api.value.Bag;
import org.ow2.authzforce.core.pdp.impl.policy.RootPolicyEvaluator;
import org.ow2.authzforce.core.xmlns.pdp.StandardCurrentTimeProvider;
import org.ow2.authzforce.core.xmlns.pdp.StandardEnvironmentAttributeSource;
/**
* Individual decision request evaluator
......@@ -51,12 +52,24 @@ public abstract class IndividualDecisionRequestEvaluator
@Override
public Map<AttributeGUID, Bag<?>> merge(final Map<AttributeGUID, Bag<?>> pdpIssuedAttributes, final Map<AttributeGUID, Bag<?>> requestAttributes)
{
assert pdpIssuedAttributes != null && requestAttributes != null;
/*
* Request attribute values override PDP issued ones Do not modify pdpIssuedAttributes directly as this may be used for other requests (Multiple Decision Profile) as well
* Request attribute values override PDP issued ones. Do not modify pdpIssuedAttributes directly as this may be used for other requests (Multiple Decision Profile) as well. so we must not
* modify it but clone it before individual decision request processing.
*/
final Map<AttributeGUID, Bag<?>> mergedAttributes = new HashMap<>(pdpIssuedAttributes);
final Map<AttributeGUID, Bag<?>> mergedAttributes;
if (pdpIssuedAttributes != null)
{
mergedAttributes = new HashMap<>(pdpIssuedAttributes);
}
else if (requestAttributes != null) // pdpIssuedAttributes == null
{
return new HashMap<>(requestAttributes);
}
else
{ // pdpIssuedAttributes == null && requestAttributes == null
return null;
}
mergedAttributes.putAll(requestAttributes);
return mergedAttributes;
}
......@@ -69,15 +82,41 @@ public abstract class IndividualDecisionRequestEvaluator
@Override
public Map<AttributeGUID, Bag<?>> merge(final Map<AttributeGUID, Bag<?>> pdpIssuedAttributes, final Map<AttributeGUID, Bag<?>> requestAttributes)
{
assert pdpIssuedAttributes != null && requestAttributes != null;
// PDP issued attribute values override request attribute values
/*
* Do not modify pdpIssuedAttributes directly as this may be used for other requests (Multiple Decision Profile) as well
* Do not modify pdpIssuedAttributes directly as this may be used for other requests (Multiple Decision Profile) as well. so we must not modify it but clone it before individual decision
* request processing.
*/
final Map<AttributeGUID, Bag<?>> mergedAttributes = new HashMap<>(requestAttributes);
final Map<AttributeGUID, Bag<?>> mergedAttributes;
if (requestAttributes != null)
{
mergedAttributes = new HashMap<>(requestAttributes);
}
else if (pdpIssuedAttributes != null) // requestAttributes == null
{
return new HashMap<>(pdpIssuedAttributes);
}
else
{ // requestAttributes == null && pdpIssuedAttributes == null
return null;
}
mergedAttributes.putAll(pdpIssuedAttributes);
return mergedAttributes;
}
};
private static final RequestAndPdpIssuedNamedAttributesMerger REQUEST_ONLY_ATTRIBUTES_MERGER = new RequestAndPdpIssuedNamedAttributesMerger()
{
@Override
public Map<AttributeGUID, Bag<?>> merge(final Map<AttributeGUID, Bag<?>> pdpIssuedAttributes, final Map<AttributeGUID, Bag<?>> requestAttributes)
{
// PDP values completely ignored
return requestAttributes == null ? null : new HashMap<>(requestAttributes);
}
};
......@@ -90,18 +129,41 @@ public abstract class IndividualDecisionRequestEvaluator
*
* @param rootPolicyEvaluator
* root policy evaluator that this request evaluator uses to evaluate individual decision request
* @param standardCurrentTimeProvider
* provider for standard environment current-time/current-date/current-dateTime attribute values (request or PDP, etc.)
* @param stdEnvAttributeSource
* (mandatory) Defines the source for the standard environment attributes specified in §10.2.5: current-time, current-date and current-dateTime. The options are:
* <ul>
* <li>REQUEST_ELSE_PDP: the default choice, that complies with the XACML standard (§10.2.5): "If values for these attributes are not present in the decision request, then their values
* MUST be supplied by the context handler", in our case, "context handler" means the PDP. In other words, the attribute values come from request by default, or from the PDP if (and
* *only if* in this case) they are not set in the request. Issue: what if the decision request only specifies current-time but not current-dateTime, and the policy requires both?
* Should the PDP provides its own value for current-dateTime? This could cause some inconsistencies since current-time and current-dateTime would come from two different
* sources/environments. With this option, we have a strict interpretation of the spec, i.e. if any of these attribute is not set in the request, the PDP uses its own value instead. So
* BEWARE. Else you have the other options below.</li>
* <li>REQUEST_ONLY: always use the value from the request, or nothing if the value is not set in the request, in which case this results in Indeterminate (missing attribute) if the
* policy evaluation requires it.</li>
* <li>PDP_ONLY: always use the values from the PDP. In other words, Request values are simply ignored; PDP values systematically override the ones from the request. This also
* guarantees that they are always set (by the PDP). NB: note that the XACML standard (§10.2.5) says: "If values for these attributes are not present in the decision request, then their
* values MUST be supplied by the context handler" but it does NOT say "If AND ONLY IF values..." So this option could still be considered XACML compliant in a strict sense.</li>
* </ul>
* @throws IllegalArgumentException
* if {@code stdEnvAttributeSource} is null or not supported
*/
protected IndividualDecisionRequestEvaluator(final RootPolicyEvaluator rootPolicyEvaluator, final StandardCurrentTimeProvider standardCurrentTimeProvider)
protected IndividualDecisionRequestEvaluator(final RootPolicyEvaluator rootPolicyEvaluator, final StandardEnvironmentAttributeSource stdEnvAttributeSource) throws IllegalArgumentException
{
assert rootPolicyEvaluator != null;
assert rootPolicyEvaluator != null && stdEnvAttributeSource != null;
this.rootPolicyEvaluator = rootPolicyEvaluator;
switch(standardCurrentTimeProvider) {
case REQUEST_ELSE_PDP:
this.reqAndPdpIssuedAttributesMerger = standardCurrentTimeProvider ? PDP_OVERRIDES_ATTRIBUTES_MERGER : REQUEST_OVERRIDES_ATTRIBUTES_MERGER;
break;
case REQUEST_ONLY
switch (stdEnvAttributeSource)
{
case PDP_ONLY:
this.reqAndPdpIssuedAttributesMerger = PDP_OVERRIDES_ATTRIBUTES_MERGER;
break;
case REQUEST_ONLY:
this.reqAndPdpIssuedAttributesMerger = REQUEST_ONLY_ATTRIBUTES_MERGER;
break;
case REQUEST_ELSE_PDP:
this.reqAndPdpIssuedAttributesMerger = REQUEST_OVERRIDES_ATTRIBUTES_MERGER;
break;
default:
throw new IllegalArgumentException("Unsupported standardEnvAttributeSource: " + stdEnvAttributeSource + ". Expected: " + Arrays.toString(StandardEnvironmentAttributeSource.values()));
}
}
......@@ -111,32 +173,19 @@ public abstract class IndividualDecisionRequestEvaluator
* </p>
*
* @param request
* a {@link org.ow2.authzforce.core.pdp.api.IndividualDecisionRequest} object.
* a non-null {@link org.ow2.authzforce.core.pdp.api.IndividualDecisionRequest} object.
* @param pdpIssuedAttributes
* a {@link java.util.Map} of PDP-issued attributes including at least the standard environment attributes: current-time, current-date, current-dateTime.
* @param returnUsedAttributes
* true iff the list of attributes used for evaluation must be included in the result
* @return a {@link oasis.names.tc.xacml._3_0.core.schema.wd_17.Result} object.
* @return the evaluation result.
*/
protected final DecisionResult evaluate(final IndividualDecisionRequest request, final Map<AttributeGUID, Bag<?>> pdpIssuedAttributes, final boolean returnUsedAttributes)
{
assert request != null && pdpIssuedAttributes != null;
assert request != null;
// convert to EvaluationContext
/*
* The pdpIssuedAttributes may be re-used for many individual requests, so we must not modify it but clone it before individual decision request processing
*/
final Map<AttributeGUID, Bag<?>> mergedNamedAttributes;
final Map<AttributeGUID, Bag<?>> reqNamedAttributes = request.getNamedAttributes();
if (reqNamedAttributes == null)
{
mergedNamedAttributes = new HashMap<>(pdpIssuedAttributes);
}
else
{
mergedNamedAttributes = reqAndPdpIssuedAttributesMerger.merge(pdpIssuedAttributes, reqNamedAttributes);
}
final Map<AttributeGUID, Bag<?>> mergedNamedAttributes = reqAndPdpIssuedAttributesMerger.merge(pdpIssuedAttributes, request.getNamedAttributes());
final EvaluationContext ctx = new IndividualDecisionRequestContext(mergedNamedAttributes, request.getExtraContentsByCategory(), request.isApplicablePolicyIdListReturned(),
returnUsedAttributes);
return rootPolicyEvaluator.findAndEvaluate(ctx);
......
......@@ -49,28 +49,10 @@ import org.ow2.authzforce.core.pdp.api.PepActions;
*
* @version $Id: $
*/
public final class BaseDecisionResult implements DecisionResult
public final class MutableDecisionResult implements DecisionResult
{
private static final IllegalArgumentException ILLEGAL_DECISION_ARGUMENT_EXCEPTION = new IllegalArgumentException("Undefined Decision");
/**
* NotApplicable decision result
*/
public static final DecisionResult NOT_APPLICABLE = new BaseDecisionResult(DecisionType.NOT_APPLICABLE, null);
/**
* Deny result with no obligation/advice/Included attribute/policy identifiers. Deny decision and nothing else.
*/
public static final DecisionResult SIMPLE_DENY = new BaseDecisionResult(DecisionType.DENY, null);
/**
* Permit result with no obligation/advice/Included attribute/policy identifiers. Permit decision and nothing else.
*/
public static final DecisionResult SIMPLE_PERMIT = new BaseDecisionResult(DecisionType.PERMIT, null);
private static final Result SIMPLE_PERMIT_XACML = new Result(DecisionType.PERMIT, null, null, null, null, null);
private static final Result SIMPLE_DENY_XACML = new Result(DecisionType.DENY, null, null, null, null, null);
private final DecisionType decision;
/**
......@@ -102,7 +84,7 @@ public final class BaseDecisionResult implements DecisionResult
private transient volatile int hashCode = 0;
private BaseDecisionResult(final DecisionType decision, final DecisionType extendedIndeterminate, final Status status, final PepActions pepActions,
private MutableDecisionResult(final DecisionType decision, final DecisionType extendedIndeterminate, final Status status, final PepActions pepActions,
final List<JAXBElement<IdReferenceType>> policyIdList, final Set<AttributeGUID> usedNamedAttributes, final Set<AttributeSelectorId> usedExtraAttributeContents)
{
if (decision == null)
......@@ -135,7 +117,7 @@ public final class BaseDecisionResult implements DecisionResult
* @param policyIdentifierList
* list of matched policy identifiers
*/
public BaseDecisionResult(final Status status, final DecisionType extendedIndeterminate, final List<JAXBElement<IdReferenceType>> policyIdentifierList)
public MutableDecisionResult(final Status status, final DecisionType extendedIndeterminate, final List<JAXBElement<IdReferenceType>> policyIdentifierList)
{
this(DecisionType.INDETERMINATE, extendedIndeterminate, status, null, policyIdentifierList, null, null);
}
......@@ -154,7 +136,7 @@ public final class BaseDecisionResult implements DecisionResult
* @param status
* reason/code for Indeterminate
*/
public BaseDecisionResult(final Status status, final DecisionType extendedIndeterminate)
public MutableDecisionResult(final Status status, final DecisionType extendedIndeterminate)
{
this(DecisionType.INDETERMINATE, extendedIndeterminate, status, null, null, null, null);
}
......@@ -169,7 +151,7 @@ public final class BaseDecisionResult implements DecisionResult
* @param usedExtraAttributeContents
* extra Attributes/Content(s) actually used for evaluating this decision
*/
public BaseDecisionResult(final Status status, final Set<AttributeGUID> usedNamedAttributes, final Set<AttributeSelectorId> usedExtraAttributeContents)
public MutableDecisionResult(final Status status, final Set<AttributeGUID> usedNamedAttributes, final Set<AttributeSelectorId> usedExtraAttributeContents)
{
this(DecisionType.INDETERMINATE, DecisionType.INDETERMINATE, status, null, null, usedNamedAttributes, usedExtraAttributeContents);
}
......@@ -180,20 +162,21 @@ public final class BaseDecisionResult implements DecisionResult
* @param status
* reason/code for Indeterminate
*/
public BaseDecisionResult(final Status status)
public MutableDecisionResult(final Status status)
{
this(DecisionType.INDETERMINATE, DecisionType.INDETERMINATE, status, null, null, null, null);
}
/**
* Instantiates a Permit/Deny decision with optional obligations and advice. See {@link #BaseDecisionResult(Status, DecisionType)} for Indeterminate, and {@link #NOT_APPLICABLE} for NotApplicable.
* Instantiates a Permit/Deny decision with optional obligations and advice. See {@link #MutableDecisionResult(Status, DecisionType)} for Indeterminate, and {@link DecisionResults#NOT_APPLICABLE}
* for NotApplicable.
*
* @param decision
* decision
* @param pepActions
* PEP actions (obligations/advices)
*/
public BaseDecisionResult(final DecisionType decision, final PepActions pepActions)
public MutableDecisionResult(final DecisionType decision, final PepActions pepActions)
{
this(decision, DecisionType.NOT_APPLICABLE, null, pepActions, null, null, null);
}
......@@ -212,7 +195,7 @@ public final class BaseDecisionResult implements DecisionResult
* @param usedExtraAttributeContents
* extra Attributes/Content(s) actually used for evaluating this decision
*/
public BaseDecisionResult(final DecisionResult algResult, final PepActions pepActions, final List<JAXBElement<IdReferenceType>> applicablePolicyIdList,
public MutableDecisionResult(final DecisionResult algResult, final PepActions pepActions, final List<JAXBElement<IdReferenceType>> applicablePolicyIdList,
final Set<AttributeGUID> usedNamedAttributes, final Set<AttributeSelectorId> usedExtraAttributeContents)
{
this(algResult.getDecision(), algResult.getExtendedIndeterminate(), algResult.getStatus(), pepActions, applicablePolicyIdList, usedNamedAttributes, usedExtraAttributeContents);
......@@ -262,7 +245,8 @@ public final class BaseDecisionResult implements DecisionResult
{
return false;
}
} else if (!this.status.equals(other.getStatus()))
}
else if (!this.status.equals(other.getStatus()))
{
return false;
}
......@@ -353,16 +337,6 @@ public final class BaseDecisionResult implements DecisionResult
@Override
public Result toXACMLResult(final List<Attributes> returnedAttributes)
{
if (this == SIMPLE_PERMIT)
{
return SIMPLE_PERMIT_XACML;
}
if (this == SIMPLE_DENY)
{
return SIMPLE_DENY_XACML;
}
final List<Obligation> obligationList = this.pepActions.getObligations();
final List<Advice> adviceList = this.pepActions.getAdvices();
return new Result(this.decision, this.status, obligationList == null || obligationList.isEmpty() ? null : new Obligations(obligationList), adviceList == null || adviceList.isEmpty() ? null
......
......@@ -356,7 +356,7 @@ public class PdpConfigurationParser
}
return new PDPImpl(attributeFactory, functionRegistry, pdpJaxbConf.getAttributeProviders(), maxVarRefDepth, enableXPath, combiningAlgRegistry, pdpJaxbConf.getRootPolicyProvider(),
pdpJaxbConf.getRefPolicyProvider(), maxPolicyRefDepth, pdpJaxbConf.getRequestFilter(), pdpJaxbConf.isStrictAttributeIssuerMatch(), pdpJaxbConf.getStdEnvTimeProvider(),
pdpJaxbConf.getRefPolicyProvider(), maxPolicyRefDepth, pdpJaxbConf.getRequestFilter(), pdpJaxbConf.isStrictAttributeIssuerMatch(), pdpJaxbConf.getStandardEnvAttributeSource(),
decisionResultFilter, jaxbDecisionCache, envProps);
}
......
......@@ -28,7 +28,7 @@ import org.ow2.authzforce.core.pdp.api.EvaluationContext;
import org.ow2.authzforce.core.pdp.api.combining.BaseCombiningAlg;
import org.ow2.authzforce.core.pdp.api.combining.CombiningAlg;
import org.ow2.authzforce.core.pdp.api.combining.CombiningAlgParameter;
import org.ow2.authzforce.core.pdp.impl.BaseDecisionResult;
import org.ow2.authzforce.core.pdp.impl.MutableDecisionResult;
/**
* This is the standard XACML 3.0 Deny-Overrides policy/rule combining algorithm. It allows a single evaluation of Deny to take precedence over any number of permit, not applicable or indeterminate
......@@ -135,7 +135,7 @@ final class DenyOverridesAlg extends BaseCombiningAlg<Decidable>
*/
if (firstIndeterminateDResult != null)
{
return new BaseDecisionResult(firstIndeterminateDResult.getStatus(), firstIndeterminatePResult != null || combinedPermitResult != null ? DecisionType.INDETERMINATE : DecisionType.DENY);
return new MutableDecisionResult(firstIndeterminateDResult.getStatus(), firstIndeterminatePResult != null || combinedPermitResult != null ? DecisionType.INDETERMINATE : DecisionType.DENY);
}
// if we got a PERMIT or Indeterminate{P}, return it, otherwise it's NOT_APPLICABLE
......@@ -149,7 +149,7 @@ final class DenyOverridesAlg extends BaseCombiningAlg<Decidable>
return firstIndeterminatePResult;
}
return BaseDecisionResult.NOT_APPLICABLE;
return MutableDecisionResult.NOT_APPLICABLE;
}
}
......
......@@ -28,7 +28,7 @@ import org.ow2.authzforce.core.pdp.api.EvaluationContext;
import org.ow2.authzforce.core.pdp.api.combining.BaseCombiningAlg;
import org.ow2.authzforce.core.pdp.api.combining.CombiningAlg;
import org.ow2.authzforce.core.pdp.api.combining.CombiningAlgParameter;
import org.ow2.authzforce.core.pdp.impl.BaseDecisionResult;
import org.ow2.authzforce.core.pdp.impl.MutableDecisionResult;
/**
* Deny-unless-permit combining algorithm
......@@ -76,7 +76,7 @@ final class DenyUnlessPermitAlg extends BaseCombiningAlg<Decidable>
}
}
return combinedDenyResult == null ? BaseDecisionResult.SIMPLE_DENY : combinedDenyResult;
return combinedDenyResult == null ? MutableDecisionResult.SIMPLE_DENY : combinedDenyResult;
}
}
......
......@@ -28,7 +28,7 @@ import org.ow2.authzforce.core.pdp.api.EvaluationContext;
import org.ow2.authzforce.core.pdp.api.combining.BaseCombiningAlg;
import org.ow2.authzforce.core.pdp.api.combining.CombiningAlg;
import org.ow2.authzforce.core.pdp.api.combining.CombiningAlgParameter;
import org.ow2.authzforce.core.pdp.impl.BaseDecisionResult;
import org.ow2.authzforce.core.pdp.impl.MutableDecisionResult;
/**
* This is the standard First-Applicable policy/rule combining algorithm. It looks through the set of policies/rules, finds the first one that applies, and returns that evaluation result.
......@@ -67,7 +67,7 @@ final class FirstApplicableAlg extends BaseCombiningAlg<Decidable>
}
// if we got here, then none of the rules applied
return BaseDecisionResult.NOT_APPLICABLE;
return MutableDecisionResult.NOT_APPLICABLE;
}
}
......
......@@ -28,7 +28,7 @@ import org.ow2.authzforce.core.pdp.api.combining.BaseCombiningAlg;
import org.ow2.authzforce.core.pdp.api.combining.CombiningAlg;
import org.ow2.authzforce.core.pdp.api.combining.CombiningAlgParameter;
import org.ow2.authzforce.core.pdp.api.policy.PolicyEvaluator;
import org.ow2.authzforce.core.pdp.impl.BaseDecisionResult;
import org.ow2.authzforce.core.pdp.impl.MutableDecisionResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -44,14 +44,14 @@ final class OnlyOneApplicableAlg extends BaseCombiningAlg<PolicyEvaluator>
{
private static final Logger LOGGER = LoggerFactory.getLogger(Evaluator.class);
private final BaseDecisionResult tooManyApplicablePoliciesIndeterminateResult;
private final MutableDecisionResult tooManyApplicablePoliciesIndeterminateResult;
private final List<? extends PolicyEvaluator> policyElements;
private Evaluator(final String algId, final List<? extends PolicyEvaluator> policyElements)
{
this.policyElements = policyElements;
this.tooManyApplicablePoliciesIndeterminateResult = new BaseDecisionResult(new StatusHelper(StatusHelper.STATUS_PROCESSING_ERROR,
this.tooManyApplicablePoliciesIndeterminateResult = new MutableDecisionResult(new StatusHelper(StatusHelper.STATUS_PROCESSING_ERROR,
"Too many (more than one) applicable policies for algorithm: " + algId));
}
......@@ -71,7 +71,7 @@ final class OnlyOneApplicableAlg extends BaseCombiningAlg<PolicyEvaluator>
} catch (final IndeterminateEvaluationException e)
{
LOGGER.info("Error checking whether {} is applicable", policy, e);
return new BaseDecisionResult(e.getStatus());
return new MutableDecisionResult(e.getStatus());
}
if (isApplicable)
......@@ -95,7 +95,7 @@ final class OnlyOneApplicableAlg extends BaseCombiningAlg<PolicyEvaluator>
return selectedPolicy.evaluate(context, true);
}
return BaseDecisionResult.NOT_APPLICABLE;
return MutableDecisionResult.NOT_APPLICABLE;
}
}
......
......@@ -28,7 +28,7 @@ import org.ow2.authzforce.core.pdp.api.EvaluationContext;
import org.ow2.authzforce.core.pdp.api.combining.BaseCombiningAlg;
import org.ow2.authzforce.core.pdp.api.combining.CombiningAlg;
import org.ow2.authzforce.core.pdp.api.combining.CombiningAlgParameter;
import org.ow2.authzforce.core.pdp.impl.BaseDecisionResult;
import org.ow2.authzforce.core.pdp.impl.MutableDecisionResult;
/**
* This is the standard Permit-Overrides policy/rule combining algorithm. It allows a single evaluation of Permit to take precedence over any number of deny, not applicable or indeterminate results.
......@@ -136,7 +136,7 @@ final class PermitOverridesAlg extends BaseCombiningAlg<Decidable>
*/
if (firstIndeterminatePResult != null)
{
return new BaseDecisionResult(firstIndeterminatePResult.getStatus(), firstIndeterminateDResult != null || combinedDenyResult != null ? DecisionType.INDETERMINATE : DecisionType.PERMIT);
return new MutableDecisionResult(firstIndeterminatePResult.getStatus(), firstIndeterminateDResult != null || combinedDenyResult != null ? DecisionType.INDETERMINATE : DecisionType.PERMIT);
}
/*
......@@ -152,7 +152,7 @@ final class PermitOverridesAlg extends BaseCombiningAlg<Decidable>
return firstIndeterminateDResult;
}
return BaseDecisionResult.NOT_APPLICABLE;
return MutableDecisionResult.NOT_APPLICABLE;
}
}
......
......@@ -28,7 +28,7 @@ import org.ow2.authzforce.core.pdp.api.EvaluationContext;
import org.ow2.authzforce.core.pdp.api.combining.BaseCombiningAlg;
import org.ow2.authzforce.core.pdp.api.combining.CombiningAlg;
import org.ow2.authzforce.core.pdp.api.combining.CombiningAlgParameter;
import org.ow2.authzforce.core.pdp.impl.BaseDecisionResult;
import org.ow2.authzforce.core.pdp.impl.MutableDecisionResult;
/**
* permit-unless-deny policy algorithm
......@@ -77,7 +77,7 @@ final class PermitUnlessDenyAlg extends BaseCombiningAlg<Decidable>
}
}
return combinedPermitResult == null ? BaseDecisionResult.SIMPLE_PERMIT : combinedPermitResult;
return combinedPermitResult == null ? MutableDecisionResult.SIMPLE_PERMIT : combinedPermitResult;
}
}
......
......@@ -62,6 +62,9 @@ final class TimeRangeComparisonFunction extends SingleParameterTypedFirstOrderFu
private static final class Call extends FirstOrderFunctionCall.EagerSinglePrimitiveTypeEval<BooleanValue, TimeValue>
{
/**
* XACML says: "If no time zone is provided for the first argument, it SHALL use the default time zone at the context handler."
*/
private static final TimeZone DEFAULT_TZ = TimeZone.getDefault();
/**
......
......@@ -74,7 +74,7 @@ import org.ow2.authzforce.core.pdp.api.policy.StaticTopLevelPolicyElementEvaluat
import org.ow2.authzforce.core.pdp.api.policy.TopLevelPolicyElementEvaluator;
import org.ow2.authzforce.core.pdp.api.policy.TopLevelPolicyElementType;
import org.ow2.authzforce.core.pdp.api.policy.VersionPatterns;
import org.ow2.authzforce.core.pdp.impl.BaseDecisionResult;
import org.ow2.authzforce.core.pdp.impl.MutableDecisionResult;
import org.ow2.authzforce.core.pdp.impl.TargetEvaluator;
import org.ow2.authzforce.core.pdp.impl.rule.RuleEvaluator;
import org.ow2.authzforce.xacml.identifiers.XACMLNodeName;
......@@ -446,7 +446,7 @@ public final class PolicyEvaluators
if (!isApplicable(context))
{
LOGGER.debug("{} -> NotApplicable", policyId);
newResult = BaseDecisionResult.NOT_APPLICABLE;
newResult = MutableDecisionResult.NOT_APPLICABLE;
return newResult;
}
} catch (final IndeterminateEvaluationException e)
......@@ -477,10 +477,10 @@ public final class PolicyEvaluators
break;
case PERMIT:
case DENY:
newResult = new BaseDecisionResult(targetMatchIndeterminateException.getStatus(), algDecision);
newResult = new MutableDecisionResult(targetMatchIndeterminateException.getStatus(), algDecision);
break;
default: // INDETERMINATE
newResult = new BaseDecisionResult(targetMatchIndeterminateException.getStatus(), algResult.getExtendedIndeterminate());
newResult = new MutableDecisionResult(targetMatchIndeterminateException.getStatus(), algResult.getExtendedIndeterminate());
break;
}
......@@ -555,13 +555,13 @@ public final class PolicyEvaluators
* error)
*/
LOGGER.info("{}/{Obligation|Advice}Expressions -> Indeterminate", policyId, e);
newResult = new BaseDecisionResult(e.getStatus(), algResultDecision, applicablePolicyIdList);
newResult = new MutableDecisionResult(e.getStatus(), algResultDecision, applicablePolicyIdList);
return newResult;
}
}
}
newResult = new BaseDecisionResult(algResult, pepActions, applicablePolicyIdList, context.getUsedNamedAttributes(), context.getUsedExtraAttributeContents());
newResult = new MutableDecisionResult(algResult, pepActions, applicablePolicyIdList, context.getUsedNamedAttributes(), context.getUsedExtraAttributeContents());
return newResult;
} finally
{
......@@ -1221,7 +1221,7 @@ public final class PolicyEvaluators
} catch (final IndeterminateEvaluationException e)
{
LOGGER.info("", e);
return new BaseDecisionResult(e.getStatus(), context.getUsedNamedAttributes(), context.getUsedExtraAttributeContents());
return new MutableDecisionResult(e.getStatus(), context.getUsedNamedAttributes(), context.getUsedExtraAttributeContents());
}
return refResolvedResult.resolvedPolicy.evaluate(context, skipTarget);
......
......@@ -36,7 +36,7 @@ import org.ow2.authzforce.core.pdp.api.policy.RootPolicyProviderModule;
import org.ow2.authzforce.core.pdp.api.policy.StaticRootPolicyProviderModule;
import org.ow2.authzforce.core.pdp.api.policy.StaticTopLevelPolicyElementEvaluator;
import org.ow2.authzforce.core.pdp.api.value.DatatypeFactoryRegistry;
import org.ow2.authzforce.core.pdp.impl.BaseDecisionResult;
import org.ow2.authzforce.core.pdp.impl.MutableDecisionResult;
import org.ow2.authzforce.core.pdp.impl.PdpExtensionLoader;
import org.ow2.authzforce.core.pdp.impl.expression.ExpressionFactoryImpl;
import org.ow2.authzforce.core.pdp.impl.func.FunctionRegistry;
......@@ -209,17 +209,17 @@ public interface RootPolicyEvaluator extends Closeable
} catch (final IndeterminateEvaluationException e)
{
LOGGER.info("Root policy Provider module {} could not find an applicable root policy to evaluate", rootPolicyProviderMod, e);
return new BaseDecisionResult(e.getStatus(), context.getUsedNamedAttributes(), context.getUsedExtraAttributeContents());
return new MutableDecisionResult(e.getStatus(), context.getUsedNamedAttributes(), context.getUsedExtraAttributeContents());
} catch (final IllegalArgumentException e)
{
LOGGER.warn("One of the possible root policies (resolved by the root policy provider module {}) is invalid", rootPolicyProviderMod, e);
// we consider that
return new BaseDecisionResult(new StatusHelper(StatusHelper.STATUS_PROCESSING_ERROR, e.getMessage()), context.getUsedNamedAttributes(), context.getUsedExtraAttributeContents());
return new MutableDecisionResult(new StatusHelper(StatusHelper.STATUS_PROCESSING_ERROR, e.getMessage()), context.getUsedNamedAttributes(), context.getUsedExtraAttributeContents());
}
if (policy == null)
{
return BaseDecisionResult.NOT_APPLICABLE;
return MutableDecisionResult.NOT_APPLICABLE;
}
return policy.evaluate(context, true);
......
......@@ -30,7 +30,7 @@ import org.ow2.authzforce.core.pdp.api.EvaluationContext;
import org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException;
import org.ow2.authzforce.core.pdp.api.PepActions;
import org.ow2.authzforce.core.pdp.api.expression.ExpressionFactory;
import org.ow2.authzforce.core.pdp.impl.BaseDecisionResult;
import org.ow2.authzforce.core.pdp.impl.MutableDecisionResult;
import org.ow2.authzforce.core.pdp.impl.TargetEvaluator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -50,7 +50,7 @@ public class RuleEvaluator implements Decidable
private final transient TargetEvaluator evaluatableTarget;
private final transient ConditionEvaluator evaluatableCondition;
private final transient RulePepActionExpressionsEvaluator effectMatchPepActionExps;
private final transient BaseDecisionResult nullActionsRuleDecisionResult;
private final transient MutableDecisionResult nullActionsRuleDecisionResult;
private final String toString;
private final String ruleId;
......@@ -66,7 +66,7 @@ public class RuleEvaluator implements Decidable
* @throws java.lang.IllegalArgumentException
* Invalid Target, Condition or Obligation/Advice expressions
*/
public RuleEvaluator(Rule ruleElt, XPathCompiler xPathCompiler, ExpressionFactory expressionFactory) throws IllegalArgumentException
public RuleEvaluator(final Rule ruleElt, final XPathCompiler xPathCompiler, final ExpressionFactory expressionFactory) throws IllegalArgumentException
{
// JAXB fields initialization
this.ruleId = ruleElt.getRuleId();
......@@ -79,7 +79,8 @@ public class RuleEvaluator implements Decidable
try
{
this.evaluatableTarget = targetElt == null ? null : new TargetEvaluator(targetElt, xPathCompiler, expressionFactory);
} catch (IllegalArgumentException e)
}
catch (final IllegalArgumentException e)
{
throw new IllegalArgumentException(this + ": Invalid Target", e);
}
......@@ -88,7 +89,8 @@ public class RuleEvaluator implements Decidable
try
{
this.evaluatableCondition = condElt == null ? null : new ConditionEvaluator(condElt, xPathCompiler, expressionFactory);
} catch (IllegalArgumentException e)
}
catch (final IllegalArgumentException e)
{
throw new IllegalArgumentException(this + ": invalid Condition", e);
}
......@@ -96,7 +98,8 @@ public class RuleEvaluator implements Decidable
try
{
this.effectMatchPepActionExps = RulePepActionExpressionsEvaluator.getInstance(ruleElt.getObligationExpressions(), ruleElt.getAdviceExpressions(), xPathCompiler, expressionFactory, effect);
} catch (IllegalArgumentException e)
}
catch (final IllegalArgumentException e)
{
throw new IllegalArgumentException(this + ": Invalid ObligationExpressions/AdviceExpressions", e);
}
......@@ -104,8 +107,9 @@ public class RuleEvaluator implements Decidable
if (this.effectMatchPepActionExps == null)
{
this.nullActionsRuleDecisionResult = new BaseDecisionResult(this.effectAsDecision, null);
} else
this.nullActionsRuleDecisionResult = new MutableDecisionResult(this.effectAsDecision, null);
}
else
{
this.nullActionsRuleDecisionResult = null;
}
......@@ -132,7 +136,7 @@ public class RuleEvaluator implements Decidable
* result before return. Indeterminate results are logged in warn level only (which "includes" debug level).
*/
@Override
public DecisionResult evaluate(EvaluationContext context)
public DecisionResult evaluate(final EvaluationContext context)
{
/*
* Null or empty Target matches all So we just check if target non-null matches
......@@ -140,20 +144,22 @@ public class RuleEvaluator implements Decidable
if (evaluatableTarget == null)
{
LOGGER.debug("{}/Target (none/empty) -> Match", this);
} else
}
else
{
try
{
if (!evaluatableTarget.match(context))
{
LOGGER.debug("{}/Target -> No-match", this);
final DecisionResult result = BaseDecisionResult.NOT_APPLICABLE;
final DecisionResult result = MutableDecisionResult.NOT_APPLICABLE;
LOGGER.debug("{} -> {}", this, result);
return result;
}
LOGGER.debug("{}/Target -> Match", this);
} catch (IndeterminateEvaluationException e)
}
catch (final IndeterminateEvaluationException e)
{
// Target is Indeterminate
/*
......@@ -164,7 +170,7 @@ public class RuleEvaluator implements Decidable
/*
* Condition is Indeterminate, determine Extended Indeterminate (section 7.11) which is the value of the Rule's Effect
*/
final DecisionResult result = new BaseDecisionResult(e.getStatus(), this.effectAsDecision);
final DecisionResult result = new MutableDecisionResult(e.getStatus(), this.effectAsDecision);
LOGGER.debug("{} -> {}", this, result);
return result;
}
......@@ -177,14 +183,16 @@ public class RuleEvaluator implements Decidable
if (evaluatableCondition == null)
{
LOGGER.debug("{}/Condition (none/empty) -> True", this);
} else
}
else
{
// ...otherwise we evaluate the condition
final boolean isConditionTrue;
try