Search in sources :

Example 1 with XmlnsFilteringParserFactory

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

Aggregations

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 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 Stream (java.util.stream.Stream)1 JAXBException (javax.xml.bind.JAXBException)1 Policy (oasis.names.tc.xacml._3_0.core.schema.wd_17.Policy)1 PolicySet (oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySet)1 EnvironmentProperties (org.ow2.authzforce.core.pdp.api.EnvironmentProperties)1 IndeterminateEvaluationException (org.ow2.authzforce.core.pdp.api.IndeterminateEvaluationException)1