Coverage Report - net.fckeditor.connector.ConnectorServlet
 
Classes in this File Line Coverage Branch Coverage Complexity
ConnectorServlet
0%
0/121
0%
0/50
0
 
 1  
 /*
 2  
  * FCKeditor - The text editor for Internet - http://www.fckeditor.net
 3  
  * Copyright (C) 2003-2008 Frederico Caldeira Knabben
 4  
  * 
 5  
  * == BEGIN LICENSE ==
 6  
  * 
 7  
  * Licensed under the terms of any of the following licenses at your
 8  
  * choice:
 9  
  * 
 10  
  *  - GNU General Public License Version 2 or later (the "GPL")
 11  
  *    http://www.gnu.org/licenses/gpl.html
 12  
  * 
 13  
  *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
 14  
  *    http://www.gnu.org/licenses/lgpl.html
 15  
  * 
 16  
  *  - Mozilla Public License Version 1.1 or later (the "MPL")
 17  
  *    http://www.mozilla.org/MPL/MPL-1.1.html
 18  
  * 
 19  
  * == END LICENSE ==
 20  
  */
 21  
 package net.fckeditor.connector;
 22  
 
 23  
 import java.io.File;
 24  
 import java.io.IOException;
 25  
 import java.io.PrintWriter;
 26  
 import java.util.List;
 27  
 
 28  
 import javax.servlet.ServletException;
 29  
 import javax.servlet.http.HttpServlet;
 30  
 import javax.servlet.http.HttpServletRequest;
 31  
 import javax.servlet.http.HttpServletResponse;
 32  
 
 33  
 import net.fckeditor.handlers.CommandHandler;
 34  
 import net.fckeditor.handlers.ConnectorHandler;
 35  
 import net.fckeditor.handlers.ExtensionsHandler;
 36  
 import net.fckeditor.handlers.RequestCycleHandler;
 37  
 import net.fckeditor.handlers.ResourceTypeHandler;
 38  
 import net.fckeditor.response.UploadResponse;
 39  
 import net.fckeditor.response.XmlResponse;
 40  
 import net.fckeditor.tool.Utils;
 41  
 import net.fckeditor.tool.UtilsFile;
 42  
 import net.fckeditor.tool.UtilsResponse;
 43  
 
 44  
 import org.apache.commons.fileupload.FileItem;
 45  
 import org.apache.commons.fileupload.FileItemFactory;
 46  
 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
 47  
 import org.apache.commons.fileupload.servlet.ServletFileUpload;
 48  
 import org.apache.commons.io.FilenameUtils;
 49  
 import org.slf4j.Logger;
 50  
 import org.slf4j.LoggerFactory;
 51  
 
 52  
 /**
 53  
  * Servlet to upload and browse files.<br />
 54  
  * 
 55  
  * This servlet accepts 4 commands which interact with the server-side
 56  
  * filesystem.<br />
 57  
  * The allowed commands are:
 58  
  * <ul>
 59  
  * <li><code>GetFolders</code>: Retrieves a list of folders in the current
 60  
  * folder</li>
 61  
  * <li><code>GetFoldersAndFiles</code>: Retrives a list of files and folders
 62  
  * in the current folder</li>
 63  
  * <li><code>CreateFolder</code>: Creates a new folder in the current folder</li>
 64  
  * <li><code>FileUpload</code>: Stores an uploaded file into the current
 65  
  * folder. (must be sent with POST)</li>
 66  
  * </ul>
 67  
  * 
 68  
  * @version $Id: ConnectorServlet.java 2101 2008-06-22 22:00:48Z mosipov $
 69  
  */
 70  0
 public class ConnectorServlet extends HttpServlet {
 71  
 
 72  
         private static final long serialVersionUID = -5742008970929377161L;
 73  0
         private static final Logger logger = LoggerFactory.getLogger(ConnectorServlet.class);
 74  
 
 75  
         /**
 76  
          * Initialize the servlet: <code>mkdir</code> &lt;DefaultUserFilesPath&gt;
 77  
          */
 78  
         public void init() throws ServletException, IllegalArgumentException {
 79  0
                 String realDefaultUserFilesPath = getServletContext().getRealPath(
 80  
                         ConnectorHandler.getDefaultUserFilesPath());
 81  
 
 82  0
                 File defaultUserFilesDir = new File(realDefaultUserFilesPath);
 83  0
                 UtilsFile.checkDirAndCreate(defaultUserFilesDir);
 84  
 
 85  0
                 logger.info("ConnectorServlet successfully initialized!");
 86  0
         }
 87  
 
 88  
         /**
 89  
          * Manage the <code>GET</code> requests (<code>GetFolders</code>,
 90  
          * <code>GetFoldersAndFiles</code>, <code>CreateFolder</code>).<br/>
 91  
          * 
 92  
          * The servlet accepts commands sent in the following format:<br/>
 93  
          * <code>connector?Command=&lt;CommandName&gt;&Type=&lt;ResourceType&gt;&CurrentFolder=&lt;FolderPath&gt;</code>
 94  
          * <p>
 95  
          * It executes the commands and then returns the result to the client in XML
 96  
          * format.
 97  
          * </p>
 98  
          */
 99  
         public void doGet(HttpServletRequest request, HttpServletResponse response)
 100  
                 throws ServletException, IOException {
 101  0
                 logger.debug("Entering ConnectorServlet#doGet");
 102  
 
 103  0
                 response.setCharacterEncoding("UTF-8");
 104  0
                 response.setContentType("application/xml; charset=UTF-8");
 105  0
                 response.setHeader("Cache-Control", "no-cache");
 106  0
                 PrintWriter out = response.getWriter();
 107  
 
 108  0
                 String commandStr = request.getParameter("Command");
 109  0
                 String typeStr = request.getParameter("Type");
 110  0
                 String currentFolderStr = request.getParameter("CurrentFolder");
 111  
 
 112  0
                 logger.debug("Parameter Command: {}", commandStr);
 113  0
                 logger.debug("Parameter Type: {}", typeStr);
 114  0
                 logger.debug("Parameter CurrentFolder: {}", currentFolderStr);
 115  
 
 116  
                 XmlResponse xr;
 117  
 
 118  0
                 if (!RequestCycleHandler.isEnabledForFileBrowsing(request))
 119  0
                         xr = new XmlResponse(XmlResponse.EN_ERROR, Messages.NOT_AUTHORIZED_FOR_BROWSING);
 120  0
                 else if (!CommandHandler.isValidForGet(commandStr))
 121  0
                         xr = new XmlResponse(XmlResponse.EN_ERROR, Messages.INVALID_COMMAND);
 122  0
                 else if (typeStr != null && !ResourceTypeHandler.isValid(typeStr))
 123  0
                         xr = new XmlResponse(XmlResponse.EN_ERROR, Messages.INVALID_TYPE);
 124  0
                 else if (!UtilsFile.isValidPath(currentFolderStr))
 125  0
                         xr = new XmlResponse(XmlResponse.EN_ERROR, Messages.INVALID_CURRENT_FOLDER);
 126  
                 else {
 127  0
                         CommandHandler command = CommandHandler.getCommand(commandStr);
 128  0
                         ResourceTypeHandler resourceType = ResourceTypeHandler.getDefaultResourceType(typeStr);
 129  
 
 130  0
                         String typePath = UtilsFile.constructServerSidePath(request, resourceType);
 131  0
                         String typeDirPath = getServletContext().getRealPath(typePath);
 132  
 
 133  0
                         File typeDir = new File(typeDirPath);
 134  0
                         UtilsFile.checkDirAndCreate(typeDir);
 135  
 
 136  0
                         File currentDir = new File(typeDir, currentFolderStr);
 137  
 
 138  0
                         if (!currentDir.exists())
 139  0
                                 xr = new XmlResponse(XmlResponse.EN_INVALID_FOLDER_NAME);
 140  
                         else {
 141  
 
 142  0
                                 xr = new XmlResponse(command, resourceType, currentFolderStr, UtilsResponse
 143  
                                         .constructResponseUrl(request, resourceType, currentFolderStr, true,
 144  
                                                 ConnectorHandler.isFullUrl()));
 145  
 
 146  0
                                 if (command.equals(CommandHandler.GET_FOLDERS))
 147  0
                                         xr.setFolders(currentDir);
 148  0
                                 else if (command.equals(CommandHandler.GET_FOLDERS_AND_FILES))
 149  0
                                         xr.setFoldersAndFiles(currentDir);
 150  0
                                 else if (command.equals(CommandHandler.CREATE_FOLDER)) {
 151  0
                                         String newFolderStr = UtilsFile.sanitizeFolderName(request
 152  
                                                 .getParameter("NewFolderName"));
 153  0
                                         logger.debug("Parameter NewFolderName: {}", newFolderStr);
 154  
 
 155  0
                                         File newFolder = new File(currentDir, newFolderStr);
 156  0
                                         int errorNumber = XmlResponse.EN_UKNOWN;
 157  
 
 158  0
                                         if (newFolder.exists())
 159  0
                                                 errorNumber = XmlResponse.EN_ALREADY_EXISTS;
 160  
                                         else {
 161  
                                                 try {
 162  0
                                                         errorNumber = (newFolder.mkdir()) ? XmlResponse.EN_OK
 163  
                                                                 : XmlResponse.EN_INVALID_FOLDER_NAME;
 164  0
                                                 } catch (SecurityException e) {
 165  0
                                                         errorNumber = XmlResponse.EN_SECURITY_ERROR;
 166  0
                                                 }
 167  
                                         }
 168  0
                                         xr.setError(errorNumber);
 169  
                                 }
 170  
                         }
 171  
                 }
 172  
 
 173  0
                 out.print(xr);
 174  0
                 out.flush();
 175  0
                 out.close();
 176  0
                 logger.debug("Exiting ConnectorServlet#doGet");
 177  0
         }
 178  
 
 179  
         /**
 180  
          * Manage the <code>POST</code> requests (<code>FileUpload</code>).<br />
 181  
          * 
 182  
          * The servlet accepts commands sent in the following format:<br />
 183  
          * <code>connector?Command=&lt;FileUpload&gt;&Type=&lt;ResourceType&gt;&CurrentFolder=&lt;FolderPath&gt;</code>
 184  
          * with the file in the <code>POST</code> body.<br />
 185  
          * <br>
 186  
          * It stores an uploaded file (renames a file if another exists with the
 187  
          * same name) and then returns the JavaScript callback.
 188  
          */
 189  
         @SuppressWarnings("unchecked")
 190  
         public void doPost(HttpServletRequest request, HttpServletResponse response)
 191  
                 throws ServletException, IOException {
 192  0
                 logger.debug("Entering Connector#doPost");
 193  
 
 194  0
                 response.setCharacterEncoding("UTF-8");
 195  0
                 response.setContentType("text/html; charset=UTF-8");
 196  0
                 response.setHeader("Cache-Control", "no-cache");
 197  0
                 PrintWriter out = response.getWriter();
 198  
 
 199  0
                 String commandStr = request.getParameter("Command");
 200  0
                 String typeStr = request.getParameter("Type");
 201  0
                 String currentFolderStr = request.getParameter("CurrentFolder");
 202  
 
 203  0
                 logger.debug("Parameter Command: {}", commandStr);
 204  0
                 logger.debug("Parameter Type: {}", typeStr);
 205  0
                 logger.debug("Parameter CurrentFolder: {}", currentFolderStr);
 206  
 
 207  
                 UploadResponse ur;
 208  
 
 209  
                 // if this is a QuickUpload request, 'commandStr' and 'currentFolderStr'
 210  
                 // are empty
 211  0
                 if (Utils.isEmpty(commandStr) && Utils.isEmpty(currentFolderStr)) {
 212  0
                         commandStr = "QuickUpload";
 213  0
                         currentFolderStr = "/";
 214  
                 }
 215  
 
 216  0
                 if (!RequestCycleHandler.isEnabledForFileUpload(request))
 217  0
                         ur = new UploadResponse(UploadResponse.SC_SECURITY_ERROR, null, null,
 218  
                                 Messages.NOT_AUTHORIZED_FOR_UPLOAD);
 219  0
                 else if (!CommandHandler.isValidForPost(commandStr))
 220  0
                         ur = new UploadResponse(UploadResponse.SC_ERROR, null, null, Messages.INVALID_COMMAND);
 221  0
                 else if (typeStr != null && !ResourceTypeHandler.isValid(typeStr))
 222  0
                         ur = new UploadResponse(UploadResponse.SC_ERROR, null, null, Messages.INVALID_TYPE);
 223  0
                 else if (!UtilsFile.isValidPath(currentFolderStr))
 224  0
                         ur = UploadResponse.UR_INVALID_CURRENT_FOLDER;
 225  
                 else {
 226  0
                         ResourceTypeHandler resourceType = ResourceTypeHandler.getDefaultResourceType(typeStr);
 227  
 
 228  0
                         String typePath = UtilsFile.constructServerSidePath(request, resourceType);
 229  0
                         String typeDirPath = getServletContext().getRealPath(typePath);
 230  
 
 231  0
                         File typeDir = new File(typeDirPath);
 232  0
                         UtilsFile.checkDirAndCreate(typeDir);
 233  
 
 234  0
                         File currentDir = new File(typeDir, currentFolderStr);
 235  
 
 236  0
                         if (!currentDir.exists())
 237  0
                                 ur = UploadResponse.UR_INVALID_CURRENT_FOLDER;
 238  
                         else {
 239  
 
 240  0
                                 String newFilename = null;
 241  0
                                 FileItemFactory factory = new DiskFileItemFactory();
 242  0
                                 ServletFileUpload upload = new ServletFileUpload(factory);
 243  
 
 244  
                                 try {
 245  
 
 246  0
                                         List<FileItem> items = upload.parseRequest(request);
 247  
 
 248  
                                         // We upload only one file at the same time
 249  0
                                         FileItem uplFile = items.get(0);
 250  0
                                         String rawName = UtilsFile.sanitizeFileName(uplFile.getName());
 251  0
                                         String filename = FilenameUtils.getName(rawName);
 252  0
                                         String baseName = FilenameUtils.removeExtension(filename);
 253  0
                                         String extension = FilenameUtils.getExtension(filename);
 254  
 
 255  0
                                         if (!ExtensionsHandler.isAllowed(resourceType, extension))
 256  0
                                                 ur = new UploadResponse(UploadResponse.SC_INVALID_EXTENSION);
 257  
                                         else {
 258  
 
 259  
                                                 // construct an unique file name
 260  0
                                                 File pathToSave = new File(currentDir, filename);
 261  0
                                                 int counter = 1;
 262  0
                                                 while (pathToSave.exists()) {
 263  0
                                                         newFilename = baseName.concat("(").concat(String.valueOf(counter))
 264  
                                                                 .concat(")").concat(".").concat(extension);
 265  0
                                                         pathToSave = new File(currentDir, newFilename);
 266  0
                                                         counter++;
 267  
                                                 }
 268  
 
 269  0
                                                 if (Utils.isEmpty(newFilename))
 270  0
                                                         ur = new UploadResponse(UploadResponse.SC_OK, UtilsResponse
 271  
                                                                 .constructResponseUrl(request, resourceType, currentFolderStr,
 272  
                                                                         true, ConnectorHandler.isFullUrl()).concat(filename));
 273  
                                                 else
 274  0
                                                         ur = new UploadResponse(UploadResponse.SC_RENAMED,
 275  
                                                                 UtilsResponse.constructResponseUrl(request, resourceType,
 276  
                                                                         currentFolderStr, true, ConnectorHandler.isFullUrl())
 277  
                                                                         .concat(newFilename), newFilename);
 278  
 
 279  
                                                 // secure image check
 280  0
                                                 if (resourceType.equals(ResourceTypeHandler.IMAGE)
 281  
                                                         && ConnectorHandler.isSecureImageUploads()) {
 282  0
                                                         if (UtilsFile.isImage(uplFile.getInputStream()))
 283  0
                                                                 uplFile.write(pathToSave);
 284  
                                                         else {
 285  0
                                                                 uplFile.delete();
 286  0
                                                                 ur = new UploadResponse(UploadResponse.SC_INVALID_EXTENSION);
 287  
                                                         }
 288  
                                                 } else
 289  0
                                                         uplFile.write(pathToSave);
 290  
 
 291  
                                         }
 292  0
                                 } catch (Exception e) {
 293  0
                                         ur = new UploadResponse(UploadResponse.SC_SECURITY_ERROR);
 294  0
                                 }
 295  
                         }
 296  
 
 297  
                 }
 298  
 
 299  0
                 out.print(ur);
 300  0
                 out.flush();
 301  0
                 out.close();
 302  
 
 303  0
                 logger.debug("Exiting Connector#doPost");
 304  0
         }
 305  
 
 306  
 }