1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.wss4j.policy.builders;
20
21 import org.apache.neethi.Assertion;
22 import org.apache.neethi.AssertionBuilderFactory;
23 import org.apache.neethi.builders.AssertionBuilder;
24 import org.apache.wss4j.policy.SP11Constants;
25 import org.apache.wss4j.policy.SP13Constants;
26 import org.apache.wss4j.policy.SPConstants;
27 import org.apache.wss4j.policy.SPUtils;
28 import org.apache.wss4j.policy.model.SignedElements;
29 import org.apache.wss4j.policy.model.XPath;
30 import org.w3c.dom.Attr;
31 import org.w3c.dom.Element;
32 import org.w3c.dom.NamedNodeMap;
33
34 import javax.xml.namespace.QName;
35 import java.util.ArrayList;
36 import java.util.HashMap;
37 import java.util.List;
38 import java.util.Map;
39
40 public class SignedElementsBuilder implements AssertionBuilder<Element> {
41
42 @Override
43 public Assertion build(Element element, AssertionBuilderFactory factory) throws IllegalArgumentException {
44
45 final SPConstants.SPVersion spVersion = SPConstants.SPVersion.getSPVersion(element.getNamespaceURI());
46 final String xPathVersion = getXPathVersion(element);
47 final List<XPath> xPaths = getXPathExpressions(element, spVersion);
48 final List<XPath> xPaths2 = getXPath2Expressions(element, spVersion);
49 xPaths.addAll(xPaths2);
50 SignedElements signedElements = new SignedElements(spVersion, xPathVersion, xPaths);
51 signedElements.setOptional(SPUtils.isOptional(element));
52 signedElements.setIgnorable(SPUtils.isIgnorable(element));
53 return signedElements;
54 }
55
56 protected List<XPath> getXPathExpressions(Element element, SPConstants.SPVersion spVersion) {
57 List<XPath> xPaths = new ArrayList<>();
58
59 Element child = SPUtils.getFirstChildElement(element);
60 while (child != null) {
61 QName xpathExpression = spVersion.getSPConstants().getXPathExpression();
62 if (SPConstants.XPATH_EXPR.equals(child.getLocalName())
63 && xpathExpression.getNamespaceURI().equals(child.getNamespaceURI())) {
64 Map<String, String> declaredNamespaces = new HashMap<>();
65 addDeclaredNamespaces(child, declaredNamespaces);
66 xPaths.add(new XPath(child.getTextContent().trim(), XPath.Version.V1, null, declaredNamespaces));
67 }
68 child = SPUtils.getNextSiblingElement(child);
69 }
70 return xPaths;
71 }
72
73 protected List<XPath> getXPath2Expressions(Element element, SPConstants.SPVersion spVersion) {
74 List<XPath> xPaths = new ArrayList<>();
75
76 Element child = SPUtils.getFirstChildElement(element);
77 while (child != null) {
78 QName xpathExpression = spVersion.getSPConstants().getXPath2Expression();
79 if (SPConstants.XPATH2_EXPR.equals(child.getLocalName())
80 && xpathExpression.getNamespaceURI().equals(child.getNamespaceURI())) {
81 Map<String, String> declaredNamespaces = new HashMap<>();
82 addDeclaredNamespaces(child, declaredNamespaces);
83 String filter = child.getAttributeNS(null, SPConstants.FILTER);
84 if (filter == null || filter.length() == 0) {
85 throw new IllegalArgumentException(SPConstants.ERR_INVALID_POLICY);
86 }
87 xPaths.add(new XPath(child.getTextContent().trim(), XPath.Version.V2, filter, declaredNamespaces));
88 }
89 child = SPUtils.getNextSiblingElement(child);
90 }
91 return xPaths;
92 }
93
94 protected String getXPathVersion(Element element) {
95 String xPathVersion = element.getAttributeNS(null, SPConstants.XPATH_VERSION);
96 if (xPathVersion == null || xPathVersion.length() == 0) {
97 xPathVersion = "1.0";
98 }
99 return xPathVersion;
100 }
101
102 protected void addDeclaredNamespaces(Element element, Map<String, String> declaredNamespaces) {
103 if (element.getParentNode() != null && element.getParentNode() instanceof Element) {
104 addDeclaredNamespaces((Element) element.getParentNode(), declaredNamespaces);
105 }
106 NamedNodeMap map = element.getAttributes();
107 for (int x = 0; x < map.getLength(); x++) {
108 Attr attr = (Attr) map.item(x);
109 if ("xmlns".equals(attr.getPrefix())) {
110 declaredNamespaces.put(attr.getLocalName(), attr.getValue());
111 }
112 }
113 }
114
115 @Override
116 public QName[] getKnownElements() {
117 return new QName[]{SP13Constants.SIGNED_ELEMENTS, SP11Constants.SIGNED_ELEMENTS};
118 }
119 }