Search in sources :

Example 1 with PrimaryPolicyMetadata

use of org.ow2.authzforce.core.pdp.api.policy.PrimaryPolicyMetadata in project core by authzforce.

the class PolicyEvaluators method getInstanceGeneric.

/**
 * Generic creation of PolicySet evaluator
 *
 * @param policySetRefChainWithArgIffRefTarget null/empty if {@code policyElement} is the root policySet; else it is the chain of top-level (as opposed to nested inline) PolicySets linked by PolicySetIdReferences from the root
 *                                             PolicySet up to (and including) the top-level (PolicySetIdReference-targeted) PolicySet that encloses or is {@code policyElement}
 */
private static <TLPEE extends TopLevelPolicyElementEvaluator, COMBINED_EVALUATOR extends PolicyEvaluator> TLPEE getInstanceGeneric(final PolicySetElementEvaluatorFactory<TLPEE, COMBINED_EVALUATOR> policyEvaluatorFactory, final PolicySet policyElement, final Deque<String> policySetRefChainWithArgIffRefTarget) throws IllegalArgumentException {
    assert policyEvaluatorFactory != null && policyElement != null;
    // final Set<PrimaryPolicyMetadata> enclosedPolicies = HashCollections.newUpdatableSet();
    final String policyId = policyElement.getPolicySetId();
    final BooleanEvaluator targetEvaluator = TargetEvaluators.getInstance(policyElement.getTarget(), policyEvaluatorFactory.expressionFactory, policyEvaluatorFactory.defaultXPathCompiler);
    /*
         * Elements defined in xs:choice of PolicySetType in XACML schema (Policy(Set)/Policy(Set)IdReference/CombinerParameters/Policy(Set)CombinerParameters
         */
    final List<Serializable> jaxbPolicySetChoiceElements = policyElement.getPolicySetsAndPoliciesAndPolicySetIdReferences();
    /*
         * Prepare the list of evaluators combined by the combining algorithm in this PolicySet, i.e. Policy(Set)/Policy(Set)IdReference evaluators. combinedEvaluators.size() <=
         * jaxbPolicySetChoiceElements.size() since combinedEvaluators does not include *CombinerParameter evaluators
         */
    final List<COMBINED_EVALUATOR> combinedEvaluators = new ArrayList<>(jaxbPolicySetChoiceElements.size());
    /*
         * Why isn't there any VariableDefinition in XACML PolicySet like in Policy? If there were, we would keep a copy of variable IDs defined in this policy, to remove them from the global manager
         * at the end of parsing this PolicySet. They should not be visible outside the scope of this.
         * <p>
         * final Set<String> variableIds = HashCollections.newUpdatableSet(jaxbPolicySetChoiceElements.size());
         */
    /*
         * Map to get child Policies by their ID so that we can resolve Policies associated with PolicyCombinerParameters Size cannot get bigger than jaxbPolicySetChoiceElements.size()
         */
    final Map<String, COMBINED_EVALUATOR> childPolicyEvaluatorsByPolicyId = HashCollections.newUpdatableMap(jaxbPolicySetChoiceElements.size());
    /*
         * Map to get child PolicySets by their ID so that we can resolve PolicySets associated with PolicySetCombinerParameters Size cannot get bigger than jaxbPolicySetChoiceElements.size()
         */
    final Map<String, COMBINED_EVALUATOR> childPolicySetEvaluatorsByPolicySetId = HashCollections.newUpdatableMap(jaxbPolicySetChoiceElements.size());
    /*
         * *CombinerParameters (combining algorithm parameters), size <= jaxbPolicySetChoiceElements.size()
         */
    final List<CombiningAlgParameter<? extends COMBINED_EVALUATOR>> combiningAlgParameters = new ArrayList<>(jaxbPolicySetChoiceElements.size());
    int childIndex = 0;
    for (final Serializable policyChildElt : jaxbPolicySetChoiceElements) {
        if (policyChildElt instanceof PolicyCombinerParameters) {
            final String combinedPolicyId = ((PolicyCombinerParameters) policyChildElt).getPolicyIdRef();
            final COMBINED_EVALUATOR childPolicyEvaluator = childPolicyEvaluatorsByPolicyId.get(combinedPolicyId);
            if (childPolicyEvaluator == null) {
                throw new IllegalArgumentException(policyEvaluatorFactory.policyMetadata + ":  invalid PolicyCombinerParameters: referencing undefined child Policy #" + combinedPolicyId + " (no such policy defined before this element)");
            }
            final BaseCombiningAlgParameter<COMBINED_EVALUATOR> combiningAlgParameter;
            try {
                combiningAlgParameter = new BaseCombiningAlgParameter<>(childPolicyEvaluator, ((CombinerParametersType) policyChildElt).getCombinerParameters(), policyEvaluatorFactory.expressionFactory, policyEvaluatorFactory.defaultXPathCompiler);
            } catch (final IllegalArgumentException e) {
                throw new IllegalArgumentException(policyEvaluatorFactory.policyMetadata + ": invalid child #" + childIndex + " (PolicyCombinerParameters)", e);
            }
            combiningAlgParameters.add(combiningAlgParameter);
        } else if (policyChildElt instanceof PolicySetCombinerParameters) {
            final String combinedPolicySetId = ((PolicySetCombinerParameters) policyChildElt).getPolicySetIdRef();
            final COMBINED_EVALUATOR combinedPolicySetEvaluator = childPolicySetEvaluatorsByPolicySetId.get(combinedPolicySetId);
            if (combinedPolicySetEvaluator == null) {
                throw new IllegalArgumentException(policyEvaluatorFactory.policyMetadata + ":  invalid PolicySetCombinerParameters: referencing undefined child PolicySet #" + combinedPolicySetId + " (no such policySet defined before this element)");
            }
            final BaseCombiningAlgParameter<COMBINED_EVALUATOR> combiningAlgParameter;
            try {
                combiningAlgParameter = new BaseCombiningAlgParameter<>(combinedPolicySetEvaluator, ((CombinerParametersType) policyChildElt).getCombinerParameters(), policyEvaluatorFactory.expressionFactory, policyEvaluatorFactory.defaultXPathCompiler);
            } catch (final IllegalArgumentException e) {
                throw new IllegalArgumentException(policyEvaluatorFactory.policyMetadata + ": invalid child #" + childIndex + " (PolicySetCombinerParameters)", e);
            }
            combiningAlgParameters.add(combiningAlgParameter);
        } else if (policyChildElt instanceof JAXBElement) {
            final JAXBElement<?> jaxbPolicyChildElt = (JAXBElement<?>) policyChildElt;
            final String eltNameLocalPart = jaxbPolicyChildElt.getName().getLocalPart();
            if (eltNameLocalPart.equals(XacmlNodeName.POLICY_ID_REFERENCE.value())) {
                final IdReferenceType policyChildIdRef = (IdReferenceType) jaxbPolicyChildElt.getValue();
                final COMBINED_EVALUATOR childEvaluator = policyEvaluatorFactory.getChildPolicyRefEvaluator(childIndex, TopLevelPolicyElementType.POLICY, policyChildIdRef, null);
                combinedEvaluators.add(childEvaluator);
                final COMBINED_EVALUATOR duplicate = childPolicySetEvaluatorsByPolicySetId.putIfAbsent(childEvaluator.getPolicyId(), childEvaluator);
                if (duplicate != null) {
                    throw new IllegalArgumentException("Duplicate PolicyIdReference's id = " + childEvaluator.getPolicyId());
                }
            } else if (eltNameLocalPart.equals(XacmlNodeName.POLICYSET_ID_REFERENCE.value())) {
                final IdReferenceType policyChildIdRef = (IdReferenceType) jaxbPolicyChildElt.getValue();
                final String policyChildId = policyChildIdRef.getValue();
                /*
                     * Add this new reference to policyChildIdRef to the policyRef chain arg of getChildPolicyRefEvaluator(...). If policySetRefChainWithArgIffRefTarget is null/empty, policyElement is
                     * the root policy (no ancestor in the chain), therefore it should be added before policyChildIdRef, as the antecedent; Else non-empty policySetRefChainWithArgIffRefTarget's last
                     * item is either policyElement (iff it is a policy ref's target) or the top-level (as opposed to nested inline) PolicySet that encloses policyElement, in which either case we just
                     * add policyChildIdRef to the chain.
                     */
                final Deque<String> newPolicySetRefChainWithArgIffRefTarget = policySetRefChainWithArgIffRefTarget == null || policySetRefChainWithArgIffRefTarget.isEmpty() ? new ArrayDeque<>(Arrays.asList(policyId, policyChildId)) : policyEvaluatorFactory.joinPolicySetRefChains(policySetRefChainWithArgIffRefTarget, Collections.singletonList(policyChildId));
                final COMBINED_EVALUATOR childEvaluator = policyEvaluatorFactory.getChildPolicyRefEvaluator(childIndex, TopLevelPolicyElementType.POLICY_SET, policyChildIdRef, newPolicySetRefChainWithArgIffRefTarget);
                combinedEvaluators.add(childEvaluator);
                final COMBINED_EVALUATOR duplicate = childPolicySetEvaluatorsByPolicySetId.put(policyChildId, childEvaluator);
                if (duplicate != null) {
                    throw new IllegalArgumentException("Duplicate PolicySetIdReference's id = " + policyChildId);
                }
            } else if (eltNameLocalPart.equals(XacmlNodeName.COMBINER_PARAMETERS.value())) {
                /*
                     * CombinerParameters that is not Policy(Set)CombinerParameters already tested before
                     */
                final BaseCombiningAlgParameter<COMBINED_EVALUATOR> combiningAlgParameter;
                try {
                    combiningAlgParameter = new BaseCombiningAlgParameter<>(null, ((CombinerParametersType) jaxbPolicyChildElt.getValue()).getCombinerParameters(), policyEvaluatorFactory.expressionFactory, policyEvaluatorFactory.defaultXPathCompiler);
                } catch (final IllegalArgumentException e) {
                    throw new IllegalArgumentException(policyEvaluatorFactory.policyMetadata + ": invalid child #" + childIndex + " (CombinerParameters)", e);
                }
                combiningAlgParameters.add(combiningAlgParameter);
            }
        } else if (policyChildElt instanceof PolicySet) {
            final PolicySet childPolicy = (PolicySet) policyChildElt;
            /*
                 * XACML spec §5.1: "ensure that no two policies visible to the PDP have the same identifier"
                 */
            final String childPolicyId = childPolicy.getPolicySetId();
            /*
                 * Create/Update the policySet ref chain if necessary. If policySetRefChainWithArgIffRefTarget is null/empty, this means policyElement is the root policyset (no antecedent), and we
                 * create a chain with its ID, to know the antecedent of the next encountered policyset ref (which may be found deep under multiple levels of nested PolicySets).; else
                 * policySetRefChainWithArgIffRefTarget's last item is either policyElement (iff it is a policy ref's target) or the top-level (as opposed to nested inline) PolicySet that encloses
                 * policyElement, in which either case we already have the info we need in the chain so keep it as is.
                 */
            final Deque<String> newPolicySetRefChain = policySetRefChainWithArgIffRefTarget == null || policySetRefChainWithArgIffRefTarget.isEmpty() ? new ArrayDeque<>(Collections.singletonList(policyId)) : policySetRefChainWithArgIffRefTarget;
            final COMBINED_EVALUATOR childEvaluator = policyEvaluatorFactory.getChildPolicySetEvaluator(childIndex, childPolicy, newPolicySetRefChain);
            combinedEvaluators.add(childEvaluator);
            final COMBINED_EVALUATOR duplicate = childPolicySetEvaluatorsByPolicySetId.putIfAbsent(childPolicyId, childEvaluator);
            if (duplicate != null) {
                throw new IllegalArgumentException("Duplicate PolicySetId = " + childPolicyId);
            }
        } else if (policyChildElt instanceof Policy) {
            final Policy childPolicy = (Policy) policyChildElt;
            /*
                 * XACML spec §5.1: "ensure that no two policies visible to the PDP have the same identifier"
                 */
            final String childPolicyId = childPolicy.getPolicyId();
            final COMBINED_EVALUATOR childEvaluator = policyEvaluatorFactory.getChildPolicyEvaluator(childIndex, childPolicy);
            combinedEvaluators.add(childEvaluator);
            final COMBINED_EVALUATOR duplicate = childPolicyEvaluatorsByPolicyId.putIfAbsent(childPolicyId, childEvaluator);
            if (duplicate != null) {
                throw new IllegalArgumentException("Duplicate PolicyId = " + childPolicyId);
            }
        }
        /*
             * Why isn't there any VariableDefinition in XACML PolicySet defined by OASIS XACML 3.0 spec, like in Policy? If there were, the following code would be used (same as in PolicyEvaluator
             * class).
             */
        // else if (policySetChildElt instanceof VariableDefinition)
        // {
        // final VariableDefinition varDef = (VariableDefinition)
        // policyChildElt;
        // final Deque<String> varDefLongestVarRefChain = new
        // ArrayDeque<>();
        // final VariableReference<?> var;
        // try
        // {
        // var = expressionFactory.addVariable(varDef, defaultXPathCompiler,
        // varDefLongestVarRefChain);
        // } catch (IllegalArgumentException e)
        // {
        // throw new IllegalArgumentException(policyFriendlyId + ": 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(policyFriendlyId + ":
        // Duplicable VariableDefinition for VariableId=" +
        // var.getVariableId());
        // }
        // 
        // localVariableIds.add(varDef.getVariableId());
        // // 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;
        // }
        // }
        childIndex++;
    }
    /*
         * Why isn't there any VariableDefinition in XACML PolicySet like in Policy? If there were, the final following code would be used: We are done parsing expressions in this policy, including
         * VariableReferences, it's time to remove variables scoped to this policy from the variable manager
         */
    // for (final String varId : variableIds)
    // {
    // expFactory.remove(varId);
    // }
    final ObligationExpressions obligationExps = policyElement.getObligationExpressions();
    final AdviceExpressions adviceExps = policyElement.getAdviceExpressions();
    return policyEvaluatorFactory.getInstance(policyEvaluatorFactory.policyMetadata, targetEvaluator, ImmutableList.of(), policyElement.getPolicyCombiningAlgId(), ImmutableList.copyOf(combinedEvaluators), ImmutableList.copyOf(combiningAlgParameters), obligationExps == null ? null : obligationExps.getObligationExpressions(), adviceExps == null ? null : adviceExps.getAdviceExpressions());
}
Also used : Serializable(java.io.Serializable) BooleanEvaluator(org.ow2.authzforce.core.pdp.impl.BooleanEvaluator) CombiningAlgParameter(org.ow2.authzforce.core.pdp.api.combining.CombiningAlgParameter) JAXBElement(javax.xml.bind.JAXBElement)

