1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.kathrynhuxtable.middleware.shibshim.filter;
19
20 import java.io.ByteArrayInputStream;
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Enumeration;
24 import java.util.HashMap;
25 import java.util.Iterator;
26 import java.util.Map;
27 import java.util.Vector;
28
29 import javax.xml.parsers.DocumentBuilderFactory;
30 import javax.xml.parsers.ParserConfigurationException;
31
32 import org.apache.log4j.Logger;
33 import org.w3c.dom.Attr;
34 import org.w3c.dom.Document;
35 import org.w3c.dom.Element;
36 import org.w3c.dom.NamedNodeMap;
37 import org.w3c.dom.Node;
38 import org.xml.sax.SAXException;
39
40
41
42
43
44 public class UserAttributesImpl extends HashMap implements UserAttributes {
45
46
47
48 private static Logger log = Logger.getLogger(UserAttributesImpl.class.getName());
49
50
51
52
53 private static final int INITIAL_CAPACITY = 5;
54
55
56
57
58
59 private static final String DTD_TEXT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE Assertion [\n"
60 + "<!ELEMENT Assertion (AttributeStatement)>\n<!ATTLIST Assertion\n"
61 + " IssueInstant CDATA #REQUIRED\n AuthenticationInstant CDATA #REQUIRED\n"
62 + " Issuer CDATA #REQUIRED\n Handle CDATA #REQUIRED>\n"
63 + "<!ELEMENT AttributeStatement (Attribute*)>\n<!ELEMENT Attribute (AttributeValue+)>\n"
64 + "<!ATTLIST Attribute\n AttributeName CDATA #REQUIRED>\n"
65 + "<!ELEMENT AttributeValue (#PCDATA | AttributeStatement)*>\n]>\n";
66
67
68
69
70
71
72
73 private static final String ATTRIBUTE_TAG = "Attribute";
74
75
76
77
78 private static final String ATTRIBUTE_NAME_TAG = "AttributeName";
79
80
81
82
83 private static final String ATTRIBUTE_VALUE_TAG = "AttributeValue";
84
85
86
87
88 private static final String ASSERTION_TAG = "Assertion";
89
90
91
92
93 private static final String ATTR_STMT_TAG = "AttributeStatement";
94
95
96
97
98
99 private boolean hasAttributes;
100
101
102
103
104
105
106 private Map attributeMap;
107
108
109
110
111
112
113
114
115
116 public UserAttributesImpl(Map attributeMap) {
117 super();
118 hasAttributes = false;
119 this.attributeMap = attributeMap;
120 }
121
122
123
124
125 public boolean isMappedAttribute(String name) {
126 return attributeMap.containsValue(name.toLowerCase());
127 }
128
129
130
131
132 public String getHeader(String name) {
133 ArrayList list = null;
134 name = name.toLowerCase();
135 if (name.startsWith("config-")) {
136 return (String) get(name);
137 }
138 list = (ArrayList) get(name);
139 log.debug("Got list = " + list + ", size = " + (list == null ? "?" : (new Integer(list.size())).toString()));
140 Object res = list == null || list.size() == 0 ? null : list.get(0);
141 if (res instanceof HashMap) {
142
143 HashMap subMap = (HashMap) res;
144 Iterator itr = (subMap.keySet()).iterator();
145 String subTable = null;
146 subTable = "<Assertion>";
147 while (itr.hasNext()) {
148 String subName = (String) itr.next();
149 subTable += "<Attribute name=\"" + subName + "\">" + subMap.get(subName) + "</Attribute>";
150 }
151 subTable += "</Assertion>";
152 return subTable;
153 }
154 return (String) res;
155 }
156
157
158
159
160 public Enumeration getHeaders(String name) {
161 ArrayList list = null;
162
163 name = name.toLowerCase();
164
165 if (name.startsWith("config-")) {
166 Vector res = new Vector();
167 res.add(get(name));
168 return res.elements();
169 } else {
170 list = (ArrayList) get(name);
171 if (list == null) {
172 return (new Vector()).elements();
173 }
174 }
175
176 return (new Vector(list)).elements();
177 }
178
179
180
181
182 public Enumeration getHeaderNames() {
183 Vector v = new Vector();
184 Iterator keys = keySet().iterator();
185 while (keys.hasNext()) {
186 String key = (String) keys.next();
187 v.add(key);
188 }
189 return v.elements();
190 }
191
192
193
194
195
196
197 public boolean hasAttributes() {
198 return hasAttributes;
199 }
200
201
202
203
204 public void clearUserInfo() {
205 Iterator keys = this.keySet().iterator();
206 Vector remMap = new Vector();
207 int track = 0;
208 while (keys.hasNext()) {
209 String key = (String) keys.next();
210 if (!key.startsWith("config-")) {
211 remMap.add(key);
212 }
213 }
214 while (track < remMap.size()) {
215 this.remove(remMap.get(track));
216 track++;
217 }
218 hasAttributes = false;
219 }
220
221
222
223
224
225
226
227
228
229
230 public void parseUserInfo(String userInfo) throws UserInfoException {
231
232 Document doc = parseXmlFile(userInfo);
233
234
235 Element top = doc.getDocumentElement();
236 if (!top.getTagName().equals(ASSERTION_TAG)) {
237 return;
238 }
239
240
241 NamedNodeMap assertionAttrs = top.getAttributes();
242 for (int i = 0; i < assertionAttrs.getLength(); i++) {
243 Attr attr = (Attr) assertionAttrs.item(i);
244 ArrayList assertionList = new ArrayList(INITIAL_CAPACITY);
245 assertionList.add(attr.getNodeValue());
246 this.put("config-" + attr.getNodeName().toLowerCase(), assertionList);
247 }
248
249
250 Node attributeStatement = top.getFirstChild();
251 if (attributeStatement == null || !attributeStatement.getNodeName().equals(ATTR_STMT_TAG) || attributeStatement.getNextSibling() != null) {
252 return;
253 }
254
255
256 for (Node attribute = attributeStatement.getFirstChild(); attribute != null; attribute = attribute.getNextSibling()) {
257 String nodeName = attribute.getNodeName();
258
259 if (nodeName == null || !nodeName.equals(ATTRIBUTE_TAG)) {
260 continue;
261 }
262
263 String attrName = ((Element) attribute).getAttribute(ATTRIBUTE_NAME_TAG);
264 if (!attributeMap.containsKey(attrName.toLowerCase())) {
265 log.debug("Skipping incoming attribute \"" + attrName + "\"");
266 continue;
267 }
268
269
270 ArrayList attrList = new ArrayList(INITIAL_CAPACITY);
271 for (Node value = attribute.getFirstChild(); value != null; value = value.getNextSibling()) {
272 String valueNodeName = value.getNodeName();
273
274
275 if (valueNodeName == null || !valueNodeName.equals(ATTRIBUTE_VALUE_TAG)) {
276 continue;
277 }
278 StringBuffer attrValue = new StringBuffer();
279 for (Node valueNode = value.getFirstChild(); valueNode != null; valueNode = valueNode.getNextSibling()) {
280 if (valueNode.getNodeName() == null || !valueNode.getNodeName().equals(ATTR_STMT_TAG)) {
281 attrValue.append(valueNode.getNodeValue());
282 } else {
283
284
285
286
287 attrValue.append(encodeAttributeStatement(valueNode));
288 }
289 }
290 if (attrValue.length() > 0) {
291 hasAttributes = true;
292 attrList.add(attrValue.toString());
293 }
294 }
295 if (!attrList.isEmpty()) {
296 log.debug("Saving attribute \"" + attributeMap.get(attrName.toLowerCase()) + "\" with value " + attrList);
297 this.put(attributeMap.get(attrName.toLowerCase()), attrList);
298 }
299 }
300 }
301
302
303
304
305
306
307
308
309
310
311
312
313 private static Document parseXmlFile(String userInfo) throws UserInfoException {
314 try {
315 userInfo = DTD_TEXT + userInfo;
316
317
318 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
319 factory.setValidating(true);
320 log.debug("User Info = \"" + userInfo + "\"");
321
322
323 ByteArrayInputStream inputStream = new ByteArrayInputStream(userInfo.getBytes());
324 return factory.newDocumentBuilder().parse(inputStream);
325 } catch (SAXException e) {
326 log.debug("ShibShimFilter::parseXmlFile:Received a SAXException::" + e.getMessage());
327 throw new UserInfoException("ShibShimFilter::parseXmlFile:Received a SAXException::" + e.getMessage());
328 } catch (ParserConfigurationException e) {
329 log.debug("ShibShimFilter::parseXmlFile:Received a ParserConfigurationException::" + e.getMessage());
330 throw new UserInfoException("ShibShimFilter::parseXmlFile:Received a ParserConfigurationException::" + e.getMessage());
331 } catch (IOException e) {
332 log.debug("ShibShimFilter::parseXmlFile:Received a IOException::" + e.getMessage());
333 throw new UserInfoException("ShibShimFilter::parseXmlFile:Received an IOException::" + e.getMessage());
334 }
335 }
336
337
338
339
340
341
342
343
344 private StringBuffer encodeAttributeStatement(Node attributeStatement) {
345 StringBuffer result = new StringBuffer();
346 result.append("<" + ATTR_STMT_TAG + ">");
347
348
349 for (Node attribute = attributeStatement.getFirstChild(); attribute != null; attribute = attribute.getNextSibling()) {
350 String nodeName = attribute.getNodeName();
351
352 if (nodeName == null || !nodeName.equals(ATTRIBUTE_TAG)) {
353 continue;
354 }
355
356 String attrName = ((Element) attribute).getAttribute(ATTRIBUTE_NAME_TAG);
357
358
359 result.append("<" + ATTRIBUTE_TAG + " " + ATTRIBUTE_NAME_TAG + "=\"" + attrName + "\">");
360 for (Node value = attribute.getFirstChild(); value != null; value = value.getNextSibling()) {
361 String valueNodeName = value.getNodeName();
362
363
364 if (valueNodeName == null || !valueNodeName.equals(ATTRIBUTE_VALUE_TAG)) {
365 continue;
366 }
367 StringBuffer attrValue = new StringBuffer();
368 for (Node valueNode = value.getFirstChild(); valueNode != null; valueNode = valueNode.getNextSibling()) {
369 if (valueNode.getNodeName() == null || !valueNode.getNodeName().equals(ATTR_STMT_TAG)) {
370 attrValue.append(valueNode.getNodeValue());
371 } else {
372
373
374
375
376 attrValue.append(encodeAttributeStatement(valueNode));
377 }
378 }
379 if (attrValue.length() > 0) {
380 result.append("<" + ATTRIBUTE_VALUE_TAG + ">");
381 result.append(attrValue.toString());
382 result.append("</" + ATTRIBUTE_VALUE_TAG + ">");
383 }
384 }
385 result.append("</" + ATTRIBUTE_TAG + ">");
386 }
387
388 result.append("</" + ATTR_STMT_TAG + ">");
389 return result;
390 }
391 }