Commit 8b027e1c authored by cdanger's avatar cdanger

Merge branch 'release/13.0.0'

parents 6075e6e2 aa2830b3
......@@ -7,6 +7,16 @@ All notable changes to this project are documented in this file following the [K
- 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.
## 13.0.0
### Changed
- authzforce-ce-core-pdp-api version: 15.0.0. [More info](https://github.com/authzforce/core-pdp-api/blob/develop/CHANGELOG.md#1500).
### Fixed
- pdp-testutils module depends on jongo version which depends on jackson-databind version < 2.9.5 affected by CVE-2018-7489. Fix: upgrade to 2.9.5.
- NPE in `CoreRootPolicyProvider#getInstance(...)` with null `environmentProperties` arg
- `BasePdpEngine#evaluate(IndividualDecisionRequest)` not using enabled decision cache
## 12.0.0
### Changed
- Dependency authzforce-ce-core-pdp-api: version 13.0.0 -> 14.0.0; changes APIs for PDP AttributeProvider and DecisionCache extensions:
......
......@@ -78,7 +78,7 @@ Java (JRE) 8 or later.
## Usage
### Getting started
#### CLI
Get the latest executable jar from Maven Central: groupId/artifactId = `org.ow2.authzforce`/`authzforce-ce-core-pdp-cli` and make sure you are allowed to run it (it is a fully executable JAR), e.g. with command:
Get the [latest executable jar from Maven Central](http://central.maven.org/maven2/org/ow2/authzforce/authzforce-ce-core-pdp-cli/) with groupId/artifactId = `org.ow2.authzforce`/`authzforce-ce-core-pdp-cli` and make sure you are allowed to run it (it is a fully executable JAR), e.g. with command:
```
$ chmod a+x authzforce-ce-core-pdp-cli-10.0.0.jar
......
......@@ -3,7 +3,7 @@
<parent>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core</artifactId>
<version>12.0.0</version>
<version>13.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>12.0.0</version>
<version>13.0.0</version>
</dependency>
<dependency>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core-pdp-io-xacml-json</artifactId>
<version>12.0.0</version>
<version>13.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>12.0.0</version>
<version>13.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
......
......@@ -3,7 +3,7 @@
<parent>
<groupId>org.ow2.authzforce</groupId>
<artifactId>authzforce-ce-core</artifactId>
<version>12.0.0</version>
<version>13.0.0</version>
<relativePath>..</relativePath>
</parent>
<artifactId>authzforce-ce-core-pdp-engine</artifactId>
......
/**
* 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.impl;
import java.util.Map;
import java.util.Set;
import org.ow2.authzforce.core.pdp.api.HashCollections;
import org.ow2.authzforce.core.pdp.api.PdpExtension;
import org.ow2.authzforce.core.pdp.api.PdpExtensionRegistry;
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;
}
}
......@@ -23,20 +23,20 @@ import java.util.Collections;
import java.util.List;
import java.util.Set;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
import org.ow2.authzforce.core.pdp.api.AttributeFqn;
import org.ow2.authzforce.core.pdp.api.AttributeFqns;
import org.ow2.authzforce.core.pdp.api.AttributeProvider;
import org.ow2.authzforce.core.pdp.api.CloseableDesignatedAttributeProvider;
import org.ow2.authzforce.core.pdp.api.DesignatedAttributeProvider;
import org.ow2.authzforce.core.pdp.api.CloseableNamedAttributeProvider;
import org.ow2.authzforce.core.pdp.api.HashCollections;
import org.ow2.authzforce.core.pdp.api.NamedAttributeProvider;
import org.ow2.authzforce.core.pdp.api.value.AttributeValueFactoryRegistry;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ListMultimap;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
/**
* Closeable AttributeProvider
* <p>
......@@ -51,9 +51,9 @@ public final class CloseableAttributeProvider extends ModularAttributeProvider i
private static final class ModuleAdapter
{
private final CloseableDesignatedAttributeProvider module;
private final CloseableNamedAttributeProvider module;
private ModuleAdapter(final CloseableDesignatedAttributeProvider module) throws IOException
private ModuleAdapter(final CloseableNamedAttributeProvider module) throws IOException
{
final Set<AttributeDesignatorType> providedAttributes = module.getProvidedAttributes();
if (providedAttributes == null || providedAttributes.isEmpty())
......@@ -81,7 +81,7 @@ public final class CloseableAttributeProvider extends ModularAttributeProvider i
return module.toString();
}
private DesignatedAttributeProvider getAdaptedModule()
private NamedAttributeProvider getAdaptedModule()
{
return this.module;
}
......@@ -99,8 +99,7 @@ public final class CloseableAttributeProvider extends ModularAttributeProvider i
try
{
mod.close();
}
catch (final IOException e)
} catch (final IOException e)
{
latestEx = e;
}
......@@ -115,8 +114,8 @@ public final class CloseableAttributeProvider extends ModularAttributeProvider i
// not-null
private final Set<ModuleAdapter> moduleClosers;
private CloseableAttributeProvider(final ImmutableListMultimap<AttributeFqn, DesignatedAttributeProvider> modulesByAttributeId, final Set<ModuleAdapter> moduleClosers,
final boolean strictAttributeIssuerMatch)
private CloseableAttributeProvider(final ImmutableListMultimap<AttributeFqn, NamedAttributeProvider> modulesByAttributeId, final Set<ModuleAdapter> moduleClosers,
final boolean strictAttributeIssuerMatch)
{
super(modulesByAttributeId, null, strictAttributeIssuerMatch);
assert moduleClosers != null;
......@@ -124,7 +123,7 @@ public final class CloseableAttributeProvider extends ModularAttributeProvider i
}
private static final CloseableAttributeProvider EVALUATION_CONTEXT_ONLY_SCOPED_CLOSEABLE_ATTRIBUTE_PROVIDER = new CloseableAttributeProvider(ImmutableListMultimap.of(),
Collections.<ModuleAdapter> emptySet(), true);
Collections.<ModuleAdapter>emptySet(), true);
/**
* Instantiates attribute Provider that tries to find attribute values in evaluation context, then, if not there, query the {@code module} providing the requested attribute ID, if any.
......@@ -144,18 +143,18 @@ public final class CloseableAttributeProvider extends ModularAttributeProvider i
* @throws java.io.IOException
* error closing the Attribute Providers created from {@code attributeProviderFactories}, when a {@link IllegalArgumentException} is raised
*/
public static CloseableAttributeProvider getInstance(final List<CloseableDesignatedAttributeProvider.DependencyAwareFactory> attributeProviderFactories,
final AttributeValueFactoryRegistry attributeFactory, final boolean strictAttributeIssuerMatch) throws IOException
public static CloseableAttributeProvider getInstance(final List<CloseableNamedAttributeProvider.DependencyAwareFactory> attributeProviderFactories,
final AttributeValueFactoryRegistry attributeFactory, final boolean strictAttributeIssuerMatch) throws IOException
{
if (attributeProviderFactories == null || attributeProviderFactories.isEmpty())
{
return EVALUATION_CONTEXT_ONLY_SCOPED_CLOSEABLE_ATTRIBUTE_PROVIDER;
}
final ListMultimap<AttributeFqn, DesignatedAttributeProvider> modulesByAttributeId = ArrayListMultimap.create();
final ListMultimap<AttributeFqn, NamedAttributeProvider> modulesByAttributeId = ArrayListMultimap.create();
final int moduleCount = attributeProviderFactories.size();
final Set<ModuleAdapter> mutableModuleCloserSet = HashCollections.newUpdatableSet(moduleCount);
for (final CloseableDesignatedAttributeProvider.DependencyAwareFactory attProviderFactory : attributeProviderFactories)
for (final CloseableNamedAttributeProvider.DependencyAwareFactory attProviderFactory : attributeProviderFactories)
{
try
{
......@@ -169,10 +168,9 @@ public final class CloseableAttributeProvider extends ModularAttributeProvider i
if (requiredAttrs == null)
{
depAttrProvider = ModularAttributeProvider.EVALUATION_CONTEXT_ONLY_SCOPED_ATTRIBUTE_PROVIDER;
}
else
} else
{
final ImmutableListMultimap<AttributeFqn, DesignatedAttributeProvider> immutableCopyOfAttrProviderModsByAttrId = ImmutableListMultimap.copyOf(modulesByAttributeId);
final ImmutableListMultimap<AttributeFqn, NamedAttributeProvider> immutableCopyOfAttrProviderModsByAttrId = ImmutableListMultimap.copyOf(modulesByAttributeId);
depAttrProvider = new ModularAttributeProvider(immutableCopyOfAttrProviderModsByAttrId, requiredAttrs, strictAttributeIssuerMatch);
}
......@@ -190,8 +188,7 @@ public final class CloseableAttributeProvider extends ModularAttributeProvider i
*/
modulesByAttributeId.put(attrGUID, moduleAdapter.getAdaptedModule());
}
}
catch (final IllegalArgumentException e)
} catch (final IllegalArgumentException e)
{
close(mutableModuleCloserSet);
throw e;
......
......@@ -22,6 +22,7 @@ package org.ow2.authzforce.core.pdp.impl;
import java.util.Set;
import org.ow2.authzforce.core.pdp.api.BasePdpExtensionRegistry;
import org.ow2.authzforce.core.pdp.api.PdpExtension;
import com.google.common.base.Preconditions;
......
......@@ -23,9 +23,9 @@ import java.util.Set;
import org.ow2.authzforce.core.pdp.api.AttributeFqn;
import org.ow2.authzforce.core.pdp.api.AttributeFqns;
import org.ow2.authzforce.core.pdp.api.AttributeProvider;
import org.ow2.authzforce.core.pdp.api.DesignatedAttributeProvider;
import org.ow2.authzforce.core.pdp.api.EvaluationContext;
import org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException;
import org.ow2.authzforce.core.pdp.api.NamedAttributeProvider;
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.Bags;
......@@ -50,61 +50,47 @@ public class ModularAttributeProvider implements AttributeProvider
{
private static final IndeterminateEvaluationException INDETERMINATE_EXCEPTION_NO_VALUE_FROM_ATTRIBUTE_PROVIDERS = new IndeterminateEvaluationException(
"No value found by any attribute provider module", XacmlStatusCode.PROCESSING_ERROR.value());
"No value found by any attribute provider module", XacmlStatusCode.PROCESSING_ERROR.value());
private interface IssuedToNonIssuedAttributeCopyMode
{
void process(AttributeFqn attributeFqn, AttributeBag<?> result, EvaluationContext context);
}
private static final IssuedToNonIssuedAttributeCopyMode ISSUED_TO_NON_ISSUED_ATTRIBUTE_COPY_ENABLED_MODE = new IssuedToNonIssuedAttributeCopyMode()
{
private static final Logger LOGGER = LoggerFactory.getLogger(ModularAttributeProvider.class);
@Override
public void process(final AttributeFqn attributeFqn, final AttributeBag<?> result, final EvaluationContext context)
private static final IssuedToNonIssuedAttributeCopyMode ISSUED_TO_NON_ISSUED_ATTRIBUTE_COPY_ENABLED_MODE = (attributeFqn, result, context) -> {
if (!attributeFqn.getIssuer().isPresent())
{
if (!attributeFqn.getIssuer().isPresent())
{
// Attribute already without Issuer -> nothing to copy
return;
}
/*
* Attribute with Issuer -> make Issuer-less copy and put same result in context for match by Issuer-less AttributeDesignator
*/
final AttributeFqn issuerLessAttributeFqn = AttributeFqns.newInstance(attributeFqn.getCategory(), Optional.empty(), attributeFqn.getId());
/*
* Cache the attribute value(s) for the issuer-less attribute in context in case there is a matching Issuer-less AttributeDesignator to evaluate
*/
context.putNamedAttributeValueIfAbsent(issuerLessAttributeFqn, result);
LOGGER.debug("strictAttributeIssuerMatch=false -> Cached values of attribute {}, type={}, derived, by removing Issuer, from attribute {} provided by AttributeProvider module: values= {}",
attributeFqn, result.getElementDatatype(), attributeFqn, result);
// Attribute already without Issuer -> nothing to copy
return;
}
/*
* Attribute with Issuer -> make Issuer-less copy and put same result in context for match by Issuer-less AttributeDesignator
*/
final AttributeFqn issuerLessAttributeFqn = AttributeFqns.newInstance(attributeFqn.getCategory(), Optional.empty(), attributeFqn.getId());
/*
* Cache the attribute value(s) for the issuer-less attribute in context in case there is a matching Issuer-less AttributeDesignator to evaluate
*/
context.putNamedAttributeValueIfAbsent(issuerLessAttributeFqn, result);
LOGGER.debug("strictAttributeIssuerMatch=false -> Cached values of attribute {}, type={}, derived, by removing Issuer, from attribute {} provided by AttributeProvider module: values= {}",
attributeFqn, result.getElementDatatype(), attributeFqn, result);
};
private static final IssuedToNonIssuedAttributeCopyMode ISSUED_TO_NON_ISSUED_ATTRIBUTE_COPY_DISABLED_MODE = new IssuedToNonIssuedAttributeCopyMode()
{
@Override
public void process(final AttributeFqn attributeFqn, final AttributeBag<?> result, final EvaluationContext context)
{
// do not copy the result to any Issuer-less attribute
}
private static final IssuedToNonIssuedAttributeCopyMode ISSUED_TO_NON_ISSUED_ATTRIBUTE_COPY_DISABLED_MODE = (attributeFqn, result, context) -> {
// do not copy the result to any Issuer-less attribute
};
private static final Logger LOGGER = LoggerFactory.getLogger(ModularAttributeProvider.class);
/*
* AttributeDesignator Provider modules by supported/provided attribute ID (global ID: category, issuer, AttributeId)
*/
private final ImmutableListMultimap<AttributeFqn, DesignatedAttributeProvider> designatorModsByAttrId;
private final ImmutableListMultimap<AttributeFqn, NamedAttributeProvider> designatorModsByAttrId;
private final IssuedToNonIssuedAttributeCopyMode issuedToNonIssuedAttributeCopyMode;
protected ModularAttributeProvider(final ImmutableListMultimap<AttributeFqn, DesignatedAttributeProvider> attributeProviderModulesByAttributeId,
final Set<AttributeDesignatorType> selectedAttributeSupport, final boolean strictAttributeIssuerMatch)
protected ModularAttributeProvider(final ImmutableListMultimap<AttributeFqn, NamedAttributeProvider> attributeProviderModulesByAttributeId,
final Set<AttributeDesignatorType> selectedAttributeSupport, final boolean strictAttributeIssuerMatch)
{
assert attributeProviderModulesByAttributeId != null;
......@@ -113,11 +99,11 @@ public class ModularAttributeProvider implements AttributeProvider
designatorModsByAttrId = attributeProviderModulesByAttributeId;
} else
{
final ListMultimap<AttributeFqn, DesignatedAttributeProvider> mutableModsByAttrIdMap = ArrayListMultimap.create(selectedAttributeSupport.size(), 1);
final ListMultimap<AttributeFqn, NamedAttributeProvider> mutableModsByAttrIdMap = ArrayListMultimap.create(selectedAttributeSupport.size(), 1);
for (final AttributeDesignatorType requiredAttr : selectedAttributeSupport)
{
final AttributeFqn requiredAttrGUID = AttributeFqns.newInstance(requiredAttr);
final ImmutableList<DesignatedAttributeProvider> requiredAttrProviderMods = attributeProviderModulesByAttributeId.get(requiredAttrGUID);
final ImmutableList<NamedAttributeProvider> requiredAttrProviderMods = attributeProviderModulesByAttributeId.get(requiredAttrGUID);
/*
* According to doc, a non-null empty list is returned if no mappings
*/
......@@ -154,8 +140,8 @@ public class ModularAttributeProvider implements AttributeProvider
* @return modular attribute provider instance; {@link #EVALUATION_CONTEXT_ONLY_SCOPED_ATTRIBUTE_PROVIDER} iff
* {@code attributeProviderModulesByAttributeId == null || attributeProviderModulesByAttributeId.isEmpty()},
*/
public static ModularAttributeProvider getInstance(final ImmutableListMultimap<AttributeFqn, DesignatedAttributeProvider> attributeProviderModulesByAttributeId,
final Set<AttributeDesignatorType> selectedAttributeSupport, final boolean strictAttributeIssuerMatch)
public static ModularAttributeProvider getInstance(final ImmutableListMultimap<AttributeFqn, NamedAttributeProvider> attributeProviderModulesByAttributeId,
final Set<AttributeDesignatorType> selectedAttributeSupport, final boolean strictAttributeIssuerMatch)
{
if (attributeProviderModulesByAttributeId == null || attributeProviderModulesByAttributeId.isEmpty())
{
......@@ -180,7 +166,7 @@ public class ModularAttributeProvider implements AttributeProvider
// else attribute not found in context, ask the Provider modules, if any
LOGGER.debug("Requesting attribute {} from Provider modules (by provided attribute ID): {}", attributeFqn, designatorModsByAttrId);
final ImmutableList<DesignatedAttributeProvider> attrProviders = designatorModsByAttrId.get(attributeFqn);
final ImmutableList<NamedAttributeProvider> attrProviders = designatorModsByAttrId.get(attributeFqn);
/*
* According to doc, a non-null empty list is returned if no mappings
*/
......@@ -189,14 +175,14 @@ public class ModularAttributeProvider implements AttributeProvider
{
LOGGER.debug("No value found for required attribute {}, type={} in evaluation context and not supported by any Attribute Provider module", attributeFqn, datatype);
throw new IndeterminateEvaluationException("Not in context and no Attribute Provider module supporting requested attribute: " + attributeFqn,
XacmlStatusCode.MISSING_ATTRIBUTE.value());
XacmlStatusCode.MISSING_ATTRIBUTE.value());
}
AttributeBag<AV> result = null;
/*
* Try all modules supporting this attribute until value found
*/
for (final DesignatedAttributeProvider attrProvider : attrProviders)
for (final NamedAttributeProvider attrProvider : attrProviders)
{
result = attrProvider.get(attributeFqn, datatype, context);
if (result != null && !result.isEmpty())
......@@ -207,6 +193,9 @@ public class ModularAttributeProvider implements AttributeProvider
if (result == null)
{
/*
* If no attribute provider can provide the attribute, it is as if it was a request attribute with no value, therefore implicitly setting AttributeSource to REQUEST.
*/
result = Bags.emptyAttributeBag(datatype, INDETERMINATE_EXCEPTION_NO_VALUE_FROM_ATTRIBUTE_PROVIDERS);
}
......@@ -259,13 +248,13 @@ public class ModularAttributeProvider implements AttributeProvider
*/
context.putNamedAttributeValueIfAbsent(attributeFqn, result);
return result;
} catch (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)
*/
throw new RuntimeException("Inconsistent AttributeProvider: throwing UnsupportedOperationException for an attribute (name=" + attributeFqn + ", type=" + datatype
+ ") that should be supported according to the provider's contract (getProvidedAttributes() result) ", e);
+ ") that should be supported according to the provider's contract (getProvidedAttributes() result) ", e);
}
}
......
......@@ -23,7 +23,7 @@ import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
import org.ow2.authzforce.core.pdp.api.CloseableDesignatedAttributeProvider;
import org.ow2.authzforce.core.pdp.api.CloseableNamedAttributeProvider;
import org.ow2.authzforce.core.pdp.api.DecisionCache;
import org.ow2.authzforce.core.pdp.api.DecisionRequestPreprocessor;
import org.ow2.authzforce.core.pdp.api.DecisionResultPostprocessor;
......@@ -61,7 +61,7 @@ public final class PdpExtensions
* Types of zero-conf (non-JAXB-bound) extension
*/
private static final Set<Class<? extends PdpExtension>> NON_JAXB_BOUND_EXTENSION_CLASSES = HashCollections
.newImmutableSet(Arrays.asList(AttributeValueFactory.class, Function.class, CombiningAlg.class, DecisionRequestPreprocessor.Factory.class, DecisionResultPostprocessor.Factory.class));
.newImmutableSet(Arrays.asList(AttributeValueFactory.class, Function.class, CombiningAlg.class, DecisionRequestPreprocessor.Factory.class, DecisionResultPostprocessor.Factory.class));
/*
* For each type of zero-conf (non-JAXB-bound) extension, have a map (extension ID -> extension instance), so that the extension ID is scoped to the extension type among the ones listed in
......@@ -93,12 +93,11 @@ public final class PdpExtensions
if (duplicate != null)
{
throw new IllegalArgumentException("Extension " + jaxbBoundExt + " (" + jaxbBoundExt.getClass() + ") is conflicting with " + duplicate + "(" + duplicate.getClass()
+ ") for the same XML/JAXB configuration class: " + jaxbBoundExt.getJaxbClass());
+ ") for the same XML/JAXB configuration class: " + jaxbBoundExt.getJaxbClass());
}
isValidExt = true;
}
else
} else
{
for (final Class<? extends PdpExtension> extClass : NON_JAXB_BOUND_EXTENSION_CLASSES)
{
......@@ -203,8 +202,8 @@ public final class PdpExtensions
* @throws java.lang.IllegalArgumentException
* if there is no extension of type {@link org.ow2.authzforce.core.pdp.api.CloseableDesignatedAttributeProvider.FactoryBuilder} supporting {@code jaxbPdpExtensionClass}
*/
public static <ATTRIBUTE_PROVIDER_CONF extends AbstractAttributeProvider> CloseableDesignatedAttributeProvider.FactoryBuilder<ATTRIBUTE_PROVIDER_CONF> getAttributeProviderFactoryBuilder(
final Class<ATTRIBUTE_PROVIDER_CONF> jaxbConfClass)
public static <ATTRIBUTE_PROVIDER_CONF extends AbstractAttributeProvider> CloseableNamedAttributeProvider.FactoryBuilder<ATTRIBUTE_PROVIDER_CONF> getAttributeProviderFactoryBuilder(
final Class<ATTRIBUTE_PROVIDER_CONF> jaxbConfClass)
{
final JaxbBoundPdpExtension<ATTRIBUTE_PROVIDER_CONF> ext = (JaxbBoundPdpExtension<ATTRIBUTE_PROVIDER_CONF>) JAXB_BOUND_EXTENSIONS_BY_JAXB_CLASS.get(jaxbConfClass);
if (ext == null)
......@@ -212,13 +211,13 @@ 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 CloseableDesignatedAttributeProvider.FactoryBuilder))
if (!(ext instanceof CloseableNamedAttributeProvider.FactoryBuilder))
{
throw new IllegalArgumentException("No PDP extension of type " + CloseableDesignatedAttributeProvider.FactoryBuilder.class
+ " (Attribute Provider factory builder) supporting JAXB/XML (configuration) type: " + jaxbConfClass);
throw new IllegalArgumentException("No PDP extension of type " + CloseableNamedAttributeProvider.FactoryBuilder.class
+ " (Attribute Provider factory builder) supporting JAXB/XML (configuration) type: " + jaxbConfClass);
}
return (CloseableDesignatedAttributeProvider.FactoryBuilder<ATTRIBUTE_PROVIDER_CONF>) ext;
return (CloseableNamedAttributeProvider.FactoryBuilder<ATTRIBUTE_PROVIDER_CONF>) ext;
}
/**
......@@ -231,7 +230,7 @@ public final class PdpExtensions
* 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(
final Class<REF_POLICY_PROVIDER_CONF> jaxbConfClass) throws IllegalArgumentException
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);
if (ext == null)
......@@ -242,7 +241,7 @@ public final class PdpExtensions
if (!(ext instanceof CloseableRefPolicyProvider.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 " + CloseableRefPolicyProvider.Factory.class + " (Reference-based Policy Provider factory) supporting JAXB/XML (configuration) type: " + jaxbConfClass);
}
return (CloseableRefPolicyProvider.Factory<REF_POLICY_PROVIDER_CONF>) ext;
......@@ -261,7 +260,7 @@ public final class PdpExtensions
*/
public static <ROOT_POLICY_PROVIDER_CONF extends AbstractPolicyProvider> RootPolicyProvider.Factory<ROOT_POLICY_PROVIDER_CONF> getRootPolicyProviderFactory(
final Class<ROOT_POLICY_PROVIDER_CONF> jaxbConfClass) throws IllegalArgumentException
final Class<ROOT_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);
if (ext == null)
......@@ -272,7 +271,7 @@ public final class PdpExtensions
if (!(ext instanceof RootPolicyProvider.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 " + RootPolicyProvider.Factory.class + " (Root Policy Provider factory) supporting JAXB/XML (configuration) type: " + jaxbConfClass);
}
return (RootPolicyProvider.Factory<ROOT_POLICY_PROVIDER_CONF>) ext;
......
......@@ -18,41 +18,40 @@
package org.ow2.authzforce.core.pdp.impl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.ow2.authzforce.core.pdp.api.EvaluationContext;
import org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException;
import org.ow2.authzforce.core.pdp.api.PepActions;
import org.ow2.authzforce.core.pdp.api.PepAction;
import org.ow2.authzforce.core.pdp.api.PepActionAttributeAssignment;
import org.ow2.authzforce.core.pdp.api.expression.ExpressionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import net.sf.saxon.s9api.XPathCompiler;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignment;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpression;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
/**
* PEP action (obligation/advice) expression evaluator
*
* @param <JAXB_PEP_ACTION>
* PEP action type in XACML/JAXB model (Obligation/Advice)
* @version $Id: $
*/
public final class PepActionExpression<JAXB_PEP_ACTION>
public final class PepActionExpression
{
private static final Logger LOGGER = LoggerFactory.getLogger(PepActionExpression.class);
private final String actionId;
private final transient JAXB_PEP_ACTION emptyPepAction;
private final transient List<AttributeAssignmentExpressionEvaluator> evaluatableAttributeAssignmentExpressions;
private final PepActions.Factory<JAXB_PEP_ACTION> pepActionFactory;
private final boolean isMandatory;
private final String infoPrefix;
private final List<AttributeAssignmentExpressionEvaluator> evaluatableAttributeAssignmentExpressions;
private final EffectType appliesTo;
private transient final String toString;
/**
* Constructor that takes all the data associated with an PEP action (obligation/advice) expression.
......@@ -62,8 +61,9 @@ public final class PepActionExpression<JAXB_PEP_ACTION>
* @param pepActionId
* the obligation's id
* @param appliesTo
* the type of decision to which the PEP action applies (ObligationExpression's FulfillOn /
* AdviceExpression's 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
* a <code>List</code> of <code>AttributeAssignmentExpression</code>s
* @param xPathCompiler
......@@ -73,54 +73,34 @@ public final class PepActionExpression<JAXB_PEP_ACTION>
* @throws java.lang.IllegalArgumentException
* one of the AttributeAssignmentExpressions' Expression is invalid
*/
public PepActionExpression(final PepActions.Factory<JAXB_PEP_ACTION> pepActionFactory, final String pepActionId,
final EffectType appliesTo, final List<AttributeAssignmentExpression> jaxbAssignmentExps,
final XPathCompiler xPathCompiler, final ExpressionFactory expFactory) throws IllegalArgumentException
public PepActionExpression(final String pepActionId, final boolean isMandatory, final List<AttributeAssignmentExpression> jaxbAssignmentExps, final XPathCompiler xPathCompiler,
final ExpressionFactory expFactory) throws IllegalArgumentException
{
Preconditions.checkArgument(pepActionId != null, "Undefined PEP action (obligation/advice) ID");
this.actionId = pepActionId;
this.appliesTo = appliesTo;
this.isMandatory = isMandatory;
this.toString = (isMandatory ? "Obligation " : "Advice ") + "'" + actionId + "'";
if (jaxbAssignmentExps == null || jaxbAssignmentExps.isEmpty())