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

Last change on this file since 32654 was 32654, checked in by kjdon, 5 years ago

forgot to add document keyword to keywords list

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