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

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

Minor reformatting

  • Property svn:executable set to *
File size: 13.4 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, GSParams.DOCUMENT_TYPE };
219 defaultParamValues = new String[] { "d", "hierarchy" };
220 }
221 //PAGE
222 else if (segments[i].equals(PAGE_PATH) && (i + 1) < segments.length)
223 {
224 gRequest.setParameter(GSParams.SUBACTION, segments[i + 1]);
225
226 additionalParameters = new String[] { GSParams.ACTION };
227 defaultParamValues = new String[] { "p" };
228 }
229 //SYSTEM
230 else if (segments[i].equals(SYSTEM_PATH) && (i + 1) < segments.length)
231 {
232 String sa = segments[i + 1];
233 if (sa.equals(SYSTEM_SUBACTION_CONFIGURE) || sa.equals(SYSTEM_SUBACTION_RECONFIGURE))
234 {
235 sa = "c";
236 }
237 else if (sa.equals(SYSTEM_SUBACTION_ACTIVATE))
238 {
239 sa = "a";
240 }
241 else if (sa.equals(SYSTEM_SUBACTION_DEACTIVATE))
242 {
243 sa = "d";
244 }
245
246 if (sa.equals("c") && (i + 2) < segments.length)
247 {
248 gRequest.setParameter(GSParams.SYSTEM_CLUSTER, segments[i + 2]);
249 }
250
251 if (sa.equals("a") && (i + 2) < segments.length)
252 {
253 gRequest.setParameter(GSParams.SYSTEM_MODULE_TYPE, "collection");
254 gRequest.setParameter(GSParams.SYSTEM_MODULE_NAME, segments[i + 2]);
255 }
256
257 if (sa.equals("d") && (i + 2) < segments.length)
258 {
259 gRequest.setParameter(GSParams.SYSTEM_CLUSTER, segments[i + 2]);
260 }
261
262 gRequest.setParameter(GSParams.SUBACTION, sa);
263
264 additionalParameters = new String[] { GSParams.ACTION };
265 defaultParamValues = new String[] { "s" };
266 }
267 //ADMIN
268 else if (segments[i].equals("admin") && (i + 1) < segments.length)
269 {
270 String pageName = segments[i + 1];
271
272 gRequest.setParameter("s1.authpage", pageName);
273
274 additionalParameters = new String[] { GSParams.ACTION, GSParams.REQUEST_TYPE, GSParams.SUBACTION, GSParams.SERVICE };
275 defaultParamValues = new String[] { "g", "r", "authen", "Authentication" };
276 }
277 //BROWSE
278 else if (segments[i].equals("browse") && (i + 1) < segments.length)
279 {
280 String cl = "";
281 for (int j = 1; (i + j) < segments.length; j++)
282 {
283 if (!segments[i + j].matches("^(CL|cl)?\\d+$"))
284 {
285 break;
286 }
287
288 if (j > 1)
289 {
290 cl += ".";
291 }
292
293 cl += segments[i + j].replace("CL", "").replace("cl", "");
294 }
295
296 gRequest.setParameter("cl", "CL" + cl);
297
298 additionalParameters = new String[] { GSParams.ACTION, GSParams.REQUEST_TYPE, GSParams.SERVICE };
299 defaultParamValues = new String[] { "b", "s", "ClassifierBrowse" };
300 }
301 //QUERY
302 else if (segments[i].equals("search"))
303 {
304 String serviceName = "";
305 if ((i + 1) < segments.length)
306 {
307 serviceName = segments[i + 1];
308 gRequest.setParameter("s", serviceName);
309
310 additionalParameters = new String[] { GSParams.ACTION, GSParams.SUBACTION, GSParams.REQUEST_TYPE };
311 defaultParamValues = new String[] { "q", "", "d" };
312 }
313 if ((i + 2) < segments.length)
314 {
315 if (serviceName.equals("TextQuery") || serviceName.equals("RawQuery"))
316 {
317 additionalParameters = new String[] { GSParams.ACTION, GSParams.SUBACTION, GSParams.REQUEST_TYPE, "s1.maxDocs", "s1.hitsPerPage", "s1.level", "s1.sortBy", "s1.index", "s1.startPage" };
318 defaultParamValues = new String[] { "q", "", "rd", "100", "20", "Sec", "rank", "ZZ", "1" };
319
320 gRequest.setParameter("s1.query", segments[i + 2]);
321 }
322 else if (serviceName.equals("FieldQuery"))
323 {
324 additionalParameters = new String[] { GSParams.ACTION, GSParams.SUBACTION, GSParams.REQUEST_TYPE, "s1.maxDocs", "s1.hitsPerPage", "s1.level", "s1.sortBy", "s1.fqf", "s1.startPage" };
325 defaultParamValues = new String[] { "q", "", "rd", "100", "20", "Sec", "rank", "ZZ", "1" };
326
327 gRequest.setParameter("s1.fqv", segments[i + 2]);
328 }
329 else if (serviceName.equals("AdvancedFieldQuery"))
330 {
331 additionalParameters = new String[] { GSParams.ACTION, GSParams.SUBACTION, GSParams.REQUEST_TYPE, "s1.maxDocs", "s1.hitsPerPage", "s1.level", "s1.sortBy", "s1.fqf", "s1.fqk", "s1.startPage" };
332 defaultParamValues = new String[] { "q", "", "rd", "100", "20", "Sec", "rank", "ZZ", "0", "1" };
333
334 gRequest.setParameter("s1.fqv", segments[i + 2]);
335 }
336 }
337 }
338 if (additionalParameters != null)
339 {
340 for (int j = 0; j < additionalParameters.length; j++)
341 {
342 if (gRequest.getParameter(additionalParameters[j]) == null)
343 {
344 gRequest.setParameter(additionalParameters[j], defaultParamValues[j]);
345 }
346 }
347 }
348 }
349 }
350
351 chain.doFilter(gRequest, response);
352 }
353 else
354 {
355 //Will this ever happen?
356 System.err.println("The request was not an HttpServletRequest");
357 }
358 }
359
360 private boolean isURLRestricted(String url)
361 {
362 for (String restrictedURL : _restrictedURLs)
363 {
364 if (url.matches(".*" + restrictedURL + ".*"))
365 {
366 return true;
367 }
368 }
369
370 return false;
371 }
372
373 private class GSHttpServletRequestWrapper extends HttpServletRequestWrapper
374 {
375 private HashMap<String, String[]> _newParams = new HashMap<String, String[]>();
376
377 public GSHttpServletRequestWrapper(ServletRequest request)
378 {
379 super((HttpServletRequest) request);
380 }
381
382 public void setParameter(String paramName, String[] paramValues)
383 {
384 _newParams.put(paramName, paramValues);
385 }
386
387 public void setParameter(String paramName, String paramValue)
388 {
389 _newParams.put(paramName, new String[] { paramValue });
390 }
391
392 public String getParameter(String paramName)
393 {
394 if (super.getParameter(paramName) != null)
395 {
396 return super.getParameter(paramName);
397 }
398 else
399 {
400 if (_newParams.get(paramName) != null && _newParams.get(paramName)[0] != null)
401 {
402 return _newParams.get(paramName)[0];
403 }
404 return null;
405 }
406 }
407
408 public String[] getParameterValues(String paramName)
409 {
410 if (super.getParameterValues(paramName) != null)
411 {
412 return super.getParameterValues(paramName);
413 }
414 else
415 {
416 return _newParams.get(paramName);
417 }
418 }
419
420 public Map<String, String[]> getParameterMap()
421 {
422 HashMap<String, String[]> returnMap = new HashMap<String, String[]>();
423 returnMap.putAll(super.getParameterMap());
424 returnMap.putAll(_newParams);
425 return returnMap;
426 }
427 }
428}
Note: See TracBrowser for help on using the repository browser.