Fix the authentication sequence in requests of a file or a folder which is public...
[pithos] / src / gr / ebs / gss / server / rest / FilesHandler.java
index 6be0580..0366a90 100644 (file)
@@ -195,7 +195,7 @@ public class FilesHandler extends RequestHandler {
                }
        String progress = req.getParameter(PROGRESS_PARAMETER);
 
-       if (logger.isDebugEnabled())
+       if (logger.isDebugEnabled())                    
                        if (content)
                        logger.debug("Serving resource '" +     path + "' headers and data");
                else
@@ -203,7 +203,6 @@ public class FilesHandler extends RequestHandler {
 
        User user = getUser(req);
        User owner = getOwner(req);
-       if (user == null) user = owner;
         boolean exists = true;
         Object resource = null;
         FileHeaderDTO file = null;
@@ -217,33 +216,24 @@ public class FilesHandler extends RequestHandler {
                        return;
                }
 
-       if (!exists) {
-                       if (authDeferred) {
-                               // We do not want to leak information if the request
-                               // was not authenticated.
-                               resp.sendError(HttpServletResponse.SC_FORBIDDEN);
-                               return;
-                       }
-               // A request for upload progress.
-               if (progress != null && content) {
-                       serveProgress(req, resp, progress, user, null);
-                               return;
-               }
-
-               resp.sendError(HttpServletResponse.SC_NOT_FOUND, req.getRequestURI());
+       if (!exists && authDeferred) {
+               // We do not want to leak information if the request
+               // was not authenticated.
+               resp.sendError(HttpServletResponse.SC_FORBIDDEN);
                return;
        }
 
        if (resource instanceof FolderDTO)
                folder = (FolderDTO) resource;
        else
-               file = (FileHeaderDTO) resource;
+               file = (FileHeaderDTO) resource;        // Note that file will be null, if (!exists).
 
        // Now it's time to perform the deferred authentication check.
                // Since regular signature checking was already performed,
                // we need to check the read-all flag or the signature-in-parameters.
                if (authDeferred)
                        if (file != null && !file.isReadForAll() && content) {
+                               logger.debug("this case refers to a file with no public privileges");
                                // Check for GET with the signature in the request parameters.
                                String auth = req.getParameter(AUTHORIZATION_PARAMETER);
                                String dateParam = req.getParameter(DATE_PARAMETER);
@@ -337,11 +327,24 @@ public class FilesHandler extends RequestHandler {
                                        return;
                                }
                                }
-                       } else if (file != null && !file.isReadForAll() || folder != null && !folder.isReadForAll()) {
-                               // Check for a read-for-all file request.
-                               resp.sendError(HttpServletResponse.SC_FORBIDDEN);
-                               return;
                        }
+               else if(folder != null && folder.isReadForAll() || file != null && file.isReadForAll()){
+                       //This case refers to a folder or file with public privileges
+                       //For a read-for-all folder request, pretend the owner is making it.
+                       logger.debug("*********this case refers to a folder or file with public privileges");
+                       user = owner;
+                       req.setAttribute(USER_ATTRIBUTE, user);
+               }else if(folder != null && !folder.isReadForAll()){
+                       //this case refers to a folder with no public privileges
+                       logger.debug("*********this case refers to a folder with no public privileges");
+                       resp.sendError(HttpServletResponse.SC_FORBIDDEN);
+                       return;
+               }
+               else{
+                       logger.debug("*********ANY other case");
+                       resp.sendError(HttpServletResponse.SC_FORBIDDEN);
+                       return;
+               }
 
        // If the resource is not a collection, and the resource path
        // ends with "/" or "\", return NOT FOUND.
@@ -358,8 +361,8 @@ public class FilesHandler extends RequestHandler {
        // A request for upload progress.
        if (progress != null && content) {
                if (file == null) {
-                       resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
-                       return;
+                       resp.sendError(HttpServletResponse.SC_NOT_FOUND, req.getRequestURI());
+                       return;
                }
                serveProgress(req, resp, progress, user, file);
                        return;
@@ -405,6 +408,7 @@ public class FilesHandler extends RequestHandler {
        // Find content type.
        String contentType = null;
        boolean isContentHtml = false;
+       boolean expectJSON = false;
 
        if (file != null) {
                contentType = version>0 ? oldBody.getMimeType() : file.getMimeType();
@@ -420,8 +424,17 @@ public class FilesHandler extends RequestHandler {
                if (accept != null && accept.contains("text/html")) {
                        contentType = "text/html;charset=UTF-8";
                        isContentHtml = true;
-               } else
+               }else if (accept != null && accept.contains("text/html") && !authDeferred){
+                       //this is the case when clients send the appropriate headers, the contentType is "text/html"
+                       //and expect a JSON response. The above check applies to FireGSS client
+                       contentType = "text/html;charset=UTF-8";
+                       isContentHtml = true;
+                       expectJSON = true;
+               }
+               else{
                        contentType = "application/json;charset=UTF-8";
+                       expectJSON = true;
+               }
                }
 
 
@@ -476,10 +489,7 @@ public class FilesHandler extends RequestHandler {
                                else
                                        throw e;
                }
-       if (folder != null
-                               || (ranges == null || ranges.isEmpty())
-                                                       && req.getHeader("Range") == null
-                                                       || ranges == FULL) {
+       if (folder != null || (ranges == null || ranges.isEmpty()) && req.getHeader("Range") == null || ranges == FULL) {
                // Set the appropriate output headers
                if (contentType != null) {
                        if (logger.isDebugEnabled())
@@ -504,9 +514,9 @@ public class FilesHandler extends RequestHandler {
                String contextServletPath = contextPath + servletPath;
                if (folder != null && content)
                        // Serve the directory browser for a public folder
-                       if (isContentHtml)
+                       if (isContentHtml && !expectJSON)
                                renderResult = renderHtml(contextServletPath, relativePath, folder,user);
-                       // Serve the directory for an ordinary folder
+                       // Serve the directory for an ordinary folder or for fireGSS client
                        else
                                try {
                                        renderResult = renderJson(user, folder);
@@ -1422,13 +1432,6 @@ public class FilesHandler extends RequestHandler {
                        if (resource instanceof FolderDTO) {
                                final FolderDTO folder = (FolderDTO) resource;
                                String name = json.optString("name");
-                               if (!name.isEmpty())
-                                       try {
-                                               name = URLDecoder.decode(name, "UTF-8");
-                                       } catch (IllegalArgumentException e) {
-                                               resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
-                                               return;
-                                       }
                                JSONArray permissions = json.optJSONArray("permissions");
                                Set<PermissionDTO> perms = null;
                                if (permissions != null)
@@ -1516,8 +1519,8 @@ public class FilesHandler extends RequestHandler {
         * Returns the new URL of an updated folder.
         */
        private String getNewUrl(HttpServletRequest req, FolderDTO folder) throws UnsupportedEncodingException {
-               String parentUrl =URLDecoder.decode(getContextPath(req, true),"UTF-8");
-               String fpath = URLDecoder.decode(req.getPathInfo(), "UTF-8");
+               String parentUrl = URLDecoder.decode(getContextPath(req, true),"UTF-8");
+               String fpath = URLDecoder.decode(getRelativePath(req), "UTF-8");
                if (parentUrl.indexOf(fpath) != -1)
                        parentUrl = parentUrl.substring(0, parentUrl.indexOf(fpath));
                if(!parentUrl.endsWith("/"))
@@ -2214,26 +2217,31 @@ public class FilesHandler extends RequestHandler {
                // Render the link to our parent (if required)
                String folderPath = folder.getPath();
                int indexFolderPath = relativePath.indexOf(folderPath);
-               String relativePathNoFolderName = relativePath.substring(0, indexFolderPath);
+               String relativePathNoFolderName = null;
+               if(indexFolderPath != 0)
+                       relativePathNoFolderName = relativePath.substring(0, indexFolderPath);
+               else
+                       relativePathNoFolderName = relativePath;
                String parentDirectory = folderPath;
+               //To-do: further search in encoding folder names with special characters
                //String rewrittenParentDirectory = rewriteUrl(parentDirectory);
                if (parentDirectory.endsWith("/"))
                        parentDirectory = parentDirectory.substring(0, parentDirectory.length() - 1);
                int slash = parentDirectory.lastIndexOf('/');
+               parentDirectory = parentDirectory.substring(0,slash);
                if (slash >= 0) {
-                       String parent = folderPath.substring(0, slash);
                        sb.append(" - <a href=\"");
                        sb.append(rewrittenContextPath);
                        sb.append(relativePathNoFolderName);
-                       //sb.append(folderPath);
-                       //if (parent.equals(""))
-                               //parent = "/";
-                       sb.append(parent);
-                       //if (!parent.endsWith("/"))
-                       //      sb.append("/");
+                       sb.append(parentDirectory);
+                       if (!parentDirectory.endsWith("/"))
+                               sb.append("/");
                        sb.append("\">");
                        sb.append("<b>");
-                       sb.append("Up To " + parentDirectory);
+                       sb.append("Up To ");
+                       if (parentDirectory.equals(""))
+                               parentDirectory = "/";
+                       sb.append(parentDirectory);
                        sb.append("</b>");
                        sb.append("</a>");
                }
@@ -2301,38 +2309,40 @@ public class FilesHandler extends RequestHandler {
                } catch (RpcException e) {
                        throw new ServletException(e.getMessage());
                }
-               for (FileHeaderDTO file : files) {
-                       String resourceName = file.getName();
-                       if (resourceName.equalsIgnoreCase("WEB-INF") || resourceName.equalsIgnoreCase("META-INF"))
-                               continue;
-
-                       sb.append("<tr");
-                       if (shade)
-                               sb.append(" bgcolor=\"#eeeeee\"");
-                       sb.append(">\r\n");
-                       shade = !shade;
-
-                       sb.append("<td align=\"left\">&nbsp;&nbsp;\r\n");
-                       sb.append("<a href=\"");
-                       sb.append(rewrittenContextPath);
-                       sb.append(relativePath);
-                       if(!relativePath.endsWith("/"))
-                               sb.append("/");
-                       sb.append(rewriteUrl(resourceName));
-                       sb.append("\"><tt>");
-                       sb.append(RequestUtil.filter(resourceName));
-                       sb.append("</tt></a></td>\r\n");
-
-                       sb.append("<td align=\"right\"><tt>");
-                       sb.append(renderSize(file.getFileSize()));
-                       sb.append("</tt></td>\r\n");
-
-                       sb.append("<td align=\"right\"><tt>");
-                       sb.append(getLastModifiedHttp(file.getAuditInfo()));
-                       sb.append("</tt></td>\r\n");
-
-                       sb.append("</tr>\r\n");
-               }
+               for (FileHeaderDTO file : files)
+                       //Display only file resources that are marked as public
+                       if(file.isReadForAll()){
+                               String resourceName = file.getName();
+                               if (resourceName.equalsIgnoreCase("WEB-INF") || resourceName.equalsIgnoreCase("META-INF"))
+                                       continue;
+
+                               sb.append("<tr");
+                               if (shade)
+                                       sb.append(" bgcolor=\"#eeeeee\"");
+                               sb.append(">\r\n");
+                               shade = !shade;
+
+                               sb.append("<td align=\"left\">&nbsp;&nbsp;\r\n");
+                               sb.append("<a href=\"");
+                               sb.append(rewrittenContextPath);
+                               sb.append(relativePath);
+                               if(!relativePath.endsWith("/"))
+                                       sb.append("/");
+                               sb.append(rewriteUrl(resourceName));
+                               sb.append("\"><tt>");
+                               sb.append(RequestUtil.filter(resourceName));
+                               sb.append("</tt></a></td>\r\n");
+
+                               sb.append("<td align=\"right\"><tt>");
+                               sb.append(renderSize(file.getFileSize()));
+                               sb.append("</tt></td>\r\n");
+
+                               sb.append("<td align=\"right\"><tt>");
+                               sb.append(getLastModifiedHttp(file.getAuditInfo()));
+                               sb.append("</tt></td>\r\n");
+
+                               sb.append("</tr>\r\n");
+                       }
 
                // Render the page footer
                sb.append("</table>\r\n");