Commit fab9c0ff authored by cdanger's avatar cdanger

- Changed parent version to 6.0.0

- Module authzforce-ce-core-pdp-engine:
	- Changed dependency authzforce-ce-core-pdp-api version to 10.0.0
	- New ApplyExpressions utility class (creates ApplyExpression,
interface moved to pdp-api)
	- New AttributeSelectorExpressions utility class (creates
AttributeSelectorExpression, interface moved to pdp-api)
	- Renamed ExpressionFactoryImpl to DepthLimitingExpressionFactory
	- AttributeDesignatorExpression moved to pdp-api
	- New impl of AttributeDesignatorExpression (backed by
AttributeProvider):
GenericAttributeProviderBasedAttributeDesignatorExpression
- Module authzforce-ce-core-pdp-testutils:
  - Added new test RefPolicyProvider implementation using MongoDB as
source database of policies and Jongo library and mongo-java-driver
library for DB client: MongoDBRefPolicyProviderModule class (modified
testutil.ext.xsd and META-INF/services PdpExtension file) with
PolicyPOJO class for mapping policy document from/to database to/from
Java with Jongo, and JUnit test classes
parent 7752d7a8
......@@ -6,3 +6,4 @@
/.pmd
/.pmdruleset.xml
/.project
/.checkstyle
......@@ -42,7 +42,7 @@
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>${artifactId.prefix}-core-pdp-api</artifactId>
<version>9.1.1-SNAPSHOT</version>
<version>10.0.0</version>
</dependency>
<!-- /Authzforce dependencies -->
......
......@@ -76,8 +76,8 @@ public final class AttributeAssignmentExpressionEvaluator
final XPathCompiler xPathCompiler, final ExpressionFactory expFactory) throws IllegalArgumentException
{
/*
* Cannot used AttributeGUID class to handle metadata because AttributeAssignment Category is not required like
* in AttributeDesignator which is what the AttributeGUID is used for
* Cannot used AttributeFQN class to handle metadata because AttributeAssignment Category is not required like
* in AttributeDesignator which is what the AttributeFQN is used for
*/
this.attributeId = Preconditions.checkNotNull(jaxbAttrAssignExp.getAttributeId(),
"Undefined AttributeAssignment/AttributeId");
......
......@@ -26,7 +26,8 @@ import java.util.Set;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
import org.ow2.authzforce.core.pdp.api.AttributeGUID;
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.AttributeProviderModule;
import org.ow2.authzforce.core.pdp.api.CloseableAttributeProviderModule;
......@@ -113,7 +114,7 @@ public final class CloseableAttributeProvider extends ModularAttributeProvider i
// not-null
private final Set<ModuleAdapter> moduleClosers;
private CloseableAttributeProvider(final Map<AttributeGUID, AttributeProviderModule> modulesByAttributeId, final Set<ModuleAdapter> moduleClosers, final boolean strictAttributeIssuerMatch)
private CloseableAttributeProvider(final Map<AttributeFQN, AttributeProviderModule> modulesByAttributeId, final Set<ModuleAdapter> moduleClosers, final boolean strictAttributeIssuerMatch)
{
super(modulesByAttributeId, null, strictAttributeIssuerMatch);
assert moduleClosers != null;
......@@ -121,7 +122,7 @@ public final class CloseableAttributeProvider extends ModularAttributeProvider i
}
private static final CloseableAttributeProvider EVALUATION_CONTEXT_ONLY_SCOPED_CLOSEABLE_ATTRIBUTE_PROVIDER = new CloseableAttributeProvider(
Collections.<AttributeGUID, AttributeProviderModule> emptyMap(), Collections.<ModuleAdapter> emptySet(), true);
Collections.<AttributeFQN, AttributeProviderModule> emptyMap(), 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.
......@@ -153,7 +154,7 @@ public final class CloseableAttributeProvider extends ModularAttributeProvider i
return EVALUATION_CONTEXT_ONLY_SCOPED_CLOSEABLE_ATTRIBUTE_PROVIDER;
}
final Map<AttributeGUID, AttributeProviderModule> modulesByAttributeId = HashCollections.newUpdatableMap();
final Map<AttributeFQN, AttributeProviderModule> modulesByAttributeId = HashCollections.newUpdatableMap();
final int moduleCount = jaxbAttributeProviderConfs.size();
final Set<ModuleAdapter> mutableModuleCloserSet = HashCollections.newUpdatableSet(moduleCount);
for (final AbstractAttributeProvider jaxbAttributeProviderConf : jaxbAttributeProviderConfs)
......@@ -176,8 +177,8 @@ public final class CloseableAttributeProvider extends ModularAttributeProvider i
}
else
{
final Map<AttributeGUID, AttributeProviderModule> immutableCopyOfAttrProviderModsByAttrId = Collections
.<AttributeGUID, AttributeProviderModule> unmodifiableMap(modulesByAttributeId);
final Map<AttributeFQN, AttributeProviderModule> immutableCopyOfAttrProviderModsByAttrId = Collections
.<AttributeFQN, AttributeProviderModule> unmodifiableMap(modulesByAttributeId);
depAttrProvider = new ModularAttributeProvider(immutableCopyOfAttrProviderModsByAttrId, requiredAttrs, strictAttributeIssuerMatch);
}
......@@ -188,7 +189,7 @@ public final class CloseableAttributeProvider extends ModularAttributeProvider i
for (final AttributeDesignatorType attrDesignator : moduleAdapter.getProvidedAttributes())
{
final AttributeGUID attrGUID = new AttributeGUID(attrDesignator);
final AttributeFQN attrGUID = AttributeFQNs.newInstance(attrDesignator);
final AttributeProviderModule duplicate = modulesByAttributeId.putIfAbsent(attrGUID, moduleAdapter.getAdaptedModule());
if (duplicate != null)
{
......
......@@ -28,17 +28,18 @@ import net.sf.saxon.s9api.XPathCompiler;
import net.sf.saxon.s9api.XdmNode;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Attributes;
import org.ow2.authzforce.core.pdp.api.AttributeGUID;
import org.ow2.authzforce.core.pdp.api.AttributeFQN;
import org.ow2.authzforce.core.pdp.api.BaseRequestFilter;
import org.ow2.authzforce.core.pdp.api.HashCollections;
import org.ow2.authzforce.core.pdp.api.ImmutablePdpDecisionRequest;
import org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException;
import org.ow2.authzforce.core.pdp.api.IndividualXACMLRequest;
import org.ow2.authzforce.core.pdp.api.JaxbXACMLUtils.JaxbXACMLAttributesParser;
import org.ow2.authzforce.core.pdp.api.PdpDecisionRequestFactory;
import org.ow2.authzforce.core.pdp.api.RequestFilter;
import org.ow2.authzforce.core.pdp.api.SingleCategoryAttributes;
import org.ow2.authzforce.core.pdp.api.StatusHelper;
import org.ow2.authzforce.core.pdp.api.value.Bag;
import org.ow2.authzforce.core.pdp.api.value.AttributeBag;
import org.ow2.authzforce.core.pdp.api.value.DatatypeFactoryRegistry;
import com.google.common.collect.ImmutableList;
......@@ -50,6 +51,17 @@ import com.google.common.collect.ImmutableList;
*/
public final class DefaultRequestFilter extends BaseRequestFilter
{
private static final PdpDecisionRequestFactory<ImmutablePdpDecisionRequest> DEFAULT_REQUEST_FACTORY = new PdpDecisionRequestFactory<ImmutablePdpDecisionRequest>()
{
@Override
public ImmutablePdpDecisionRequest getInstance(final Map<AttributeFQN, AttributeBag<?>> namedAttributes, final Map<String, XdmNode> extraContentsByCategory,
final boolean returnApplicablePolicies)
{
return ImmutablePdpDecisionRequest.getInstance(namedAttributes, extraContentsByCategory, returnApplicablePolicies);
}
};
/**
*
* Factory for this type of request filter that allows duplicate &lt;Attribute&gt; with same meta-data in the same &lt;Attributes&gt; element of a Request (complying with XACML 3.0 core spec,
......@@ -73,7 +85,7 @@ public final class DefaultRequestFilter extends BaseRequestFilter
public RequestFilter getInstance(final DatatypeFactoryRegistry datatypeFactoryRegistry, final boolean strictAttributeIssuerMatch, final boolean requireContentForXPath,
final Processor xmlProcessor)
{
return new DefaultRequestFilter(datatypeFactoryRegistry, strictAttributeIssuerMatch, true, requireContentForXPath, xmlProcessor);
return new DefaultRequestFilter(datatypeFactoryRegistry, DEFAULT_REQUEST_FACTORY, strictAttributeIssuerMatch, true, requireContentForXPath, xmlProcessor);
}
/**
......@@ -103,14 +115,34 @@ public final class DefaultRequestFilter extends BaseRequestFilter
public RequestFilter getInstance(final DatatypeFactoryRegistry datatypeFactoryRegistry, final boolean strictAttributeIssuerMatch, final boolean requireContentForXPath,
final Processor xmlProcessor)
{
return new DefaultRequestFilter(datatypeFactoryRegistry, strictAttributeIssuerMatch, false, requireContentForXPath, xmlProcessor);
return new DefaultRequestFilter(datatypeFactoryRegistry, DEFAULT_REQUEST_FACTORY, strictAttributeIssuerMatch, false, requireContentForXPath, xmlProcessor);
}
}
private DefaultRequestFilter(final DatatypeFactoryRegistry datatypeFactoryRegistry, final boolean strictAttributeIssuerMatch, final boolean allowAttributeDuplicates,
final boolean requireContentForXPath, final Processor xmlProcessor)
private final PdpDecisionRequestFactory<ImmutablePdpDecisionRequest> reqFactory;
/**
* Creates instance of default request filter
*
* @param datatypeFactoryRegistry
* attribute datatype registry
* @param requestFactory
* decision request factory
* @param strictAttributeIssuerMatch
* true iff strict attribute Issuer match must be enforced (in particular request attributes with empty Issuer only match corresponding AttributeDesignators with empty Issuer)
* @param allowAttributeDuplicates
* true iff duplicate Attribute (with same metadata) elements in Request (for multi-valued attributes) must be allowed
* @param requireContentForXPath
* true iff Content elements must be parsed, else ignored
* @param xmlProcessor
* XML processor for parsing Content elements iff {@code requireContentForXPath}
*/
public DefaultRequestFilter(final DatatypeFactoryRegistry datatypeFactoryRegistry, final PdpDecisionRequestFactory<ImmutablePdpDecisionRequest> requestFactory,
final boolean strictAttributeIssuerMatch, final boolean allowAttributeDuplicates, final boolean requireContentForXPath, final Processor xmlProcessor)
{
super(datatypeFactoryRegistry, strictAttributeIssuerMatch, allowAttributeDuplicates, requireContentForXPath, xmlProcessor);
assert requestFactory != null;
reqFactory = requestFactory;
}
/** {@inheritDoc} */
......@@ -118,7 +150,7 @@ public final class DefaultRequestFilter extends BaseRequestFilter
public List<? extends IndividualXACMLRequest> filter(final List<Attributes> attributesList, final JaxbXACMLAttributesParser xacmlAttrsParser, final boolean isApplicablePolicyIdListReturned,
final boolean combinedDecision, final XPathCompiler xPathCompiler, final Map<String, String> namespaceURIsByPrefix) throws IndeterminateEvaluationException
{
final Map<AttributeGUID, Bag<?>> namedAttributes = HashCollections.newUpdatableMap(attributesList.size());
final Map<AttributeFQN, AttributeBag<?>> namedAttributes = HashCollections.newUpdatableMap(attributesList.size());
final Map<String, XdmNode> extraContentsByCategory = HashCollections.newUpdatableMap(attributesList.size());
/*
* attributesToIncludeInResult.size() <= attributesList.size()
......@@ -155,7 +187,7 @@ public final class DefaultRequestFilter extends BaseRequestFilter
* "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. (That is, every subsequent test of that attribute shall use the same bag of values that was initially tested.)"
* </i></p>
*/
for (final Entry<AttributeGUID, Bag<?>> attrEntry : categorySpecificAttributes)
for (final Entry<AttributeFQN, AttributeBag<?>> attrEntry : categorySpecificAttributes)
{
namedAttributes.put(attrEntry.getKey(), attrEntry.getValue());
}
......@@ -167,7 +199,7 @@ public final class DefaultRequestFilter extends BaseRequestFilter
}
}
return Collections.singletonList(new IndividualXACMLRequest(new ImmutablePdpDecisionRequest(namedAttributes, extraContentsByCategory, isApplicablePolicyIdListReturned), ImmutableList
return Collections.singletonList(new IndividualXACMLRequest(reqFactory.getInstance(namedAttributes, extraContentsByCategory, isApplicablePolicyIdListReturned), ImmutableList
.copyOf(attributesToIncludeInResult)));
}
}
......@@ -21,11 +21,12 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import net.sf.saxon.s9api.XdmNode;
import org.ow2.authzforce.core.pdp.api.AttributeGUID;
import org.ow2.authzforce.core.pdp.api.AttributeFQN;
import org.ow2.authzforce.core.pdp.api.AttributeSelectorId;
import org.ow2.authzforce.core.pdp.api.EvaluationContext;
import org.ow2.authzforce.core.pdp.api.HashCollections;
......@@ -34,14 +35,21 @@ import org.ow2.authzforce.core.pdp.api.PdpDecisionRequest;
import org.ow2.authzforce.core.pdp.api.StatusHelper;
import org.ow2.authzforce.core.pdp.api.UpdatableCollections;
import org.ow2.authzforce.core.pdp.api.UpdatableMap;
import org.ow2.authzforce.core.pdp.api.UpdatableSet;
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.StandardDatatypes;
import org.ow2.authzforce.core.pdp.api.value.Value;
import org.ow2.authzforce.core.pdp.api.value.XPathValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ClassToInstanceMap;
import com.google.common.collect.MutableClassToInstanceMap;
/**
* An {@link EvaluationContext} associated to an XACML Individual Decision Request, i.e. for evaluation to a single authorization decision Result (see Multiple Decision Profile spec for more
* information on Individual Decision Request as opposed to Multiple Decision Request).
......@@ -55,11 +63,7 @@ public final class IndividualDecisionRequestContext implements EvaluationContext
*/
private static final Logger LOGGER = LoggerFactory.getLogger(IndividualDecisionRequestContext.class);
private final Map<AttributeGUID, Bag<?>> namedAttributes;
private final Map<String, Value> varValsById = HashCollections.newMutableMap();
private final Map<String, Object> mutableProperties = HashCollections.newMutableMap();
private final Map<AttributeFQN, AttributeBag<?>> namedAttributes;
/*
* Corresponds to Attributes/Content (by attribute category) marshalled to XPath data model for XPath evaluation: AttributeSelector evaluation, XPath-based functions, etc. This may be empty if no
......@@ -73,46 +77,39 @@ public final class IndividualDecisionRequestContext implements EvaluationContext
*/
private final UpdatableMap<AttributeSelectorId, Bag<?>> attributeSelectorResults;
// not null
private final UpdatableSet<AttributeGUID> usedNamedAttributeIdSet;
private final Map<String, Value> varValsById = HashCollections.newMutableMap();
// not null
private final UpdatableSet<AttributeSelectorId> usedAttributeSelectorIdSet;
private final Map<String, Object> mutableProperties = HashCollections.newMutableMap();
private final boolean returnApplicablePolicyIdList;
private final ClassToInstanceMap<Listener> listeners = MutableClassToInstanceMap.create();
/**
* Constructs a new <code>IndividualDecisionRequestContext</code> based on the given request attributes and extra contents with support for XPath evaluation against Content element in Attributes
*
* @param namedAttributeMap
* updatable named attribute map (attribute key and value pairs) from the original Request; null iff none. An attribute key is a global ID based on attribute category,issuer,id. An
* attribute value is a bag of primitive values.
* @param contentNodesByCategory
* @param extraContentsByCategory
* extra contents by attribute category (equivalent to XACML Attributes/Content elements); null iff no Content in the attribute category.
* @param returnApplicablePolicyIdList
* true iff list of IDs of policies matched during evaluation must be returned
* @param returnUsedAttributes
* true iff the list of attributes used during evaluation may be requested by
*/
public IndividualDecisionRequestContext(final Map<AttributeGUID, Bag<?>> namedAttributeMap, final Map<String, XdmNode> contentNodesByCategory,
final boolean returnApplicablePolicyIdList, final boolean returnUsedAttributes)
public IndividualDecisionRequestContext(final Map<AttributeFQN, AttributeBag<?>> namedAttributeMap, final Map<String, XdmNode> extraContentsByCategory, final boolean returnApplicablePolicyIdList)
{
this.namedAttributes = namedAttributeMap == null ? HashCollections.<AttributeGUID, Bag<?>> newUpdatableMap() : namedAttributeMap;
this.namedAttributes = namedAttributeMap == null ? HashCollections.<AttributeFQN, AttributeBag<?>> newUpdatableMap() : HashCollections
.<AttributeFQN, AttributeBag<?>> newUpdatableMap(namedAttributeMap);
this.returnApplicablePolicyIdList = returnApplicablePolicyIdList;
this.usedNamedAttributeIdSet = returnUsedAttributes ? UpdatableCollections.<AttributeGUID> newUpdatableSet() : UpdatableCollections.<AttributeGUID> emptySet();
if (contentNodesByCategory == null)
if (extraContentsByCategory == null)
{
this.extraContentsByAttributeCategory = Collections.emptyMap();
this.attributeSelectorResults = UpdatableCollections.emptyMap();
// not used since there is no <Content>
// (extraContentsByAttributeCategory == null)
this.usedAttributeSelectorIdSet = UpdatableCollections.emptySet();
}
else
{
this.extraContentsByAttributeCategory = contentNodesByCategory;
this.extraContentsByAttributeCategory = extraContentsByCategory;
this.attributeSelectorResults = UpdatableCollections.newUpdatableMap();
this.usedAttributeSelectorIdSet = returnUsedAttributes ? UpdatableCollections.<AttributeSelectorId> newUpdatableSet() : UpdatableCollections.<AttributeSelectorId> emptySet();
}
}
......@@ -121,46 +118,43 @@ public final class IndividualDecisionRequestContext implements EvaluationContext
*
* @param individualDecisionReq
* individual decision request
* @param returnUsedAttributes
* true iff the list of attributes used during evaluation may be requested by
*/
public IndividualDecisionRequestContext(final PdpDecisionRequest individualDecisionReq, final boolean returnUsedAttributes)
public IndividualDecisionRequestContext(final PdpDecisionRequest individualDecisionReq)
{
this(individualDecisionReq.getNamedAttributes(), individualDecisionReq.getContentNodesByCategory(), individualDecisionReq.isApplicablePolicyIdListReturned(), returnUsedAttributes);
this(individualDecisionReq.getNamedAttributes(), individualDecisionReq.getExtraContentsByCategory(), individualDecisionReq.isApplicablePolicyIdListReturned());
}
/** {@inheritDoc} */
@Override
public <AV extends AttributeValue> Bag<AV> getAttributeDesignatorResult(final AttributeGUID attributeGUID, final Datatype<AV> attributeDatatype) throws IndeterminateEvaluationException
public <AV extends AttributeValue> AttributeBag<AV> getNamedAttributeValue(final AttributeFQN attributeFQN, final BagDatatype<AV> attributeBagDatatype) throws IndeterminateEvaluationException
{
this.usedNamedAttributeIdSet.add(attributeGUID);
final Bag<?> bagResult = namedAttributes.get(attributeGUID);
final AttributeBag<?> bagResult = namedAttributes.get(attributeFQN);
if (bagResult == null)
{
return null;
}
if (!bagResult.getElementDatatype().equals(attributeDatatype))
final Datatype<?> expectedElementDatatype = attributeBagDatatype.getElementType();
if (!bagResult.getElementDatatype().equals(expectedElementDatatype))
{
throw new IndeterminateEvaluationException("Datatype (" + bagResult.getElementDatatype() + ") of AttributeDesignator " + attributeGUID
+ " in context is different from expected/requested (" + attributeDatatype
throw new IndeterminateEvaluationException("Datatype (" + bagResult.getElementDatatype() + ") of AttributeDesignator " + attributeFQN
+ " in context is different from expected/requested (" + expectedElementDatatype
+ "). May be caused by refering to the same Attribute Category/Id/Issuer with different Datatypes in different policy elements and/or attribute providers, which is not allowed.",
StatusHelper.STATUS_SYNTAX_ERROR);
}
/*
* If datatype classes match, bagResult should have same type as datatypeClass.
*
* TODO: to avoid unchecked cast, we might want to return a new Bag after casting all values in bagResult with datatypeClass. Is it worth the trouble?
*/
return (Bag<AV>) bagResult;
final AttributeBag<AV> result = attributeBagDatatype.castAttributeBag(bagResult);
this.listeners.forEach((lt, l) -> l.namedAttributeValueConsumed(attributeFQN, result));
return result;
}
/** {@inheritDoc} */
@Override
public boolean putAttributeDesignatorResultIfAbsent(final AttributeGUID id, final Bag<?> result)
public boolean putNamedAttributeValueIfAbsent(final AttributeFQN attributeFQN, final AttributeBag<?> result)
{
final Bag<?> duplicate = namedAttributes.putIfAbsent(id, result);
final Bag<?> duplicate = namedAttributes.putIfAbsent(attributeFQN, result);
if (duplicate != null)
{
/*
......@@ -168,10 +162,11 @@ public final class IndividualDecisionRequestContext implements EvaluationContext
* putAttributeDesignatorResultIfAbsent() in this case. In any case, we do not support setting a different result for same id (but different datatype URI/datatype class) in the same
* context
*/
LOGGER.warn("Attempt to override value of AttributeDesignator {} already set in evaluation context. Overriding value: {}", id, result);
LOGGER.warn("Attempt to override value of AttributeDesignator {} already set in evaluation context. Overriding value: {}", attributeFQN, result);
return false;
}
this.listeners.forEach((lt, l) -> l.namedAttributeValueProduced(attributeFQN, result));
/*
* Attribute value cannot change during evaluation context, so if old value already there, put it back
*/
......@@ -187,85 +182,96 @@ public final class IndividualDecisionRequestContext implements EvaluationContext
/** {@inheritDoc} */
@Override
public <V extends Value> V getVariableValue(final String variableId, final Datatype<V> expectedDatatype) throws IndeterminateEvaluationException
public <AV extends AttributeValue> Bag<AV> getAttributeSelectorResult(final AttributeSelectorExpression<AV> attributeSelector) throws IndeterminateEvaluationException
{
final Value val = varValsById.get(variableId);
if (val == null)
final Bag<?> bagResult = attributeSelectorResults.get(attributeSelector.getAttributeSelectorId());
if (bagResult == null)
{
return null;
}
try
{
return expectedDatatype.cast(val);
}
catch (final ClassCastException e)
final Datatype<Bag<AV>> expectedBagDatatype = attributeSelector.getReturnType();
final Datatype<?> expectedElementDatatype = expectedBagDatatype.getTypeParameter().get();
if (!bagResult.getElementDatatype().equals(expectedElementDatatype))
{
throw new IndeterminateEvaluationException("Datatype of variable '" + variableId + "' in context does not match expected datatype: " + expectedDatatype,
StatusHelper.STATUS_PROCESSING_ERROR, e);
throw new IndeterminateEvaluationException("Datatype (" + bagResult.getElementDatatype() + ")of AttributeSelector " + attributeSelector.getAttributeSelectorId()
+ " in context is different from actually expected/requested (" + expectedElementDatatype
+ "). May be caused by use of same AttributeSelector Category/Path/ContextSelectorId with different Datatypes in different in different policy elements, which is not allowed.",
StatusHelper.STATUS_SYNTAX_ERROR);
}
/*
* If datatype classes match, bagResult should has same type as datatypeClass.
*/
final Bag<AV> result = expectedBagDatatype.cast(bagResult);
this.listeners.forEach((lt, l) -> l.attributeSelectorResultConsumed(attributeSelector, result));
return result;
}
/** {@inheritDoc} */
@Override
public boolean putVariableIfAbsent(final String variableId, final Value value)
public <AV extends AttributeValue> boolean putAttributeSelectorResultIfAbsent(final AttributeSelectorExpression<AV> attributeSelector, final Bag<AV> result)
throws IndeterminateEvaluationException
{
if (varValsById.putIfAbsent(variableId, value) != null)
final AttributeSelectorId attSelectorId = attributeSelector.getAttributeSelectorId();
if (attributeSelectorResults.putIfAbsent(attSelectorId, result) != null)
{
LOGGER.error("Attempt to override value of Variable '{}' already set in evaluation context. Overriding value: {}", variableId, value);
LOGGER.error("Attempt to override value of AttributeSelector {} already set in evaluation context. Overriding value: {}", attSelectorId, result);
return false;
}
return true;
}
for (final Listener listener : this.listeners.values())
{
final Optional<AttributeFQN> optionalContextSelectorFQN = attributeSelector.getContextSelectorFQN();
final Optional<AttributeBag<XPathValue>> contextSelectorValue = optionalContextSelectorFQN.isPresent() ? Optional.of(getNamedAttributeValue(optionalContextSelectorFQN.get(),
StandardDatatypes.XPATH_FACTORY.getBagDatatype())) : Optional.empty();
listener.attributeSelectorResultProduced(attributeSelector, contextSelectorValue, result);
}
/** {@inheritDoc} */
@Override
public Value removeVariable(final String variableId)
{
return varValsById.remove(variableId);
return true;
}
/** {@inheritDoc} */
@Override
public <AV extends AttributeValue> Bag<AV> getAttributeSelectorResult(final AttributeSelectorId id, final Datatype<AV> datatype) throws IndeterminateEvaluationException
public <V extends Value> V getVariableValue(final String variableId, final Datatype<V> expectedDatatype) throws IndeterminateEvaluationException
{
this.usedAttributeSelectorIdSet.add(id);
final Bag<?> bagResult = attributeSelectorResults.get(id);
if (bagResult == null)
final Value val = varValsById.get(variableId);
if (val == null)
{
return null;
}
if (!bagResult.getElementDatatype().equals(datatype))
try
{
throw new IndeterminateEvaluationException("Datatype (" + bagResult.getElementDatatype() + ")of AttributeSelector " + id + " in context is different from actually expected/requested ("
+ datatype
+ "). May be caused by use of same AttributeSelector Category/Path/ContextSelectorId with different Datatypes in different in different policy elements, which is not allowed.",
StatusHelper.STATUS_SYNTAX_ERROR);
return expectedDatatype.cast(val);
}
catch (final ClassCastException e)
{
throw new IndeterminateEvaluationException("Datatype of variable '" + variableId + "' in context does not match expected datatype: " + expectedDatatype,
StatusHelper.STATUS_PROCESSING_ERROR, e);
}
/*
* If datatype classes match, bagResult should has same type as datatypeClass.
*
* TODO: to avoid unchecked cast, we might want to return a new Bag after casting all values in bagResult with datatypeClass. Is it worth the trouble?
*/
return (Bag<AV>) bagResult;
}
/** {@inheritDoc} */
@Override
public boolean putAttributeSelectorResultIfAbsent(final AttributeSelectorId id, final Bag<?> result) throws IndeterminateEvaluationException
public boolean putVariableIfAbsent(final String variableId, final Value value)
{
if (attributeSelectorResults.putIfAbsent(id, result) != null)
if (varValsById.putIfAbsent(variableId, value) != null)
{
LOGGER.error("Attempt to override value of AttributeSelector {} already set in evaluation context. Overriding value: {}", id, result);
LOGGER.error("Attempt to override value of Variable '{}' already set in evaluation context. Overriding value: {}", variableId, value);
return false;
}
return true;
}
/** {@inheritDoc} */
@Override
public Value removeVariable(final String variableId)
{
return varValsById.remove(variableId);
}
/** {@inheritDoc} */
@Override
public Object getOther(final String key)
......@@ -296,27 +302,27 @@ public final class IndividualDecisionRequestContext implements EvaluationContext
/** {@inheritDoc} */
@Override
public Iterator<Entry<AttributeGUID, Bag<?>>> getAttributes()
public Iterator<Entry<AttributeFQN, AttributeBag<?>>> getNamedAttributes()
{
final Set<Entry<AttributeGUID, Bag<?>>> immutableAttributeSet = Collections.unmodifiableSet(namedAttributes.entrySet());
final Set<Entry<AttributeFQN, AttributeBag<?>>> immutableAttributeSet = Collections.unmodifiableSet(namedAttributes.entrySet());
return immutableAttributeSet.iterator();
}
@Override
public Set<AttributeGUID> getUsedNamedAttributes()
public boolean isApplicablePolicyIdListRequested()
{
return usedNamedAttributeIdSet.copy();
return returnApplicablePolicyIdList;
}
@Override
public Set<AttributeSelectorId> getUsedExtraAttributeContents()
public <L extends Listener> L putListener(final Class<L> listenerType, final L listener)
{
return usedAttributeSelectorIdSet.copy();
return this.listeners.putInstance(listenerType, listener);
}
@Override
public boolean isApplicablePolicyIdListRequested()
public <L extends Listener> L getListener(final Class<L> listenerType)
{
return returnApplicablePolicyIdList;
return this.listeners.getInstance(listenerType);
}
}
......@@ -24,7 +24,7 @@ import java.util.Map;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.Result;
import org.ow2.authzforce.core.pdp.api.AttributeGUID;
import org.ow2.authzforce.core.pdp.api.AttributeFQN;
import org.ow2.authzforce.core.pdp.api.DecisionResultFilter;
import org.ow2.authzforce.core.pdp.api.DecisionResultFilter.FilteringResultCollector;
import org.ow2.authzforce.core.pdp.api.EvaluationContext;
......@@ -34,7 +34,7 @@ import org.ow2.authzforce.core.pdp.api.IndividualXACMLRequest;
import org.ow2.authzforce.core.pdp.api.PdpDecisionRequest;
import org.ow2.authzforce.core.pdp.api.PdpDecisionResult;
import org.ow2.authzforce.core.pdp.api.StatusHelper;
import org.ow2.authzforce.core.pdp.api.value.Bag;