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

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

If a file cannot be found in the given interface then check if it is in the base interface

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