Example 2 with PrimaryPolicyMetadata

use of org.ow2.authzforce.core.pdp.api.policy.PrimaryPolicyMetadata 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 3 with PrimaryPolicyMetadata

use of org.ow2.authzforce.core.pdp.api.policy.PrimaryPolicyMetadata in project core by authzforce.

the class PdpGetStaticApplicablePoliciesTest method test.

@Test
public void test() throws IllegalArgumentException, IOException, URISyntaxException, JAXBException {
    final String testResourceLocationPrefix = TEST_RESOURCES_DIRECTORY_LOCATION + "/";
    /*
		 * Policies
		 * 
		 * If there is a "$TEST_DIR/$POLICIES_DIR_NAME" directory, then load all policies from there, including root policy from "$TEST_DIR/$POLICIES_DIR_NAME/$ROOT_POLICY_FILENAME" Else load only the
		 * root policy from "$TEST_DIR/$ROOT_POLICY_FILENAME"
		 */
    final Path policiesDir = Paths.get(testResourceLocationPrefix + XacmlXmlPdpTest.POLICIES_DIR_NAME);
    final Optional<Path> optPoliciesDir;
    final Path rootPolicyFile;
    if (Files.isDirectory(policiesDir)) {
        optPoliciesDir = Optional.of(policiesDir);
        rootPolicyFile = policiesDir.resolve(XacmlXmlPdpTest.ROOT_POLICY_FILENAME);
    } else {
        optPoliciesDir = Optional.empty();
        rootPolicyFile = Paths.get(testResourceLocationPrefix + XacmlXmlPdpTest.ROOT_POLICY_FILENAME);
    }
    /*
		 * Create PDP
		 */
    final PdpEngineConfiguration pdpEngineConf = optPoliciesDir.isPresent() ? TestUtils.newPdpEngineConfiguration(TestUtils.getPolicyRef(rootPolicyFile), optPoliciesDir.get(), false, Optional.empty(), null, null) : TestUtils.newPdpEngineConfiguration(rootPolicyFile, false, Optional.empty(), null, null);
    try (final PdpEngineInoutAdapter<Request, Response> pdp = PdpEngineAdapters.newXacmlJaxbInoutAdapter(pdpEngineConf)) {
        final Iterable<PrimaryPolicyMetadata> staticApplicablePolicies = pdp.getApplicablePolicies();
        assertNotNull("One of the policies may not be statically resolved", staticApplicablePolicies);
        final Iterator<PrimaryPolicyMetadata> staticApplicablePoliciesIterator = pdp.getApplicablePolicies().iterator();
        assertTrue("No root policy in PDP's applicable policies (statically resolved)", staticApplicablePoliciesIterator.hasNext());
        assertEquals("Invalid root policy in PDP's applicable policies (statically resolved)", ROOT_POLICYSET_METADATA, staticApplicablePoliciesIterator.next());
        for (final PrimaryPolicyMetadata expectedRefPolicyMeta : REF_POLICYSET_METADATA_SET) {
            assertTrue("No (more) referenced policy in PDP's applicable policies (statically resolved) although expected", staticApplicablePoliciesIterator.hasNext());
            assertEquals("Invalid referenced policy in PDP's applicable policies (statically resolved)", expectedRefPolicyMeta, staticApplicablePoliciesIterator.next());
        }
    }
}
Also used : Path(java.nio.file.Path) Response(oasis.names.tc.xacml._3_0.core.schema.wd_17.Response) PdpEngineConfiguration(org.ow2.authzforce.core.pdp.impl.PdpEngineConfiguration) Request(oasis.names.tc.xacml._3_0.core.schema.wd_17.Request) PrimaryPolicyMetadata(org.ow2.authzforce.core.pdp.api.policy.PrimaryPolicyMetadata) XacmlXmlPdpTest(org.ow2.authzforce.core.pdp.testutil.XacmlXmlPdpTest) Test(org.junit.Test)

