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
RevLine 
[25267]1package org.greenstone.gsdl3.core;
2
[27987]3import java.io.File;
[25267]4import java.io.IOException;
5import java.util.ArrayList;
[32646]6import java.util.Arrays;
[25267]7import java.util.HashMap;
8import java.util.Map;
9
10import javax.servlet.Filter;
11import javax.servlet.FilterChain;
12import javax.servlet.FilterConfig;
[30482]13import javax.servlet.ServletContext;
[25267]14import javax.servlet.ServletException;
[27987]15import javax.servlet.ServletOutputStream;
[25267]16import javax.servlet.ServletRequest;
17import javax.servlet.ServletResponse;
[30482]18import javax.servlet.http.HttpSession;
[25267]19import javax.servlet.http.HttpServletRequest;
20import javax.servlet.http.HttpServletRequestWrapper;
21
[27992]22import org.apache.commons.io.FileUtils;
[32646]23import org.apache.commons.lang.StringUtils;
24
[25267]25import org.apache.log4j.Logger;
26import org.greenstone.gsdl3.util.GSParams;
27import org.greenstone.gsdl3.util.GSXML;
28import org.greenstone.gsdl3.util.UserContext;
[27987]29import org.greenstone.gsdl3.util.XMLConverter;
[25267]30import org.w3c.dom.Document;
31import org.w3c.dom.Element;
[25309]32import org.w3c.dom.NodeList;
[25267]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());
[25350]38
[25267]39 //Restricted URLs
40 protected static final String SITECONFIG_URL = "sites/[^/]+/siteConfig.xml";
[27923]41 protected static final String USERS_DB_URL = "etc/usersDB/.*";
[25267]42 protected static final ArrayList<String> _restrictedURLs;
43 static
44 {
45 ArrayList<String> restrictedURLs = new ArrayList<String>();
46 restrictedURLs.add(SITECONFIG_URL);
[26538]47 restrictedURLs.add(USERS_DB_URL);
[25267]48 _restrictedURLs = restrictedURLs;
49 }
50
[25591]51 //Constants
52 protected static final String DOCUMENT_PATH = "document";
53 protected static final String COLLECTION_PATH = "collection";
[32646]54 protected static final String GROUP_PATH = "group";
[25591]55 protected static final String PAGE_PATH = "page";
56 protected static final String SYSTEM_PATH = "system";
[32646]57 protected static final String BROWSE_PATH = "browse";
58 protected static final String SEARCH_PATH = "search";
[25591]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/";
[27987]63 protected static final String INTERFACE_PATH = "/interfaces/";
[25645]64
[25591]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
[25267]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
[30482]80 @SuppressWarnings("deprecation")
[25267]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);
[30482]86 HttpSession hSession = hRequest.getSession();
87 ServletContext context = hSession.getServletContext();
88
[25267]89 GSHttpServletRequestWrapper gRequest = new GSHttpServletRequestWrapper(hRequest);
90
[32646]91 // this is the part before the ?
[25267]92 String url = hRequest.getRequestURI().toString();
[25350]93
94 if (isURLRestricted(url))
[25267]95 {
96 response.getWriter().println("Access to this page is forbidden.");
97 return;
98 }
[25350]99
[25591]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))
[25267]102 {
103 String dir = null;
[25591]104 int dirStart = url.indexOf(ASSOCIATED_FILE_PATH) + ASSOCIATED_FILE_PATH.length();
[25267]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;
[25591]120 int colStart = url.indexOf(COLLECTION_FILE_PATH) + COLLECTION_FILE_PATH.length();
[25267]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
[30482]135 MessageRouter gsRouter = (MessageRouter) context.getAttribute("GSRouter");
136
[25267]137 if (gsRouter == null)
138 {
139 _logger.error("Receptionist is null, stopping filter");
140 return;
141 }
142
[28971]143 Document gsDoc = XMLConverter.newDOM();
[25267]144
145 Element metaMessage = gsDoc.createElement(GSXML.MESSAGE_ELEM);
[25591]146 Element metaRequest = GSXML.createBasicRequest(gsDoc, GSXML.REQUEST_TYPE_PROCESS, collection + "/" + METADATA_RETRIEVAL_SERVICE, new UserContext());
[25267]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);
[25350]167
[25309]168 NodeList metadataList = metaResponse.getElementsByTagName(GSXML.METADATA_ELEM);
[25350]169 if (metadataList.getLength() == 0)
[25309]170 {
171 _logger.error("Could not find the document related to this url");
172 }
173 else
174 {
[25350]175 Element metadata = (Element) metadataList.item(0);
[25309]176 String document = metadata.getTextContent();
[25350]177
[25309]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);
[25350]189
[25309]190 if (!groups.contains(""))
191 {
192 boolean found = false;
193 for (String group : groups)
194 {
[25350]195 if (((HttpServletRequest) request).isUserInRole(group))
[25309]196 {
197 found = true;
198 break;
199 }
200 }
[25350]201
202 if (!found)
[25309]203 {
204 return;
205 }
206 }
207 }
[25267]208 }
[27987]209 else if (url.contains(INTERFACE_PATH))
[30483]210 {
[30482]211 String fileURL = url.replaceFirst(context.getContextPath(), "");
[30483]212 File requestedFile = new File(context.getRealPath(fileURL));
[30482]213
[27987]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);
[30482]220 File interfaceConfigFile = new File(context.getRealPath(interfacesDir + interfaceName + "/interfaceConfig.xml"));
[27987]221
222 if (interfaceConfigFile.exists())
223 {
[28971]224 Document interfaceConfigDoc = XMLConverter.getDOM(interfaceConfigFile);
[27987]225
226 String baseInterface = interfaceConfigDoc.getDocumentElement().getAttribute("baseInterface");
227 if (baseInterface.length() > 0)
228 {
[30482]229 File baseInterfaceFile = new File(context.getRealPath(fileURL.replace("/" + interfaceName + "/", "/" + baseInterface + "/")));
[27987]230 if (baseInterfaceFile.exists())
231 {
232 ServletOutputStream out = response.getOutputStream();
[27992]233 out.write(FileUtils.readFileToByteArray(baseInterfaceFile));
[28280]234 out.flush();
235 out.close();
[27989]236 return;
[27987]237 }
238 }
239 }
240 }
241 }
[25267]242 else
243 {
[32646]244 ArrayList<String> keywords = new ArrayList<String>();
245 keywords.add(PAGE_PATH);
246 keywords.add(BROWSE_PATH);
247 keywords.add(SEARCH_PATH);
[25591]248 //If we have a jsessionid on the end of our URL we want to ignore it
[25536]249 int index;
[25591]250 if ((index = url.indexOf(";jsessionid")) != -1)
[25536]251 {
252 url = url.substring(0, index);
253 }
[25267]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
[32646]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]);
[25267]273 }
[32646]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 }
[25267]291 //DOCUMENT
[25591]292 else if (segments[i].equals(DOCUMENT_PATH) && (i + 1) < segments.length)
[25267]293 {
294 gRequest.setParameter(GSParams.DOCUMENT, segments[i + 1]);
295
[26232]296 additionalParameters = new String[] { GSParams.ACTION };
297 defaultParamValues = new String[] { "d" };
[25267]298 }
299 //PAGE
[25591]300 else if (segments[i].equals(PAGE_PATH) && (i + 1) < segments.length)
[25267]301 {
302 gRequest.setParameter(GSParams.SUBACTION, segments[i + 1]);
303
304 additionalParameters = new String[] { GSParams.ACTION };
305 defaultParamValues = new String[] { "p" };
306 }
[25591]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 }
[25645]323
[25591]324 if (sa.equals("c") && (i + 2) < segments.length)
325 {
326 gRequest.setParameter(GSParams.SYSTEM_CLUSTER, segments[i + 2]);
327 }
[25645]328
[25591]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 }
[25645]334
[25591]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 }
[25267]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);
[25350]351
[25267]352 additionalParameters = new String[] { GSParams.ACTION, GSParams.REQUEST_TYPE, GSParams.SUBACTION, GSParams.SERVICE };
353 defaultParamValues = new String[] { "g", "r", "authen", "Authentication" };
354 }
355 //BROWSE
[32646]356 else if (segments[i].equals(BROWSE_PATH) && (i + 1) < segments.length)
[25267]357 {
358 String cl = "";
359 for (int j = 1; (i + j) < segments.length; j++)
360 {
[26232]361 String currentSegment = segments[i + j].replace("CL", "").replace("cl", "");
362 if (currentSegment.contains("."))
[25267]363 {
[26232]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;
[25267]380 }
[26232]381 if (!currentSegment.matches("^(CL|cl)?\\d+$"))
382 {
383 continue;
384 }
[25267]385
[26232]386 if (cl.length() > 0)
[25267]387 {
388 cl += ".";
389 }
390
[26232]391 cl += currentSegment;
[25267]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
[32646]400 else if (segments[i].equals(SEARCH_PATH))
[25267]401 {
[25424]402 String serviceName = "";
403 if ((i + 1) < segments.length)
[25267]404 {
[25424]405 serviceName = segments[i + 1];
406 gRequest.setParameter("s", serviceName);
[25591]407
[25424]408 additionalParameters = new String[] { GSParams.ACTION, GSParams.SUBACTION, GSParams.REQUEST_TYPE };
409 defaultParamValues = new String[] { "q", "", "d" };
410 }
[25591]411 if ((i + 2) < segments.length)
[25424]412 {
413 if (serviceName.equals("TextQuery") || serviceName.equals("RawQuery"))
414 {
[25267]415
416 gRequest.setParameter("s1.query", segments[i + 2]);
417 }
[25424]418 else if (serviceName.equals("FieldQuery"))
419 {
[25267]420 gRequest.setParameter("s1.fqv", segments[i + 2]);
421 }
[25424]422 else if (serviceName.equals("AdvancedFieldQuery"))
423 {
[25267]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 }
[25350]449
[25267]450 private boolean isURLRestricted(String url)
451 {
[25350]452 for (String restrictedURL : _restrictedURLs)
[25267]453 {
[25350]454 if (url.matches(".*" + restrictedURL + ".*"))
[25267]455 {
456 return true;
457 }
458 }
459
460 return false;
461 }
462
[30482]463}
Note: See TracBrowser for help on using the repository browser.