use of org.ow2.authzforce.xacml.identifiers.XPathVersion in project core by authzforce.
the class PolicyEvaluators method getInstance.
/**
* Creates Policy handler from XACML Policy element
*
* @param policyElement Policy (XACML)
* @param parentDefaultXPathCompiler XPath compiler corresponding to parent PolicyDefaults/XPathVersion; undefined if this Policy has no parent Policy (root), or none defined in parent, or XPath disabled by PDP configuration
* @param namespacePrefixToUriMap namespace prefix-URI mappings from the original XACML Policy (XML) document, to be used for namespace-aware XPath evaluation; empty iff XPath support disabled or: {@code parentDefaultXPathCompiler.isPresent()} and they can be retrieved already from {@code parentDefaultXPathCompiler.get().getDeclaredNamespacePrefixToUriMap()}
* @param expressionFactory Expression factory/parser
* @param combiningAlgRegistry rule/policy combining algorithm registry
* @return instance
* @throws IllegalArgumentException if any argument is invalid
*/
public static StaticTopLevelPolicyElementEvaluator getInstance(final Policy policyElement, final ExpressionFactory expressionFactory, final CombiningAlgRegistry combiningAlgRegistry, final Optional<XPathCompilerProxy> parentDefaultXPathCompiler, final Map<String, String> namespacePrefixToUriMap) throws IllegalArgumentException {
if (policyElement == null) {
throw NULL_XACML_POLICY_ARG_EXCEPTION;
}
if (expressionFactory == null) {
throw NULL_EXPRESSION_FACTORY_EXCEPTION;
}
if (combiningAlgRegistry == null) {
throw NULL_XACML_COMBINING_ALG_ARG_EXCEPTION;
}
final String policyId = policyElement.getPolicyId();
final PolicyVersion policyVersion = new PolicyVersion(policyElement.getVersion());
final PrimaryPolicyMetadata policyMetadata = new BasePrimaryPolicyMetadata(TopLevelPolicyElementType.POLICY, policyId, policyVersion);
final BooleanEvaluator targetEvaluator = TargetEvaluators.getInstance(policyElement.getTarget(), expressionFactory, parentDefaultXPathCompiler);
/*
* Elements defined in xs:choice of XACML schema type PolicyType: Rules/(Rule)CombinerParameters/VariableDefinitions
*/
final List<Serializable> policyChoiceElements = policyElement.getCombinerParametersAndRuleCombinerParametersAndVariableDefinitions();
/*
* There are at most as many combining alg parameters as policyChoiceElements.size().
*/
final List<CombiningAlgParameter<? extends RuleEvaluator>> combiningAlgParameters = new ArrayList<>(policyChoiceElements.size());
/*
* Keep a copy of locally-defined variables defined in this policy, to remove them from the global manager at the end of parsing this policy. They should not be visible outside the scope of
* this policy. There are at most as many VariableDefinitions as policyChoiceElements.size().
*/
final List<VariableReference<?>> localVariables = new ArrayList<>(policyChoiceElements.size());
final DefaultsType policyDefaults = policyElement.getPolicyDefaults();
Optional<XPathCompilerProxy> childXpathCompiler;
/*
* Leave childXpathCompiler undefined if XPath support disabled globally.
*
* Else (XPath support enabled globally, but may be disabled locally for this specific Policy if XPathVersion undefined in it and any enclosing PolicySet)...
* Reminder: According to the XACML standard, the Policy(Set)Defaults/XPathVersion must be specified (non-null) in the current Policy(Set) or any of its enclosing/ancestor PolicySet for XPath expressions to be allowed (therefore a need for a XPathCompiler), e.g. in AttributeSelectors, XPath functions, etc.
*/
if (expressionFactory.isXPathEnabled()) {
/*
If both policyDefaults and parentDefaultXPathCompiler undefined, it means no Policy(Set)Defaults/XPathVersion defined (in current Policy and any enclosing PolicySet), i.e. XPath support is disabled for this Policy, so leave childXpathCompiler undefined like parentDefaultXPathCompiler.
We may reuse parentDefaultXPathCompiler if:
- parentDefaultXPathCompiler is defined
- AND policyDefaults/XPathVersion is undefined OR the XPath version matches the policyDefaults/XPathVersion
- AND namespacePrefixToUriMap is empty (i.e. only the ones from parentDefaultXPathCompiler apply)
*/
if (policyDefaults == null) {
if (parentDefaultXPathCompiler.isEmpty() || namespacePrefixToUriMap.isEmpty()) {
childXpathCompiler = parentDefaultXPathCompiler;
} else {
// parentDefaultXPathCompiler defined AND namespacePrefixToUriMap not empty -> new XPathCompiler to handle these new namespacePrefixToUriMap map
childXpathCompiler = Optional.of(new ImmutableXPathCompiler(parentDefaultXPathCompiler.get().getXPathVersion(), namespacePrefixToUriMap, List.of()));
}
} else {
// policyDefaults defined
final String xpathVersionUri = policyDefaults.getXPathVersion();
assert xpathVersionUri != null : "PolicyDefaults(non-null)/XPathVersion = null, which violates the XACML schema! Fix: enforce XACML schema validation.";
try {
final XPathVersion xPathVersion = XPathVersion.fromURI(xpathVersionUri);
if (parentDefaultXPathCompiler.isEmpty()) {
childXpathCompiler = Optional.of(new ImmutableXPathCompiler(xPathVersion, namespacePrefixToUriMap, List.of()));
} else // parentDefaultXPathCompiler defined, re-use it only if XPath version matches policyDefaults and namespacePrefixToUriMap empty
if (parentDefaultXPathCompiler.get().getXPathVersion().equals(xPathVersion) && namespacePrefixToUriMap.isEmpty()) {
childXpathCompiler = parentDefaultXPathCompiler;
} else {
childXpathCompiler = Optional.of(new ImmutableXPathCompiler(xPathVersion, namespacePrefixToUriMap, List.of()));
}
} catch (final IllegalArgumentException e) {
throw new IllegalArgumentException(policyMetadata + ": Invalid PolicySetDefaults/XPathVersion or XML namespace prefix/URI undefined", e);
}
}
} else {
// XPath support disabled globally
childXpathCompiler = Optional.empty();
}
/*
childXpathCompiler is empty iff XPath support disabled globally (!expressionFactory.isXPathEnabled()) OR (policyDefaults ==null AND parentDefaultXPathCompiler.isEmpty()), in other words iff XPath support disabled for this Policy
*/
/*
If XPath support enabled, we can reuse the same XPathCompiler as long as there is no new VariableDefinition
*/
boolean isNewChildXpathCompilerRequired = false;
/*
* We keep a record of the size of the longest chain of VariableReference in this policy, and update it when a VariableDefinition occurs
*/
int sizeOfPolicyLongestVarRefChain = 0;
/*
* Map to get rules by their ID so that we can resolve rules associated with RuleCombinerParameters, and detect duplicate RuleId. We want to preserve insertion order, to get map.values() in
* order of declaration, so that ordered-* algorithms have rules in order. There are at most as many Rules as policyChoiceElements.size().
*/
final Map<String, RuleEvaluator> ruleEvaluatorsByRuleIdInOrderOfDeclaration = new LinkedHashMap<>(policyChoiceElements.size());
int childIndex = 0;
for (final Serializable policyChildElt : policyChoiceElements) {
/*
If and only if XPath enabled for this Policy (childXpathCompiler.isPresent()), XPath compiler needed for each child, can we reuse the same one as last time (it was used to create a child element evaluator) ?
*/
if (childXpathCompiler.isPresent() && isNewChildXpathCompilerRequired) {
/*
New Variables defined since last XPath compiler created -> we need to use a new one to handle the new XACML Variables as XPath variables
*/
childXpathCompiler = Optional.of(new ImmutableXPathCompiler(childXpathCompiler.get().getXPathVersion(), namespacePrefixToUriMap, localVariables));
isNewChildXpathCompilerRequired = false;
}
if (policyChildElt instanceof RuleCombinerParameters) {
final String combinedRuleId = ((RuleCombinerParameters) policyChildElt).getRuleIdRef();
final RuleEvaluator ruleEvaluator = ruleEvaluatorsByRuleIdInOrderOfDeclaration.get(combinedRuleId);
if (ruleEvaluator == null) {
throw new IllegalArgumentException(policyMetadata + ": invalid RuleCombinerParameters: referencing undefined child Rule #" + combinedRuleId + " (no such rule defined before this element)");
}
final BaseCombiningAlgParameter<RuleEvaluator> combiningAlgParameter;
try {
combiningAlgParameter = new BaseCombiningAlgParameter<>(ruleEvaluator, ((CombinerParametersType) policyChildElt).getCombinerParameters(), expressionFactory, childXpathCompiler);
} catch (final IllegalArgumentException e) {
throw new IllegalArgumentException(policyMetadata + ": invalid child #" + childIndex + " (RuleCombinerParameters)", e);
}
combiningAlgParameters.add(combiningAlgParameter);
} else if (policyChildElt instanceof CombinerParametersType) {
/*
* CombinerParameters that is not RuleCombinerParameters already tested before
*/
final BaseCombiningAlgParameter<RuleEvaluator> combiningAlgParameter;
try {
combiningAlgParameter = new BaseCombiningAlgParameter<>(null, ((CombinerParametersType) policyChildElt).getCombinerParameters(), expressionFactory, childXpathCompiler);
} catch (final IllegalArgumentException e) {
throw new IllegalArgumentException(policyMetadata + ": invalid child #" + childIndex + " (CombinerParameters)", e);
}
combiningAlgParameters.add(combiningAlgParameter);
} else if (policyChildElt instanceof VariableDefinition) {
final VariableDefinition varDef = (VariableDefinition) policyChildElt;
final Deque<String> varDefLongestVarRefChain = new ArrayDeque<>();
final VariableReference<?> var;
try {
var = expressionFactory.addVariable(varDef, varDefLongestVarRefChain, childXpathCompiler);
} catch (final IllegalArgumentException e) {
throw new IllegalArgumentException(policyMetadata + ": invalid child #" + childIndex + " (VariableDefinition)", e);
}
if (var != null) {
/*
* Conflicts can occur between variables defined in this policy but also with others already in a wider scope, i.e. defined in parent/ancestor policy
*/
throw new IllegalArgumentException(policyMetadata + ": Duplicable VariableDefinition for VariableId = " + var.getVariableId());
}
localVariables.add(expressionFactory.getVariableExpression(varDef.getVariableId()));
/*
New Variables defined since last XPath compiler created -> we need to use a new one to handle the new XACML Variables as XPath variables in the subsequent child elements
*/
isNewChildXpathCompilerRequired = true;
/*
* check whether the longest VariableReference chain in the VariableDefinition is longer than what we've got so far
*/
final int sizeOfVarDefLongestVarRefChain = varDefLongestVarRefChain.size();
if (sizeOfVarDefLongestVarRefChain > sizeOfPolicyLongestVarRefChain) {
sizeOfPolicyLongestVarRefChain = sizeOfVarDefLongestVarRefChain;
}
} else if (policyChildElt instanceof Rule) {
final RuleEvaluator ruleEvaluator;
try {
ruleEvaluator = new RuleEvaluator((Rule) policyChildElt, expressionFactory, childXpathCompiler);
} catch (final IllegalArgumentException e) {
throw new IllegalArgumentException(policyMetadata + ": Error parsing child #" + childIndex + " (Rule)", e);
}
final RuleEvaluator conflictingRuleEvaluator = ruleEvaluatorsByRuleIdInOrderOfDeclaration.putIfAbsent(ruleEvaluator.getRuleId(), ruleEvaluator);
if (conflictingRuleEvaluator != null) {
/*
* Conflict: 2 Rule elements with same RuleId -> violates uniqueness of RuleId within a Policy (XACML spec)
*/
throw new IllegalArgumentException(policyMetadata + ": Duplicate Rule with RuleId = " + conflictingRuleEvaluator.getRuleId());
}
}
childIndex++;
}
final ObligationExpressions obligationExps = policyElement.getObligationExpressions();
final AdviceExpressions adviceExps = policyElement.getAdviceExpressions();
final StaticTopLevelPolicyElementEvaluator policyEvaluator = new StaticBaseTopLevelPolicyElementEvaluator<>(RuleEvaluator.class, policyMetadata, Optional.empty(), targetEvaluator, ImmutableList.copyOf(localVariables), policyElement.getRuleCombiningAlgId(), ImmutableList.copyOf(ruleEvaluatorsByRuleIdInOrderOfDeclaration.values()), ImmutableList.copyOf(combiningAlgParameters), obligationExps == null ? null : obligationExps.getObligationExpressions(), adviceExps == null ? null : adviceExps.getAdviceExpressions(), expressionFactory, combiningAlgRegistry, childXpathCompiler);
/*
* We are done parsing expressions in this policy, including VariableReferences, it's time to remove variables scoped to this policy from the variable manager
*/
localVariables.forEach(var -> expressionFactory.removeVariable(var.getVariableId()));
return policyEvaluator;
}
use of org.ow2.authzforce.xacml.identifiers.XPathVersion in project core by authzforce.
the class MongoDbPolicyProvider method getPolicy.
@Override
public StaticTopLevelPolicyElementEvaluator getPolicy(final String policyId, final Optional<PolicyVersionPatterns> policyPolicyVersionPatterns) throws IndeterminateEvaluationException {
/*
* TODO: use a policy cache and check it before requesting the database.
*/
final PolicyQueryResult xmlParsingResult = getJaxbPolicyElement(XACML3_POLICY_TYPE_ID, policyId, policyPolicyVersionPatterns);
if (xmlParsingResult == null) {
return null;
}
final PolicyPojo policyPOJO = xmlParsingResult.policyPojo;
final Object jaxbPolicyOrPolicySetObj = xmlParsingResult.resultJaxbObj;
final Map<String, String> nsPrefixUriMap = xmlParsingResult.xmlnsToPrefixMap;
if (!(jaxbPolicyOrPolicySetObj instanceof Policy)) {
throw new IndeterminateEvaluationException("PolicyProvider " + id + ": 'content' of the policy document " + policyPOJO + " retrieved from database is not consistent with its 'type' (expected: Policy). Actual content type: " + jaxbPolicyOrPolicySetObj.getClass() + " (corrupted database?).", XacmlStatusCode.PROCESSING_ERROR.value());
}
final Policy jaxbPolicy = (Policy) jaxbPolicyOrPolicySetObj;
final String contentPolicyId = jaxbPolicy.getPolicyId();
if (!contentPolicyId.equals(policyPOJO.getId())) {
throw new IndeterminateEvaluationException("PolicyProvider " + id + ": PolicyId in 'content' of the policy document " + policyPOJO + " retrieved from database is not consistent with 'id'. Actual PolicyId: " + contentPolicyId + " (corrupted database?).", XacmlStatusCode.PROCESSING_ERROR.value());
}
final String contentPolicyVersion = jaxbPolicy.getVersion();
if (!contentPolicyVersion.equals(policyPOJO.getVersion())) {
throw new IndeterminateEvaluationException("PolicyProvider " + id + ": Version in 'content' of the policy document " + policyPOJO + " retrieved from database is not consistent with 'version'. Actual Version: " + contentPolicyVersion + " (corrupted database?).", XacmlStatusCode.PROCESSING_ERROR.value());
}
try {
/*
XPath compiler shall be initialized in PolicyEvaluators#getInstance(...) based on PolicyDefaults/XPathVersion if present
*/
return PolicyEvaluators.getInstance(jaxbPolicy, expressionFactory, combiningAlgRegistry, Optional.empty(), nsPrefixUriMap);
} catch (final IllegalArgumentException e) {
throw new IllegalArgumentException("Invalid Policy in 'content' of the policy document " + policyPOJO + " retrieved from database", e);
}
}
use of org.ow2.authzforce.xacml.identifiers.XPathVersion in project core by authzforce.
the class BaseXacmlJsonRequestPreprocessor method process.
@Override
public final List<IndividualXacmlJsonRequest> process(final JSONObject request, final Map<String, String> namespaceURIsByPrefix) throws IndeterminateEvaluationException {
if (request == null) {
throw NULL_REQUEST_ARGUMENT_EXCEPTION;
}
try {
XacmlJsonUtils.REQUEST_SCHEMA.validate(request);
} catch (final ValidationException e) {
LOGGER.debug(e.toJSON().toString(4));
throw new IndeterminateEvaluationException(INVALID_REQ_ERR_STATUS, e);
}
final JSONObject requestJsonObj = request.optJSONObject("Request");
if (requestJsonObj == null) {
throw MISSING_REQUEST_OBJECT_EXCEPTION;
}
/*
* No support for MultiRequests (ยง2.4 of Multiple Decision Profile).
*/
if (requestJsonObj.has("MultiRequests")) {
/*
* According to 7.19.1 Unsupported functionality, return Indeterminate with syntax-error code for unsupported element
*/
throw UNSUPPORTED_MULTI_REQUESTS_EXCEPTION;
}
/*
* No support for CombinedDecision = true if result processor does not support it. (The use of the CombinedDecision attribute is specified in Multiple Decision Profile.)
*/
final boolean combinedDecisionRequested;
if (requestJsonObj.optBoolean("CombinedDecision", false)) {
if (!this.isCombinedDecisionSupported) {
/*
* According to XACML core spec, 5.42, <i>If the PDP does not implement the relevant functionality in [Multiple Decision Profile], then the PDP must return an Indeterminate with a status
* code of urn:oasis:names:tc:xacml:1.0:status:processing-error if it receives a request with this attribute set to "true".</i>
*/
throw UNSUPPORTED_COMBINED_DECISION_EXCEPTION;
}
combinedDecisionRequested = true;
} else {
combinedDecisionRequested = false;
}
final boolean returnPolicyIdList = requestJsonObj.optBoolean("ReturnPolicyIdList", false);
final Map<String, String> newNsPrefixToUriMap;
final Optional<XPathCompilerProxy> xPathCompiler;
if (requestJsonObj.has("XPathVersion")) {
try {
final XPathVersion xPathVersion = XPathVersion.fromURI(requestJsonObj.getString("XPathVersion"));
xPathCompiler = Optional.of(new BasicImmutableXPathCompilerProxy(xPathVersion, namespaceURIsByPrefix));
/*
namespaceURIsByPrefix already held by xPathCompiler and retrievable from it with getDeclaredNamespacePrefixToUriMap().
*/
newNsPrefixToUriMap = Map.of();
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Invalid/unsupported XPathVersion in JSON Request/XPathVersion", e);
}
} else {
xPathCompiler = Optional.empty();
newNsPrefixToUriMap = namespaceURIsByPrefix;
}
final SingleCategoryXacmlAttributesParser<JSONObject> xacmlAttrsParser = xacmlAttrsParserFactory.getInstance();
return process(requestJsonObj.optJSONArray("Category"), xacmlAttrsParser, returnPolicyIdList, combinedDecisionRequested, xPathCompiler, newNsPrefixToUriMap);
}
use of org.ow2.authzforce.xacml.identifiers.XPathVersion in project core by authzforce.
the class CoreStaticPolicyProvider method getInstance.
/**
* Creates an instance from policy locations
*
* @param providerParams location of Policy(Set) elements (JAXB) to be parsed for future reference by Policy(Set)IdReferences
* @param ignoreOldPolicyVersions for any given policy ID, ignore all versions except the last one if there are multiple versions of the policy
* @param xacmlParserFactory XACML parser factory for parsing any XACML Policy(Set)
* @param maxPolicySetRefDepth maximum allowed depth of PolicySet reference chain (via PolicySetIdReference): PolicySet1 -> PolicySet2 -> ...; a strictly negative value means no limit
* @param combiningAlgRegistry registry of policy/rule combining algorithms
* @param expressionFactory Expression factory for parsing Expressions used in the policy(set)
* @param otherPolicyProvider other (supporting) policy provider, used to resolve policy references that do not match any of {@code providerParams}
* @return instance of this class
* @throws java.lang.IllegalArgumentException if {@code policyURLs == null || policyURLs.length == 0 || xacmlParserFactory == null || expressionFactory == null || combiningAlgRegistry == null}; or one of {@code policyURLs} is
* null or is not a valid XACML Policy(Set) or conflicts with another because it has same Policy(Set)Id and Version. Beware that the Policy(Set)Issuer is ignored from this check!
*/
public static CoreStaticPolicyProvider getInstance(final List<StaticPolicyProviderInParam> providerParams, final boolean ignoreOldPolicyVersions, final XmlnsFilteringParserFactory xacmlParserFactory, final int maxPolicySetRefDepth, final ExpressionFactory expressionFactory, final CombiningAlgRegistry combiningAlgRegistry, final Optional<StaticPolicyProvider> otherPolicyProvider) throws IllegalArgumentException {
if (providerParams == null || providerParams.isEmpty()) {
throw ILLEGAL_POLICY_URLS_ARGUMENT_EXCEPTION;
}
if (xacmlParserFactory == null) {
throw ILLEGAL_XACML_PARSER_FACTORY_ARGUMENT_EXCEPTION;
}
if (expressionFactory == null) {
throw ILLEGAL_EXPRESSION_FACTORY_ARGUMENT_EXCEPTION;
}
if (combiningAlgRegistry == null) {
throw ILLEGAL_COMBINING_ALG_REGISTRY_ARGUMENT_EXCEPTION;
}
final XmlnsFilteringParser xacmlParser;
try {
xacmlParser = xacmlParserFactory.getInstance();
} catch (final JAXBException e) {
throw new IllegalArgumentException("Failed to create JAXB unmarshaller for XML Policy(Set)", e);
}
final Table<String, PolicyVersion, StaticTopLevelPolicyElementEvaluator> updatablePolicyTable = HashBasedTable.create();
final Table<String, PolicyVersion, PolicyWithNamespaces<PolicySet>> updatablePolicySetTable = HashBasedTable.create();
int providerParamIndex = 0;
for (final StaticPolicyProviderInParam providerParam : providerParams) {
if (providerParam == null) {
throw new IllegalArgumentException("Policy provider parameter #" + providerParamIndex + " undefined");
}
final Object jaxbPolicyOrPolicySetObj;
if (providerParam instanceof XacmlPolicyParam) {
jaxbPolicyOrPolicySetObj = ((XacmlPolicyParam) providerParam).policy;
} else {
final URL policyURL = ((PolicyLocationParam) providerParam).policyLocation;
try {
jaxbPolicyOrPolicySetObj = xacmlParser.parse(policyURL);
} catch (final JAXBException e) {
throw new IllegalArgumentException("Failed to unmarshall Policy(Set) XML document from policy location: " + policyURL, e);
}
}
final ImmutableMap<String, String> nsPrefixUriMap = xacmlParser.getNamespacePrefixUriMap();
if (jaxbPolicyOrPolicySetObj instanceof Policy) {
final Policy jaxbPolicy = (Policy) jaxbPolicyOrPolicySetObj;
final String policyId = jaxbPolicy.getPolicyId();
final String policyVersionStr = jaxbPolicy.getVersion();
final PolicyVersion policyVersion = new PolicyVersion(policyVersionStr);
if (ignoreOldPolicyVersions) {
final Map<PolicyVersion, StaticTopLevelPolicyElementEvaluator> updatablePolicyVersions = updatablePolicyTable.row(policyId);
// Empty map returned if no mappings
final boolean isOld = updatablePolicyVersions.keySet().parallelStream().anyMatch(v -> policyVersion.compareTo(v) <= 0);
if (isOld) {
// skip
continue;
}
/*
* Else replace/overwrite with this new version (make sure it is the only one), so empty the row first
*/
updatablePolicyVersions.clear();
}
final StaticTopLevelPolicyElementEvaluator policyEvaluator;
try {
/*
XPath compiler shall be initialized in PolicyEvaluators#getInstance(...) based on PolicyDefaults/XPathVersion if present
*/
policyEvaluator = PolicyEvaluators.getInstance(jaxbPolicy, expressionFactory, combiningAlgRegistry, Optional.empty(), nsPrefixUriMap);
} catch (final IllegalArgumentException e) {
throw new IllegalArgumentException("Invalid Policy with PolicyId=" + policyId + ", Version=" + policyVersionStr, e);
}
final StaticTopLevelPolicyElementEvaluator previousValue = updatablePolicyTable.put(policyId, policyVersion, policyEvaluator);
if (previousValue != null) {
throw new IllegalArgumentException("Policy conflict: two policies with same PolicyId=" + policyId + ", Version=" + policyVersionStr);
}
} else if (jaxbPolicyOrPolicySetObj instanceof PolicySet) {
final PolicySet jaxbPolicySet = (PolicySet) jaxbPolicyOrPolicySetObj;
final String policyId = jaxbPolicySet.getPolicySetId();
final String policyVersionStr = jaxbPolicySet.getVersion();
final PolicyVersion policyVersion = new PolicyVersion(policyVersionStr);
if (ignoreOldPolicyVersions) {
final Map<PolicyVersion, PolicyWithNamespaces<PolicySet>> updatablePolicyVersions = updatablePolicySetTable.row(policyId);
// Empty map returned if no mapping
final boolean isOld = updatablePolicyVersions.keySet().parallelStream().anyMatch(v -> policyVersion.compareTo(v) <= 0);
if (isOld) {
// skip
continue;
}
/*
* Else replace/overwrite with this new version (make sure it is the only one), so empty the row first
*/
updatablePolicyVersions.clear();
}
final PolicyWithNamespaces<PolicySet> previousValue = updatablePolicySetTable.put(policyId, policyVersion, new PolicyWithNamespaces<>(jaxbPolicySet, nsPrefixUriMap));
if (previousValue != null) {
throw new IllegalArgumentException("Policy conflict: two PolicySets with same PolicySetId=" + policyId + ", Version=" + policyVersionStr);
}
/*
* PolicySets cannot be parsed before we have collected them all, because each PolicySet may refer to others via PolicySetIdReferences
*/
} else {
throw new IllegalArgumentException("Unexpected element found as root of the policy document: " + jaxbPolicyOrPolicySetObj.getClass().getSimpleName());
}
providerParamIndex++;
}
final PolicyMap<StaticTopLevelPolicyElementEvaluator> policyMap = new PolicyMap<>(updatablePolicyTable.rowMap());
final PolicyMap<PolicyWithNamespaces<PolicySet>> policySetMap = new PolicyMap<>(updatablePolicySetTable.rowMap());
return new CoreStaticPolicyProvider(policyMap, policySetMap, maxPolicySetRefDepth, expressionFactory, combiningAlgRegistry, otherPolicyProvider);
}
use of org.ow2.authzforce.xacml.identifiers.XPathVersion in project core by authzforce.
the class ConditionEvaluators method getInstance.
/**
* Instantiates a Condition evaluator from XACML-Schema-derived <code>Condition</code>
*
* @param condition
* XACML-schema-derived JAXB Condition element
* @param expressionFactory
* expression factory
* @param xPathCompiler
* XPath compiler, defined if XPath support enabled (by PDP configuration and some enclosing Policy(Set) defines a XPathVersion according to XACML standard)
* @return instance of Condition evaluator
* @throws java.lang.IllegalArgumentException
* if the expression is not a valid boolean Expression
*/
public static BooleanEvaluator getInstance(final Condition condition, final ExpressionFactory expressionFactory, final Optional<XPathCompilerProxy> xPathCompiler) throws IllegalArgumentException {
if (condition == null) {
return TRUE_CONDITION;
}
/*
* condition != null -> condition's Expression is not null (by definition of XACML schema), therefore expressionFactory is needed
*/
final ExpressionType exprElt = condition.getExpression().getValue();
if (expressionFactory == null) {
throw NULL_EXPR_FACTORY_ARGUMENT_EXCEPTION;
}
final Expression<?> expr = expressionFactory.getInstance(exprElt, null, xPathCompiler);
// make sure it's a boolean expression...
if (!(expr.getReturnType().equals(StandardDatatypes.BOOLEAN))) {
throw new IllegalArgumentException("Invalid return datatype (" + expr.getReturnType() + ") for Expression (" + expr.getClass().getSimpleName() + ") in Condition. Expected: Boolean.");
}
// WARNING: unchecked cast
final Expression<BooleanValue> evaluableExpression = (Expression<BooleanValue>) expr;
/*
* Check whether the expression is constant
*/
final Optional<BooleanValue> constant = evaluableExpression.getValue();
if (constant.isPresent()) {
if (constant.get().getUnderlyingValue()) {
// constant TRUE
LOGGER.warn("Condition's expression is equivalent to constant True -> optimization: replacing with constant True condition");
return TRUE_CONDITION;
}
// constant False -> unacceptable
throw INVALID_CONSTANT_FALSE_EXPRESSION_EXCEPTION;
}
// constant == null
LOGGER.debug("Condition's Expression is not constant (evaluation without context failed)");
return new BooleanExpressionEvaluator(evaluableExpression);
}
Aggregations