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

Last change on this file since 26232 was 26232, checked in by sjm84, 12 years ago

CL names can now be specified with either dots or slashes in URLs e.g. cl1.2 or cl1/2

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