blob: 0b5ab80458d3e6d893794f3769be7317cf7b4226 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
/*
* AT&T - PROPRIETARY
* THIS FILE CONTAINS PROPRIETARY INFORMATION OF
* AT&T AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN
* ACCORDANCE WITH APPLICABLE AGREEMENTS.
*
* Copyright (c) 2014 AT&T Knowledge Ventures
* Unpublished and Not for Publication
* All Rights Reserved
*/
package org.apache.openaz.xacml.util;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Iterator;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilder;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeSelectorType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.IdReferenceType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionsType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableDefinitionType;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.openaz.xacml.api.Advice;
import org.apache.openaz.xacml.api.Attribute;
import org.apache.openaz.xacml.api.AttributeAssignment;
import org.apache.openaz.xacml.api.Obligation;
import org.apache.openaz.xacml.std.IdentifierImpl;
import org.apache.openaz.xacml.std.StdAttribute;
import org.apache.openaz.xacml.std.StdAttributeAssignment;
import org.apache.openaz.xacml.std.StdAttributeValue;
import org.apache.openaz.xacml.std.StdMutableAdvice;
import org.apache.openaz.xacml.std.StdMutableObligation;
import org.apache.openaz.xacml.std.dom.DOMUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* class XACMLPolicyScanner This class traverses the hierarchy of a XACML 3.0 policy. You can optionally pass
* a Callback class and override any desired methods to retrieve information from a policy.
*/
public class XACMLPolicyScanner {
/**
* Very simple enumeration used in the callback class. Return CONTINUE to instruct the XACMLPolicyScanner
* to continue scanning the policy. Otherwise, call STOP to terminate scanning the policy.
*/
public enum CallbackResult {
//
// Continue scanning the policy
//
CONTINUE,
//
// Terminate scanning
//
STOP;
}
/**
* This is a simple callback interface that can be implemented and passed to the XACMLPolicyScanner. When
* the XACMLPolicyScanner encounters a relevant element in the policy, it calls the appropriate method.
*/
public interface Callback {
/**
* Called when the scanning begins with the root element.
*
* @param root - The root PolicySet/Policy object.
* @return CallbackResult - CONTINUE or STOP scanning the policy.
*/
CallbackResult onBeginScan(Object root);
/**
* Called when the scanning finishes with the root element.
*
* @param root - The root PolicySet/Policy object.
*/
void onFinishScan(Object root);
/**
* Called when the scanning of the policy first encounters a PolicySet
*
* @param parent - The parent PolicySet of the policySet. Can be null if this is the root PolicySet.
* @param policySet - The PolicySet object.
* @return CallbackResult - CONTINUE or STOP scanning the policy.
*/
CallbackResult onPreVisitPolicySet(PolicySetType parent, PolicySetType policySet);
/**
* Called when the scanning of the PolicySet has finished.
*
* @param parent - The parent PolicySet of the policySet. Can be null if this is the root PolicySet.
* @param policySet - The PolicySet object.
* @return CallbackResult - CONTINUE or STOP scanning the policy.
*/
CallbackResult onPostVisitPolicySet(PolicySetType parent, PolicySetType policySet);
/**
* Called when the scanning of the policy first encounters a Policy
*
* @param parent - The parent PolicySet of the policy. This can be null if this policy is the root.
* @param policy - The policy.
* @return CallbackResult - CONTINUE or STOP scanning the policy.
*/
CallbackResult onPreVisitPolicy(PolicySetType parent, PolicyType policy);
/**
* Called when the scanning of the Policy has finished.
*
* @param parent - The parent PolicySet of the policy. This can be null if this policy is the root.
* @param policy - The policy.
* @return CallbackResult - CONTINUE or STOP scanning the policy.
*/
CallbackResult onPostVisitPolicy(PolicySetType parent, PolicyType policy);
/**
* Called when the scanning of the policy first encounters a Rule
*
* @param parent - The parent policy of the rule
* @param rule - The rule
* @return CallbackResult - CONTINUE or STOP scanning the policy.
*/
CallbackResult onPreVisitRule(PolicyType parent, RuleType rule);
/**
* Called when the scanning of the Rule has finished.
*
* @param parent - The parent policy of the rule
* @param rule - The rule
* @return CallbackResult - CONTINUE or STOP scanning the policy.
*/
CallbackResult onPostVisitRule(PolicyType parent, RuleType rule);
/**
* When an attribute has been encountered.
*
* @param parent - The parent PolicySet/Policy/Rule for this attribute.
* @param container - What part of the PolicySet/Policy/Rule this attribute is located. eg. Target,
* Condition
* @param attribute - The attribute
* @return CallbackResult - CONTINUE or STOP scanning the policy.
*/
CallbackResult onAttribute(Object parent, Object container, Attribute attribute);
/**
* When an obligation has been encountered.
*
* @param parent - The parent PolicySet/Policy/Rule for the obligation.
* @param obligation - The obligation.
* @return CallbackResult - CONTINUE or STOP scanning the policy.
*/
CallbackResult onObligation(Object parent, ObligationExpressionType expression,
Obligation obligation);
/**
* When an advice has been encountered.
*
* @param parent - The parent PolicySet/Policy/Rule for the obligation.
* @param advice - The advice.
* @return CallbackResult - CONTINUE or STOP scanning the policy.
*/
CallbackResult onAdvice(Object parent, AdviceExpressionType expression, Advice advice);
/**
* When a variable definition has been encountered.
*
* @param policy - The Policy the variable is located in.
* @param variable - The variable.
* @return CallbackResult - CONTINUE or STOP scanning the policy.
*/
CallbackResult onVariable(PolicyType policy, VariableDefinitionType variable);
/**
* When a condition has been encountered.
*
* @param rule - The Rule containing the condition.
* @param condition - The condition
* @return CallbackResult - CONTINUE or STOP scanning the policy.
*/
CallbackResult onCondition(RuleType rule, ConditionType condition);
/**
* When a reference to another PolicySet is encountered.
*
* @param reference - The Policy Set Reference ID
* @param parent - The parent PolicySet that holds the reference
* @return CallbackResult - CONTINUE or STOP scanning the policy.
*/
CallbackResult onPolicySetIdReference(IdReferenceType reference, PolicySetType parent);
/**
* When a reference to another PolicySet is encountered.
*
* @param reference - The Policy Set Reference ID
* @param parent - The parent PolicySet that holds the reference
* @return CallbackResult - CONTINUE or STOP scanning the policy.
*/
CallbackResult onPolicyIdReference(IdReferenceType reference, PolicySetType parent);
}
/**
* This is a simple implementation of the Callback. Extend this if you don't wish to implement all the
* callback functions available. Each method simply returns CallbackResult.CONTINUE.
*/
public static class SimpleCallback implements Callback {
@Override
public CallbackResult onBeginScan(Object root) {
return CallbackResult.CONTINUE;
}
@Override
public void onFinishScan(Object root) {
}
@Override
public CallbackResult onPreVisitPolicySet(PolicySetType parent, PolicySetType policySet) {
return CallbackResult.CONTINUE;
}
@Override
public CallbackResult onPostVisitPolicySet(PolicySetType parent, PolicySetType policySet) {
return CallbackResult.CONTINUE;
}
@Override
public CallbackResult onPreVisitPolicy(PolicySetType parent, PolicyType policy) {
return CallbackResult.CONTINUE;
}
@Override
public CallbackResult onPostVisitPolicy(PolicySetType parent, PolicyType policy) {
return CallbackResult.CONTINUE;
}
@Override
public CallbackResult onPreVisitRule(PolicyType parent, RuleType rule) {
return CallbackResult.CONTINUE;
}
@Override
public CallbackResult onPostVisitRule(PolicyType parent, RuleType rule) {
return CallbackResult.CONTINUE;
}
@Override
public CallbackResult onAttribute(Object parent, Object container, Attribute attribute) {
return CallbackResult.CONTINUE;
}
@Override
public CallbackResult onObligation(Object parent, ObligationExpressionType expression,
Obligation obligation) {
return CallbackResult.CONTINUE;
}
@Override
public CallbackResult onAdvice(Object parent, AdviceExpressionType expression, Advice advice) {
return CallbackResult.CONTINUE;
}
@Override
public CallbackResult onVariable(PolicyType policy, VariableDefinitionType o) {
return CallbackResult.CONTINUE;
}
@Override
public CallbackResult onCondition(RuleType rule, ConditionType condition) {
return CallbackResult.CONTINUE;
}
@Override
public CallbackResult onPolicySetIdReference(IdReferenceType reference, PolicySetType parent) {
return CallbackResult.CONTINUE;
}
@Override
public CallbackResult onPolicyIdReference(IdReferenceType reference, PolicySetType parent) {
return CallbackResult.CONTINUE;
}
}
private static final Log logger = LogFactory.getLog(XACMLPolicyScanner.class);
private Object policyObject = null;
private Callback callback = null;
public XACMLPolicyScanner(Path filename, Callback callback) {
try (InputStream is = Files.newInputStream(filename)) {
this.policyObject = XACMLPolicyScanner.readPolicy(is);
} catch (IOException e) {
logger.error("Failed to read policy", e);
}
this.callback = callback;
}
public XACMLPolicyScanner(PolicySetType policySet, Callback callback) {
this.policyObject = policySet;
this.callback = callback;
}
public XACMLPolicyScanner(PolicySetType policySet) {
this(policySet, null);
}
public XACMLPolicyScanner(PolicyType policy, Callback callback) {
this.policyObject = policy;
this.callback = callback;
}
public XACMLPolicyScanner(PolicyType policy) {
this(policy, null);
}
/**
* Sets the callback interface to be used.
*
* @param cb
*/
public void setCallback(Callback cb) {
this.callback = cb;
}
/**
* Saves the given callback object then calls the scan() method.
*
* @param cb
* @return
*/
public Object scan(Callback cb) {
this.callback = cb;
return this.scan();
}
/**
* This begins the scanning of the contained object.
*
* @return - The PolicySet/Policy that was scanned.
*/
public Object scan() {
if (this.policyObject == null) {
return null;
}
if (this.callback != null
&& this.callback.onBeginScan(this.policyObject) == CallbackResult.STOP) {
return this.policyObject;
}
if (this.policyObject instanceof PolicyType) {
this.scanPolicy(null, (PolicyType)this.policyObject);
} else if (this.policyObject instanceof PolicySetType) {
this.scanPolicySet(null, (PolicySetType)this.policyObject);
} else {
logger.error("Unknown class type: " + this.policyObject.getClass().getCanonicalName());
}
if (this.callback != null) {
this.callback.onFinishScan(this.policyObject);
}
return this.policyObject;
}
/**
* This performs the scan of a PolicySet
*
* @param parent - Its parent PolicySet. Can be null if this is the root.
* @param policySet - The PolicySet object.
* @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
*/
/**
* @param parent
* @param policySet
* @return
*/
protected CallbackResult scanPolicySet(PolicySetType parent, PolicySetType policySet) {
if (logger.isTraceEnabled()) {
logger.trace("scanning policy set: " + policySet.getPolicySetId() + " "
+ policySet.getDescription());
}
if (this.callback != null
&& this.callback.onPreVisitPolicySet(parent, policySet) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
//
// Scan its info
//
if (this.scanTarget(policySet, policySet.getTarget()) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
if (this.scanObligations(policySet, policySet.getObligationExpressions()) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
if (this.scanAdvice(policySet, policySet.getAdviceExpressions()) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
//
// Iterate the policy sets and/or policies
//
List<JAXBElement<?>> list = policySet.getPolicySetOrPolicyOrPolicySetIdReference();
for (JAXBElement<?> element : list) {
if (element.getName().getLocalPart().equals("PolicySet")) {
if (this.scanPolicySet(policySet, (PolicySetType)element.getValue()) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
} else if (element.getName().getLocalPart().equals("Policy")) {
if (this.scanPolicy(policySet, (PolicyType)element.getValue()) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
} else if (element.getValue() instanceof IdReferenceType) { //NOPMD
/*TODO if (element.getName().getLocalPart().equals("PolicySetIdReference")) {
} else if (element.getName().getLocalPart().equals("PolicyIdReference")) {
}*/
} else {
logger.warn("generating policy sets found unsupported element: "
+ element.getName().getNamespaceURI());
}
}
if (this.callback != null
&& this.callback.onPostVisitPolicySet(parent, policySet) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
return CallbackResult.CONTINUE;
}
/**
* This performs scanning of the Policy object.
*
* @param parent - The parent PolicySet of the policy. This can be null if this is a root Policy.
* @param policy - The policy being scanned.
* @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
*/
protected CallbackResult scanPolicy(PolicySetType parent, PolicyType policy) {
if (logger.isTraceEnabled()) {
logger.trace("scanning policy: " + policy.getPolicyId() + " " + policy.getDescription());
}
if (this.callback != null
&& this.callback.onPreVisitPolicy(parent, policy) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
//
// Scan its info
//
if (this.scanTarget(policy, policy.getTarget()) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
if (this.scanVariables(policy,
policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
if (this.scanObligations(policy, policy.getObligationExpressions()) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
if (this.scanAdvice(policy, policy.getAdviceExpressions()) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
//
// Iterate the rules
//
List<Object> list = policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition();
for (Object o : list) {
if (o instanceof RuleType) {
RuleType rule = (RuleType)o;
if (logger.isTraceEnabled()) {
logger.trace("scanning rule: " + rule.getRuleId() + " " + rule.getDescription());
}
if (this.callback != null
&& this.callback.onPreVisitRule(policy, rule) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
if (this.scanTarget(rule, rule.getTarget()) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
if (this.scanConditions(rule, rule.getCondition()) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
if (this.scanObligations(rule, rule.getObligationExpressions()) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
if (this.scanAdvice(rule, rule.getAdviceExpressions()) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
if (this.callback != null
&& this.callback.onPostVisitRule(policy, rule) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
} else if (o instanceof VariableDefinitionType) {
if (this.callback != null
&& this.callback.onVariable(policy, (VariableDefinitionType)o) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("scanning policy rules found unsupported object:" + o.toString());
}
}
}
if (this.callback != null
&& this.callback.onPostVisitPolicy(parent, policy) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
return CallbackResult.CONTINUE;
}
/**
* Scans the given target for attributes. Its sole purpose is to return attributes found.
*
* @param parent - The parent PolicySet/Policy/Rule for the target.
* @param target - The target.
* @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
*/
protected CallbackResult scanTarget(Object parent, TargetType target) {
if (target == null) {
return CallbackResult.CONTINUE;
}
List<AnyOfType> anyOfList = target.getAnyOf();
if (anyOfList != null) {
Iterator<AnyOfType> iterAnyOf = anyOfList.iterator();
while (iterAnyOf.hasNext()) {
AnyOfType anyOf = iterAnyOf.next();
List<AllOfType> allOfList = anyOf.getAllOf();
if (allOfList != null) {
Iterator<AllOfType> iterAllOf = allOfList.iterator();
while (iterAllOf.hasNext()) {
AllOfType allOf = iterAllOf.next();
List<MatchType> matchList = allOf.getMatch();
if (matchList != null) {
Iterator<MatchType> iterMatch = matchList.iterator();
while (iterMatch.hasNext()) {
MatchType match = iterMatch.next();
//
// Finally down to the actual attribute
//
StdAttribute attribute = null;
AttributeValueType value = match.getAttributeValue();
if (match.getAttributeDesignator() != null && value != null) {
AttributeDesignatorType designator = match.getAttributeDesignator();
//
// The content may be tricky
//
attribute = new StdAttribute(
new IdentifierImpl(designator.getCategory()),
new IdentifierImpl(designator
.getAttributeId()),
new StdAttributeValue<List<?>>(
new IdentifierImpl(
value
.getDataType()),
value
.getContent()),
designator.getIssuer(), false);
} else if (match.getAttributeSelector() != null && value != null) {
AttributeSelectorType selector = match.getAttributeSelector();
attribute = new StdAttribute(
new IdentifierImpl(selector.getCategory()),
new IdentifierImpl(selector
.getContextSelectorId()),
new StdAttributeValue<List<?>>(
new IdentifierImpl(
value
.getDataType()),
value
.getContent()),
null, false);
} else {
logger.warn("NULL designator/selector or value for match.");
}
if (attribute != null && this.callback != null
&& this.callback.onAttribute(parent, target, attribute) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
}
}
}
}
}
}
return CallbackResult.CONTINUE;
}
/**
* Scan the list of obligations.
*
* @param parent - The parent PolicySet/Policy/Rule for the obligation.
* @param obligationExpressionsType - All the obligation expressions.
* @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
*/
protected CallbackResult scanObligations(Object parent,
ObligationExpressionsType obligationExpressionsType) {
if (obligationExpressionsType == null) {
return CallbackResult.CONTINUE;
}
List<ObligationExpressionType> expressions = obligationExpressionsType.getObligationExpression();
if (expressions == null || expressions.size() == 0) {
return CallbackResult.CONTINUE;
}
for (ObligationExpressionType expression : expressions) {
StdMutableObligation ob = new StdMutableObligation(new IdentifierImpl(
expression
.getObligationId()));
List<AttributeAssignmentExpressionType> assignments = expression
.getAttributeAssignmentExpression();
if (assignments != null) {
for (AttributeAssignmentExpressionType assignment : assignments) {
// category is optional and may be null
IdentifierImpl categoryId = null;
if (assignment.getCategory() != null) {
categoryId = new IdentifierImpl(assignment.getCategory());
}
AttributeAssignment attribute = new StdAttributeAssignment(
categoryId,
new IdentifierImpl(assignment
.getAttributeId()),
assignment.getIssuer(),
new StdAttributeValue<Object>(
null,
null));
ob.addAttributeAssignment(attribute);
}
}
if (this.callback != null
&& this.callback.onObligation(parent, expression, ob) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
}
return CallbackResult.CONTINUE;
}
/**
* Scans the list of advice expressions returning each individually.
*
* @param parent - The parent PolicySet/Policy/Rule for the advice.
* @param adviceExpressionstype - The list of advice expressions.
* @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
*/
protected CallbackResult scanAdvice(Object parent, AdviceExpressionsType adviceExpressionstype) {
if (adviceExpressionstype == null) {
return CallbackResult.CONTINUE;
}
List<AdviceExpressionType> expressions = adviceExpressionstype.getAdviceExpression();
if (expressions == null || expressions.size() == 0) {
return CallbackResult.CONTINUE;
}
for (AdviceExpressionType expression : expressions) {
StdMutableAdvice ob = new StdMutableAdvice(new IdentifierImpl(expression.getAdviceId()));
List<AttributeAssignmentExpressionType> assignments = expression
.getAttributeAssignmentExpression();
if (assignments != null) {
for (AttributeAssignmentExpressionType assignment : assignments) {
IdentifierImpl categoryId = null;
if (assignment.getCategory() != null) {
categoryId = new IdentifierImpl(assignment.getCategory());
}
AttributeAssignment attribute = new StdAttributeAssignment(
categoryId,
new IdentifierImpl(assignment
.getAttributeId()),
assignment.getIssuer(),
new StdAttributeValue<Object>(
null,
null));
ob.addAttributeAssignment(attribute);
}
}
if (this.callback != null
&& this.callback.onAdvice(parent, expression, ob) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
}
return CallbackResult.CONTINUE;
}
/**
* Scans the list of variable definitions.
*
* @param policy - Policy object containing the variable definition.
* @param list - List of variable definitions.
* @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
*/
protected CallbackResult scanVariables(PolicyType policy, List<Object> list) {
if (list == null) {
return CallbackResult.CONTINUE;
}
for (Object o : list) {
if (o instanceof VariableDefinitionType && this.callback != null
&& this.callback.onVariable(policy, (VariableDefinitionType)o) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
}
return CallbackResult.CONTINUE;
}
/**
* Scans the list of conditions.
*
* @param rule
* @param condition
* @return
*/
protected CallbackResult scanConditions(RuleType rule, ConditionType condition) {
if (condition != null && this.callback != null
&& this.callback.onCondition(rule, condition) == CallbackResult.STOP) {
return CallbackResult.STOP;
}
return CallbackResult.CONTINUE;
}
/**
* Reads the XACML XML policy file in and returns the version contained in the root Policy/PolicySet
* element.
*
* @param policy - The policy file.
* @return - The version string from the file (uninterpreted)
* @throws java.io.IOException
*/
public static String getVersion(Path policy) throws IOException {
Object data = null;
try (InputStream is = Files.newInputStream(policy)) {
data = XACMLPolicyScanner.readPolicy(is);
} catch (IOException e) {
logger.error("Failed to read policy", e);
throw e;
}
if (data == null) {
logger.warn("Version is null.");
return null;
}
return getVersion(data);
}
/**
* Reads the Policy/PolicySet element object and returns its current version.
*
* @param data - Either a PolicySet or Policy XACML type object.
* @return - The integer version value. -1 if it doesn't exist or was un-parsable.
*/
public static String getVersion(Object data) {
String version = null;
try {
if (data instanceof PolicySetType) {
version = ((PolicySetType)data).getVersion();
} else if (data instanceof PolicyType) {
version = ((PolicyType)data).getVersion();
} else {
if (data != null) {
logger.error("Expecting a PolicySet/Policy/Rule object. Got: "
+ data.getClass().getCanonicalName());
}
return null;
}
if (version != null && version.length() > 0) {
return version;
} else {
logger.warn("No version set in policy");
}
} catch (NumberFormatException e) {
logger.error("Invalid version contained in policy: " + version);
return null;
}
return null;
}
/**
* Returns the Policy or PolicySet ID.
*
* @param data - A XACML 3.0 Policy or PolicySet element object.
* @return The policy/policyset's policy ID
*/
public static String getID(Object data) {
if (data instanceof PolicySetType) {
return ((PolicySetType)data).getPolicySetId();
} else if (data instanceof PolicyType) {
return ((PolicyType)data).getPolicyId();
} else {
logger.error("Expecting a PolicySet/Policy/Rule object. Got: "
+ data.getClass().getCanonicalName());
return null;
}
}
/**
* readPolicy - does the work to read in policy data from a file.
*
* @param policy - The path to the policy file.
* @return - The policy data object. This *should* be either a PolicySet or a Policy.
*/
public static Object readPolicy(InputStream is) {
try {
//
// Parse the policy file
//
DocumentBuilder db = DOMUtil.getDocumentBuilder();
Document doc = db.parse(is);
//
// Because there is no root defined in xacml,
// find the first element
//
NodeList nodes = doc.getChildNodes();
Node node = nodes.item(0);
Element e = null;
if (node.getNodeType() == Node.ELEMENT_NODE) {
e = (Element)node;
//
// Is it a 3.0 policy?
//
if (e.getNamespaceURI().equals("urn:oasis:names:tc:xacml:3.0:core:schema:wd-17")) {
//
// A policyset or policy could be the root
//
if (e.getNodeName().endsWith("Policy")) {
//
// Now we can create the context for the policy set
// and unmarshall the policy into a class.
//
JAXBContext context = JAXBContext.newInstance(PolicyType.class);
Unmarshaller um = context.createUnmarshaller();
JAXBElement<PolicyType> root = um.unmarshal(e, PolicyType.class);
//
// Here is our policy set class
//
return root.getValue();
} else if (e.getNodeName().endsWith("PolicySet")) {
//
// Now we can create the context for the policy set
// and unmarshall the policy into a class.
//
JAXBContext context = JAXBContext.newInstance(PolicySetType.class);
Unmarshaller um = context.createUnmarshaller();
JAXBElement<PolicySetType> root = um.unmarshal(e, PolicySetType.class);
//
// Here is our policy set class
//
return root.getValue();
} else {
if (logger.isDebugEnabled()) {
logger.debug("Not supported yet: " + e.getNodeName());
}
}
} else {
logger.warn("unsupported namespace: " + e.getNamespaceURI());
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("No root element contained in policy " + " Name: " + node.getNodeName()
+ " type: " + node.getNodeType() + " Value: " + node.getNodeValue());
}
}
} catch (Exception e) {
logger.error(e.getMessage());
}
return null;
}
}