Example 4 with PrimaryPolicyMetadata

use of org.ow2.authzforce.core.pdp.api.policy.PrimaryPolicyMetadata in project core by authzforce.

the class BaseXacmlJsonResultPostprocessor method convert.

private static JSONObject convert(final IndividualXacmlJsonRequest request, final DecisionResult result) {
    assert request != null && result != null;
    final Map<String, Object> jsonPropertyMap = HashCollections.newUpdatableMap(6);
    // Decision
    jsonPropertyMap.put("Decision", result.getDecision().value());
    // Status
    final Optional<ImmutableXacmlStatus> optStatus = result.getStatus();
    optStatus.ifPresent(immutableXacmlStatus -> jsonPropertyMap.put("Status", toJson(immutableXacmlStatus)));
    // Obligations/Advice
    final ImmutableList<PepAction> pepActions = result.getPepActions();
    assert pepActions != null;
    if (!pepActions.isEmpty()) {
        final int numOfPepActions = pepActions.size();
        final List<JSONObject> jsonObligations = new ArrayList<>(numOfPepActions);
        final List<JSONObject> jsonAdvices = new ArrayList<>(numOfPepActions);
        pepActions.forEach(pepAction -> {
            final JSONObject pepActionJsonObject = toJson(pepAction.getId(), pepAction.getAttributeAssignments());
            final List<JSONObject> pepActionJsonObjects = pepAction.isMandatory() ? jsonObligations : jsonAdvices;
            pepActionJsonObjects.add(pepActionJsonObject);
        });
        if (!jsonObligations.isEmpty()) {
            jsonPropertyMap.put("Obligations", new JSONArray(jsonObligations));
        }
        if (!jsonAdvices.isEmpty()) {
            jsonPropertyMap.put("AssociatedAdvice", new JSONArray(jsonAdvices));
        }
    }
    // IncludeInResult categories
    final List<JSONObject> attributesByCategoryToBeReturned = request.getAttributesByCategoryToBeReturned();
    if (!attributesByCategoryToBeReturned.isEmpty()) {
        jsonPropertyMap.put("Category", new JSONArray(attributesByCategoryToBeReturned));
    }
    // PolicyIdentifierList
    final ImmutableList<PrimaryPolicyMetadata> applicablePolicies = result.getApplicablePolicies();
    if (applicablePolicies != null && !applicablePolicies.isEmpty()) {
        final List<JSONObject> policyRefs = new ArrayList<>(applicablePolicies.size());
        final List<JSONObject> policySetRefs = new ArrayList<>(applicablePolicies.size());
        for (final PrimaryPolicyMetadata applicablePolicy : applicablePolicies) {
            final JSONObject ref = new JSONObject(HashCollections.newImmutableMap("Id", applicablePolicy.getId(), "Version", applicablePolicy.getVersion().toString()));
            final List<JSONObject> refs = applicablePolicy.getType() == TopLevelPolicyElementType.POLICY ? policyRefs : policySetRefs;
            refs.add(ref);
        }
        final Map<String, Object> policyListJsonObjMap = HashCollections.newUpdatableMap(2);
        if (!policyRefs.isEmpty()) {
            policyListJsonObjMap.put("PolicyIdReference", new JSONArray(policyRefs));
        }
        if (!policySetRefs.isEmpty()) {
            policyListJsonObjMap.put("PolicySetIdReference", new JSONArray(policySetRefs));
        }
        jsonPropertyMap.put("PolicyIdentifierList", new JSONObject(policyListJsonObjMap));
    }
    // final Result
    return new JSONObject(jsonPropertyMap);
}
Also used : JSONArray(org.json.JSONArray) PrimaryPolicyMetadata(org.ow2.authzforce.core.pdp.api.policy.PrimaryPolicyMetadata) JSONObject(org.json.JSONObject) JSONObject(org.json.JSONObject)

