Commit c42844d2 authored by cdanger's avatar cdanger

Merge branch 'release/14.0.0'

parents 0037b128 0558c865
......@@ -3,9 +3,27 @@ All notable changes to this project are documented in this file following the [K
## Issue references
- Issues reported on [GitHub](https://github.com/authzforce/core/issues) are referenced in the form of `[GH-N]`, where N is the issue number.
- Issues reported on [OW2's JIRA](https://jira.ow2.org/browse/AUTHZFORCE/) are referenced in the form of `[JIRA-N]`, where N is the issue number.
- Issues reported on [OW2's GitLab](https://gitlab.ow2.org/authzforce/core/issues) are referenced in the form of `[GL-N]`, where N is the issue number.
## 14.0.0
### Changed
- [GH-28]: simplified the PolicyProvider model, i.e. changed the following:
- **PDP configuration format** (XML Schema 'pdp.xsd') v7.0.0 (more info in [migration guide](MIGRATION.md) )
- Replaced 'refPolicyProvider' and 'rootPolicyProvider' XML elements with 'policyProvider' and 'rootPolicyRef'.
- StaticRootPolicyProvider and StaticRefPolicyProvider XML types replaced by one StaticPolicyProvider type.
- **PolicyProvider extension API** (interfaces):
- Upgraded core-pdp-api dependency version: 16.0.0 (more info in [core-pdp-api's changelog](https://github.com/authzforce/core-pdp-api/blob/develop/CHANGELOG.md#1600) ):
- Replaced CloseableRefPolicyProvider and BaseStaticRefPolicyProvider classes with CloseablePolicyProvider and BaseStaticPolicyProvider
- pdp-testutils module's dependency 'jackson-databind' upgraded to v2.9.10 (CVE fix)
### Fixed
- CVE-2019-14439
### Added
- Support for **Multiple Decision Profile when used with XACML/JSON Profile** (JSON input)
## 13.3.1
### Fixed
- CVE affecting Spring v4.3.18: upgraded dependencies to depend on
......@@ -55,7 +73,7 @@ properties and environment variables (enclosed between '${...}') with default va
- authzforce-ce-xacml-json-model: 2.0.0
### Fixed
- Fixed #13: changed pdp-testutils module's dependencies:
- [GH-13]: changed pdp-testutils module's dependencies:
- mongo-java-driver: 2.14.12 -> 3.5.0
- jongo: 1.3.0 -> 1.4.0
......
## Migration from v13.x to v14.x
- Make sure all your custom PolicyProviders implement the new PolicyProvider interfaces, i.e. BaseStaticPolicyProvider or, as fallback option, CloseableStaticPolicyProvider
- Modify the PDP configuration (XML):
- Merge 'rootPolicyProvider' and 'refPolicyprovider' into one 'policyProvider' using the new 'StaticPolicyProvider' type if you were using 'StaticRefPolicyprovider' or 'StaticRootPolicyProvider', else your new custom PolicyProvider types if you were using custom ones.
- Add 'rootPolicyRef' element with policyId of the root policy.
\ No newline at end of file
......@@ -41,16 +41,16 @@ AuthzForce Core may be used in the following ways:
* Optional **strict multivalued attribute parsing**: if enabled, multivalued attributes must be formed by grouping all `AttributeValue` elements in the same Attribute element (instead of duplicate Attribute elements); this does not fully comply with [XACML 3.0 Core specification of Multivalued attributes (§7.3.3)](http://docs.oasis-open.org/xacml/3.0/xacml-3.0-core-spec-os-en.html#_Toc325047176), but it usually performs better than the default mode since it simplifies the parsing of attribute values in the request.
* Optional **strict attribute Issuer matching**: if enabled, `AttributeDesignators` without Issuer only match request Attributes without Issuer (and same AttributeId, Category...); this option is not fully compliant with XACML 3.0, §5.29, in the case that the Issuer is indeed not present on a AttributeDesignator; but it is the recommended option when all AttributeDesignators have an Issuer (the XACML 3.0 specification (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.*);
* Extensibility points:
* **Attribute Datatypes**: you may extend the PDP engine with custom XACML attribute datatypes;
* **Functions**: you may extend the PDP engine with custom XACML functions;
* **Combining Algorithms**: you may extend the PDP engine with custom XACML policy/rule combining algorithms;
* **Attribute Providers a.k.a. PIPs** (Policy Information Points): you may plug custom attribute providers into the PDP engine to allow it to retrieve attributes from other attribute sources (e.g. remote service) than the input XACML Request during evaluation;
* **Request Preprocessor**: you may customize the processing of XACML Requests before evaluation by the PDP core engine, e.g. used for supporting new XACML Request formats, and/or implementing [XACML v3.0 Multiple Decision Profile Version 1.0 - Repeated attribute categories](http://docs.oasis-open.org/xacml/3.0/multiple/v1.0/cs02/xacml-3.0-multiple-v1.0-cs02.html#_Toc388943334);
* **Result Postprocessor**: you may customize the processing of XACML Results after evaluation by the PDP engine, e.g. used for supporting new XACML Response formats, and/or implementing [XACML v3.0 Multiple Decision Profile Version 1.0 - Requests for a combined decision](http://docs.oasis-open.org/xacml/3.0/xacml-3.0-multiple-v1-spec-cd-03-en.html#_Toc260837890);
* **[Attribute Datatypes](https://github.com/authzforce/core/wiki/XACML-Data-Types)**: you may extend the PDP engine with custom XACML attribute datatypes;
* **[Functions](https://github.com/authzforce/core/wiki/XACML-Functions)**: you may extend the PDP engine with custom XACML functions;
* **[Combining Algorithms](https://github.com/authzforce/core/wiki/XACML-Combining-Algorithms)**: you may extend the PDP engine with custom XACML policy/rule combining algorithms;
* **[Attribute Providers a.k.a. PIPs](https://github.com/authzforce/core/wiki/Attribute-Providers)** (Policy Information Points): you may plug custom attribute providers into the PDP engine to allow it to retrieve attributes from other attribute sources (e.g. remote service) than the input XACML Request during evaluation;
* **[Request Preprocessor](https://github.com/authzforce/core/wiki/XACML-Request-Preprocessors)**: you may customize the processing of XACML Requests before evaluation by the PDP core engine, e.g. used for supporting new XACML Request formats, and/or implementing [XACML v3.0 Multiple Decision Profile Version 1.0 - Repeated attribute categories](http://docs.oasis-open.org/xacml/3.0/multiple/v1.0/cs02/xacml-3.0-multiple-v1.0-cs02.html#_Toc388943334);
* **[Result Postprocessor](https://github.com/authzforce/core/wiki/XACML-Result-Postprocessors)**: you may customize the processing of XACML Results after evaluation by the PDP engine, e.g. used for supporting new XACML Response formats, and/or implementing [XACML v3.0 Multiple Decision Profile Version 1.0 - Requests for a combined decision](http://docs.oasis-open.org/xacml/3.0/xacml-3.0-multiple-v1-spec-cd-03-en.html#_Toc260837890);
* **Root Policy Provider**: you may plug custom policy providers into the PDP engine to allow it to retrieve the root policy from specific sources (e.g. remote service);
* **Policy-by-reference Provider**: you may plug custom policy providers into the PDP engine to allow it to resolve `PolicyIdReference` or `PolicySetIdReference`;
* **[Policy-by-reference Provider](https://github.com/authzforce/core/wiki/Policy-Providers)**: you may plug custom policy providers into the PDP engine to allow it to resolve `PolicyIdReference` or `PolicySetIdReference`;
* **Decision Cache**: you may extend the PDP engine with a custom XACML decision cache, allowing the PDP to skip evaluation and retrieve XACML decisions from cache for recurring XACML Requests;
* Java extension mechanism to switch HashMap/HashSet implementations (e.g. to get different performance results).
* Java [extension mechanism to switch HashMap/HashSet implementations](https://github.com/authzforce/core/wiki/Hashed-Collections) (e.g. to get different performance results).
* PIP (Policy Information Point): AuthzForce provides XACML PIP features in the form of extensions called *Attribute Providers*. More information in the previous list of *Extensibility points*.
......@@ -131,7 +131,7 @@ Then instantiate a PDP engine configuration with method [PdpEngineConfiguration#
```xml
<?xml version="1.0" encoding="UTF-8"?>
<pdp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://authzforce.github.io/core/xmlns/pdp/6.0" version="6.0.0">
<pdp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://authzforce.github.io/core/xmlns/pdp/7.0" version="7.0.0">
<rootPolicyProvider id="rootPolicyProvider" xsi:type="StaticRootPolicyProvider" policyLocation="${PARENT_DIR}/policy.xml" />
</pdp>
```
......
......@@ -3,7 +3,7 @@
<parent>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core</artifactId>
<version>13.3.1</version>
<version>14.0.0</version>
<relativePath>..</relativePath>
</parent>
<artifactId>authzforce-ce-core-pdp-cli</artifactId>
......@@ -30,12 +30,12 @@
<dependency>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core-pdp-engine</artifactId>
<version>13.3.1</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core-pdp-io-xacml-json</artifactId>
<version>13.3.1</version>
<version>14.0.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
......@@ -46,7 +46,7 @@
<dependency>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core-pdp-testutils</artifactId>
<version>13.3.1</version>
<version>14.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
......
<?xml version="1.0" encoding="UTF-8"?>
<pdp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://authzforce.github.io/core/xmlns/pdp/6.0" version="6.0.0">
<rootPolicyProvider id="rootPolicyProvider" xsi:type="StaticRootPolicyProvider" policyLocation="${PARENT_DIR}/IIA001/Policy.xml" />
<ioProcChain>
<requestPreproc>urn:ow2:authzforce:feature:pdp:request-preproc:xacml-json:default-lax</requestPreproc>
<resultPostproc>urn:ow2:authzforce:feature:pdp:result-postproc:xacml-json:default</resultPostproc>
</ioProcChain>
<pdp
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://authzforce.github.io/core/xmlns/pdp/7.0"
version="7.0.0">
<policyProvider
id="rootPolicyProvider"
xsi:type="StaticPolicyProvider">
<policyLocation>${PARENT_DIR}/IIA001/Policy.xml</policyLocation>
</policyProvider>
<rootPolicyRef>urn:oasis:names:tc:xacml:2.0:conformance-test:IIA1:policy</rootPolicyRef>
<ioProcChain>
<requestPreproc>urn:ow2:authzforce:feature:pdp:request-preproc:xacml-json:default-lax</requestPreproc>
<resultPostproc>urn:ow2:authzforce:feature:pdp:result-postproc:xacml-json:default</resultPostproc>
</ioProcChain>
</pdp>
......@@ -3,7 +3,7 @@
<parent>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core</artifactId>
<version>13.3.1</version>
<version>14.0.0</version>
<relativePath>..</relativePath>
</parent>
<artifactId>authzforce-ce-core-pdp-engine</artifactId>
......
......@@ -42,7 +42,7 @@ import com.google.common.collect.ListMultimap;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
/**
* AttributeProvider that tries to resolve attributes in current request context first, else delegates to {@link DesignatedAttributeProvider}s.
* AttributeProvider that tries to resolve attributes in current request context first, else delegates to {@link NamedAttributeProvider}s.
*
* @version $Id: $
*/
......@@ -97,7 +97,8 @@ public class ModularAttributeProvider implements AttributeProvider
if (selectedAttributeSupport == null)
{
designatorModsByAttrId = attributeProviderModulesByAttributeId;
} else
}
else
{
final ListMultimap<AttributeFqn, NamedAttributeProvider> mutableModsByAttrIdMap = ArrayListMultimap.create(selectedAttributeSupport.size(), 1);
for (final AttributeDesignatorType requiredAttr : selectedAttributeSupport)
......@@ -206,7 +207,8 @@ public class ModularAttributeProvider implements AttributeProvider
LOGGER.debug("Values of attribute {}, type={} returned by attribute Provider module #{} (cached in context): {}", attributeFqn, datatype, attrProviders, result);
issuedToNonIssuedAttributeCopyMode.process(attributeFqn, result, context);
return result;
} catch (final IndeterminateEvaluationException e)
}
catch (final IndeterminateEvaluationException e)
{
/*
* This error does not necessarily matter, it depends on whether the attribute is required, i.e. MustBePresent=true for AttributeDesignator/Selector So we let
......@@ -248,7 +250,8 @@ public class ModularAttributeProvider implements AttributeProvider
*/
context.putNamedAttributeValueIfAbsent(attributeFqn, result);
return result;
} catch (final UnsupportedOperationException e)
}
catch (final UnsupportedOperationException e)
{
/*
* Should not happen, this is highly unexpected and should be considered a fatal error (it means the AttributeProvider does not respect its contract)
......
......@@ -32,8 +32,7 @@ import org.ow2.authzforce.core.pdp.api.JaxbBoundPdpExtension;
import org.ow2.authzforce.core.pdp.api.PdpExtension;
import org.ow2.authzforce.core.pdp.api.combining.CombiningAlg;
import org.ow2.authzforce.core.pdp.api.func.Function;
import org.ow2.authzforce.core.pdp.api.policy.CloseableRefPolicyProvider;
import org.ow2.authzforce.core.pdp.api.policy.RootPolicyProvider;
import org.ow2.authzforce.core.pdp.api.policy.CloseablePolicyProvider;
import org.ow2.authzforce.core.pdp.api.value.AttributeValueFactory;
import org.ow2.authzforce.xmlns.pdp.ext.AbstractAttributeProvider;
import org.ow2.authzforce.xmlns.pdp.ext.AbstractDecisionCache;
......@@ -97,7 +96,8 @@ public final class PdpExtensions
}
isValidExt = true;
} else
}
else
{
for (final Class<? extends PdpExtension> extClass : NON_JAXB_BOUND_EXTENSION_CLASSES)
{
......@@ -229,7 +229,7 @@ public final class PdpExtensions
* @throws java.lang.IllegalArgumentException
* if there is no extension of type {@link org.ow2.authzforce.core.pdp.api.policy.CloseableRefPolicyProvider.Factory} supporting {@code jaxbPdpExtensionClass}
*/
public static <REF_POLICY_PROVIDER_CONF extends AbstractPolicyProvider> CloseableRefPolicyProvider.Factory<REF_POLICY_PROVIDER_CONF> getRefPolicyProviderFactory(
public static <REF_POLICY_PROVIDER_CONF extends AbstractPolicyProvider> CloseablePolicyProvider.Factory<REF_POLICY_PROVIDER_CONF> getRefPolicyProviderFactory(
final Class<REF_POLICY_PROVIDER_CONF> jaxbConfClass) throws IllegalArgumentException
{
final JaxbBoundPdpExtension<REF_POLICY_PROVIDER_CONF> ext = (JaxbBoundPdpExtension<REF_POLICY_PROVIDER_CONF>) JAXB_BOUND_EXTENSIONS_BY_JAXB_CLASS.get(jaxbConfClass);
......@@ -238,43 +238,43 @@ public final class PdpExtensions
throw new IllegalArgumentException("No PDP extension found supporting JAXB (configuration) type: " + jaxbConfClass + ". Expected types: " + JAXB_BOUND_EXTENSIONS_BY_JAXB_CLASS.keySet());
}
if (!(ext instanceof CloseableRefPolicyProvider.Factory))
if (!(ext instanceof CloseablePolicyProvider.Factory))
{
throw new IllegalArgumentException(
"No PDP extension of type " + CloseableRefPolicyProvider.Factory.class + " (Reference-based Policy Provider factory) supporting JAXB/XML (configuration) type: " + jaxbConfClass);
"No PDP extension of type " + CloseablePolicyProvider.Factory.class + " (Reference-based Policy Provider factory) supporting JAXB/XML (configuration) type: " + jaxbConfClass);
}
return (CloseableRefPolicyProvider.Factory<REF_POLICY_PROVIDER_CONF>) ext;
return (CloseablePolicyProvider.Factory<REF_POLICY_PROVIDER_CONF>) ext;
}
/**
* Create RootPolicyProvider
* Create PolicyProvider
*
* @param jaxbConfClass
* XML-schema-derived type of policy provider configuration
*
* @return Root Policy Provider
* @return Policy Provider
* @throws java.lang.IllegalArgumentException
* if there is no extension of type {@link org.ow2.authzforce.core.pdp.api.policy.RootPolicyProvider.Factory} supporting {@code jaxbPdpExtensionClass} or invalid
* if there is no extension of type {@link org.ow2.authzforce.core.pdp.api.policy.CloseablePolicyProvider.Factory} supporting {@code jaxbPdpExtensionClass} or invalid
* {@code jaxbRootPolicyProviderConf}
*/
public static <ROOT_POLICY_PROVIDER_CONF extends AbstractPolicyProvider> RootPolicyProvider.Factory<ROOT_POLICY_PROVIDER_CONF> getRootPolicyProviderFactory(
final Class<ROOT_POLICY_PROVIDER_CONF> jaxbConfClass) throws IllegalArgumentException
public static <POLICY_PROVIDER_CONF extends AbstractPolicyProvider> CloseablePolicyProvider.Factory<POLICY_PROVIDER_CONF> getRootPolicyProviderFactory(
final Class<POLICY_PROVIDER_CONF> jaxbConfClass) throws IllegalArgumentException
{
final JaxbBoundPdpExtension<ROOT_POLICY_PROVIDER_CONF> ext = (JaxbBoundPdpExtension<ROOT_POLICY_PROVIDER_CONF>) JAXB_BOUND_EXTENSIONS_BY_JAXB_CLASS.get(jaxbConfClass);
final JaxbBoundPdpExtension<POLICY_PROVIDER_CONF> ext = (JaxbBoundPdpExtension<POLICY_PROVIDER_CONF>) JAXB_BOUND_EXTENSIONS_BY_JAXB_CLASS.get(jaxbConfClass);
if (ext == null)
{
throw new IllegalArgumentException("No PDP extension found supporting JAXB (configuration) type: " + jaxbConfClass + ". Expected types: " + JAXB_BOUND_EXTENSIONS_BY_JAXB_CLASS.keySet());
}
if (!(ext instanceof RootPolicyProvider.Factory))
if (!(ext instanceof CloseablePolicyProvider.Factory))
{
throw new IllegalArgumentException(
"No PDP extension of type " + RootPolicyProvider.Factory.class + " (Root Policy Provider factory) supporting JAXB/XML (configuration) type: " + jaxbConfClass);
"No PDP extension of type " + CloseablePolicyProvider.Factory.class + " (Policy Provider factory) supporting JAXB/XML (configuration) type: " + jaxbConfClass);
}
return (RootPolicyProvider.Factory<ROOT_POLICY_PROVIDER_CONF>) ext;
return (CloseablePolicyProvider.Factory<POLICY_PROVIDER_CONF>) ext;
}
/**
......
......@@ -56,12 +56,8 @@ public final class PepActionExpression
/**
* Constructor that takes all the data associated with an PEP action (obligation/advice) expression.
*
* @param pepActionFactory
* PEP action factory
* @param pepActionId
* the obligation's id
* @param appliesTo
* the type of decision to which the PEP action applies (ObligationExpression's FulfillOn / AdviceExpression's AppliesTo)
* @param isMandatory
* true iff the PEP action is mandatory (XACML Obligation, as opposed to Advice)
* @param jaxbAssignmentExps
......@@ -84,7 +80,8 @@ public final class PepActionExpression
if (jaxbAssignmentExps == null || jaxbAssignmentExps.isEmpty())
{
this.evaluatableAttributeAssignmentExpressions = Collections.emptyList();
} else
}
else
{
this.evaluatableAttributeAssignmentExpressions = new ArrayList<>(jaxbAssignmentExps.size());
for (final AttributeAssignmentExpression jaxbAttrAssignExp : jaxbAssignmentExps)
......@@ -93,7 +90,8 @@ public final class PepActionExpression
try
{
attrAssignExp = new AttributeAssignmentExpressionEvaluator(jaxbAttrAssignExp, xPathCompiler, expFactory);
} catch (final IllegalArgumentException e)
}
catch (final IllegalArgumentException e)
{
throw new IllegalArgumentException("Invalid " + toString + ": Invalid AttributeAssignmentExpression[@AttributeId=" + jaxbAttrAssignExp.getAttributeId() + "]", e);
}
......@@ -142,7 +140,8 @@ public final class PepActionExpression
{
attrAssignsFromExpr = attrAssignmentExpr.evaluate(context);
LOGGER.debug("{}/{} -> {}", this, attrAssignmentExpr, attrAssignsFromExpr);
} catch (final IndeterminateEvaluationException e)
}
catch (final IndeterminateEvaluationException e)
{
throw new IndeterminateEvaluationException(this + ": Error evaluating " + attrAssignmentExpr, e.getStatusCode(), e);
}
......
/**
* Copyright 2012-2019 THALES.
*
* This file is part of AuthzForce CE.
*
* 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 org.ow2.authzforce.core.pdp.impl.policy;
import java.util.Optional;
import org.ow2.authzforce.core.pdp.api.EnvironmentProperties;
import org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException;
import org.ow2.authzforce.core.pdp.api.XmlUtils.XmlnsFilteringParserFactory;
import org.ow2.authzforce.core.pdp.api.combining.CombiningAlgRegistry;
import org.ow2.authzforce.core.pdp.api.expression.ExpressionFactory;
import org.ow2.authzforce.core.pdp.api.policy.CloseableRefPolicyProvider;
import org.ow2.authzforce.core.pdp.api.policy.PolicyVersionPatterns;
import org.ow2.authzforce.core.pdp.api.policy.RootPolicyProvider;
import org.ow2.authzforce.core.pdp.api.policy.StaticRefPolicyProvider;
import org.ow2.authzforce.core.pdp.api.policy.StaticRootPolicyProvider;
import org.ow2.authzforce.core.pdp.api.policy.StaticTopLevelPolicyElementEvaluator;
import org.ow2.authzforce.core.pdp.api.policy.TopLevelPolicyElementType;
import org.ow2.authzforce.core.xmlns.pdp.StaticRefBasedRootPolicyProvider;
import com.google.common.base.Preconditions;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.IdReferenceType;
/**
* This Root policy provider retrieves the root policy from a {@link CloseableRefPolicyProvider} statically (once and for all), based on a XACML PolicySetIdReference.
*/
public class CoreRefBasedRootPolicyProvider implements StaticRootPolicyProvider
{
private static final String NULL_REF_POLICY_PROVIDER_CONF_MESSAGE = "Undefined refPolicyProvider. Root policy provider '" + CoreRefBasedRootPolicyProvider.class
+ "' requires a refPolicyProvider.";
private static final String ILLEGAL_XML_CONF_ARG_MESSAGE = "Undefined XML/JAXB configuration";
private static final String ILLEGAL_XACML_POLICY_REF_ARG_MESSAGE = "Undefined XACML PolicySetIdReference";
/**
* Provider factory
*
*/
public static class Factory extends RootPolicyProvider.Factory<StaticRefBasedRootPolicyProvider>
{
@Override
public Class<StaticRefBasedRootPolicyProvider> getJaxbClass() {
return StaticRefBasedRootPolicyProvider.class;
}
@Override
public RootPolicyProvider getInstance(final StaticRefBasedRootPolicyProvider jaxbConf, final XmlnsFilteringParserFactory xacmlParserFactory, final ExpressionFactory expressionFactory,
final CombiningAlgRegistry combiningAlgRegistry, final Optional<CloseableRefPolicyProvider> optionalRefPolicyProvider, final EnvironmentProperties environmentProperties) {
Preconditions.checkNotNull(jaxbConf, ILLEGAL_XML_CONF_ARG_MESSAGE);
Preconditions.checkArgument(optionalRefPolicyProvider.isPresent(), NULL_REF_POLICY_PROVIDER_CONF_MESSAGE);
return new CoreRefBasedRootPolicyProvider(jaxbConf.getPolicyRef(), optionalRefPolicyProvider.get());
}
}
private final StaticTopLevelPolicyElementEvaluator rootPolicy;
/**
* Creates instance with the root PolicySet retrieved from the refPolicyprovider once and for all
*
* @param policyRef
* Policy(Set)Id reference to be resolved by the {@code refPolicyProvider}
* @param refPolicyProvider
* (mandatory) Policy-by-reference Provider used by this Root Policy Provider to resolve policy references, if not null. If null, policy references are not supported.
* @throws IllegalArgumentException
* if {@code policyRef} is null/invalid, or if {@code refPolicyProvider == null || !(refPolicyProvider instanceof StaticRefPolicyProvider)} or no PolicySet matching {@code policyRef}
* could be resolved by the refPolicyProvider
*/
public CoreRefBasedRootPolicyProvider(final IdReferenceType policyRef, final CloseableRefPolicyProvider refPolicyProvider) throws IllegalArgumentException
{
Preconditions.checkNotNull(policyRef, ILLEGAL_XACML_POLICY_REF_ARG_MESSAGE);
Preconditions.checkNotNull(refPolicyProvider, NULL_REF_POLICY_PROVIDER_CONF_MESSAGE);
Preconditions.checkArgument(refPolicyProvider instanceof StaticRefPolicyProvider,
"RefPolicyProvider arg '" + refPolicyProvider + "' incompatible with " + CoreRefBasedRootPolicyProvider.class + ". Expected: instance of " + StaticRefPolicyProvider.class
+ ". Make sure the PDP extension of type " + CloseableRefPolicyProvider.Factory.class + " corresponding to the refPolicyProvider in PDP configuration can create instances of "
+ StaticRefPolicyProvider.class);
final String policySetId = policyRef.getValue();
final PolicyVersionPatterns PolicyVersionPatterns = new PolicyVersionPatterns(policyRef.getVersion(), policyRef.getEarliestVersion(), policyRef.getLatestVersion());
try
{
rootPolicy = ((StaticRefPolicyProvider) refPolicyProvider).get(TopLevelPolicyElementType.POLICY_SET, policySetId, Optional.of(PolicyVersionPatterns), null);
} catch (final IndeterminateEvaluationException e)
{
throw new IllegalArgumentException("Failed to find a root PolicySet with id = '" + policySetId + "', " + PolicyVersionPatterns, e);
}
if (rootPolicy == null)
{
throw new IllegalArgumentException("No policy found by the refPolicyProvider for the specified PolicySetIdReference: PolicySetId = '" + policySetId + "'; " + PolicyVersionPatterns);
}
}
@Override
public StaticTopLevelPolicyElementEvaluator getPolicy() {
return rootPolicy;
}
@Override
public void close() {
// Nothing to close - erase exception from the close() signature
}
}
......@@ -18,16 +18,21 @@
package org.ow2.authzforce.core.pdp.impl.policy;
import java.io.IOException;
import java.util.Optional;
import org.ow2.authzforce.core.pdp.api.DecisionResult;
import org.ow2.authzforce.core.pdp.api.DecisionResults;
import org.ow2.authzforce.core.pdp.api.EvaluationContext;
import org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException;
import org.ow2.authzforce.core.pdp.api.expression.ExpressionFactory;
import org.ow2.authzforce.core.pdp.api.policy.CloseablePolicyProvider;
import org.ow2.authzforce.core.pdp.api.policy.CloseableStaticPolicyProvider;
import org.ow2.authzforce.core.pdp.api.policy.PolicyEvaluator;
import org.ow2.authzforce.core.pdp.api.policy.RootPolicyProvider;
import org.ow2.authzforce.core.pdp.api.policy.StaticRootPolicyProvider;
import org.ow2.authzforce.core.pdp.api.policy.PolicyVersionPatterns;
import org.ow2.authzforce.core.pdp.api.policy.StaticPolicyProvider;
import org.ow2.authzforce.core.pdp.api.policy.StaticTopLevelPolicyElementEvaluator;
import org.ow2.authzforce.core.pdp.api.policy.TopLevelPolicyElementEvaluator;
import org.ow2.authzforce.core.pdp.api.policy.TopLevelPolicyElementType;
import org.ow2.authzforce.xacml.identifiers.XacmlStatusCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -40,6 +45,25 @@ import org.slf4j.LoggerFactory;
*/
public final class RootPolicyEvaluators
{
private static <PE extends TopLevelPolicyElementEvaluator> PE getRootPolicyEvaluator(final CloseablePolicyProvider<PE> rootPolicyProvider,
final Optional<TopLevelPolicyElementType> rootPolicyElementType, final String rootPolicyId, final Optional<PolicyVersionPatterns> optRootPolicyVersionPatterns,
final EvaluationContext context, final Logger logger) throws IllegalArgumentException, IndeterminateEvaluationException
{
if (rootPolicyElementType.isPresent())
{
return rootPolicyProvider.get(rootPolicyElementType.get(), rootPolicyId, optRootPolicyVersionPatterns, null, context);
}
final PE xacmlPolicyEvaluator = rootPolicyProvider.get(TopLevelPolicyElementType.POLICY, rootPolicyId, optRootPolicyVersionPatterns, null, context);
if (xacmlPolicyEvaluator != null)
{
logger.debug("Root policy element type undefined. Searched for XACML Policy first and found.");
return xacmlPolicyEvaluator;
}
logger.debug("Root policy element type undefined. Searched for XACML Policy, not found. Searching for XACML PolicySet...");
return rootPolicyProvider.get(TopLevelPolicyElementType.POLICY_SET, rootPolicyId, optRootPolicyVersionPatterns, null, context);
}
/**
* Root Policy Evaluator base implementation.
......@@ -51,7 +75,11 @@ public final class RootPolicyEvaluators
private static final Logger LOGGER = LoggerFactory.getLogger(Base.class);
private final RootPolicyProvider rootPolicyProvider;
private final CloseablePolicyProvider<?> rootPolicyProvider;
private final Optional<TopLevelPolicyElementType> rootPolicyElementType;
private final String rootPolicyId;
private final Optional<PolicyVersionPatterns> optRootPolicyVersionPatterns;
private transient final ExpressionFactory expressionFactory;
......@@ -66,29 +94,39 @@ public final class RootPolicyEvaluators
* @param xacmlExpressionFactory
* XACML expression factory
*
* @param rootPolicyProvider
* @param policyProvider
* Root Policy Provider - mandatory
* @param rootPolicyElementType
* type of root policy element (XACML Policy or XACML PolicySet)
* @param rootPolicyId
* root Policy(Set) ID
* @param optRootPolicyVersionPatterns
* root policy version patterns to be matched
*
* @throws java.lang.IllegalArgumentException
* If {@code expressionFactory == null || rootPolicyProvider == null}
*/
public Base(final ExpressionFactory xacmlExpressionFactory, final RootPolicyProvider rootPolicyProvider) throws IllegalArgumentException
public Base(final CloseablePolicyProvider<?> policyProvider, final Optional<TopLevelPolicyElementType> rootPolicyElementType, final String rootPolicyId,
final Optional<PolicyVersionPatterns> optRootPolicyVersionPatterns, final ExpressionFactory xacmlExpressionFactory) throws IllegalArgumentException
{
if (xacmlExpressionFactory == null)
{
throw NULL_EXPRESSIONFACTORY_ARGUMENT_EXCEPTION;
}
if (rootPolicyProvider == null)
if (policyProvider == null)
{
throw NULL_ROOTPOLICYPROVIDER_ARGUMENT_EXCEPTION;
}
this.rootPolicyProvider = policyProvider;
this.isRootPolicyProviderStatic = rootPolicyProvider instanceof StaticPolicyProvider;
this.rootPolicyElementType = rootPolicyElementType;
this.rootPolicyId = rootPolicyId;
this.optRootPolicyVersionPatterns = optRootPolicyVersionPatterns;
// Initialize ExpressionFactory
this.expressionFactory = xacmlExpressionFactory;
this.rootPolicyProvider = rootPolicyProvider;
this.isRootPolicyProviderStatic = rootPolicyProvider instanceof StaticRootPolicyProvider;
}
@Override
......@@ -101,10 +139,10 @@ public final class RootPolicyEvaluators
@Override
public DecisionResult findAndEvaluate(final EvaluationContext context)
{
final PolicyEvaluator policy;
final PolicyEvaluator policyEvaluator;
try
{
policy = rootPolicyProvider.getPolicy(context);
policyEvaluator = getRootPolicyEvaluator(this.rootPolicyProvider, this.rootPolicyElementType, this.rootPolicyId, this.optRootPolicyVersionPatterns, context, LOGGER);
}
catch (final IndeterminateEvaluationException e)
{
......@@ -117,12 +155,12 @@ public final class RootPolicyEvaluators
return DecisionResults.newIndeterminate(null, new IndeterminateEvaluationException(e.getMessage(), XacmlStatusCode.PROCESSING_ERROR.value()), null);
}
if (policy == null)
if (policyEvaluator == null)
{
return DecisionResults.SIMPLE_NOT_APPLICABLE;
}
return policy.evaluate(context, true);
return policyEvaluator.evaluate(context, true);
}
@Override
......@@ -138,18 +176,21 @@ public final class RootPolicyEvaluators
*
* @return static view of this policy evaluator; or null if none could be created because the internal root policy provider depends on the evaluation context to find the root policy (no static
* resolution is possible). If not null, this evaluator's policy provider responsible for finding the policy in {@link #findAndEvaluate(EvaluationContext)} is closed (calling
* {@link RootPolicyProvider#close()} and therefore not useable anymore. The resulting static view must be used instead.
* {@link CloseableStaticPolicyProvider#close()} and therefore not useable anymore. The resulting static view must be used instead.
* @throws IOException
* error closing the evaluator's policy provider responsible for finding the policy in {@link #findAndEvaluate(EvaluationContext)}
* @throws IndeterminateEvaluationException
* if error resolving the policy
*/
public RootPolicyEvaluator toStatic() throws IOException
public RootPolicyEvaluator toStatic() throws IOException, IndeterminateEvaluationException
{
/*
* If staticView not yet initialized and root policy provider is actually static (in which case staticView can be initialized)
*/
if (staticView == null && isRootPolicyProviderStatic)
{
staticView = new StaticView((StaticRootPolicyProvider) rootPolicyProvider, this.expressionFactory);
staticView = new StaticView((CloseableStaticPolicyProvider) rootPolicyProvider, this.rootPolicyElementType, this.rootPolicyId, this.optRootPolicyVersionPatterns,
this.expressionFactory);
}
return staticView;
......@@ -164,18 +205,26 @@ public final class RootPolicyEvaluators
*/
static class StaticView implements RootPolicyEvaluator
{
private static final Logger LOGGER = LoggerFactory.getLogger(StaticView.class);
private final StaticTopLevelPolicyElementEvaluator staticRootPolicyEvaluator;
private final ExpressionFactory expressionFactory;
private transient final FlattenedPolicyTree staticApplicablePolicies;
private StaticView(final StaticRootPolicyProvider staticProvider, final ExpressionFactory expressionFactoryForClosing) throws IOException
private StaticView(final CloseableStaticPolicyProvider staticPolicyProvider, final Optional<TopLevelPolicyElementType> rootPolicyElementType, final String rootPolicyId,
final Optional<PolicyVersionPatterns> optRootPolicyVersionPatterns, final ExpressionFactory expressionFactoryForClosing) throws IOException, IndeterminateEvaluationException
{
assert staticProvider != null && expressionFactoryForClosing != null;
assert staticPolicyProvider != null && expressionFactoryForClosing != null;
this.expressionFactory = expressionFactoryForClosing;
this.staticRootPolicyEvaluator = staticProvider.getPolicy();
this.staticRootPolicyEvaluator = getRootPolicyEvaluator(staticPolicyProvider, rootPolicyElementType, rootPolicyId, optRootPolicyVersionPatterns, null, LOGGER);
if (this.staticRootPolicyEvaluator == null)
{
throw new IllegalArgumentException("No such " + (rootPolicyElementType.isPresent() ? rootPolicyElementType.get() : "Policy(Set)") + " found: ID = '" + rootPolicyId + "'"
+ (optRootPolicyVersionPatterns.isPresent() ? ", version pattern = " + optRootPolicyVersionPatterns.get() : ""));
}
this.staticApplicablePolicies = new FlattenedPolicyTree(staticRootPolicyEvaluator.getPrimaryPolicyMetadata(), staticRootPolicyEvaluator.getPolicyRefsMetadata());
staticProvider.close();
staticPolicyProvider.close();
}