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

Revision 30483, 13.3 KB (checked in by davidb, 3 years ago)

Tidy up on comments.

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