Example 5 with PrimaryPolicyMetadata

use of org.ow2.authzforce.core.pdp.api.policy.PrimaryPolicyMetadata in project core-pdp-api by authzforce.

the class XacmlJaxbParsingUtils method parseXacmlJaxbResult.

/**
 * Parse/convert XACML/XML Result into AuthzForce decision result
 *
 * @param xacmlResult
 *            XACML/XML Result (XML-schema-derived JAXB model)
 * @param attributeValueFactories
 *            AttributeValue factories (registry of datatype-specific parsers)
 * @return decision result in AuthzForce data model
 */
public static DecisionResult parseXacmlJaxbResult(final Result xacmlResult, final AttributeValueFactoryRegistry attributeValueFactories) {
    final PolicyIdentifierList xacmlPolicyIdentifiers = xacmlResult.getPolicyIdentifierList();
    final ImmutableList<PrimaryPolicyMetadata> immutableApplicablePolicyIdList;
    if (xacmlPolicyIdentifiers == null) {
        immutableApplicablePolicyIdList = null;
    } else {
        final List<PrimaryPolicyMetadata> applicablePolicyIdentifiers = xacmlPolicyIdentifiers.getPolicyIdReferencesAndPolicySetIdReferences().stream().map(jaxbElt -> {
            final IdReferenceType idRef = jaxbElt.getValue();
            return new BasePrimaryPolicyMetadata(jaxbElt.getName().getLocalPart().equals("PolicyIdReference") ? TopLevelPolicyElementType.POLICY : TopLevelPolicyElementType.POLICY_SET, idRef.getValue(), new PolicyVersion(idRef.getVersion()));
        }).collect(Collectors.toList());
        immutableApplicablePolicyIdList = ImmutableList.copyOf(applicablePolicyIdentifiers);
    }
    final Obligations xacmlObligations = xacmlResult.getObligations();
    final List<Obligation> nonNullXacmlObligationList;
    if (xacmlObligations == null) {
        nonNullXacmlObligationList = Collections.emptyList();
    } else {
        final List<Obligation> xacmlObligationList = xacmlObligations.getObligations();
        nonNullXacmlObligationList = xacmlObligationList == null ? Collections.emptyList() : xacmlObligationList;
    }
    final AssociatedAdvice xacmlAdvice = xacmlResult.getAssociatedAdvice();
    final List<Advice> nonNullXacmlAdviceList;
    if (xacmlAdvice == null) {
        nonNullXacmlAdviceList = Collections.emptyList();
    } else {
        final List<Advice> xacmlAdviceList = xacmlAdvice.getAdvices();
        nonNullXacmlAdviceList = xacmlAdviceList == null ? Collections.emptyList() : xacmlAdviceList;
    }
    final ImmutableList<PepAction> pepActions;
    if (nonNullXacmlObligationList.isEmpty() && nonNullXacmlAdviceList.isEmpty()) {
        pepActions = ImmutableList.of();
    } else {
        final List<PepAction> mutablePepActions = new ArrayList<>(nonNullXacmlObligationList.size() + nonNullXacmlAdviceList.size());
        nonNullXacmlObligationList.forEach(xacmlOb -> mutablePepActions.add(new PepAction(xacmlOb.getObligationId(), true, xacmlToAuthzForceAttributeAssignments(xacmlOb.getAttributeAssignments(), attributeValueFactories))));
        nonNullXacmlAdviceList.forEach(xacmlAd -> mutablePepActions.add(new PepAction(xacmlAd.getAdviceId(), false, xacmlToAuthzForceAttributeAssignments(xacmlAd.getAttributeAssignments(), attributeValueFactories))));
        pepActions = ImmutableList.copyOf(mutablePepActions);
    }
    final Status status = xacmlResult.getStatus();
    final Optional<ImmutableXacmlStatus> optImmutableStatus;
    if (status == null) {
        optImmutableStatus = Optional.empty();
    } else {
        // StatusDetail not supported and should be null
        assert status.getStatusDetail() == null;
        optImmutableStatus = Optional.of(new ImmutableXacmlStatus(status.getStatusCode(), status.getStatusMessage()));
    }
    switch(xacmlResult.getDecision()) {
        case DENY:
            return DecisionResults.getDeny(optImmutableStatus, pepActions, immutableApplicablePolicyIdList);
        case PERMIT:
            return DecisionResults.getPermit(optImmutableStatus, pepActions, immutableApplicablePolicyIdList);
        case NOT_APPLICABLE:
            return DecisionResults.getNotApplicable(optImmutableStatus);
        default:
            // Some XACML Status must be defined for Indeterminate Results
            assert optImmutableStatus.isPresent();
            return DecisionResults.newIndeterminate(null, new IndeterminateEvaluationException(optImmutableStatus.get()), immutableApplicablePolicyIdList);
    }
}
Also used : oasis.names.tc.xacml._3_0.core.schema.wd_17(oasis.names.tc.xacml._3_0.core.schema.wd_17) java.util(java.util) AttributeValueFactoryRegistry(org.ow2.authzforce.core.pdp.api.value.AttributeValueFactoryRegistry) NamedAttributeIteratorConverter(org.ow2.authzforce.core.pdp.api.io.SingleCategoryAttributes.NamedAttributeIteratorConverter) AttributeValueFactory(org.ow2.authzforce.core.pdp.api.value.AttributeValueFactory) ImmutableList(com.google.common.collect.ImmutableList) XdmNode(net.sf.saxon.s9api.XdmNode) NoXmlnsFilteringParser(org.ow2.authzforce.core.pdp.api.XmlUtils.NoXmlnsFilteringParser) BasePrimaryPolicyMetadata(org.ow2.authzforce.core.pdp.api.policy.BasePrimaryPolicyMetadata) XacmlStatusCode(org.ow2.authzforce.xacml.identifiers.XacmlStatusCode) Unmarshaller(javax.xml.bind.Unmarshaller) XPathCompilerProxy(org.ow2.authzforce.core.pdp.api.expression.XPathCompilerProxy) Xacml3JaxbHelper(org.ow2.authzforce.xacml.Xacml3JaxbHelper) AttributeValue(org.ow2.authzforce.core.pdp.api.value.AttributeValue) Collectors(java.util.stream.Collectors) Serializable(java.io.Serializable) Element(org.w3c.dom.Element) PrimaryPolicyMetadata(org.ow2.authzforce.core.pdp.api.policy.PrimaryPolicyMetadata) SAXBasedXmlnsFilteringParser(org.ow2.authzforce.core.pdp.api.XmlUtils.SAXBasedXmlnsFilteringParser) XmlnsFilteringParserFactory(org.ow2.authzforce.core.pdp.api.XmlUtils.XmlnsFilteringParserFactory) ConstantExpression(org.ow2.authzforce.core.pdp.api.expression.ConstantExpression) TopLevelPolicyElementType(org.ow2.authzforce.core.pdp.api.policy.TopLevelPolicyElementType) DocumentBuilder(net.sf.saxon.s9api.DocumentBuilder) org.ow2.authzforce.core.pdp.api(org.ow2.authzforce.core.pdp.api) PolicyVersion(org.ow2.authzforce.core.pdp.api.policy.PolicyVersion) PolicyVersion(org.ow2.authzforce.core.pdp.api.policy.PolicyVersion) BasePrimaryPolicyMetadata(org.ow2.authzforce.core.pdp.api.policy.BasePrimaryPolicyMetadata) PrimaryPolicyMetadata(org.ow2.authzforce.core.pdp.api.policy.PrimaryPolicyMetadata) BasePrimaryPolicyMetadata(org.ow2.authzforce.core.pdp.api.policy.BasePrimaryPolicyMetadata)

