Initial OpenECOMP policy/engine commit
[policy/engine.git] / ECOMP-XACML / src / main / java / org / openecomp / policy / xacml / util / XACMLPolicyScanner.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ECOMP-XACML
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.openecomp.policy.xacml.util;
21
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.nio.file.Files;
25 import java.nio.file.Path;
26 import java.util.Arrays;
27 import java.util.Iterator;
28 import java.util.List;
29
30 import javax.xml.bind.JAXBContext;
31 import javax.xml.bind.JAXBElement;
32 import javax.xml.bind.Unmarshaller;
33 import javax.xml.parsers.DocumentBuilder;
34 import javax.xml.parsers.DocumentBuilderFactory;
35
36 import org.apache.commons.logging.Log;
37 import org.apache.commons.logging.LogFactory;
38 import org.w3c.dom.Document;
39 import org.w3c.dom.Element;
40 import org.w3c.dom.Node;
41 import org.w3c.dom.NodeList;
42
43 import org.openecomp.policy.common.logging.eelf.MessageCodes;
44 import org.openecomp.policy.common.logging.eelf.PolicyLogger;
45
46 import com.att.research.xacml.api.AttributeAssignment;
47 import com.att.research.xacml.std.IdentifierImpl;
48 import com.att.research.xacml.std.StdAttribute;
49 import com.att.research.xacml.std.StdAttributeAssignment;
50 import com.att.research.xacml.std.StdAttributeValue;
51 import com.att.research.xacml.std.StdMutableAdvice;
52 import com.att.research.xacml.std.StdMutableObligation;
53 import com.att.research.xacml.util.XACMLPolicyScanner.Callback;
54 import com.att.research.xacml.util.XACMLPolicyScanner.CallbackResult;
55
56 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
57 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
58 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
59 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
60 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
61 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
62 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeSelectorType;
63 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
64 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType;
65 import oasis.names.tc.xacml._3_0.core.schema.wd_17.IdReferenceType;
66 import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
67 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionType;
68 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionsType;
69 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
70 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
71 import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
72 import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
73 import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableDefinitionType;
74
75 /**
76  * class XACMLPolicyScanner
77  * 
78  * This class traverses the hierarchy of a XACML 3.0 policy. You can optionally pass a Callback class
79  * and override any desired methods to retrieve information from a policy. 
80  * 
81  *
82  */
83 public class XACMLPolicyScanner {
84         
85         private static final Log logger                         = LogFactory.getLog(XACMLPolicyScanner.class);
86         private Object policyObject = null;
87         private Callback callback = null;
88         
89         public XACMLPolicyScanner(Path filename, Callback callback) {
90                 try (InputStream is = Files.newInputStream(filename)) {
91                         this.policyObject = XACMLPolicyScanner.readPolicy(is);
92                 } catch (IOException e) {
93                         //TODO:EELF Cleanup - Remove logger
94                         //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Failed to read policy", e);
95                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Failed to read policy");
96                 }
97                 this.callback = callback;
98         }
99         
100         public XACMLPolicyScanner(PolicySetType policySet, Callback callback) {
101                 this.policyObject = policySet;
102                 this.callback = callback;
103         }
104         
105         public XACMLPolicyScanner(PolicySetType policySet) {
106                 this(policySet, null);
107         }
108         
109         public XACMLPolicyScanner(PolicyType policy, Callback callback) {
110                 this.policyObject = policy;
111                 this.callback = callback;
112         }
113         
114         public XACMLPolicyScanner(PolicyType policy) {
115                 this(policy, null);
116         }
117         
118         /**
119          * Sets the callback interface to be used.
120          * 
121          * @param cb
122          */
123         public void setCallback(Callback cb) {
124                 this.callback = cb;
125         }
126         
127         /**
128          * Saves the given callback object then calls the scan() method.
129          * 
130          * @param cb
131          * @return
132          */
133         public Object scan(Callback cb) {
134                 this.callback = cb;
135                 return this.scan();
136         }
137         
138         /**
139          * 
140          * This begins the scanning of the contained object.
141          * 
142          * @return - The PolicySet/Policy that was scanned.
143          */
144         public Object scan() {
145                 if (this.policyObject == null) {
146                         return null;
147                 }
148                 if (this.callback != null) {
149                         if (this.callback.onBeginScan(this.policyObject) == CallbackResult.STOP) {
150                                 return this.policyObject;
151                         }
152                 }
153                 if (this.policyObject instanceof PolicyType) {
154                         this.scanPolicy(null, (PolicyType) this.policyObject);
155                 } else if (this.policyObject instanceof PolicySetType) {
156                         this.scanPolicySet(null, (PolicySetType) this.policyObject);
157                 } else {
158                         //TODO:EELF Cleanup - Remove logger
159                         //logger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + "Unknown class type: " + this.policyObject.getClass().getCanonicalName());
160                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW + "Unknown class type: " + this.policyObject.getClass().getCanonicalName());
161                 }
162                 if (this.callback != null) {
163                         this.callback.onFinishScan(this.policyObject);
164                 }
165                 return this.policyObject;
166         }
167         
168         /**
169          * This performs the scan of a PolicySet
170          * 
171          * @param parent - Its parent PolicySet. Can be null if this is the root.
172          * @param policySet - The PolicySet object.
173          * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
174          */
175         /**
176          * @param parent
177          * @param policySet
178          * @return
179          */
180         protected CallbackResult scanPolicySet(PolicySetType parent, PolicySetType policySet) {
181                 if (logger.isTraceEnabled()) {
182                         logger.trace("scanning policy set: " + policySet.getPolicySetId() + " " + policySet.getDescription());
183                 }
184                 if (this.callback != null) {
185                         if (this.callback.onPreVisitPolicySet(parent, policySet) == CallbackResult.STOP) {
186                                 return CallbackResult.STOP;
187                         }
188                 }
189                 //
190                 // Scan its info
191                 //
192                 if (this.scanTarget(policySet, policySet.getTarget()) == CallbackResult.STOP) {
193                         return CallbackResult.STOP;
194                 }
195                 if (this.scanObligations(policySet, policySet.getObligationExpressions()) == CallbackResult.STOP) {
196                         return CallbackResult.STOP;
197                 }
198                 if (this.scanAdvice(policySet, policySet.getAdviceExpressions()) == CallbackResult.STOP) {
199                         return CallbackResult.STOP;
200                 }
201                 //
202                 // Iterate the policy sets and/or policies
203                 //
204                 List<JAXBElement<?>> list = policySet.getPolicySetOrPolicyOrPolicySetIdReference();
205                 for (JAXBElement<?> element: list) {
206                         if (element.getName().getLocalPart().equals("PolicySet")) {
207                                 if (this.scanPolicySet(policySet, (PolicySetType)element.getValue()) == CallbackResult.STOP) {
208                                         return CallbackResult.STOP;
209                                 }
210                         } else if (element.getName().getLocalPart().equals("Policy")) {
211                                 if (this.scanPolicy(policySet, (PolicyType)element.getValue()) == CallbackResult.STOP) {
212                                         return CallbackResult.STOP;
213                                 }
214                         } else if (element.getValue() instanceof IdReferenceType) {
215                                 if (element.getName().getLocalPart().equals("PolicySetIdReference")) {
216                                         
217                                 } else if (element.getName().getLocalPart().equals("PolicyIdReference")) {
218                                         
219                                 }
220                         } else {
221                                 logger.warn("generating policy sets found unsupported element: " + element.getName().getNamespaceURI());
222                         }
223                 }
224                 if (this.callback != null) {
225                         if (this.callback.onPostVisitPolicySet(parent, policySet) == CallbackResult.STOP) {
226                                 return CallbackResult.STOP;
227                         }
228                 }
229                 return CallbackResult.CONTINUE;
230         }
231         
232         /**
233          * 
234          * This performs scanning of the Policy object.
235          * 
236          * @param parent - The parent PolicySet of the policy. This can be null if this is a root Policy.
237          * @param policy - The policy being scanned.
238          * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
239          */
240         protected CallbackResult scanPolicy(PolicySetType parent, PolicyType policy) {
241                 if (logger.isTraceEnabled()) {
242                         logger.trace("scanning policy: " + policy.getPolicyId() + " " + policy.getDescription());
243                 }
244                 if (this.callback != null) {
245                         if (this.callback.onPreVisitPolicy(parent, policy) == CallbackResult.STOP) {
246                                 return CallbackResult.STOP;
247                         }
248                 }
249                 //
250                 // Scan its info
251                 //
252                 if (this.scanTarget(policy, policy.getTarget()) == CallbackResult.STOP) {
253                         return CallbackResult.STOP;
254                 }
255                 if (this.scanVariables(policy, policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition()) == CallbackResult.STOP) {
256                         return CallbackResult.STOP;
257                 }
258                 if (this.scanObligations(policy, policy.getObligationExpressions()) == CallbackResult.STOP) {
259                         return CallbackResult.STOP;
260                 }
261                 if (this.scanAdvice(policy, policy.getAdviceExpressions()) == CallbackResult.STOP) {
262                         return CallbackResult.STOP;
263                 }
264                 //
265                 // Iterate the rules
266                 //
267                 List<Object> list = policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition();
268                 for (Object o: list) {
269                         if (o instanceof RuleType) {
270                                 RuleType rule = (RuleType) o;
271                                 if (logger.isTraceEnabled()) {
272                                         logger.trace("scanning rule: " + rule.getRuleId() + " " + rule.getDescription());
273                                 }
274                                 if (this.callback != null) {
275                                         if (this.callback.onPreVisitRule(policy, rule) == CallbackResult.STOP) {
276                                                 return CallbackResult.STOP;
277                                         }
278                                 }
279                                 if (this.scanTarget(rule, rule.getTarget()) == CallbackResult.STOP) {
280                                         return CallbackResult.STOP;
281                                 }
282                                 if (this.scanConditions(rule, rule.getCondition()) == CallbackResult.STOP) {
283                                         return CallbackResult.STOP;
284                                 }
285                                 if (this.scanObligations(rule, rule.getObligationExpressions()) == CallbackResult.STOP) {
286                                         return CallbackResult.STOP;
287                                 }
288                                 if (this.scanAdvice(rule, rule.getAdviceExpressions()) == CallbackResult.STOP) {
289                                         return CallbackResult.STOP;
290                                 }
291                                 if (this.callback != null) {
292                                         if (this.callback.onPostVisitRule(policy, rule) == CallbackResult.STOP) {
293                                                 return CallbackResult.STOP;
294                                         }
295                                 }
296                         } else if (o instanceof VariableDefinitionType) {
297                                 if (this.callback != null) {
298                                         if (this.callback.onVariable(policy, (VariableDefinitionType) o) == CallbackResult.STOP) {
299                                                 return CallbackResult.STOP;
300                                         }
301                                 }
302                         } else {
303                                 if (logger.isDebugEnabled()) {
304                                         logger.debug("scanning policy rules found unsupported object:" + o.toString());
305                                 }
306                         }
307                 }
308                 if (this.callback != null) {
309                         if (this.callback.onPostVisitPolicy(parent, policy) == CallbackResult.STOP) {
310                                 return CallbackResult.STOP;
311                         }
312                 }
313                 return CallbackResult.CONTINUE;
314         }
315         
316         /**
317          * Scans the given target for attributes. Its sole purpose is to return attributes found.
318          * 
319          * @param parent - The parent PolicySet/Policy/Rule for the target.
320          * @param target - The target.
321          * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
322          */
323         protected CallbackResult scanTarget(Object parent, TargetType target) {
324                 if (target == null) {
325                         return CallbackResult.CONTINUE;
326                 }
327                 List<AnyOfType> anyOfList = target.getAnyOf();
328                 if (anyOfList != null) {
329                         Iterator<AnyOfType> iterAnyOf = anyOfList.iterator();
330                         while (iterAnyOf.hasNext()) {
331                                 AnyOfType anyOf = iterAnyOf.next();
332                                 List<AllOfType> allOfList = anyOf.getAllOf();
333                                 if (allOfList != null) {
334                                         Iterator<AllOfType> iterAllOf = allOfList.iterator();
335                                         while (iterAllOf.hasNext()) {
336                                                 AllOfType allOf = iterAllOf.next();
337                                                 List<MatchType> matchList = allOf.getMatch();
338                                                 if (matchList != null) {
339                                                         Iterator<MatchType> iterMatch = matchList.iterator();
340                                                         while (iterMatch.hasNext()) {
341                                                                 MatchType match = iterMatch.next();
342                                                                 //
343                                                                 // Finally down to the actual attribute
344                                                                 //
345                                                                 StdAttribute attribute = null;
346                                                                 AttributeValueType value = match.getAttributeValue();
347                                                                 if (match.getAttributeDesignator() != null && value != null) {
348                                                                         AttributeDesignatorType designator = match.getAttributeDesignator();
349                                                                         //
350                                                                         // The content may be tricky
351                                                                         //
352                                                                         attribute = new StdAttribute(new IdentifierImpl(designator.getCategory()),
353                                                                                                                                                         new IdentifierImpl(designator.getAttributeId()),
354                                                                                                                                                         new StdAttributeValue<List<?>>(new IdentifierImpl(value.getDataType()), value.getContent()),
355                                                                                                                                                         designator.getIssuer(),
356                                                                                                                                                         false);
357                                                                 } else if (match.getAttributeSelector() != null && value != null) {
358                                                                         AttributeSelectorType selector = match.getAttributeSelector();
359                                                                         attribute = new StdAttribute(new IdentifierImpl(selector.getCategory()),
360                                                                                                                                                         new IdentifierImpl(selector.getContextSelectorId()),
361                                                                                                                                                         new StdAttributeValue<List<?>>(new IdentifierImpl(value.getDataType()), value.getContent()),
362                                                                                                                                                         null,
363                                                                                                                                                         false);
364                                                                 } else {
365                                                                         logger.warn("NULL designator/selector or value for match.");
366                                                                 }
367                                                                 if (attribute != null && this.callback != null) {
368                                                                         if (this.callback.onAttribute(parent, target, attribute) == CallbackResult.STOP) {
369                                                                                 return CallbackResult.STOP;
370                                                                         }
371                                                                 }
372                                                         }
373                                                 }
374                                         }
375                                 }
376                         }
377                 }
378                 return CallbackResult.CONTINUE;
379         }
380         
381         /**
382          * Scan the list of obligations.
383          * 
384          * @param parent - The parent PolicySet/Policy/Rule for the obligation.
385          * @param obligationExpressionsType - All the obligation expressions.
386          * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
387          */
388         protected CallbackResult scanObligations(Object parent, ObligationExpressionsType obligationExpressionsType) {
389                 if (obligationExpressionsType == null) {
390                         return CallbackResult.CONTINUE;
391                 }
392                 List<ObligationExpressionType> expressions = obligationExpressionsType.getObligationExpression();
393                 if (expressions == null || expressions.size() == 0) {
394                         return CallbackResult.CONTINUE;
395                 }
396                 for (ObligationExpressionType expression : expressions) {
397                         StdMutableObligation ob = new StdMutableObligation(new IdentifierImpl(expression.getObligationId()));
398                         List<AttributeAssignmentExpressionType> assignments = expression.getAttributeAssignmentExpression();
399                         if (assignments != null) {
400                                 for (AttributeAssignmentExpressionType assignment : assignments) {
401                                         // category is optional and may be null
402                                         IdentifierImpl categoryId = null;
403                                         if (assignment.getCategory() != null) {
404                                                 categoryId = new IdentifierImpl(assignment.getCategory());
405                                         }
406                                         AttributeAssignment attribute = new StdAttributeAssignment(
407                                                                                                 categoryId,
408                                                                                                 new IdentifierImpl(assignment.getAttributeId()),
409                                                                                                 assignment.getIssuer(),
410                                                                                                 new StdAttributeValue<Object>(null, null)
411                                                                                                 );
412                                         ob.addAttributeAssignment(attribute);
413                                 }
414                         }
415                         if (this.callback != null) {
416                                 if (this.callback.onObligation(parent, expression, ob) == CallbackResult.STOP) {
417                                         return CallbackResult.STOP;
418                                 }
419                         }
420                 }
421                 return CallbackResult.CONTINUE;
422         }
423
424         /**
425          * 
426          * Scans the list of advice expressions returning each individually.
427          * 
428          * @param parent - The parent PolicySet/Policy/Rule for the advice.
429          * @param adviceExpressionstype - The list of advice expressions.
430          * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
431          */
432         protected CallbackResult scanAdvice(Object parent, AdviceExpressionsType adviceExpressionstype) {
433                 if (adviceExpressionstype == null) {
434                         return CallbackResult.CONTINUE;
435                 }
436                 List<AdviceExpressionType> expressions = adviceExpressionstype.getAdviceExpression();
437                 if (expressions == null || expressions.size() == 0) {
438                         return CallbackResult.CONTINUE;
439                 }
440                 for (AdviceExpressionType expression : expressions) {
441                         StdMutableAdvice ob = new StdMutableAdvice(new IdentifierImpl(expression.getAdviceId()));
442                         List<AttributeAssignmentExpressionType> assignments = expression.getAttributeAssignmentExpression();
443                         if (assignments != null) {
444                                 for (AttributeAssignmentExpressionType assignment : assignments) {
445                                         IdentifierImpl categoryId = null;
446                                         if (assignment.getCategory() != null) {
447                                                 categoryId = new IdentifierImpl(assignment.getCategory());
448                                         }
449                                         AttributeAssignment attribute = new StdAttributeAssignment(
450                                                                                                 categoryId,
451                                                                                                 new IdentifierImpl(assignment.getAttributeId()),
452                                                                                                 assignment.getIssuer(),
453                                                                                                 new StdAttributeValue<Object>(null, null)
454                                                                                                 );
455                                         ob.addAttributeAssignment(attribute);
456                                 }
457                         }
458                         if (this.callback != null) {
459                                 if (this.callback.onAdvice(parent, expression, ob) == CallbackResult.STOP) {
460                                         return CallbackResult.STOP;
461                                 }
462                         }
463                 }
464                 return CallbackResult.CONTINUE;
465         }
466         
467         /**
468          * Scans the list of variable definitions.
469          * 
470          * @param policy - Policy object containing the variable definition.
471          * @param list - List of variable definitions.
472          * @return CallbackResult - CONTINUE to continue, STOP to terminate scanning.
473          */
474         protected CallbackResult scanVariables(PolicyType policy, List<Object> list) {
475                 if (list == null) {
476                         return CallbackResult.CONTINUE;
477                 }
478                 for (Object o : list) {
479                         if (o instanceof VariableDefinitionType) {
480                                 if (this.callback != null) {
481                                         if (this.callback.onVariable(policy, (VariableDefinitionType) o) == CallbackResult.STOP) {
482                                                 return CallbackResult.STOP;
483                                         }
484                                 }
485                         }
486                 }
487                 
488                 return CallbackResult.CONTINUE;
489         }
490         
491         /**
492          * Scans the list of conditions.
493          * 
494          * @param rule
495          * @param condition
496          * @return
497          */
498         protected CallbackResult scanConditions(RuleType rule, ConditionType condition) {
499                 if (condition != null) {
500                         if (this.callback != null) {
501                                 if (this.callback.onCondition(rule, condition) == CallbackResult.STOP) {
502                                         return CallbackResult.STOP;
503                                 }
504                         }
505                 }
506                 return CallbackResult.CONTINUE;
507         }
508         
509         /**
510          * Reads the XACML XML policy file in and returns the version contained in the root Policy/PolicySet element.
511          * 
512          * @param policy - The policy file.
513          * @return - The version string from the file (uninterpreted)
514          * @throws IOException 
515          */
516         public static String    getVersion(Path policy) throws IOException {
517                 Object data = null;
518                 try (InputStream is = Files.newInputStream(policy)) {
519                         data = XACMLPolicyScanner.readPolicy(is);
520                 } catch (IOException e) {
521                         //TODO:EELF Cleanup - Remove logger
522                         //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Failed to read policy", e);
523                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Failed to read policy");
524                         throw e;
525                 }
526                 if (data == null) {
527                         logger.warn("Version is null.");
528                         return null;
529                 }
530                 return getVersion(data);
531         }
532                 
533         /**
534          * Reads the Policy/PolicySet element object and returns its current version.
535          * 
536          * @param data - Either a PolicySet or Policy XACML type object.
537          * @return - The integer version value. -1 if it doesn't exist or was un-parsable.
538          */
539         public static String    getVersion(Object data) {
540                 String version = null;
541                 try {
542                         if (data instanceof PolicySetType) {
543                                 version = ((PolicySetType)data).getVersion();
544                         } else if (data instanceof PolicyType) {
545                                 version = ((PolicyType)data).getVersion();
546                         } else {
547                                 if (data != null) {
548                                         //TODO:EELF Cleanup - Remove logger
549                                         //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Expecting a PolicySet/Policy/Rule object. Got: " + data.getClass().getCanonicalName());
550                                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Expecting a PolicySet/Policy/Rule object. Got: " + data.getClass().getCanonicalName());
551                                 }
552                                 return null;
553                         }
554                         if (version != null && version.length() > 0) {
555                                 return version;
556                         } else {
557                                 logger.warn("No version set in policy");
558                         }
559                 } catch (NumberFormatException e) {
560                         //TODO:EELF Cleanup - Remove logger
561                         //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid version contained in policy: " + version);
562                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, e, "XACMLPolicyScanner", "Invalid version contained in policy: " + version);
563                         return null;
564                 }
565                 return null;
566         }
567         
568         /**
569          * Returns the Policy or PolicySet ID.
570          * 
571          * @param data - A XACML 3.0 Policy or PolicySet element object.
572          * @return The policy/policyset's policy ID
573          */
574         public static String getID(Object data) {
575                 if (data instanceof PolicySetType) {
576                         return ((PolicySetType)data).getPolicySetId();
577                 } else if (data instanceof PolicyType) {
578                         return ((PolicyType)data).getPolicyId();
579                 } else {
580                         //TODO:EELF Cleanup - Remove logger
581                         //logger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + "Expecting a PolicySet/Policy/Rule object. Got: " + data.getClass().getCanonicalName());
582                         PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE + "Expecting a PolicySet/Policy/Rule object. Got: " + data.getClass().getCanonicalName());
583                         return null;
584                 }
585         }
586         
587         public static List<String> getCreatedByModifiedBy(Path policyPath) throws IOException{
588                 String createdBy = "";
589                 String modifiedBy= "";
590                 String cValue = "@CreatedBy:";
591                 String mValue = "@ModifiedBy:";
592                 for(String line: Files.readAllLines(policyPath)){
593                         line = line.replaceAll("\\s+", "");
594                         if(line.isEmpty()){
595                                 continue;
596                         }
597                         if(line.contains("<Description>") && line.contains(cValue) && line.contains(mValue)){
598                                 createdBy = line.substring(line.indexOf(cValue) + cValue.length(), line.lastIndexOf(cValue));
599                                 modifiedBy = line.substring(line.indexOf(mValue) + mValue.length(), line.lastIndexOf(mValue));
600                                 break;
601                         }
602                 }
603                 return Arrays.asList(createdBy, modifiedBy);
604         }
605         
606         //get the Created Name of the User on reading the Xml file
607         public static String getCreatedBy(Path policyPath) throws IOException{
608                 String userId = "";
609                 String value = "@CreatedBy:";
610                 for(String line: Files.readAllLines(policyPath)){
611                         line = line.replaceAll("\\s+", "");
612                         if(line.isEmpty()){
613                                 continue;
614                         }
615                         if(line.contains("<Description>") && line.contains(value)){
616                                 userId = line.substring(line.indexOf(value) + value.length(), line.lastIndexOf(value));
617                                 break;
618                         }
619                 }
620                 return userId;
621         }
622         
623         //get the Modified Name of the User on reading the Xml file
624         public static String getModifiedBy(Path policyPath) throws IOException{
625                 String modifiedBy = "";
626                 String value = "@ModifiedBy:";
627                 for(String line: Files.readAllLines(policyPath)){
628                         line = line.replaceAll("\\s+", "");
629                         if(line.isEmpty()){
630                                 continue;
631                         }
632                         if(line.contains("<Description>") && line.contains(value)){
633                                 modifiedBy = line.substring(line.indexOf(value) + value.length(), line.lastIndexOf(value));
634                                 break;
635                         }
636                 }
637                 return modifiedBy;
638         }
639
640         /**
641          * readPolicy - does the work to read in policy data from a file.
642          * 
643          * @param policy - The path to the policy file.
644          * @return - The policy data object. This *should* be either a PolicySet or a Policy.
645          */
646         public static Object readPolicy(InputStream is) {
647                 try {
648                         //
649                         // Create a DOM parser
650                         //
651                         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
652                     dbf.setNamespaceAware(true);
653                     DocumentBuilder db = dbf.newDocumentBuilder();
654                     //
655                     // Parse the policy file
656                     //
657                     Document doc = db.parse(is);
658                     //
659                     // Because there is no root defined in xacml,
660                     // find the first element
661                     //
662                         NodeList nodes = doc.getChildNodes();
663                         Node node = nodes.item(0);
664                         Element e = null;
665                         if (node.getNodeType() == Node.ELEMENT_NODE) {
666                                 e = (Element) node;
667                                 //
668                                 // Is it a 3.0 policy?
669                                 //
670                                 if (e.getNamespaceURI().equals("urn:oasis:names:tc:xacml:3.0:core:schema:wd-17")) {
671                                         //
672                                         // A policyset or policy could be the root
673                                         //
674                                         if (e.getNodeName().endsWith("Policy")) {
675                                                 //
676                                                 // Now we can create the context for the policy set
677                                                 // and unmarshall the policy into a class.
678                                                 //
679                                                 JAXBContext context = JAXBContext.newInstance(PolicyType.class);
680                                                 Unmarshaller um = context.createUnmarshaller();
681                                                 JAXBElement<PolicyType> root = um.unmarshal(e, PolicyType.class);
682                                                 //
683                                                 // Here is our policy set class
684                                                 //
685                                                 return root.getValue();
686                                         } else if (e.getNodeName().endsWith("PolicySet")) {
687                                                 //
688                                                 // Now we can create the context for the policy set
689                                                 // and unmarshall the policy into a class.
690                                                 //
691                                                 JAXBContext context = JAXBContext.newInstance(PolicySetType.class);
692                                                 Unmarshaller um = context.createUnmarshaller();
693                                                 JAXBElement<PolicySetType> root = um.unmarshal(e, PolicySetType.class);
694                                                 //
695                                                 // Here is our policy set class
696                                                 //
697                                                 return root.getValue();
698                                         } else {
699                                                 if (logger.isDebugEnabled()) {
700                                                         logger.debug("Not supported yet: " + e.getNodeName());
701                                                 }
702                                         }
703                                 } else {
704                                         logger.warn("unsupported namespace: " + e.getNamespaceURI());
705                                 }
706                         } else {
707                                 if (logger.isDebugEnabled()) {
708                                         logger.debug("No root element contained in policy " + 
709                                                                 " Name: " + node.getNodeName() + " type: " + node.getNodeType() + 
710                                                                 " Value: " + node.getNodeValue());
711                                 }
712                         }
713                 } catch (Exception e) {
714                         //TODO:EELF Cleanup - Remove logger
715                         //logger.error(XACMLErrorConstants.ERROR_SCHEMA_INVALID + e.getMessage());
716                         PolicyLogger.error(MessageCodes.ERROR_SCHEMA_INVALID, e, "XACMLPolicyScanner", "Exception in readPolicy");
717                 }
718                 return null;
719         }
720
721         /**
722          * @return the policyObject
723          */
724         public Object getPolicyObject() {
725                 return policyObject;
726         }
727 }