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

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

we are now putting group info into restful url, eg library/group/MyGroup/SubGroup, or library/collection/MyGroup/collname

  • 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 //If we have a jsessionid on the end of our URL we want to ignore it
249 int index;
250 if ((index = url.indexOf(";jsessionid")) != -1)
251 {
252 url = url.substring(0, index);
253 }
254 String[] segments = url.split("/");
255 for (int i = 0; i < segments.length; i++)
256 {
257 String[] additionalParameters = null;
258 String[] defaultParamValues = null;
259 //COLLECTION
260 if (segments[i].equals(COLLECTION_PATH) && (i + 1) < segments.length) {
261 int j=i+1;
262 while(j+1 < segments.length && !keywords.contains(segments[j+1])) {
263 j++;
264 }
265
266 if (j>i+1) {
267 // we had a group part
268 String [] groups = Arrays.copyOfRange(segments, i+1, j);
269 String group = StringUtils.join(groups, "/");
270 gRequest.setParameter(GSParams.GROUP, group);
271 }
272 gRequest.setParameter(GSParams.COLLECTION, segments[j]);
273 }
274 // GROUP
275 else if(segments[i].equals(GROUP_PATH) && (i + 1) < segments.length)
276 {
277 // assume for now, no other path parts for group links
278 int j= segments.length - 1;
279 String group;
280 if (j==i+1) {
281 group = segments[j];
282 } else {
283 String [] groups = Arrays.copyOfRange(segments, i+1, j+1);
284 group = StringUtils.join(groups, "/");
285 }
286 gRequest.setParameter(GSParams.GROUP, group);
287 gRequest.setParameter(GSParams.ACTION, "p");
288 gRequest.setParameter(GSParams.SUBACTION, "home");
289
290 }
291 //DOCUMENT
292 else if (segments[i].equals(DOCUMENT_PATH) && (i + 1) < segments.length)
293 {
294 gRequest.setParameter(GSParams.DOCUMENT, segments[i + 1]);
295
296 additionalParameters = new String[] { GSParams.ACTION };
297 defaultParamValues = new String[] { "d" };
298 }
299 //PAGE
300 else if (segments[i].equals(PAGE_PATH) && (i + 1) < segments.length)
301 {
302 gRequest.setParameter(GSParams.SUBACTION, segments[i + 1]);
303
304 additionalParameters = new String[] { GSParams.ACTION };
305 defaultParamValues = new String[] { "p" };
306 }
307 //SYSTEM
308 else if (segments[i].equals(SYSTEM_PATH) && (i + 1) < segments.length)
309 {
310 String sa = segments[i + 1];
311 if (sa.equals(SYSTEM_SUBACTION_CONFIGURE) || sa.equals(SYSTEM_SUBACTION_RECONFIGURE))
312 {
313 sa = "c";
314 }
315 else if (sa.equals(SYSTEM_SUBACTION_ACTIVATE))
316 {
317 sa = "a";
318 }
319 else if (sa.equals(SYSTEM_SUBACTION_DEACTIVATE))
320 {
321 sa = "d";
322 }
323
324 if (sa.equals("c") && (i + 2) < segments.length)
325 {
326 gRequest.setParameter(GSParams.SYSTEM_CLUSTER, segments[i + 2]);
327 }
328
329 if (sa.equals("a") && (i + 2) < segments.length)
330 {
331 gRequest.setParameter(GSParams.SYSTEM_MODULE_TYPE, "collection");
332 gRequest.setParameter(GSParams.SYSTEM_MODULE_NAME, segments[i + 2]);
333 }
334
335 if (sa.equals("d") && (i + 2) < segments.length)
336 {
337 gRequest.setParameter(GSParams.SYSTEM_CLUSTER, segments[i + 2]);
338 }
339
340 gRequest.setParameter(GSParams.SUBACTION, sa);
341
342 additionalParameters = new String[] { GSParams.ACTION };
343 defaultParamValues = new String[] { "s" };
344 }
345 //ADMIN
346 else if (segments[i].equals("admin") && (i + 1) < segments.length)
347 {
348 String pageName = segments[i + 1];
349
350 gRequest.setParameter("s1.authpage", pageName);
351
352 additionalParameters = new String[] { GSParams.ACTION, GSParams.REQUEST_TYPE, GSParams.SUBACTION, GSParams.SERVICE };
353 defaultParamValues = new String[] { "g", "r", "authen", "Authentication" };
354 }
355 //BROWSE
356 else if (segments[i].equals(BROWSE_PATH) && (i + 1) < segments.length)
357 {
358 String cl = "";
359 for (int j = 1; (i + j) < segments.length; j++)
360 {
361 String currentSegment = segments[i + j].replace("CL", "").replace("cl", "");
362 if (currentSegment.contains("."))
363 {
364 String[] subsegments = currentSegment.split("\\.");
365 for (String subsegment : subsegments)
366 {
367 subsegment = subsegment.replace("CL", "").replace("cl", "");
368
369 if (cl.length() > 0)
370 {
371 cl += ".";
372 }
373
374 if (subsegment.length() > 0)
375 {
376 cl += subsegment;
377 }
378 }
379 continue;
380 }
381 if (!currentSegment.matches("^(CL|cl)?\\d+$"))
382 {
383 continue;
384 }
385
386 if (cl.length() > 0)
387 {
388 cl += ".";
389 }
390
391 cl += currentSegment;
392 }
393
394 gRequest.setParameter("cl", "CL" + cl);
395
396 additionalParameters = new String[] { GSParams.ACTION, GSParams.REQUEST_TYPE, GSParams.SERVICE };
397 defaultParamValues = new String[] { "b", "s", "ClassifierBrowse" };
398 }
399 //QUERY
400 else if (segments[i].equals(SEARCH_PATH))
401 {
402 String serviceName = "";
403 if ((i + 1) < segments.length)
404 {
405 serviceName = segments[i + 1];
406 gRequest.setParameter("s", serviceName);
407
408 additionalParameters = new String[] { GSParams.ACTION, GSParams.SUBACTION, GSParams.REQUEST_TYPE };
409 defaultParamValues = new String[] { "q", "", "d" };
410 }
411 if ((i + 2) < segments.length)
412 {
413 if (serviceName.equals("TextQuery") || serviceName.equals("RawQuery"))
414 {
415
416 gRequest.setParameter("s1.query", segments[i + 2]);
417 }
418 else if (serviceName.equals("FieldQuery"))
419 {
420 gRequest.setParameter("s1.fqv", segments[i + 2]);
421 }
422 else if (serviceName.equals("AdvancedFieldQuery"))
423 {
424 gRequest.setParameter("s1.fqv", segments[i + 2]);
425 }
426 }
427 }
428 if (additionalParameters != null)
429 {
430 for (int j = 0; j < additionalParameters.length; j++)
431 {
432 if (gRequest.getParameter(additionalParameters[j]) == null)
433 {
434 gRequest.setParameter(additionalParameters[j], defaultParamValues[j]);
435 }
436 }
437 }
438 }
439 }
440
441 chain.doFilter(gRequest, response);
442 }
443 else
444 {
445 //Will this ever happen?
446 System.err.println("The request was not an HttpServletRequest");
447 }
448 }
449
450 private boolean isURLRestricted(String url)
451 {
452 for (String restrictedURL : _restrictedURLs)
453 {
454 if (url.matches(".*" + restrictedURL + ".*"))
455 {
456 return true;
457 }
458 }
459
460 return false;
461 }
462
463}
Note: See TracBrowser for help on using the repository browser.