Search in sources :

Example 1 with XPathCompilerProxy

use of org.ow2.authzforce.core.pdp.api.expression.XPathCompilerProxy 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;
}
Also used : Serializable(java.io.Serializable) BaseXPathCompilerProxy(org.ow2.authzforce.core.pdp.api.expression.BaseXPathCompilerProxy) XPathCompilerProxy(org.ow2.authzforce.core.pdp.api.expression.XPathCompilerProxy) BooleanEvaluator(org.ow2.authzforce.core.pdp.impl.BooleanEvaluator) CombiningAlgParameter(org.ow2.authzforce.core.pdp.api.combining.CombiningAlgParameter) VariableReference(org.ow2.authzforce.core.pdp.api.expression.VariableReference) RuleEvaluator(org.ow2.authzforce.core.pdp.impl.rule.RuleEvaluator) XPathVersion(org.ow2.authzforce.xacml.identifiers.XPathVersion)

Example 2 with XPathCompilerProxy

use of org.ow2.authzforce.core.pdp.api.expression.XPathCompilerProxy 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);
}
Also used : ValidationException(org.everit.json.schema.ValidationException) JSONObject(org.json.JSONObject) BasicImmutableXPathCompilerProxy(org.ow2.authzforce.core.pdp.api.expression.BasicImmutableXPathCompilerProxy) BasicImmutableXPathCompilerProxy(org.ow2.authzforce.core.pdp.api.expression.BasicImmutableXPathCompilerProxy) XPathCompilerProxy(org.ow2.authzforce.core.pdp.api.expression.XPathCompilerProxy) XPathVersion(org.ow2.authzforce.xacml.identifiers.XPathVersion)

Example 3 with XPathCompilerProxy

use of org.ow2.authzforce.core.pdp.api.expression.XPathCompilerProxy in project core-pdp-api by authzforce.

the class XPathValue method evaluate.

/**
 * Convenient method to get the XML nodes ("node-set") matching the XPath expression from the Content node of the XACML Attributes element with category <i>XPathCategory</i> in this
 * {@code context}. <i>XPathCategory</i> is extracted from the attribute of the same name in {@code otherXmlAttributes} argument passed to {@link #XPathValue(String, Map, XPathCompilerProxy)} when
 * creating this instance. To be used by XPath-based functions defined in section A.3.15 of XACML 3.0 Core specification.
 *
 * @param context
 *            current evaluation context
 * @return node-set
 * @throws org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException
 *             error evaluating the XPath expression
 */
public XdmValue evaluate(final EvaluationContext context) throws IndeterminateEvaluationException {
    if (context == null) {
        throw this.missingContextException;
    }
    final XdmNode contentNode = context.getAttributesContent(this.xpathCategory);
    if (contentNode == null) {
        throw this.missingAttributesContentException;
    }
    /*
		 * An XPathExecutable is immutable, and therefore thread-safe. It is simpler to load a new XPathSelector each time the expression is to be evaluated. However, the XPathSelector is serially
		 * reusable within a single thread. See Saxon Javadoc.
		 */
    final XPathSelector xpathSelector = xPathEvaluator.load();
    try {
        for (final VariableReference<?> xpathVar : xpathVariables) {
            final Value val = context.getVariableValue(xpathVar.getVariableId(), xpathVar.getReturnType());
            xpathSelector.setVariable(xpathVar.getXPathVariableName(), val.getXdmValue());
        }
        xpathSelector.setContextItem(contentNode);
        return xpathSelector.evaluate();
    } catch (final SaxonApiException e) {
        throw new IndeterminateEvaluationException(this.xpathEvalExceptionStatus, e);
    }
}
Also used : IndeterminateEvaluationException(org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException)

Example 4 with XPathCompilerProxy

use of org.ow2.authzforce.core.pdp.api.expression.XPathCompilerProxy in project core by authzforce.

the class SingleDecisionXacmlJsonRequestPreprocessor method process.

