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

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

Return was in the wrong place

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