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());
}
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;
}
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());
}
}
}
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);
}
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);
}
}
Aggregations