source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/core/URLFilter.java@ 26538

Last change on this file since 26538 was 26538, checked in by sjm84, 11 years ago

Added the usersdb directory to the list of places that shouldn't be accessible

  • Property svn:executable set to *
File size: 14.0 KB
Line 
1package org.greenstone.gsdl3.core;
2
3import java.io.IOException;
4import java.util.ArrayList;
5import java.util.HashMap;
6import java.util.Map;
7
8import javax.servlet.Filter;
9import javax.servlet.FilterChain;
10import javax.servlet.FilterConfig;
11import javax.servlet.ServletException;
12import javax.servlet.ServletRequest;
13import javax.servlet.ServletResponse;
14import javax.servlet.http.HttpServletRequest;
15import javax.servlet.http.HttpServletRequestWrapper;
16
17import org.apache.log4j.Logger;
18import org.greenstone.gsdl3.util.GSParams;
19import org.greenstone.gsdl3.util.GSXML;
20import org.greenstone.gsdl3.util.UserContext;
21import org.w3c.dom.Document;
22import org.w3c.dom.Element;
23import org.w3c.dom.NodeList;
24
25public class URLFilter implements Filter
26{
27 private FilterConfig _filterConfig = null;
28 private static Logger _logger = Logger.getLogger(org.greenstone.gsdl3.core.URLFilter.class.getName());
29
30 //Restricted URLs
31 protected static final String SITECONFIG_URL = "sites/[^/]+/siteConfig.xml";
32 protected static final String USERS_DB_URL = "sites/[^/]+/etc/usersDB/.*";
33 protected static final ArrayList<String> _restrictedURLs;
34 static
35 {
36 ArrayList<String> restrictedURLs = new ArrayList<String>();
37 restrictedURLs.add(SITECONFIG_URL);
38 restrictedURLs.add(USERS_DB_URL);
39 _restrictedURLs = restrictedURLs;
40 }
41
42 //Constants
43 protected static final String DOCUMENT_PATH = "document";
44 protected static final String COLLECTION_PATH = "collection";
45 protected static final String PAGE_PATH = "page";
46 protected static final String SYSTEM_PATH = "system";
47
48 protected static final String METADATA_RETRIEVAL_SERVICE = "DocumentMetadataRetrieve";
49 protected static final String ASSOCIATED_FILE_PATH = "/index/assoc/";
50 protected static final String COLLECTION_FILE_PATH = "/collect/";
51
52 protected static final String SYSTEM_SUBACTION_CONFIGURE = "configure";
53 protected static final String SYSTEM_SUBACTION_RECONFIGURE = "reconfigure";
54 protected static final String SYSTEM_SUBACTION_ACTIVATE = "activate";
55 protected static final String SYSTEM_SUBACTION_DEACTIVATE = "deactivate";
56
57 public void init(FilterConfig filterConfig) throws ServletException
58 {
59 this._filterConfig = filterConfig;
60 }
61
62 public void destroy()
63 {
64 this._filterConfig = null;
65 }
66
67 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
68 {
69 if (request instanceof HttpServletRequest)
70 {
71 HttpServletRequest hRequest = ((HttpServletRequest) request);
72 GSHttpServletRequestWrapper gRequest = new GSHttpServletRequestWrapper(hRequest);
73
74 String url = hRequest.getRequestURI().toString();
75
76 if (isURLRestricted(url))
77 {
78 response.getWriter().println("Access to this page is forbidden.");
79 return;
80 }
81
82 //If the user is trying to access a collection file we need to run a security check
83 if (url.contains(ASSOCIATED_FILE_PATH))
84 {
85 String dir = null;
86 int dirStart = url.indexOf(ASSOCIATED_FILE_PATH) + ASSOCIATED_FILE_PATH.length();
87 int dirEnd = -1;
88 if (dirStart < url.length() && url.indexOf("/", dirStart) != -1)
89 {
90 dirEnd = url.indexOf("/", dirStart);
91 }
92 if (dirEnd != -1)
93 {
94 dir = url.substring(dirStart, dirEnd);
95 }
96 if (dir == null)
97 {
98 return;
99 }
100
101 String collection = null;
102 int colStart = url.indexOf(COLLECTION_FILE_PATH) + COLLECTION_FILE_PATH.length();
103 int colEnd = -1;
104 if (colStart < url.length() && url.indexOf("/", colStart) != -1)
105 {
106 colEnd = url.indexOf("/", colStart);
107 }
108 if (colEnd != -1)
109 {
110 collection = url.substring(colStart, colEnd);
111 }
112 if (collection == null)
113 {
114 return;
115 }
116
117 MessageRouter gsRouter = (MessageRouter) request.getServletContext().getAttribute("GSRouter");
118 if (gsRouter == null)
119 {
120 _logger.error("Receptionist is null, stopping filter");
121 return;
122 }
123
124 Document gsDoc = (Document) request.getServletContext().getAttribute("GSDocument");
125 if (gsDoc == null)
126 {
127 _logger.error("Document is null, stopping filter");
128 return;
129 }
130
131 Element metaMessage = gsDoc.createElement(GSXML.MESSAGE_ELEM);
132 Element metaRequest = GSXML.createBasicRequest(gsDoc, GSXML.REQUEST_TYPE_PROCESS, collection + "/" + METADATA_RETRIEVAL_SERVICE, new UserContext());
133 metaMessage.appendChild(metaRequest);
134
135 Element paramList = gsDoc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
136 metaRequest.appendChild(paramList);
137
138 Element param = gsDoc.createElement(GSXML.PARAM_ELEM);
139 paramList.appendChild(param);
140
141 param.setAttribute(GSXML.NAME_ATT, "metadata");
142 param.setAttribute(GSXML.VALUE_ATT, "contains");
143
144 Element docList = gsDoc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
145 metaRequest.appendChild(docList);
146
147 Element doc = gsDoc.createElement(GSXML.DOC_NODE_ELEM);
148 docList.appendChild(doc);
149
150 doc.setAttribute(GSXML.NODE_ID_ATT, dir);
151
152 Element metaResponse = (Element) gsRouter.process(metaMessage);
153
154 NodeList metadataList = metaResponse.getElementsByTagName(GSXML.METADATA_ELEM);
155 if (metadataList.getLength() == 0)
156 {
157 _logger.error("Could not find the document related to this url");
158 }
159 else
160 {
161 Element metadata = (Element) metadataList.item(0);
162 String document = metadata.getTextContent();
163
164 //Get the security info for this collection
165 Element securityMessage = gsDoc.createElement(GSXML.MESSAGE_ELEM);
166 Element securityRequest = GSXML.createBasicRequest(gsDoc, GSXML.REQUEST_TYPE_SECURITY, collection, new UserContext());
167 securityMessage.appendChild(securityRequest);
168 if (document != null && !document.equals(""))
169 {
170 securityRequest.setAttribute(GSXML.NODE_OID, document);
171 }
172
173 Element securityResponse = (Element) GSXML.getChildByTagName(gsRouter.process(securityMessage), GSXML.RESPONSE_ELEM);
174 ArrayList<String> groups = GSXML.getGroupsFromSecurityResponse(securityResponse);
175
176 if (!groups.contains(""))
177 {
178 boolean found = false;
179 for (String group : groups)
180 {
181 if (((HttpServletRequest) request).isUserInRole(group))
182 {
183 found = true;
184 break;
185 }
186 }
187
188 if (!found)
189 {
190 return;
191 }
192 }
193 }
194 }
195 else
196 {
197 //If we have a jsessionid on the end of our URL we want to ignore it
198 int index;
199 if ((index = url.indexOf(";jsessionid")) != -1)
200 {
201 url = url.substring(0, index);
202 }
203 String[] segments = url.split("/");
204 for (int i = 0; i < segments.length; i++)
205 {
206 String[] additionalParameters = null;
207 String[] defaultParamValues = null;
208
209 //COLLECTION
210 if (segments[i].equals(COLLECTION_PATH) && (i + 1) < segments.length)
211 {
212 gRequest.setParameter(GSParams.COLLECTION, segments[i + 1]);
213 }
214 //DOCUMENT
215 else if (segments[i].equals(DOCUMENT_PATH) && (i + 1) < segments.length)
216 {
217 gRequest.setParameter(GSParams.DOCUMENT, segments[i + 1]);
218
219 additionalParameters = new String[] { GSParams.ACTION };
220 defaultParamValues = new String[] { "d" };
221 //additionalParameters = new String[] { GSParams.ACTION, GSParams.DOCUMENT_TYPE };
222 //defaultParamValues = new String[] { "d", "hierarchy" };
223 }
224 //PAGE
225 else if (segments[i].equals(PAGE_PATH) && (i + 1) < segments.length)
226 {
227 gRequest.setParameter(GSParams.SUBACTION, segments[i + 1]);
228
229 additionalParameters = new String[] { GSParams.ACTION };
230 defaultParamValues = new String[] { "p" };
231 }
232 //SYSTEM
233 else if (segments[i].equals(SYSTEM_PATH) && (i + 1) < segments.length)
234 {
235 String sa = segments[i + 1];
236 if (sa.equals(SYSTEM_SUBACTION_CONFIGURE) || sa.equals(SYSTEM_SUBACTION_RECONFIGURE))
237 {
238 sa = "c";
239 }
240 else if (sa.equals(SYSTEM_SUBACTION_ACTIVATE))
241 {
242 sa = "a";
243 }
244 else if (sa.equals(SYSTEM_SUBACTION_DEACTIVATE))
245 {
246 sa = "d";
247 }
248
249 if (sa.equals("c") && (i + 2) < segments.length)
250 {
251 gRequest.setParameter(GSParams.SYSTEM_CLUSTER, segments[i + 2]);
252 }
253
254 if (sa.equals("a") && (i + 2) < segments.length)
255 {
256 gRequest.setParameter(GSParams.SYSTEM_MODULE_TYPE, "collection");
257 gRequest.setParameter(GSParams.SYSTEM_MODULE_NAME, segments[i + 2]);
258 }
259
260 if (sa.equals("d") && (i + 2) < segments.length)
261 {
262 gRequest.setParameter(GSParams.SYSTEM_CLUSTER, segments[i + 2]);
263 }
264
265 gRequest.setParameter(GSParams.SUBACTION, sa);
266
267 additionalParameters = new String[] { GSParams.ACTION };
268 defaultParamValues = new String[] { "s" };
269 }
270 //ADMIN
271 else if (segments[i].equals("admin") && (i + 1) < segments.length)
272 {
273 String pageName = segments[i + 1];
274
275 gRequest.setParameter("s1.authpage", pageName);
276
277 additionalParameters = new String[] { GSParams.ACTION, GSParams.REQUEST_TYPE, GSParams.SUBACTION, GSParams.SERVICE };
278 defaultParamValues = new String[] { "g", "r", "authen", "Authentication" };
279 }
280 //BROWSE
281 else if (segments[i].equals("browse") && (i + 1) < segments.length)
282 {
283 String cl = "";
284 for (int j = 1; (i + j) < segments.length; j++)
285 {
286 String currentSegment = segments[i + j].replace("CL", "").replace("cl", "");
287 if (currentSegment.contains("."))
288 {
289 String[] subsegments = currentSegment.split("\\.");
290 for (String subsegment : subsegments)
291 {
292 subsegment = subsegment.replace("CL", "").replace("cl", "");
293
294 if (cl.length() > 0)
295 {
296 cl += ".";
297 }
298
299 if (subsegment.length() > 0)
300 {
301 cl += subsegment;
302 }
303 }
304 continue;
305 }
306 if (!currentSegment.matches("^(CL|cl)?\\d+$"))
307 {
308 continue;
309 }
310
311 if (cl.length() > 0)
312 {
313 cl += ".";
314 }
315
316 cl += currentSegment;
317 }
318
319 gRequest.setParameter("cl", "CL" + cl);
320
321 additionalParameters = new String[] { GSParams.ACTION, GSParams.REQUEST_TYPE, GSParams.SERVICE };
322 defaultParamValues = new String[] { "b", "s", "ClassifierBrowse" };
323 }
324 //QUERY
325 else if (segments[i].equals("search"))
326 {
327 String serviceName = "";
328 if ((i + 1) < segments.length)
329 {
330 serviceName = segments[i + 1];
331 gRequest.setParameter("s", serviceName);
332
333 additionalParameters = new String[] { GSParams.ACTION, GSParams.SUBACTION, GSParams.REQUEST_TYPE };
334 defaultParamValues = new String[] { "q", "", "d" };
335 }
336 if ((i + 2) < segments.length)
337 {
338 if (serviceName.equals("TextQuery") || serviceName.equals("RawQuery"))
339 {
340 additionalParameters = new String[] { GSParams.ACTION, GSParams.SUBACTION, GSParams.REQUEST_TYPE, "s1.maxDocs", "s1.hitsPerPage", "s1.level", "s1.sortBy", "s1.index", "s1.startPage" };
341 defaultParamValues = new String[] { "q", "", "rd", "100", "20", "Sec", "rank", "ZZ", "1" };
342
343 gRequest.setParameter("s1.query", segments[i + 2]);
344 }
345 else if (serviceName.equals("FieldQuery"))
346 {
347 additionalParameters = new String[] { GSParams.ACTION, GSParams.SUBACTION, GSParams.REQUEST_TYPE, "s1.maxDocs", "s1.hitsPerPage", "s1.level", "s1.sortBy", "s1.fqf", "s1.startPage" };
348 defaultParamValues = new String[] { "q", "", "rd", "100", "20", "Sec", "rank", "ZZ", "1" };
349
350 gRequest.setParameter("s1.fqv", segments[i + 2]);
351 }
352 else if (serviceName.equals("AdvancedFieldQuery"))
353 {
354 additionalParameters = new String[] { GSParams.ACTION, GSParams.SUBACTION, GSParams.REQUEST_TYPE, "s1.maxDocs", "s1.hitsPerPage", "s1.level", "s1.sortBy", "s1.fqf", "s1.fqk", "s1.startPage" };
355 defaultParamValues = new String[] { "q", "", "rd", "100", "20", "Sec", "rank", "ZZ", "0", "1" };
356
357 gRequest.setParameter("s1.fqv", segments[i + 2]);
358 }
359 }
360 }
361 if (additionalParameters != null)
362 {
363 for (int j = 0; j < additionalParameters.length; j++)
364 {
365 if (gRequest.getParameter(additionalParameters[j]) == null)
366 {
367 gRequest.setParameter(additionalParameters[j], defaultParamValues[j]);
368 }
369 }
370 }
371 }
372 }
373
374 chain.doFilter(gRequest, response);
375 }
376 else
377 {
378 //Will this ever happen?
379 System.err.println("The request was not an HttpServletRequest");
380 }
381 }
382
383 private boolean isURLRestricted(String url)
384 {
385 for (String restrictedURL : _restrictedURLs)
386 {
387 if (url.matches(".*" + restrictedURL + ".*"))
388 {
389 return true;
390 }
391 }
392
393 return false;
394 }
395
396 private class GSHttpServletRequestWrapper extends HttpServletRequestWrapper
397 {
398 private HashMap<String, String[]> _newParams = new HashMap<String, String[]>();
399
400 public GSHttpServletRequestWrapper(ServletRequest request)
401 {
402 super((HttpServletRequest) request);
403 }
404
405 public void setParameter(String paramName, String[] paramValues)
406 {
407 _newParams.put(paramName, paramValues);
408 }
409
410 public void setParameter(String paramName, String paramValue)
411 {
412 _newParams.put(paramName, new String[] { paramValue });
413 }
414
415 public String getParameter(String paramName)
416 {
417 if (super.getParameter(paramName) != null)
418 {
419 return super.getParameter(paramName);
420 }
421 else
422 {
423 if (_newParams.get(paramName) != null && _newParams.get(paramName)[0] != null)
424 {
425 return _newParams.get(paramName)[0];
426 }
427 return null;
428 }
429 }
430
431 public String[] getParameterValues(String paramName)
432 {
433 if (super.getParameterValues(paramName) != null)
434 {
435 return super.getParameterValues(paramName);
436 }
437 else
438 {
439 return _newParams.get(paramName);
440 }
441 }
442
443 public Map<String, String[]> getParameterMap()
444 {
445 HashMap<String, String[]> returnMap = new HashMap<String, String[]>();
446 returnMap.putAll(super.getParameterMap());
447 returnMap.putAll(_newParams);
448 return returnMap;
449 }
450 }
451}
Note: See TracBrowser for help on using the repository browser.