X-Git-Url: https://gerrit.onap.org/r/gitweb?p=policy%2Fengine.git;a=blobdiff_plain;f=ONAP-XACML%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Fpolicy%2Fxacml%2Futil%2FXACMLPolicyScanner.java;h=228354c4f489233e219aeeebf7ff14ab9e036138;hp=b8b19ec9327e55d1bc8a982ff2efe23ecb3d87e7;hb=d089848fdb0beef8446bdcf60cdb14e4655a93e5;hpb=4d503f398d2f309cc077b55b5f1cce4c4bd773e6 diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/util/XACMLPolicyScanner.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/util/XACMLPolicyScanner.java index b8b19ec93..228354c4f 100644 --- a/ONAP-XACML/src/main/java/org/onap/policy/xacml/util/XACMLPolicyScanner.java +++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/util/XACMLPolicyScanner.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP-XACML * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed 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. @@ -17,8 +17,19 @@ * limitations under the License. * ============LICENSE_END========================================================= */ + package org.onap.policy.xacml.util; +import com.att.research.xacml.api.AttributeAssignment; +import com.att.research.xacml.std.IdentifierImpl; +import com.att.research.xacml.std.StdAttribute; +import com.att.research.xacml.std.StdAttributeAssignment; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.StdMutableAdvice; +import com.att.research.xacml.std.StdMutableObligation; +import com.att.research.xacml.util.XACMLPolicyScanner.Callback; +import com.att.research.xacml.util.XACMLPolicyScanner.CallbackResult; + import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; @@ -33,26 +44,6 @@ import javax.xml.bind.Unmarshaller; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import org.onap.policy.common.logging.eelf.MessageCodes; -import org.onap.policy.common.logging.eelf.PolicyLogger; - -import com.att.research.xacml.api.AttributeAssignment; -import com.att.research.xacml.std.IdentifierImpl; -import com.att.research.xacml.std.StdAttribute; -import com.att.research.xacml.std.StdAttributeAssignment; -import com.att.research.xacml.std.StdAttributeValue; -import com.att.research.xacml.std.StdMutableAdvice; -import com.att.research.xacml.std.StdMutableObligation; -import com.att.research.xacml.util.XACMLPolicyScanner.Callback; -import com.att.research.xacml.util.XACMLPolicyScanner.CallbackResult; - 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; @@ -62,7 +53,6 @@ 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; @@ -72,650 +62,603 @@ 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.onap.policy.common.logging.eelf.MessageCodes; +import org.onap.policy.common.logging.eelf.PolicyLogger; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + /** - * 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. - * + * 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 { - - 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) { - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Failed to read policy"); - } - this.callback = callback; - } - - public XACMLPolicyScanner(InputStream filename, Callback callback) { - try (InputStream is = filename) { - this.policyObject = XACMLPolicyScanner.readPolicy(is); - } catch (IOException e) { - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Failed to read policy"); - } - 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) { - if (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 { - PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + "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) { - if (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> list = policySet.getPolicySetOrPolicyOrPolicySetIdReference(); - for (JAXBElement element: list) { - if ("PolicySet".equals(element.getName().getLocalPart())) { - if (this.scanPolicySet(policySet, (PolicySetType)element.getValue()) == CallbackResult.STOP) { - return CallbackResult.STOP; - } - } else if ("Policy".equals(element.getName().getLocalPart())) { - if (this.scanPolicy(policySet, (PolicyType)element.getValue()) == CallbackResult.STOP) { - return CallbackResult.STOP; - } - } else if (element.getValue() instanceof IdReferenceType) { - if ("PolicySetIdReference".equals(element.getName().getLocalPart())) { - - } else if ("PolicyIdReference".equals(element.getName().getLocalPart())) { - - } - } else { - logger.warn("generating policy sets found unsupported element: " + element.getName().getNamespaceURI()); - } - } - if (this.callback != null) { - if (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) { - if (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 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) { - if (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) { - if (this.callback.onPostVisitRule(policy, rule) == CallbackResult.STOP) { - return CallbackResult.STOP; - } - } - } else if (o instanceof VariableDefinitionType) { - if (this.callback != null) { - if (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) { - if (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 anyOfList = target.getAnyOf(); - if (anyOfList != null) { - Iterator iterAnyOf = anyOfList.iterator(); - while (iterAnyOf.hasNext()) { - AnyOfType anyOf = iterAnyOf.next(); - List allOfList = anyOf.getAllOf(); - if (allOfList != null) { - Iterator iterAllOf = allOfList.iterator(); - while (iterAllOf.hasNext()) { - AllOfType allOf = iterAllOf.next(); - List matchList = allOf.getMatch(); - if (matchList != null) { - Iterator 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>(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>(new IdentifierImpl(value.getDataType()), value.getContent()), - null, - false); - } else { - logger.warn("NULL designator/selector or value for match."); - } - if (attribute != null && this.callback != null) { - if (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 expressions = obligationExpressionsType.getObligationExpression(); - if (expressions == null || expressions.isEmpty()) { - return CallbackResult.CONTINUE; - } - for (ObligationExpressionType expression : expressions) { - StdMutableObligation ob = new StdMutableObligation(new IdentifierImpl(expression.getObligationId())); - List 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(null, null) - ); - ob.addAttributeAssignment(attribute); - } - } - if (this.callback != null) { - if (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 expressions = adviceExpressionstype.getAdviceExpression(); - if (expressions == null || expressions.isEmpty()) { - return CallbackResult.CONTINUE; - } - for (AdviceExpressionType expression : expressions) { - StdMutableAdvice ob = new StdMutableAdvice(new IdentifierImpl(expression.getAdviceId())); - List 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(null, null) - ); - ob.addAttributeAssignment(attribute); - } - } - if (this.callback != null) { - if (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 list) { - if (list == null) { - return CallbackResult.CONTINUE; - } - for (Object o : list) { - if (o instanceof VariableDefinitionType) { - if (this.callback != null) { - if (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) { - if (this.callback != null) { - if (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 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) { - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Failed to read policy"); - 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) { - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "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) { - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "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 { - PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Expecting a PolicySet/Policy/Rule object. Got: " + data.getClass().getCanonicalName()); - return null; - } - } - - public static List getCreatedByModifiedBy(Path policyPath) throws IOException{ - String createdBy = ""; - String modifiedBy= ""; - String cValue = "@CreatedBy:"; - String mValue = "@ModifiedBy:"; - for(String line: Files.readAllLines(policyPath)){ - line = line.replaceAll("\\s+", ""); - if(line.isEmpty()){ - continue; - } - if(line.contains("") && line.contains(cValue) && line.contains(mValue)){ - createdBy = line.substring(line.indexOf(cValue) + cValue.length(), line.lastIndexOf(cValue)); - modifiedBy = line.substring(line.indexOf(mValue) + mValue.length(), line.lastIndexOf(mValue)); - break; - } - } - return Arrays.asList(createdBy, modifiedBy); - } - - //get the Created Name of the User on reading the Xml file - public static String getCreatedBy(Path policyPath) throws IOException{ - String userId = ""; - String value = "@CreatedBy:"; - for(String line: Files.readAllLines(policyPath)){ - line = line.replaceAll("\\s+", ""); - if(line.isEmpty()){ - continue; - } - if(line.contains("") && line.contains(value)){ - userId = line.substring(line.indexOf(value) + value.length(), line.lastIndexOf(value)); - break; - } - } - return userId; - } - - //get the Modified Name of the User on reading the Xml file - public static String getModifiedBy(Path policyPath) throws IOException{ - String modifiedBy = ""; - String value = "@ModifiedBy:"; - for(String line: Files.readAllLines(policyPath)){ - line = line.replaceAll("\\s+", ""); - if(line.isEmpty()){ - continue; - } - if(line.contains("") && line.contains(value)){ - modifiedBy = line.substring(line.indexOf(value) + value.length(), line.lastIndexOf(value)); - break; - } - } - return modifiedBy; - } - - /** - * 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 { - // - // Create a DOM parser - // - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder db = dbf.newDocumentBuilder(); - // - // Parse the policy file - // - 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); - if (node.getNodeType() == Node.ELEMENT_NODE) { - Element e = (Element) node; - // - // Is it a 3.0 policy? - // - if ("urn:oasis:names:tc:xacml:3.0:core:schema:wd-17".equals(e.getNamespaceURI())) { - // - // 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 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 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) { - PolicyLogger.error(MessageCodes.ERROR_SCHEMA_INVALID, e, "XACMLPolicyScanner", "Exception in readPolicy"); - } - return null; - } - - /** - * @return the policyObject - */ - public Object getPolicyObject() { - return policyObject; - } + + private static final Log logger = LogFactory.getLog(XACMLPolicyScanner.class); + private Object policyObject = null; + private Callback callback = null; + + /** + * constructor. + * + * @param filename Path + * @param callback Callback + */ + public XACMLPolicyScanner(Path filename, Callback callback) { + try (InputStream is = Files.newInputStream(filename)) { + this.policyObject = XACMLPolicyScanner.readPolicy(is); + } catch (IOException e) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Failed to read policy"); + } + this.callback = callback; + } + + /** + * Constructor. + * + * @param filename InputStream + * @param callback Callback + */ + public XACMLPolicyScanner(InputStream filename, Callback callback) { + try (InputStream is = filename) { + this.policyObject = XACMLPolicyScanner.readPolicy(is); + } catch (IOException e) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Failed to read policy"); + } + 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 Callback object + */ + public void setCallback(Callback cb) { + this.callback = cb; + } + + /** + * Saves the given callback object then calls the scan() method. + * + * @param cb Callback object + * @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 { + PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + "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. + */ + 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> list = policySet.getPolicySetOrPolicyOrPolicySetIdReference(); + for (JAXBElement element : list) { + if ("PolicySet".equals(element.getName().getLocalPart()) + && this.scanPolicySet(policySet, (PolicySetType) element.getValue()) == CallbackResult.STOP) { + return CallbackResult.STOP; + } else if ("Policy".equals(element.getName().getLocalPart()) + && this.scanPolicy(policySet, (PolicyType) element.getValue()) == CallbackResult.STOP) { + return CallbackResult.STOP; + } 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 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; + } + for (AnyOfType anyOf : target.getAnyOf()) { + for (AllOfType allOf : anyOf.getAllOf()) { + for (MatchType match : allOf.getMatch()) { + // + // 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>(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>(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 expressions = obligationExpressionsType.getObligationExpression(); + for (ObligationExpressionType expression : expressions) { + StdMutableObligation ob = new StdMutableObligation(new IdentifierImpl(expression.getObligationId())); + for (AttributeAssignmentExpressionType assignment : expression.getAttributeAssignmentExpression()) { + // 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(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 expressions = adviceExpressionstype.getAdviceExpression(); + for (AdviceExpressionType expression : expressions) { + StdMutableAdvice ob = new StdMutableAdvice(new IdentifierImpl(expression.getAdviceId())); + for (AttributeAssignmentExpressionType assignment : expression.getAttributeAssignmentExpression()) { + 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(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 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 RuleType + * @param condition ConditionType + * @return CallbackResult + */ + 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 IOException 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) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Failed to read policy"); + 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; + if (data instanceof PolicySetType) { + version = ((PolicySetType) data).getVersion(); + } else if (data instanceof PolicyType) { + version = ((PolicyType) data).getVersion(); + } else { + if (data != null) { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Expecting a PolicySet/Policy/Rule object. Got: " + + data.getClass().getCanonicalName()); + } + return null; + } + if (version != null && version.length() > 0) { + return version; + } + logger.warn("No version set in policy"); + 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 { + PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Expecting a PolicySet/Policy/Rule object. Got: " + + data.getClass().getCanonicalName()); + return null; + } + } + + /** + * getCreatedByModifiedBy. + * + * @param policyPath Path + * @return List of String + * @throws IOException IOException + */ + public static List getCreatedByModifiedBy(Path policyPath) throws IOException { + String createdBy = ""; + String modifiedBy = ""; + String createdValue = "@CreatedBy:"; + String modifiedValue = "@ModifiedBy:"; + for (String line : Files.readAllLines(policyPath)) { + line = line.replaceAll("\\s+", ""); + if (line.isEmpty()) { + continue; + } + if (line.contains("") && line.contains(createdValue) && line.contains(modifiedValue)) { + createdBy = line.substring(line.indexOf(createdValue) + createdValue.length(), + line.lastIndexOf(createdValue)); + modifiedBy = line.substring(line.indexOf(modifiedValue) + modifiedValue.length(), + line.lastIndexOf(modifiedValue)); + break; + } + } + return Arrays.asList(createdBy, modifiedBy); + } + + // get the Created Name of the User on reading the Xml file + /** + * getCreatedBy. + * + * @param policyPath Path + * @return String + * @throws IOException IOException + */ + public static String getCreatedBy(Path policyPath) throws IOException { + String userId = ""; + String value = "@CreatedBy:"; + for (String line : Files.readAllLines(policyPath)) { + line = line.replaceAll("\\s+", ""); + if (line.isEmpty()) { + continue; + } + if (line.contains("") && line.contains(value)) { + userId = line.substring(line.indexOf(value) + value.length(), line.lastIndexOf(value)); + break; + } + } + return userId; + } + + // get the Modified Name of the User on reading the Xml file + /** + * getModifiedBy. + * + * @param policyPath Path + * @return String + * @throws IOException IOException + */ + public static String getModifiedBy(Path policyPath) throws IOException { + String modifiedBy = ""; + String value = "@ModifiedBy:"; + for (String line : Files.readAllLines(policyPath)) { + line = line.replaceAll("\\s+", ""); + if (line.isEmpty()) { + continue; + } + if (line.contains("") && line.contains(value)) { + modifiedBy = line.substring(line.indexOf(value) + value.length(), line.lastIndexOf(value)); + break; + } + } + return modifiedBy; + } + + /** + * readPolicy - does the work to read in policy data from a file. + * + * @param is - 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 { + // + // Create a DOM parser + // + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + DocumentBuilder db = dbf.newDocumentBuilder(); + // + // Parse the policy file + // + Document doc = db.parse(is); + Element element = doc.getDocumentElement(); + // + // Is it a 3.0 policy? + // + if ("urn:oasis:names:tc:xacml:3.0:core:schema:wd-17".equals(element.getNamespaceURI())) { + // + // A policyset or policy could be the root + // + if (element.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 root = um.unmarshal(element, PolicyType.class); + // + // Here is our policy set class + // + return root.getValue(); + } else if (element.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 root = um.unmarshal(element, PolicySetType.class); + // + // Here is our policy set class + // + return root.getValue(); + } else { + if (logger.isDebugEnabled()) { + logger.debug("Not supported yet: " + element.getNodeName()); + } + } + } else { + logger.warn("unsupported namespace: " + element.getNamespaceURI()); + } + } catch (Exception e) { + PolicyLogger.error(MessageCodes.ERROR_SCHEMA_INVALID, e, "XACMLPolicyScanner", "Exception in readPolicy"); + } + return null; + } + + /** + * getPolicyObject. + * + * @return the policyObject + */ + public Object getPolicyObject() { + return policyObject; + } }