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

Revision 32646, 14.7 KB (checked in by kjdon, 7 months 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 *
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 browser.