Search in sources :

Example 1 with XPathVersion

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;
}
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 XPathVersion

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);
    }
}
Also used : Policy(oasis.names.tc.xacml._3_0.core.schema.wd_17.Policy) IndeterminateEvaluationException(org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException)

Example 3 with XPathVersion

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);
}
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 4 with XPathVersion

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);
}
Also used : Policy(oasis.names.tc.xacml._3_0.core.schema.wd_17.Policy) java.util(java.util) org.ow2.authzforce.core.pdp.api.policy(org.ow2.authzforce.core.pdp.api.policy) URL(java.net.URL) LoggerFactory(org.slf4j.LoggerFactory) HashBasedTable(com.google.common.collect.HashBasedTable) CombiningAlgRegistry(org.ow2.authzforce.core.pdp.api.combining.CombiningAlgRegistry) EnvironmentProperties(org.ow2.authzforce.core.pdp.api.EnvironmentProperties) Matcher(java.util.regex.Matcher) Policy(oasis.names.tc.xacml._3_0.core.schema.wd_17.Policy) Path(java.nio.file.Path) Logger(org.slf4j.Logger) ImmutableMap(com.google.common.collect.ImmutableMap) MalformedURLException(java.net.MalformedURLException) Files(java.nio.file.Files) XmlnsFilteringParser(org.ow2.authzforce.core.pdp.api.XmlUtils.XmlnsFilteringParser) IOException(java.io.IOException) JAXBException(javax.xml.bind.JAXBException) FileNotFoundException(java.io.FileNotFoundException) IndeterminateEvaluationException(org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException) ResourceUtils(org.springframework.util.ResourceUtils) PolicySet(oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySet) Stream(java.util.stream.Stream) ExpressionFactory(org.ow2.authzforce.core.pdp.api.expression.ExpressionFactory) XmlnsFilteringParserFactory(org.ow2.authzforce.core.pdp.api.XmlUtils.XmlnsFilteringParserFactory) Paths(java.nio.file.Paths) Entry(java.util.Map.Entry) Pattern(java.util.regex.Pattern) Table(com.google.common.collect.Table) URL(java.net.URL) PolicySet(oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySet) XmlnsFilteringParser(org.ow2.authzforce.core.pdp.api.XmlUtils.XmlnsFilteringParser) JAXBException(javax.xml.bind.JAXBException) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 5 with XPathVersion

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);
}
Also used : Expression(org.ow2.authzforce.core.pdp.api.expression.Expression) BooleanValue(org.ow2.authzforce.core.pdp.api.value.BooleanValue) ExpressionType(oasis.names.tc.xacml._3_0.core.schema.wd_17.ExpressionType)

Aggregations

XPathCompilerProxy (org.ow2.authzforce.core.pdp.api.expression.XPathCompilerProxy)3 XPathVersion (org.ow2.authzforce.xacml.identifiers.XPathVersion)3 Policy (oasis.names.tc.xacml._3_0.core.schema.wd_17.Policy)2 IndeterminateEvaluationException (org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException)2 BasicImmutableXPathCompilerProxy (org.ow2.authzforce.core.pdp.api.expression.BasicImmutableXPathCompilerProxy)2 HashBasedTable (com.google.common.collect.HashBasedTable)1 ImmutableMap (com.google.common.collect.ImmutableMap)1 Table (com.google.common.collect.Table)1 FileNotFoundException (java.io.FileNotFoundException)1 IOException (java.io.IOException)1 Serializable (java.io.Serializable)1 MalformedURLException (java.net.MalformedURLException)1 URL (java.net.URL)1 Files (java.nio.file.Files)1 Path (java.nio.file.Path)1 Paths (java.nio.file.Paths)1 java.util (java.util)1 Entry (java.util.Map.Entry)1 Matcher (java.util.regex.Matcher)1 Pattern (java.util.regex.Pattern)1