| /* |
| * 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; |
| } |
| } |