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

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

Fixing a bug caused when the context and the interface have the same name

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