use of org.ow2.authzforce.core.pdp.api.XmlUtils.XmlnsFilteringParserFactory 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);
}
Aggregations