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