...
 
Commits (76)
......@@ -2,6 +2,66 @@
All notable changes to this project are documented in this file following the [Keep a CHANGELOG](http://keepachangelog.com) conventions. This project adheres to [Semantic Versioning](http://semver.org).
## 15.3.0
### Changed
- Parent project version: 7.5.0 -> changed dependency versions:
- authzforce-ce-xmlns-model: 7.5.0
- authzforce-ce-xacml-model: 7.5.0
- authzforce-ce-pdp-ext-model: 7.5.0
- Guava: 24.1.1-jre
- Replaced dependency mailapi with javax.mail-api v1.6.0
## 15.2.0
### Added
- ExpressionFactory interface: new method `getVariableExpression(variableId)`
- Apply class: added check for VariableReference used as first arg (sub-function) to higher-order function: variables (resolved at evaluation time) are not allowed, only constant
- TimeValue class: more Javadoc giving info about underlying XmlGregorianCalendar's year/month/day fields (set to DatatypeConstants.FIELD_UNDEFINED)
- GenericAttributeProviderBasedAttributeDesignatorExpression class: moved from authzforce-ce-core-pdp-engine project
## 15.1.0
### Changed
- Parent project (authzforce-ce-parent) version: 7.3.0, which changes dependency versions:
- authzforce-ce-xmlns-model: 7.3.0
- authzforce-ce-xacml-model: 7.3.0
- authzforce-ce-pdp-ext-model: 7.3.0
- Spring: 4.3.14.RELEASE
- Saxon-HE: 9.8.0-12
### Added
- Interfaces: PolicyEvaluator has new method getEnclosedPolicies(), used to detect duplicate PolicyId/Version
## 15.0.0
### Added
- Classes from authzforce-ce-core-pdp-engine, which may be useful to PEP implementations (PEPs should not depend on authzforce-ce-core-pdp-engine except if using an embedded PDP):
- `StandardAttributeValueFactories` (for mapping standard Java types or XACML datatypes into AuthzForce data model)
- `ImmutableAttributeValueFactoryRegistry` (required by the previous one)
- `BasePdpExtensionRegistry` (required by the previous one).
- `AttributeValueFactoryRegistry#getCompatibleFactory(Class)` method: used in unit tests.
- `AttributeValueFactoryRegistry#newAttributeBag(Collection, AttributeSource)`: creates an AttributeBag with a custom AttributeSource
- `PrimitiveDatatype#getInstanceClass()` method: gives the Java class associated to the (XACML) datatype, in AuthzForce data model.
- `XacmlJaxbParsingUtils#parseXacmlJaxbResult(Result)` method: to convert XACML/XML Result into AuthzForce data model's DecisionResult
### Changed
- For more flexibility, genericity and code simplification (better adaptation to non-XML formats such as JSON in particular), AuthzForce data model classes (e.g. `AttributeValue`) no longer extend XACML-schema-derived (JAXB-annotated) classes (e.g. `AttributeValueType`).
- `DecisionCache.Factory#getInstance(...)`: new AttributeValueFactoryRegistry parameter for the decision cache system to be able to create/restore AttributeValues from deserialized data stored or produced by external - possibly remote - systems (e.g. cache storage database).
- `CloseableDesignatedAttributeProvider` (resp. `BaseDesignatedAttributeProvider`) class renamed to `CloseableNamedAttributeProvider` (resp. `BaseNamedAttributeProvider`) to reuse the official term "named attribute" from §7.3 of XACML 3.0 spec.
### Fixed
- IllegalArgumentException for empty XACML anyURI, i.e. `<AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI" />`. XACML 3.0 spec's anyURI datatype (annex B.3) is defined by W3C XML schema specification (2004)'s anyURI datatype, itself defined by RFC 2396 and 2732 at IETF. An empty URI is valid according to RFC 2396 (section 4.2), therefore an empty AttributeValue with anyURI datatype must be parsed successfully into an empty value. (Fix to `SimpleValue` class.)
- AuthzForce `IntegerValue`s wrongly considered not equal if created from different Java integer types (for the same value), e.g. `1` (Integer) and `1L` (Long). (Fix to equals() implementations in `GenericInteger` subclasses.)
## 14.0.0
### Changed
- Interface method DecisionCache.Factory#getInstance(...): added EnvironmentProperties parameter to allow passing environment properties to DecisionCache implementations
- Interface method AttributeProvider#get(...): replaced parameter type BagDatatype with Datatype to simplify AttributeProviders' code
- Interface method EvaluationContext#getNamedAttributeValue(...): replaced parameter type BagDatatype with Datatype to simplify AttributeProviders' code
- Class VersionPatterns renamed to PolicyVersionPatterns because depends on PolicyVersionPattern (with no 's') class
## 13.0.0
### Changed
- Updated authzforce-ce-parent version: 7.1.0 -> 7.2.0:
......
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/2804cd619dde437a883da48ad5c283bc)](https://www.codacy.com/app/coder103/authzforce-ce-core-pdp-api?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=authzforce/core-pdp-api&amp;utm_campaign=Badge_Grade)
[![Javadocs](http://javadoc.io/badge/org.ow2.authzforce/authzforce-ce-core-pdp-api.svg)](http://javadoc.io/doc/org.ow2.authzforce/authzforce-ce-core-pdp-api)
# AuthZForce Core PDP API
High-level API for using AuthZForce PDP engine and implementing PDP engine extensions: attribute datatypes, functions, policy/rule combining algorithms, attribute providers, policy providers, XACML Request/Result filters, etc.
# AuthzForce Core PDP API
High-level API for using AuthzForce PDP engine and implementing PDP engine extensions: attribute datatypes, functions, policy/rule combining algorithms, attribute providers, policy providers, XACML Request/Result filters, etc.
## Support
If you are experiencing any problem with this project, you may report it on the [OW2 Issue Tracker](https://jira.ow2.org/browse/AUTHZFORCE/).
If you are experiencing any problem with this project, you may report it on the github Issues.
Please include as much information as possible; the more we know, the better the chance of a quicker resolution:
* Software version
......@@ -14,5 +15,16 @@ Please include as much information as possible; the more we know, the better the
* Log output can be useful too; sometimes enabling DEBUG logging can help;
* Your code & configuration files are often useful.
If you wish to contact the developers for other reasons, use [Authzforce contact mailing list](http://scr.im/azteam).
If you wish to contact the developers for other reasons, use [AuthzForce contact mailing list](http://scr.im/azteam).
## Known issues
### Class not found: com.sun.mail.XXX
If you need to use XACML RFC822Name datatype, you need to add an actual implementation of JavaMail API as dependency (must match the version of `javax.mail-api` dependency in the [POM](pom.xml) ), such as:
```xml
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.0</version>
</dependency>
```
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.1.xsd">
<suppress>
<notes><![CDATA[
file name: mailapi-1.5.6.jar,
false positive reported: https://github.com/jeremylong/DependencyCheck/issues/912
]]></notes>
<cpe>cpe:/a:mail_project:mail</cpe>
<cpe>cpe:/a:sun:javamail</cpe>
<cve>CVE-2007-6059</cve>
<cve>CVE-2015-9097</cve>
</suppress>
<!--See issue #2 on Github-->
<cve>CVE-2018-8088</cve>
</suppress>
</suppressions>
\ No newline at end of file
......@@ -3,10 +3,10 @@
<parent>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-parent</artifactId>
<version>7.2.0</version>
<version>7.5.0</version>
</parent>
<artifactId>authzforce-ce-core-pdp-api</artifactId>
<version>12.2.1-SNAPSHOT</version>
<version>15.3.1-SNAPSHOT</version>
<name>${project.groupId}:${project.artifactId}</name>
<description>AuthzForce - Core PDP API</description>
<url>${project.url}</url>
......@@ -32,9 +32,9 @@
</dependency>
<dependency>
<!-- For validation of XACML RFC822Name (email address) -->
<groupId>com.sun.mail</groupId>
<artifactId>mailapi</artifactId>
<version>1.5.6</version>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<!-- For extra collections (Multiset class used for XACML Bags, Table class, ImmutableSet/ImmutableMap/ImmutableList), and validating IP addresses (XACML IPAdress datatype), Domain names (XACML
......@@ -87,7 +87,6 @@
</executions>
</plugin>
<plugin>
<!-- Consider combining with Red Hat Victims and OSS Index. More info on Victims vs. Dependency-check: https://bugzilla.redhat.com/show_bug.cgi?id=1388712 -->
<groupId>org.owasp</groupId>
<artifactId>dependency-check-maven</artifactId>
<configuration>
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......@@ -127,7 +127,9 @@ public final class AttributeFqns
{
if (toString == null)
{
toString = "[category='" + category + "', issuer=" + getIssuer() + ", id='" + id + "']";
final Optional<String> optIssuer = getIssuer();
toString = "[category='" + category + "', issuer=" + (optIssuer.isPresent() ? "'" + optIssuer.get() + "'" : null) + ", id='" + id + "']";
}
return toString;
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......@@ -19,7 +19,7 @@ package org.ow2.authzforce.core.pdp.api;
import org.ow2.authzforce.core.pdp.api.value.AttributeBag;
import org.ow2.authzforce.core.pdp.api.value.AttributeValue;
import org.ow2.authzforce.core.pdp.api.value.BagDatatype;
import org.ow2.authzforce.core.pdp.api.value.Datatype;
/**
* Attribute provider used to resolve {@link oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType}s in a specific way (e.g. from a specific attribute source)
......@@ -35,12 +35,14 @@ public interface AttributeProvider
* the global identifier (Category,Issuer,AttributeId) of the attribute to find
* @param context
* the request context
* @param returnDatatype
* attribute value bag datatype
* @return the result of retrieving the attribute, which will be a bag of values of type defined by {@code attributeDatatype}; empty bag iff no value found and no error occurred.
* @param datatype
* attribute datatype
* @return the result of retrieving the attribute, which will be a bag of values of type defined by {@code returnDatatype}; empty bag iff no value found and no error occurred.
* @throws UnsupportedOperationException
* {@code attributeFQN} or {@code returnDatatype} are not supported (the PDP engine should try another attribute provider if any)
* @throws IndeterminateEvaluationException
* if any error finding the attribute value(s)
* {@code attributeFQN} or {@code returnDatatype} are supported but some error occurred while trying to resolve the attribute value(s)
*/
<AV extends AttributeValue> AttributeBag<AV> get(AttributeFqn attributeFQN, BagDatatype<AV> returnDatatype, EvaluationContext context) throws IndeterminateEvaluationException;
<AV extends AttributeValue> AttributeBag<AV> get(AttributeFqn attributeFQN, Datatype<AV> datatype, EvaluationContext context) throws IndeterminateEvaluationException;
}
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......@@ -19,19 +19,21 @@ package org.ow2.authzforce.core.pdp.api;
import java.util.Objects;
import com.google.common.collect.ImmutableList;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Status;
/**
* This class provides a skeletal implementation of the {@link DecisionResult} interface to minimize the effort required to implement this interface. Note that this class only overrides/implements
* {@link #equals(Object)}, {@link #hashCode()} and {@link #getStatus()}.
*/
public abstract class AbstractDecisionResult implements DecisionResult
public abstract class BaseDecisionResult implements DecisionResult
{
private final Status status;
private transient volatile int hashCode = 0;
protected AbstractDecisionResult(final Status status)
protected BaseDecisionResult(final Status status)
{
this.status = status;
}
......@@ -80,12 +82,9 @@ public abstract class AbstractDecisionResult implements DecisionResult
return false;
}
final PepActions otherPepActions = other.getPepActions();
final PepActions thisPepActions = other.getPepActions();
if (thisPepActions == null)
{
return otherPepActions == null || otherPepActions.isEmpty();
}
final ImmutableList<PepAction> otherPepActions = other.getPepActions();
assert otherPepActions != null;
final ImmutableList<PepAction> thisPepActions = this.getPepActions();
return thisPepActions.equals(otherPepActions);
}
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......@@ -18,15 +18,11 @@
package org.ow2.authzforce.core.pdp.api;
/**
* This is a convenience class to help implement {@link CloseableDesignatedAttributeProvider}.
* This is a convenience class to help implement {@link CloseableNamedAttributeProvider}.
*/
public abstract class BaseDesignatedAttributeProvider implements CloseableDesignatedAttributeProvider
public abstract class BaseNamedAttributeProvider implements CloseableNamedAttributeProvider
{
protected static final UnsupportedOperationException UNSUPPORTED_ATTRIBUTE_CATEGORY_EXCEPTION = new UnsupportedOperationException("Unsupported attribute category");
protected static final UnsupportedOperationException UNSUPPORTED_ATTRIBUTE_ISSUER_EXCEPTION = new UnsupportedOperationException("Unsupported attribute issuer");
protected static final UnsupportedOperationException UNSUPPORTED_ATTRIBUTE_ID_EXCEPTION = new UnsupportedOperationException("Unsupported attribute ID");
protected static final UnsupportedOperationException UNSUPPORTED_ATTRIBUTE_DATATYPE_EXCEPTION = new UnsupportedOperationException("Unsupported attribute datetype");
private static final IllegalArgumentException UNDEF_INSTANCE_ID = new IllegalArgumentException("Undefined Attribute Provider's instance ID");
private final String instanceID;
......@@ -43,7 +39,7 @@ public abstract class BaseDesignatedAttributeProvider implements CloseableDesign
* @throws IllegalArgumentException
* if instanceId null
*/
protected BaseDesignatedAttributeProvider(final String instanceID) throws IllegalArgumentException
protected BaseNamedAttributeProvider(final String instanceID) throws IllegalArgumentException
{
if (instanceID == null)
{
......@@ -79,12 +75,12 @@ public abstract class BaseDesignatedAttributeProvider implements CloseableDesign
return true;
}
if (!(obj instanceof BaseDesignatedAttributeProvider))
if (!(obj instanceof BaseNamedAttributeProvider))
{
return false;
}
final BaseDesignatedAttributeProvider other = (BaseDesignatedAttributeProvider) obj;
final BaseNamedAttributeProvider other = (BaseNamedAttributeProvider) obj;
return this.instanceID.equals(other.instanceID);
}
......
/**
* Copyright 2012-2018 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.api;
import java.util.Map;
import java.util.Set;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
/**
* This is a base implementation of <code>PdpExtensionRegistry</code>. This should be used as basis to implement (in a final class) an immutable PDP extension registry of a specific type. If you need
* a generic immutable PDP extension registry, see {
*
* @param <T>
* type of extension in this registry
* @version $Id: $
*/
public abstract class BasePdpExtensionRegistry<T extends PdpExtension> implements PdpExtensionRegistry<T>
{
private final Class<? super T> extClass;
private final Map<String, T> extensionsById;
private final transient String toString;
/**
* Instantiates immutable registry from a map.
*
* @param extensionClass
* extension class
* @param extensionsById
* extensions input map; the registry actually creates and uses an immutable copy of this map internally to avoid external modifications on the internal map
*/
protected BasePdpExtensionRegistry(final Class<? super T> extensionClass, final Map<String, ? extends T> extensionsById)
{
assert extensionClass != null && extensionsById != null;
this.extClass = extensionClass;
this.extensionsById = HashCollections.newImmutableMap(extensionsById);
this.toString = this + "( extensionClass= " + extClass.getCanonicalName() + " )";
}
/** {@inheritDoc} */
@Override
public final T getExtension(final String identity)
{
return extensionsById.get(identity);
}
/** {@inheritDoc} */
@Override
public final Set<T> getExtensions()
{
return HashCollections.newImmutableSet(extensionsById.values());
}
private static final class ExtensionToIdFunction<E extends PdpExtension> implements Function<E, String>
{
@Override
public String apply(final E extension) throws NullPointerException
{
assert extension != null;
return Preconditions.checkNotNull(extension, "One of the input extensions is invalid (null)").getId();
}
}
private static final Function<? extends PdpExtension, String> EXTENSION_TO_ID_FUNCTION = new ExtensionToIdFunction<>();
@SuppressWarnings("unchecked")
private static <E extends PdpExtension> Map<String, E> newImmutableMap(final Set<E> extensions)
{
return Maps.uniqueIndex(extensions, (Function<E, String>) EXTENSION_TO_ID_FUNCTION);
}
/**
* Instantiates immutable registry from a set of extensions
*
* @param extensionClass
* extension class (required not null)
* @param extensions
* extensions (required not null)
*/
protected BasePdpExtensionRegistry(final Class<? super T> extensionClass, final Set<? extends T> extensions)
{
this(extensionClass, newImmutableMap(extensions));
}
@Override
public String toString()
{
return toString;
}
}
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......@@ -20,24 +20,24 @@ package org.ow2.authzforce.core.pdp.api;
import java.io.Closeable;
import java.util.Set;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
import org.ow2.authzforce.core.pdp.api.value.AttributeValueFactoryRegistry;
import org.ow2.authzforce.xmlns.pdp.ext.AbstractAttributeProvider;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
/**
* {@link DesignatedAttributeProvider} that extends {@link Closeable} because it may may use resources external to the JVM such as a cache, a disk, a connection to a remote server, etc. for retrieving
* the attribute values. Therefore, these resources must be released by calling {@link #close()} when it is no longer needed.
* {@link NamedAttributeProvider} that extends {@link Closeable} because it may may use resources external to the JVM such as a cache, a disk, a connection to a remote server, etc. for retrieving the
* attribute values. Therefore, these resources must be released by calling {@link #close()} when it is no longer needed.
* <p>
* PDP extensions of this type (to support new ways of providing attributes) must implement the {@link FactoryBuilder} class.
*/
public interface CloseableDesignatedAttributeProvider extends DesignatedAttributeProvider, Closeable
public interface CloseableNamedAttributeProvider extends NamedAttributeProvider, Closeable
{
/**
* Intermediate dependency-aware {@link CloseableDesignatedAttributeProvider} factory that can create instances of Attribute Providers from a XML/JAXB configuration, and also provides the
* dependencies (required attributes) (based on this configuration), that any such instance (created by it) will need. Providing the dependencies helps to optimize the {@code depAttrProvider}
* argument to {@link #getInstance(AttributeValueFactoryRegistry, AttributeProvider)} and therefore optimize the created provider's job of finding its own supported attribute values based on other
* attributes in the evaluation context.
* Intermediate dependency-aware {@link CloseableNamedAttributeProvider} factory that can create instances of Attribute Providers from a XML/JAXB configuration, and also provides the dependencies
* (required attributes) (based on this configuration), that any such instance (created by it) will need. Providing the dependencies helps to optimize the {@code depAttrProvider} argument to
* {@link #getInstance(AttributeValueFactoryRegistry, AttributeProvider)} and therefore optimize the created provider's job of finding its own supported attribute values based on other attributes
* in the evaluation context.
*
*/
interface DependencyAwareFactory
......@@ -56,14 +56,14 @@ public interface CloseableDesignatedAttributeProvider extends DesignatedAttribut
/**
* Create Attribute Provider instance
*
* @param attributeValueFactoryRegistry
* registry of Attribute value factories for the Provider to be able to create attribute values
* @param depAttrProvider
* @param attributeValueFactories
* AttributeValue factories for the Provider to be able to create AttributeValues
* @param dependencyAttributeProvider
* Existing Attribute Provider supplying the possibly required attributes that new Providers instantiated here will depend on
*
* @return attribute value in internal model
*/
CloseableDesignatedAttributeProvider getInstance(AttributeValueFactoryRegistry attributeValueFactoryRegistry, AttributeProvider depAttrProvider);
CloseableNamedAttributeProvider getInstance(AttributeValueFactoryRegistry attributeValueFactories, AttributeProvider dependencyAttributeProvider);
}
/**
......@@ -84,13 +84,15 @@ public interface CloseableDesignatedAttributeProvider extends DesignatedAttribut
/**
* Creates an attribute-dependency-aware AttributeProvider factory by inferring attribute dependencies (required attributes) from {@code conf}.
*
* @param conf
* @param configuration
* configuration, that may define what attributes are required (dependency attributes)
* @param environmentProperties
* global PDP configuration environment properties
* @return a factory aware of dependencies (required attributes) possibly inferred from input {@code conf}
* @throws IllegalArgumentException
* invalid {code configuration}
*/
public abstract DependencyAwareFactory getInstance(CONF_T conf, EnvironmentProperties environmentProperties);
public abstract DependencyAwareFactory getInstance(CONF_T configuration, EnvironmentProperties environmentProperties) throws IllegalArgumentException;
}
}
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......@@ -21,6 +21,7 @@ import java.io.Closeable;
import java.util.List;
import java.util.Map;
import org.ow2.authzforce.core.pdp.api.value.AttributeValueFactoryRegistry;
import org.ow2.authzforce.xmlns.pdp.ext.AbstractDecisionCache;
/**
......@@ -48,9 +49,14 @@ public interface DecisionCache extends Closeable
*
* @param conf
* extension parameters
* @param envProps
* environment properties
* @param attributeValueFactories
* AttributeValue factories for the decision cache system to be able to create/restore AttributeValues from deserialized data stored or produced by external - possibly remote -
* systems (e.g. cache storage database). Remember that such attribute values can be present in decision results, typically in AttributeAssignments of Obligations/Advice.
* @return instance of extension
*/
public abstract DecisionCache getInstance(CONF_T conf);
public abstract DecisionCache getInstance(CONF_T conf, AttributeValueFactoryRegistry attributeValueFactories, EnvironmentProperties envProps);
}
/**
......@@ -70,7 +76,8 @@ public interface DecisionCache extends Closeable
* @param evalCtx
* evaluation context that can be used to save context about any partial/preliminary evaluation done by this decision cache when there is no cached result for {code request} yet. In
* this case, the PDP will call back {@link DecisionCache#put(DecisionRequest, DecisionResult, EvaluationContext)} with this same {@code evalCtx} after the PDP has computed the new
* result. Therefore, this allows the decision cache to reuse some context during an evaluation, and also to do some evaluation itself.
* result. Therefore, this allows the decision cache to reuse some context during an evaluation, and also to do some evaluation itself. This argument may be null if not required, i.e.
* {@link #isEvaluationContextRequired()} returns false.
* @return the corresponding decision result from cache; null if there is no such result in cache.
*/
DecisionResult get(DecisionRequest request, EvaluationContext evalCtx);
......@@ -96,7 +103,7 @@ public interface DecisionCache extends Closeable
* the corresponding decision result
* @param evalCtx
* evaluation context that can be used to retrieve context about any partial/preliminary evaluation done by this decision cache when {@link #get(DecisionRequest, EvaluationContext)} was
* called in the same request context.
* called in the same request context. This argument may be null if not required, i.e. {@link #isEvaluationContextRequired()} returns false.
*/
void put(DecisionRequest request, DecisionResult result, EvaluationContext evalCtx);
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......@@ -25,18 +25,18 @@ import org.ow2.authzforce.core.pdp.api.policy.PrimaryPolicyMetadata;
import com.google.common.collect.ImmutableList;
/**
* Result of evaluation of {@link Decidable} (Policy, Rule...) with Obligations/Advice elements packaged together in a {@link PepActions} field.
* Result of evaluation of {@link Decidable} (Policy, Rule...) with PEP actions (Obligations/Advice).
*
*/
public interface DecisionResult extends ExtendedDecision
{
/**
* Get PEP actions (Obligations/Advices), may be null if the decision is neither Permit or Deny
* Get PEP actions (Obligations/Advices), may be empty - but <b>not null</b> - if the decision is neither Permit or Deny
*
* @return PEP actions
*/
ImmutablePepActions getPepActions();
ImmutableList<PepAction> getPepActions();
/**
* Get the list of the "applicable" policy elements (XACML Policy/PolicySet elements) that contributed to this decision.
......@@ -52,7 +52,7 @@ public interface DecisionResult extends ExtendedDecision
* More formally: {@code isApplicable(policy) iff evaluate(policy) != NotApplicable && (policy.parent == null || isApplicable(policy.parent)) }
*
* @return identifiers of policies found applicable for the decision request. Must be null if and only if the decision is NotApplicable. In particular, if the decision is different from
* NotApplicable but no applicable policy is returned (e.g. it was not requested to return such a list in the request), the returned list must be an empty list, not null.
* NotApplicable but no applicable policy is returned (e.g. it was not requested to return such a list in the request), the returned list must be an empty list, <b>not null</b>.
*/
ImmutableList<PrimaryPolicyMetadata> getApplicablePolicies();
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......@@ -19,21 +19,21 @@ package org.ow2.authzforce.core.pdp.api;
import java.util.Optional;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.DecisionType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Status;
import org.ow2.authzforce.core.pdp.api.policy.PrimaryPolicyMetadata;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.DecisionType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Status;
/**
* Factory for creating immutable {@link DecisionResult}s
*
*/
public final class DecisionResults
{
private static final class ImmutableNotApplicableResult extends AbstractDecisionResult
private static final class ImmutableNotApplicableResult extends BaseDecisionResult
{
private transient volatile String toString = null;
......@@ -49,21 +49,21 @@ public final class DecisionResults
{
if (toString == null)
{
toString = "Result( decision= NotApplicable, status=" + getStatus() + " )";
toString = "Result[ decision= NotApplicable, status=" + getStatus() + " ]";
}
return toString;
}
@Override
public ImmutablePepActions getPepActions()
public ImmutableList<PepAction> getPepActions()
{
return null;
return ImmutableList.of();
}
@Override
public ImmutableList<PrimaryPolicyMetadata> getApplicablePolicies()
{
return null;
return ImmutableList.of();
}
@Override
......@@ -85,7 +85,7 @@ public final class DecisionResults
}
}
private static abstract class ApplicableResult extends AbstractDecisionResult
private static abstract class ApplicableResult extends BaseDecisionResult
{
protected final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList;
......@@ -94,7 +94,7 @@ public final class DecisionResults
{
super(status);
this.applicablePolicyIdList = applicablePolicyIdList == null ? ImmutableList.<PrimaryPolicyMetadata> of() : applicablePolicyIdList;
this.applicablePolicyIdList = applicablePolicyIdList == null ? ImmutableList.<PrimaryPolicyMetadata>of() : applicablePolicyIdList;
}
@Override
......@@ -148,9 +148,9 @@ public final class DecisionResults
}
@Override
public ImmutablePepActions getPepActions()
public ImmutableList<PepAction> getPepActions()
{
return null;
return ImmutableList.of();
}
@Override
......@@ -179,20 +179,20 @@ public final class DecisionResults
private final DecisionType decision;
private final ImmutablePepActions pepActions;
private final ImmutableList<PepAction> pepActions;
private transient volatile String toString = null;
/*
* For permit/deny result
*/
private ImmutableDPResult(final DecisionType decision, final Status status, final ImmutablePepActions pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
private ImmutableDPResult(final DecisionType decision, final Status status, final ImmutableList<PepAction> pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
{
super(status, applicablePolicyIdList);
assert decision == DecisionType.PERMIT || decision == DecisionType.DENY;
this.decision = decision;
this.pepActions = pepActions == null ? ImmutablePepActions.EMPTY : pepActions;
this.pepActions = pepActions == null ? ImmutableList.of() : pepActions;
}
/** {@inheritDoc} */
......@@ -219,7 +219,7 @@ public final class DecisionResults
}
@Override
public ImmutablePepActions getPepActions()
public ImmutableList<PepAction> getPepActions()
{
return this.pepActions;
}
......@@ -259,7 +259,7 @@ public final class DecisionResults
* list of identifiers of applicable policies that contributed to this result. If not null, the created instance uses only an immutable copy of this list.
* @return permit result, more particularly {@link #SIMPLE_PERMIT} iff {@code status == null && pepActions == null}.
*/
public static DecisionResult getPermit(final Status status, final ImmutablePepActions pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
public static DecisionResult getPermit(final Status status, final ImmutableList<PepAction> pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
{
if (status == null && (pepActions == null || pepActions.isEmpty()) && (applicablePolicyIdList == null || applicablePolicyIdList.isEmpty()))
{
......@@ -282,7 +282,7 @@ public final class DecisionResults
* list of identifiers of applicable policies that contributed to this result. If not null, the created instance uses only an immutable copy of this list.
* @return deny result, more particularly {@link #SIMPLE_DENY} iff {@code status == null && pepActions == null}.
*/
public static DecisionResult getDeny(final Status status, final ImmutablePepActions pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
public static DecisionResult getDeny(final Status status, final ImmutableList<PepAction> pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
{
if (status == null && (pepActions == null || pepActions.isEmpty()) && (applicablePolicyIdList == null || applicablePolicyIdList.isEmpty()))
{
......@@ -331,7 +331,7 @@ public final class DecisionResults
* if {@code cause == null}
*/
public static DecisionResult newIndeterminate(final DecisionType extendedIndeterminate, final IndeterminateEvaluationException cause,
final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList) throws IllegalArgumentException
final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList) throws IllegalArgumentException
{
Preconditions.checkNotNull(cause, "No cause defined for Indeterminate result");
return new ImmutableIndeterminateResult(extendedIndeterminate == null ? DecisionType.INDETERMINATE : extendedIndeterminate, cause, applicablePolicyIdList);
......@@ -351,8 +351,8 @@ public final class DecisionResults
* if
* {@code extendedDecision == null || extendedDecision.getDecision() ==null || (extendedDecision.getDecision() == INDETERMINATE && !extendedDecision.getCauseForIndeterminate().isPresent())}
*/
public static DecisionResult getInstance(final ExtendedDecision extendedDecision, final ImmutablePepActions pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
throws IllegalArgumentException
public static DecisionResult getInstance(final ExtendedDecision extendedDecision, final ImmutableList<PepAction> pepActions, final ImmutableList<PrimaryPolicyMetadata> applicablePolicyIdList)
throws IllegalArgumentException
{
Preconditions.checkNotNull(extendedDecision, "Undefined extendedDecision");
final DecisionType decision = extendedDecision.getDecision();
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......@@ -21,18 +21,17 @@ import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Optional;
import net.sf.saxon.s9api.XdmNode;
import org.ow2.authzforce.core.pdp.api.expression.AttributeDesignatorExpression;
import org.ow2.authzforce.core.pdp.api.expression.AttributeSelectorExpression;
import org.ow2.authzforce.core.pdp.api.value.AttributeBag;
import org.ow2.authzforce.core.pdp.api.value.AttributeValue;
import org.ow2.authzforce.core.pdp.api.value.Bag;
import org.ow2.authzforce.core.pdp.api.value.BagDatatype;
import org.ow2.authzforce.core.pdp.api.value.Datatype;
import org.ow2.authzforce.core.pdp.api.value.Value;
import org.ow2.authzforce.core.pdp.api.value.XPathValue;
import net.sf.saxon.s9api.XdmNode;
/**
* Manages context for the policy evaluation of a given authorization decision request. Typically, an instance of this is instantiated whenever the PDP gets a request and needs to perform an
* evaluation to a authorization decision. Such a context is used and possibly updated all along the evaluation of the request.
......@@ -60,7 +59,7 @@ public interface EvaluationContext
<AV extends AttributeValue> void namedAttributeValueProduced(AttributeFqn attributeFQN, AttributeBag<AV> value);
/**
* To be called when {@link EvaluationContext#getNamedAttributeValue(AttributeFqn, BagDatatype)} is called
* To be called when {@link EvaluationContext#getNamedAttributeValue(AttributeFqn, Datatype)} is called
*
* @param attributeFQN
* attribute GUID (global ID = Category,Issuer,AttributeId)
......@@ -95,24 +94,24 @@ public interface EvaluationContext
/**
* Returns the value of a named attribute available in the request context. Used to evaluate {@link AttributeDesignatorExpression}, ContextSelectorId of {@link AttributeSelectorExpression}, or to
* get values of attributes on which {@link DesignatedAttributeProvider}s depends to resolve their own attributes (e.g. some module may need attribute X, such as a subject ID, as input to resolve
* get values of attributes on which {@link NamedAttributeProvider}s depends to resolve their own attributes (e.g. some module may need attribute X, such as a subject ID, as input to resolve
* attribute Y from an external source, such as subject role from a user database).
*
* @param attributeFQN
* attribute GUID (global ID = Category,Issuer,AttributeId)
* @param returnDatatype
* attribute value bag datatype
* @param datatype
* attribute value datatype
*
* @return attribute value(s), null iff attribute unknown (not set) in this context, empty if attribute known in this context but no value
* @throws IndeterminateEvaluationException
* if error occurred trying to determine the attribute value(s) in context. This is different from finding without error that the attribute is not in the context (and/or no value),
* e.g. if there is a result but type is different from {@code attributeDatatype}.
*/
<AV extends AttributeValue> AttributeBag<AV> getNamedAttributeValue(AttributeFqn attributeFQN, BagDatatype<AV> returnDatatype) throws IndeterminateEvaluationException;
<AV extends AttributeValue> AttributeBag<AV> getNamedAttributeValue(AttributeFqn attributeFQN, Datatype<AV> datatype) throws IndeterminateEvaluationException;
/**
* Get immutable iterator over the context attributes. DO NOT ever use this method to retrieve one or more specific attributes, in which case you must use
* {@link #getNamedAttributeValue(AttributeFqn, BagDatatype)} instead. This is only for iterating over all the attributes, e.g. for debugging/auditing.
* {@link #getNamedAttributeValue(AttributeFqn, Datatype)} instead. This is only for iterating over all the attributes, e.g. for debugging/auditing.
*
* @return context attributes iterator (implementations must guarantee that the iterator is immutable, i.e. does not allow changing the internal context)
*/
......@@ -121,7 +120,7 @@ public interface EvaluationContext
/**
* Put Attribute values in the context, only if the attribute is not already known to this context. Indeed, an attribute value cannot be overridden once it is set in the context to comply with
* 7.3.5 Attribute retrieval: "Regardless of any dynamic modifications of the request context during policy evaluation, the PDP SHALL behave as if each bag of attribute values is fully populated
* in the context before it is first tested, and is thereafter immutable during evaluation." Therefore, {@link #getNamedAttributeValue(AttributeFqn, BagDatatype)} should be called always before
* in the context before it is first tested, and is thereafter immutable during evaluation." Therefore, {@link #getNamedAttributeValue(AttributeFqn, Datatype)} should be called always before
* calling this, for the same {@code attributeFQN}
*
* @param attributeFQN
......@@ -265,12 +264,11 @@ public interface EvaluationContext
<L extends Listener> L putListener(Class<L> listenerType, L listener);
/**
* Returns the listener the specified class is mapped to, or null if no entry for this class is present. This will only return a value that was bound to this specific class, not a value that may
* have been bound to a subtype.
* Returns the listener the specified class is mapped to. This will only return a value that was bound to this specific class, not a value that may have been bound to a subtype.
*
* @param listenerType
* listener type, used as key to retrieve the listener registered with this type with {@link #putListener(Class, Listener)}
* @return the listener associated with this class
* @return the listener associated with this class, or null if no entry for this class is present
*/
<L extends Listener> L getListener(Class<L> listenerType);
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
*
* 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.api;
import java.util.Objects;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Advice;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Obligation;
import com.google.common.collect.ImmutableList;
/**
* Static immutable {@link PepActions}, e.g. empty actions, or static methods returning immutable {@link PepActions} or
*
*/
public final class ImmutablePepActions implements PepActions
{
// always non-null fields, immutable
private final ImmutableList<Obligation> obligationList;
private final ImmutableList<Advice> adviceList;
private transient volatile int hashCode;
private transient volatile String toString;
private ImmutablePepActions()
{
this.obligationList = ImmutableList.of();
this.adviceList = ImmutableList.of();
this.hashCode = 1;
this.toString = "( obligation_list= null, advice_list= null )";
}
/**
* Instantiates PEP action set from obligations/advice. Not used if there is neither any obligation and nor any advice, in which case the {@link ImmutablePepActions#EMPTY} must be used.
*
* @param obligationList
* obligation list; null if no obligation
* @param adviceList
* advice list; null if no advice
*/
public ImmutablePepActions(final ImmutableList<Obligation> obligationList, final ImmutableList<Advice> adviceList)
{
assert obligationList != null && !obligationList.isEmpty() || adviceList != null && !adviceList.isEmpty();
this.obligationList = obligationList == null ? ImmutableList.<Obligation> of() : obligationList;
this.adviceList = adviceList == null ? ImmutableList.<Advice> of() : adviceList;
this.hashCode = 0;
this.toString = null;
}
/**
* {@inheritDoc}
*
* Get the internal obligation list
*/
@Override
public ImmutableList<Obligation> getObligatory()
{
return obligationList;
}
/**
* {@inheritDoc}
*
* Get the internal advice list
*/
@Override
public ImmutableList<Advice> getAdvisory()
{
return adviceList;
}
/** {@inheritDoc} */
@Override
public int hashCode()
{
if (hashCode == 0)
{
hashCode = Objects.hash(this.obligationList, this.adviceList);
}
return hashCode;
}
/** {@inheritDoc} */
@Override
public boolean equals(final Object obj)
{
if (this == obj)
{
return true;
}
if (!(obj instanceof PepActions))
{
return false;
}
final PepActions other = (PepActions) obj;
return this.obligationList.equals(other.getObligatory()) && this.adviceList.equals(other.getAdvisory());
}
/** {@inheritDoc} */
@Override
public String toString()
{
if (toString == null)
{
toString = "[obligation_list=" + obligationList + ", advice_list=" + adviceList + "]";
}
return toString;
}
/**
* Get immutable {@link PepActions} from obligations/advice elements.
*
* @param obligationList
* obligations; null if no obligation
* @param adviceList
* advice elements; null if no advice
* @return immutable instance; {@link ImmutablePepActions#EMPTY} is returned if {@code obligationList == null || obligationList.isEmpty()) && (adviceList == null || adviceList.isEmpty()}
*/
public static ImmutablePepActions getInstance(final ImmutableList<Obligation> obligationList, final ImmutableList<Advice> adviceList)
{
if ((obligationList == null || obligationList.isEmpty()) && (adviceList == null || adviceList.isEmpty()))
{
return EMPTY;
}
return new ImmutablePepActions(obligationList, adviceList);
}
/**
* Get immutable view (copy) of other PEP actions.
*
* @param pepActions
* obligations; null if no obligation
*
* @return immutable instance; {@link ImmutablePepActions#EMPTY} is returned if {@code pepActions == null || (obligationList == null || obligationList.isEmpty()) && (adviceList == null ||
adviceList.isEmpty())}
*/
public static ImmutablePepActions getInstance(final PepActions pepActions)
{
if (pepActions == null)
{
return EMPTY;
}
return getInstance(pepActions.getObligatory(), pepActions.getAdvisory());
}
/**
* Empty PEP actions (no obligation/advice)
*/
public static final ImmutablePepActions EMPTY = new ImmutablePepActions();
@Override
public boolean isEmpty()
{
return this.obligationList.isEmpty() && this.adviceList.isEmpty();
}
}
\ No newline at end of file
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*
* This file is part of AuthzForce CE.
*
......
/**
* Copyright 2012-2018 Thales Services SAS.
* Copyright 2012-2018 THALES.
*