@Override
public List<IndividualXacmlJsonRequest> process(final JSONArray jsonArrayOfRequestAttributeCategoryObjects, final SingleCategoryXacmlAttributesParser<JSONObject> xacmlAttrsParser, final boolean isApplicablePolicyIdListReturned, final boolean combinedDecision, final Optional<XPathCompilerProxy> xPathCompiler, final Map<String, String> namespaceURIsByPrefix) throws IndeterminateEvaluationException {
    final Map<AttributeFqn, AttributeBag<?>> namedAttributes = HashCollections.newUpdatableMap(jsonArrayOfRequestAttributeCategoryObjects.length());
    /*
		 * TODO: Content object not supported yet (optional in XACML)
		 */
    final Map<String, XdmNode> extraContentsByCategory = Collections.emptyMap();
    /*
		 * requestAttributeCategoryObjectsIncludedInResult.size() <= jsonArrayOfRequestAttributeCategoryObjects.size()
		 */
    final List<JSONObject> requestAttributeCategoryObjectsIncludedInResult = new ArrayList<>(jsonArrayOfRequestAttributeCategoryObjects.length());
    for (final Object requestAttributeCategoryObject : jsonArrayOfRequestAttributeCategoryObjects) {
        if (!(requestAttributeCategoryObject instanceof JSONObject)) {
            throw INVALID_REQUEST_CATEGORY_ARRAY_ELEMENT_TYPE_EXCEPTION;
        }
        final JSONObject requestAttCatJsonObj = (JSONObject) requestAttributeCategoryObject;
        final SingleCategoryAttributes<?, JSONObject> categorySpecificAttributes = xacmlAttrsParser.parseAttributes(requestAttCatJsonObj, xPathCompiler);
        if (categorySpecificAttributes == null) {
            // skip this empty Attributes
            continue;
        }
        /*
			 * Convert growable (therefore mutable) bag of attribute values to immutable ones. Indeed, we must guarantee that attribute values remain constant during the evaluation of the request, as
			 * mandated by the XACML spec, section 7.3.5: <p> <i>
			 * "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<AttributeFqn, AttributeBag<?>> attrEntry : categorySpecificAttributes) {
            namedAttributes.put(attrEntry.getKey(), attrEntry.getValue());
        }
        final JSONObject catSpecificAttrsToIncludeInResult = categorySpecificAttributes.getAttributesToIncludeInResult();
        if (catSpecificAttrsToIncludeInResult != null) {
            requestAttributeCategoryObjectsIncludedInResult.add(catSpecificAttrsToIncludeInResult);
        }
    }
    final ImmutableDecisionRequest pdpEngineReq = reqFactory.getInstance(namedAttributes, extraContentsByCategory, isApplicablePolicyIdListReturned);
    return Collections.singletonList(new IndividualXacmlJsonRequest(pdpEngineReq, ImmutableList.copyOf(requestAttributeCategoryObjectsIncludedInResult)));
}
Also used : XdmNode(net.sf.saxon.s9api.XdmNode) JSONObject(org.json.JSONObject) JSONObject(org.json.JSONObject) AttributeBag(org.ow2.authzforce.core.pdp.api.value.AttributeBag)

Example 5 with XPathCompilerProxy

use of org.ow2.authzforce.core.pdp.api.expression.XPathCompilerProxy in project core by authzforce.

the class SingleDecisionXacmlJaxbRequestPreprocessor method process.

@Override
public List<IndividualXacmlJaxbRequest> process(final List<Attributes> attributesList, final SingleCategoryXacmlAttributesParser<Attributes> xacmlAttrsParser, final boolean isApplicablePolicyIdListReturned, final boolean combinedDecision, final Optional<XPathCompilerProxy> xPathCompiler, final Map<String, String> namespaceURIsByPrefix) throws IndeterminateEvaluationException {
    final Map<AttributeFqn, AttributeBag<?>> namedAttributes = HashCollections.newUpdatableMap(attributesList.size());
    final Map<String, XdmNode> extraContentsByCategory = HashCollections.newUpdatableMap(attributesList.size());
    /*
		 * attributesToIncludeInResult.size() <= attributesList.size()
		 */
    final List<Attributes> attributesToIncludeInResult = new ArrayList<>(attributesList.size());
    for (final Attributes jaxbAttributes : attributesList) {
        final SingleCategoryAttributes<?, Attributes> categorySpecificAttributes = xacmlAttrsParser.parseAttributes(jaxbAttributes, xPathCompiler);
        if (categorySpecificAttributes == null) {
            // skip this empty Attributes
            continue;
        }
        final String categoryId = categorySpecificAttributes.getCategoryId();
        final XdmNode newContentNode = categorySpecificAttributes.getExtraContent();
        if (newContentNode != null) {
            final XdmNode duplicate = extraContentsByCategory.putIfAbsent(categoryId, newContentNode);
            /*
				 * No support for Multiple Decision Profile -> no support for repeated categories as specified in Multiple Decision Profile. So we must check duplicate attribute categories.
				 */
            if (duplicate != null) {
                throw new IndeterminateEvaluationException("Unsupported repetition of Attributes[@Category='" + categoryId + "'] (feature 'urn:oasis:names:tc:xacml:3.0:profile:multiple:repeated-attribute-categories' is not supported)", XacmlStatusCode.SYNTAX_ERROR.value());
            }
        }
        /*
			 * Convert growable (therefore mutable) bag of attribute values to immutable ones. Indeed, we must guarantee that attribute values remain constant during the evaluation of the request, as
			 * mandated by the XACML spec, section 7.3.5: <p> <i>
			 * "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<AttributeFqn, AttributeBag<?>> attrEntry : categorySpecificAttributes) {
            namedAttributes.put(attrEntry.getKey(), attrEntry.getValue());
        }
        final Attributes catSpecificAttrsToIncludeInResult = categorySpecificAttributes.getAttributesToIncludeInResult();
        if (catSpecificAttrsToIncludeInResult != null) {
            attributesToIncludeInResult.add(catSpecificAttrsToIncludeInResult);
        }
    }
    return Collections.singletonList(new IndividualXacmlJaxbRequest(reqFactory.getInstance(namedAttributes, extraContentsByCategory, isApplicablePolicyIdListReturned), ImmutableList.copyOf(attributesToIncludeInResult)));
}
Also used : SingleCategoryAttributes(org.ow2.authzforce.core.pdp.api.io.SingleCategoryAttributes) Attributes(oasis.names.tc.xacml._3_0.core.schema.wd_17.Attributes) XdmNode(net.sf.saxon.s9api.XdmNode) IndividualXacmlJaxbRequest(org.ow2.authzforce.core.pdp.api.io.IndividualXacmlJaxbRequest) AttributeBag(org.ow2.authzforce.core.pdp.api.value.AttributeBag)

Aggregations

XPathCompilerProxy (org.ow2.authzforce.core.pdp.api.expression.XPathCompilerProxy)3 XPathVersion (org.ow2.authzforce.xacml.identifiers.XPathVersion)3 XdmNode (net.sf.saxon.s9api.XdmNode)2 Attributes (oasis.names.tc.xacml._3_0.core.schema.wd_17.Attributes)2 JSONObject (org.json.JSONObject)2 BasicImmutableXPathCompilerProxy (org.ow2.authzforce.core.pdp.api.expression.BasicImmutableXPathCompilerProxy)2 AttributeBag (org.ow2.authzforce.core.pdp.api.value.AttributeBag)2 Serializable (java.io.Serializable)1 ExpressionType (oasis.names.tc.xacml._3_0.core.schema.wd_17.ExpressionType)1 RequestDefaults (oasis.names.tc.xacml._3_0.core.schema.wd_17.RequestDefaults)1 ValidationException (org.everit.json.schema.ValidationException)1 AttributeFqn (org.ow2.authzforce.core.pdp.api.AttributeFqn)1 IndeterminateEvaluationException (org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException)1 CombiningAlgParameter (org.ow2.authzforce.core.pdp.api.combining.CombiningAlgParameter)1 BaseXPathCompilerProxy (org.ow2.authzforce.core.pdp.api.expression.BaseXPathCompilerProxy)1 Expression (org.ow2.authzforce.core.pdp.api.expression.Expression)1 VariableReference (org.ow2.authzforce.core.pdp.api.expression.VariableReference)1 IndividualXacmlJaxbRequest (org.ow2.authzforce.core.pdp.api.io.IndividualXacmlJaxbRequest)1 SingleCategoryAttributes (org.ow2.authzforce.core.pdp.api.io.SingleCategoryAttributes)1 BooleanValue (org.ow2.authzforce.core.pdp.api.value.BooleanValue)1