Aggregations

PrimaryPolicyMetadata (org.ow2.authzforce.core.pdp.api.policy.PrimaryPolicyMetadata)5 Serializable (java.io.Serializable)3 JAXBElement (javax.xml.bind.JAXBElement)2 CombiningAlgParameter (org.ow2.authzforce.core.pdp.api.combining.CombiningAlgParameter)2 XPathCompilerProxy (org.ow2.authzforce.core.pdp.api.expression.XPathCompilerProxy)2 BooleanEvaluator (org.ow2.authzforce.core.pdp.impl.BooleanEvaluator)2 ImmutableList (com.google.common.collect.ImmutableList)1 Path (java.nio.file.Path)1 java.util (java.util)1 Collectors (java.util.stream.Collectors)1 Unmarshaller (javax.xml.bind.Unmarshaller)1 DOMResult (javax.xml.transform.dom.DOMResult)1 DocumentBuilder (net.sf.saxon.s9api.DocumentBuilder)1 XdmNode (net.sf.saxon.s9api.XdmNode)1 oasis.names.tc.xacml._3_0.core.schema.wd_17 (oasis.names.tc.xacml._3_0.core.schema.wd_17)1 Request (oasis.names.tc.xacml._3_0.core.schema.wd_17.Request)1 Response (oasis.names.tc.xacml._3_0.core.schema.wd_17.Response)1 JSONArray (org.json.JSONArray)1 JSONObject (org.json.JSONObject)1 Test (org.junit.Test)1