1 package com.atlassian.seraph.service;
2
3 import com.atlassian.seraph.SecurityService;
4 import com.atlassian.seraph.config.SecurityConfig;
5 import com.atlassian.seraph.util.CachedPathMapper;
6 import com.atlassian.seraph.util.XMLUtils;
7
8 import org.apache.commons.collections.map.LRUMap;
9 import org.apache.log4j.Category;
10 import org.w3c.dom.Document;
11 import org.w3c.dom.Element;
12 import org.w3c.dom.NodeList;
13
14 import com.opensymphony.util.ClassLoaderUtil;
15
16 import java.net.URL;
17 import java.util.Collection;
18 import java.util.Collections;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.Iterator;
22 import java.util.Map;
23 import java.util.Set;
24 import java.util.StringTokenizer;
25
26 import javax.servlet.http.HttpServletRequest;
27 import javax.xml.parsers.DocumentBuilderFactory;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public class PathService implements SecurityService
52 {
53 private static final Category log = Category.getInstance(PathService.class);
54 static String CONFIG_FILE_PARAM_KEY = "config.file";
55
56 String configFileLocation = "seraph-paths.xml";
57
58
59 private final CachedPathMapper pathMapper = new CachedPathMapper(Collections.synchronizedMap(new LRUMap(10)), Collections.synchronizedMap(new LRUMap(10)));
60
61
62 private final Map
63
64
65
66
67 public void init(final Map params, final SecurityConfig config)
68 {
69 if (params.get(CONFIG_FILE_PARAM_KEY) != null)
70 {
71 configFileLocation = (String) params.get(CONFIG_FILE_PARAM_KEY);
72 }
73
74 configurePathMapper();
75 }
76
77
78
79
80 private void configurePathMapper()
81 {
82 try
83 {
84 final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
85 URL fileUrl = ClassLoaderUtil.getResource(configFileLocation, this.getClass());
86
87 if (fileUrl == null)
88 {
89 fileUrl = ClassLoaderUtil.getResource("/" + configFileLocation, this.getClass());
90 }
91
92 if (fileUrl == null)
93 {
94 return;
95 }
96
97
98 final Document doc = factory.newDocumentBuilder().parse(fileUrl.toString());
99
100
101 final Element root = doc.getDocumentElement();
102 final NodeList pathNodes = root.getElementsByTagName("path");
103
104 final Map
105
106 for (int i = 0; i < pathNodes.getLength(); i++)
107 {
108 final Element path = (Element) pathNodes.item(i);
109
110 final String pathName = path.getAttribute("name");
111 final String roleNames = XMLUtils.getContainedText(path, "role-name");
112 final String urlPattern = XMLUtils.getContainedText(path, "url-pattern");
113
114 if ((roleNames != null) && (urlPattern != null))
115 {
116 final String[] rolesArr = parseRoles(roleNames);
117 paths.put(pathName, rolesArr);
118 pathMaps.put(pathName, urlPattern);
119 }
120 }
121 pathMapper.set(pathMaps);
122 }
123 catch (final Exception ex)
124 {
125 log.error(ex);
126 }
127 }
128
129 protected String[] parseRoles(final String roleNames)
130 {
131 final StringTokenizer st = new StringTokenizer(roleNames, ",; \t\n", false);
132 final String[] roles = new String[st.countTokens()];
133 int i = 0;
134 while (st.hasMoreTokens())
135 {
136 roles[i] = st.nextToken();
137 i++;
138 }
139 return roles;
140 }
141
142 public void destroy()
143 {}
144
145 public Set getRequiredRoles(final HttpServletRequest request)
146 {
147 final String servletPath = request.getServletPath();
148 return getRequiredRoles(servletPath);
149 }
150
151 public Set getRequiredRoles(final String servletPath)
152 {
153 final Set requiredRoles = new HashSet();
154
155
156 final Collection constraintMatches = pathMapper.getAll(servletPath);
157
158 if (constraintMatches == null)
159 {
160 throw new RuntimeException("No constraints matched for path " + servletPath);
161 }
162 for (final Iterator iterator = constraintMatches.iterator(); iterator.hasNext();)
163 {
164 final String constraint = (String) iterator.next();
165
166 final String[] rolesForPath = (String[]) paths.get(constraint);
167 for (int i = 0; i < rolesForPath.length; i++)
168 {
169 if (!requiredRoles.contains(rolesForPath[i]))
170 {
171 requiredRoles.add(rolesForPath[i]);
172 }
173 }
174 }
175 return Collections.unmodifiableSet(requiredRoles);
176 }
177 }