Commit 736a7da3 authored by cdanger's avatar cdanger

- Upgraded parent version: 3.4.0

- pdp.xsd:
	- Removed functionSet element (no longer supported)
	- Added attribute 'pdpStdTimeOverrides' boolean for enabling/disabling
PDP issued standard env current date/time override of matching request
attributes
	
parent c684ff9a
......@@ -5,7 +5,7 @@ All notable changes to this project are documented in this file following the [K
## 4.0.2
### Fixed
- Issues reported by Codacyi (including fixed issues in upgraded dependency core-pdp-api 4.0.2)
- Issues reported by Codacy (including fixed issues in upgraded dependency core-pdp-api 4.0.2)
## 4.0.0
......
......@@ -3,7 +3,7 @@
<parent>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-parent</artifactId>
<version>3.3.7</version>
<version>3.4.0</version>
</parent>
<artifactId>authzforce-ce-core</artifactId>
<version>4.0.3-SNAPSHOT</version>
......@@ -66,7 +66,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.5</version>
<!-- target JDK already set by parent project's maven.compiler.target property -->
<configuration>
<verbose>true</verbose>
......@@ -88,14 +87,6 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<!-- Enables analysis which takes more memory but finds more bugs. If you run out of memory, changes the value of the effort element to 'Low'. -->
<effort>Max</effort>
<!-- Reports all bugs (other values are medium and max) -->
<threshold>Low</threshold>
<failOnError>true</failOnError>
</configuration>
<executions>
<execution>
<phase>verify</phase>
......@@ -141,7 +132,7 @@
<!-- debug=true will generate JAXBDebug class. More info: https://github.com/highsource/maven-jaxb2-plugin/wiki/Miscellaneous -->
<debug>false</debug>
<strict>false</strict>
<verbose>false</verbose>
<verbose>true</verbose>
<removeOldOutput>true</removeOldOutput>
<extension>true</extension>
<args>
......@@ -167,7 +158,7 @@
<episode>
<groupId>${project.groupId}</groupId>
<artifactId>${artifactId.prefix}-pdp-ext-model</artifactId>
<version>3.3.7</version>
<version>3.4.0</version>
</episode>
</episodes>
<catalog>src/main/jaxb/catalog.xml</catalog>
......
......@@ -38,18 +38,69 @@ import org.ow2.authzforce.core.pdp.impl.policy.RootPolicyEvaluator;
*/
public abstract class IndividualDecisionRequestEvaluator
{
private interface RequestAndPdpIssuedNamedAttributesMerger
{
Map<AttributeGUID, Bag<?>> merge(final Map<AttributeGUID, Bag<?>> pdpIssuedAttributes, final Map<AttributeGUID, Bag<?>> requestAttributes);
}
private static final RequestAndPdpIssuedNamedAttributesMerger REQUEST_OVERRIDES_ATTRIBUTES_MERGER = new RequestAndPdpIssuedNamedAttributesMerger()
{
@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
*/
final Map<AttributeGUID, Bag<?>> mergedAttributes = new HashMap<>(pdpIssuedAttributes);
mergedAttributes.putAll(requestAttributes);
return mergedAttributes;
}
};
private static final RequestAndPdpIssuedNamedAttributesMerger PDP_OVERRIDES_ATTRIBUTES_MERGER = new RequestAndPdpIssuedNamedAttributesMerger()
{
@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
*/
final Map<AttributeGUID, Bag<?>> mergedAttributes = new HashMap<>(requestAttributes);
mergedAttributes.putAll(pdpIssuedAttributes);
return mergedAttributes;
}
};
private final RootPolicyEvaluator rootPolicyEvaluator;
private final RequestAndPdpIssuedNamedAttributesMerger reqAndPdpIssuedAttributesMerger;
/**
* Creates an evaluator
*
* @param rootPolicyEvaluator
* root policy evaluator that this request evaluator uses to evaluate individual decision request
* @param pdpStdTimeEnvOverrides
* True iff the PDP's values for the standard environment attributes specified in §10.2.5 (current-time, current-date and current-dateTime) must always be set and override values from
* the Request, if any. WARNING: 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 setting this flag to true could still be considered XACML compliant in a strict sense. Besides, 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. So BEWARE.
*/
protected IndividualDecisionRequestEvaluator(final RootPolicyEvaluator rootPolicyEvaluator)
protected IndividualDecisionRequestEvaluator(final RootPolicyEvaluator rootPolicyEvaluator, final boolean pdpStdTimeEnvOverrides)
{
assert rootPolicyEvaluator != null;
this.rootPolicyEvaluator = rootPolicyEvaluator;
this.reqAndPdpIssuedAttributesMerger = pdpStdTimeEnvOverrides ? PDP_OVERRIDES_ATTRIBUTES_MERGER : REQUEST_OVERRIDES_ATTRIBUTES_MERGER;
}
/**
......@@ -60,27 +111,31 @@ public abstract class IndividualDecisionRequestEvaluator
* @param request
* a {@link org.ow2.authzforce.core.pdp.api.IndividualDecisionRequest} object.
* @param pdpIssuedAttributes
* a {@link java.util.Map} object.
* 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.
*/
protected final DecisionResult evaluate(final IndividualDecisionRequest request, final Map<AttributeGUID, Bag<?>> pdpIssuedAttributes, final boolean returnUsedAttributes)
{
assert request != null;
assert request != null && pdpIssuedAttributes != 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<?>> pdpEnhancedNamedAttributes = pdpIssuedAttributes == null ? new HashMap<AttributeGUID, Bag<?>>() : new HashMap<>(pdpIssuedAttributes);
final Map<AttributeGUID, Bag<?>> mergedNamedAttributes;
final Map<AttributeGUID, Bag<?>> reqNamedAttributes = request.getNamedAttributes();
if (reqNamedAttributes != null)
if (reqNamedAttributes == null)
{
mergedNamedAttributes = new HashMap<>(pdpIssuedAttributes);
}
else
{
pdpEnhancedNamedAttributes.putAll(reqNamedAttributes);
mergedNamedAttributes = reqAndPdpIssuedAttributesMerger.merge(pdpIssuedAttributes, reqNamedAttributes);
}
final EvaluationContext ctx = new IndividualDecisionRequestContext(pdpEnhancedNamedAttributes, request.getExtraContentsByCategory(), request.isApplicablePolicyIdListReturned(),
final EvaluationContext ctx = new IndividualDecisionRequestContext(mergedNamedAttributes, request.getExtraContentsByCategory(), request.isApplicablePolicyIdListReturned(),
returnUsedAttributes);
return rootPolicyEvaluator.findAndEvaluate(ctx);
}
......@@ -91,11 +146,11 @@ public abstract class IndividualDecisionRequestEvaluator
* </p>
*
* @param individualDecisionRequests
* a {@link java.util.List} object.
* a {@link java.util.List} of individual decision requests.
* @param pdpIssuedAttributes
* a {@link java.util.Map} object.
* @return a {@link java.util.List} object.
* a {@link java.util.Map} of PDP-issued attributes including at least the standard environment attributes: current-time, current-date, current-dateTime.
* @return a {@link java.util.List} of evaluation results (one per individual decision request).
*/
protected abstract <INDIVIDUAL_DECISION_REQ_T extends IndividualDecisionRequest> List<Result> evaluate(List<INDIVIDUAL_DECISION_REQ_T> individualDecisionRequests,
Map<AttributeGUID, Bag<?>> pdpIssuedAttributes);
final Map<AttributeGUID, Bag<?>> pdpIssuedAttributes);
}
......@@ -119,9 +119,9 @@ public class PDPImpl implements CloseablePDP
private static class NonCachingIndividualDecisionRequestEvaluator extends IndividualDecisionRequestEvaluator
{
private NonCachingIndividualDecisionRequestEvaluator(final RootPolicyEvaluator rootPolicyEvaluator)
private NonCachingIndividualDecisionRequestEvaluator(final RootPolicyEvaluator rootPolicyEvaluator, final boolean pdpStdTimeEnvOverrides)
{
super(rootPolicyEvaluator);
super(rootPolicyEvaluator, pdpStdTimeEnvOverrides);
}
@Override
......@@ -155,9 +155,9 @@ public class PDPImpl implements CloseablePDP
private final DecisionCache decisionCache;
private CachingIndividualRequestEvaluator(final RootPolicyEvaluator rootPolicyEvaluator, final DecisionCache decisionCache)
private CachingIndividualRequestEvaluator(final RootPolicyEvaluator rootPolicyEvaluator, final boolean pdpStdTimeEnvOverrides, final DecisionCache decisionCache)
{
super(rootPolicyEvaluator);
super(rootPolicyEvaluator, pdpStdTimeEnvOverrides);
assert decisionCache != null;
this.decisionCache = decisionCache;
}
......@@ -205,7 +205,8 @@ public class PDPImpl implements CloseablePDP
finalResult = evaluate(individuaDecisionRequest, pdpIssuedAttributes, true);
newResultsByRequest.put(individuaDecisionRequest, finalResult);
} else
}
else
{
finalResult = cachedResult;
}
......@@ -218,10 +219,10 @@ public class PDPImpl implements CloseablePDP
}
}
private final RootPolicyEvaluator rootPolicyEvaluator;
private final DecisionCache decisionCache;
private final RequestFilter reqFilter;
private final IndividualDecisionRequestEvaluator individualReqEvaluator;
private final DecisionCache decisionCache;
private final RootPolicyEvaluator rootPolicyEvaluator;
private final DecisionResultFilter resultFilter;
/**
......@@ -236,6 +237,7 @@ public class PDPImpl implements CloseablePDP
* AttributeSelectors/AttributeDesignators are not supported
* @param maxVariableReferenceDepth
* max depth of VariableReference chaining: VariableDefinition -> VariableDefinition ->... ('->' represents a VariableReference); strictly negative value means no limit
*
* @param enableXPath
* allow XPath evaluation, i.e. AttributeSelectors and xpathExpressions (experimental, not for production, use with caution)
* @param requestFilterId
......@@ -258,6 +260,12 @@ public class PDPImpl implements CloseablePDP
* AttributeDesignators have an Issuer (best practice). Reminder: the XACML 3.0 specification for AttributeDesignator evaluation (5.29) says: "If the Issuer is not present in the
* attribute designator, then the matching of the attribute to the named attribute SHALL be governed by AttributeId and DataType attributes alone." if one of the mandatory arguments is
* null
* @param pdpStdTimeEnvOverrides
* True iff the PDP's values for the standard environment attributes specified in §10.2.5 (current-time, current-date and current-dateTime) must always be set and override values from
* the Request, if any. WARNING: 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 setting this flag to true could still be considered XACML compliant in a strict sense. Besides, 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. So BEWARE.
* @param environmentProperties
* PDP configuration environment properties
* @throws java.lang.IllegalArgumentException
......@@ -271,8 +279,8 @@ public class PDPImpl implements CloseablePDP
public PDPImpl(final DatatypeFactoryRegistry attributeFactory, final FunctionRegistry functionRegistry, final List<AbstractAttributeProvider> jaxbAttributeProviderConfs,
final int maxVariableReferenceDepth, final boolean enableXPath, final CombiningAlgRegistry combiningAlgRegistry, final AbstractPolicyProvider jaxbRootPolicyProviderConf,
final AbstractPolicyProvider jaxbRefPolicyProviderConf, final int maxPolicySetRefDepth, final String requestFilterId, final boolean strictAttributeIssuerMatch,
final DecisionResultFilter decisionResultFilter, final AbstractDecisionCache jaxbDecisionCacheConf, final EnvironmentProperties environmentProperties) throws IllegalArgumentException,
IOException
final boolean pdpStdTimeEnvOverrides, final DecisionResultFilter decisionResultFilter, final AbstractDecisionCache jaxbDecisionCacheConf, final EnvironmentProperties environmentProperties)
throws IllegalArgumentException, IOException
{
final RequestFilter.Factory requestFilterFactory = requestFilterId == null ? DefaultRequestFilter.LaxFilterFactory.INSTANCE : PdpExtensionLoader.getExtension(RequestFilter.Factory.class,
requestFilterId);
......@@ -286,7 +294,8 @@ public class PDPImpl implements CloseablePDP
if (staticRootPolicyEvaluator == null)
{
this.rootPolicyEvaluator = candidateRootPolicyEvaluator;
} else
}
else
{
this.rootPolicyEvaluator = staticRootPolicyEvaluator;
}
......@@ -297,14 +306,15 @@ public class PDPImpl implements CloseablePDP
if (jaxbDecisionCacheConf == null)
{
this.decisionCache = null;
} else
}
else
{
final DecisionCache.Factory<AbstractDecisionCache> responseCacheStoreFactory = PdpExtensionLoader.getJaxbBoundExtension(DecisionCache.Factory.class, jaxbDecisionCacheConf.getClass());
this.decisionCache = responseCacheStoreFactory.getInstance(jaxbDecisionCacheConf);
}
this.individualReqEvaluator = this.decisionCache == null ? new NonCachingIndividualDecisionRequestEvaluator(rootPolicyEvaluator) : new CachingIndividualRequestEvaluator(rootPolicyEvaluator,
this.decisionCache);
this.individualReqEvaluator = this.decisionCache == null ? new NonCachingIndividualDecisionRequestEvaluator(rootPolicyEvaluator, pdpStdTimeEnvOverrides)
: new CachingIndividualRequestEvaluator(rootPolicyEvaluator, pdpStdTimeEnvOverrides, this.decisionCache);
this.resultFilter = decisionResultFilter == null ? DEFAULT_RESULT_FILTER : decisionResultFilter;
}
......@@ -318,10 +328,13 @@ public class PDPImpl implements CloseablePDP
}
/*
* Every request context (named attributes) is completed with common current date/time attribute (same values) set/"issued" locally (here by the PDP engine) according to XACML core spec:
* "This identifier indicates the current time at the context handler. In practice it is the time at which the request context was created." (� B.7).
* Every request context (named attributes) is completed with common standard current date/time attribute (same values) set/"issued" locally (here by the PDP engine) according to XACML core
* spec: "This identifier indicates the current time at the context handler. In practice it is the time at which the request context was created." (§B.7). 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". <p> These current date/time values are set here once before
* every individual request is evaluated to make sure they all use the same value for current-time/current-date/current-dateTime if no value supplied in the decision request, or if the request
* evaluator is set to pdp-overrides mode (PDP issued attribute values override request values). More info in IndividualDecisionRequestEvaluator class.
*/
final Map<AttributeGUID, Bag<?>> pdpIssuedAttributes = new HashMap<>();
final Map<AttributeGUID, Bag<?>> pdpIssuedAttributes = new HashMap<>(3);
// current datetime
final DateTimeValue currentDateTimeValue = new DateTimeValue(new GregorianCalendar());
pdpIssuedAttributes.put(ENVIRONMENT_CURRENT_DATETIME_ATTRIBUTE_GUID, Bags.singleton(StandardDatatypes.DATETIME_FACTORY.getDatatype(), currentDateTimeValue));
......@@ -367,7 +380,8 @@ public class PDPImpl implements CloseablePDP
try
{
individualDecisionRequests = reqFilter.filter(request, namespaceURIsByPrefix);
} catch (final IndeterminateEvaluationException e)
}
catch (final IndeterminateEvaluationException e)
{
LOGGER.info("Invalid or unsupported input XACML Request syntax", e);
return new Response(Collections.<Result> singletonList(new Result(DecisionType.INDETERMINATE, e.getStatus(), null, null, null, null)));
......
......@@ -207,7 +207,8 @@ public class PdpConfigurationParser
try
{
confFile = ResourceUtils.getFile(confLocation);
} catch (final FileNotFoundException e)
}
catch (final FileNotFoundException e)
{
throw new IllegalArgumentException("Invalid PDP configuration location: " + confLocation, e);
}
......@@ -250,7 +251,8 @@ public class PdpConfigurationParser
try
{
pdpJaxbConf = modelHandler.unmarshal(new StreamSource(confFile), Pdp.class);
} catch (final JAXBException e)
}
catch (final JAXBException e)
{
throw new IllegalArgumentException("Invalid PDP configuration file", e);
}
......@@ -315,7 +317,8 @@ public class PdpConfigurationParser
try
{
alg = PdpExtensionLoader.getExtension(CombiningAlg.class, algId);
} catch (final IllegalArgumentException e)
}
catch (final IllegalArgumentException e)
{
throw new IllegalArgumentException("Unsupported combining algorithm: " + algId, e);
}
......@@ -335,7 +338,8 @@ public class PdpConfigurationParser
try
{
maxVarRefDepth = bigMaxVarRefDepth == null ? -1 : org.ow2.authzforce.core.pdp.api.value.IntegerValue.intValueExact(bigMaxVarRefDepth);
} catch (final ArithmeticException e)
}
catch (final ArithmeticException e)
{
throw new IllegalArgumentException("Invalid maxVariableRefDepth: " + bigMaxVarRefDepth, e);
}
......@@ -345,13 +349,15 @@ public class PdpConfigurationParser
try
{
maxPolicyRefDepth = bigMaxPolicyRefDepth == null ? -1 : org.ow2.authzforce.core.pdp.api.value.IntegerValue.intValueExact(bigMaxPolicyRefDepth);
} catch (final ArithmeticException e)
}
catch (final ArithmeticException e)
{
throw new IllegalArgumentException("Invalid maxPolicyRefDepth: " + bigMaxPolicyRefDepth, e);
}
return new PDPImpl(attributeFactory, functionRegistry, pdpJaxbConf.getAttributeProviders(), maxVarRefDepth, enableXPath, combiningAlgRegistry, pdpJaxbConf.getRootPolicyProvider(),
pdpJaxbConf.getRefPolicyProvider(), maxPolicyRefDepth, pdpJaxbConf.getRequestFilter(), pdpJaxbConf.isStrictAttributeIssuerMatch(), decisionResultFilter, jaxbDecisionCache, envProps);
pdpJaxbConf.getRefPolicyProvider(), maxPolicyRefDepth, pdpJaxbConf.getRequestFilter(), pdpJaxbConf.isStrictAttributeIssuerMatch(), pdpJaxbConf.isPdpStdTimeEnvOverrides(),
decisionResultFilter, jaxbDecisionCache, envProps);
}
private static boolean isXpathBased(final Function<?> function)
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment