0

Problem:My java based software product has the facility to create support files as a zip file, if a user has an issue I ask them to email me or upload the file using something like dropbox. The trouble is the support file is often too large to send by email and using a tool such as dropbox is difficult for some users.

I have a server (running apache tomcat) with ftp support so I could give the user to simply upload the file, however it requires username and password. Embedding the username and password in the application is surely a bad idea, perhaps I could configure a location which requires no username/password but then how do I protect users data form other users.

Uploading support files is standard behaviour for many applications but I am unclear how it is best achieved.

Paul Taylor
  • 13,411
  • 42
  • 184
  • 351

2 Answers2

0

In short

You want to create a password protect directory for users to upload contents via ftp.

There is a good article on this site

I am quoting the basic steps here

  1. Add user, password and role in conf/tomcat-users.xml
  2. In the webapps/examples/WEB-INF/web.xml specify role, method and urls.
  3. Restart Tomcat and check.

Examples are also there


I don't have any affiliation with them

Community
  • 1
  • 1
Sagar V
  • 12,158
  • 7
  • 41
  • 68
0

Your users only need to upload a support file, they don't need to (and you don't want them to) view it after upload, even less so other files sent by other users. So I would recommend against FTP.

You can instead deploy a simple application in your Tomcat, with a simple servlet that accepts files uploaded with HTTP POST. Here is a great answer that explains how to develop such a servlet (ignore the "Introduction" paragraph that does not apply to you, but read on the rest). The servlet just needs to reply with something like "Support file uploaded with ticket number 12345, thank you". That servlet should be protected, the minimum would be to only accept uploads along with a token that you would distribute with your application.

Within that servlet, you'll need to save the file at an appropriate location, here is another detailed answer (by same author) to decide on that. In your case, the simplest would be to save it at a location that Tomcat does not serve, so only you could go & collect them on your server using SSH. Alternatively you could save the files to a protected location so that you can see & download the files, but not your users (so you only need 1 password, for you, not your users).

Working example that assumes servlet 3.1, which requires Tomcat 8, see linked answers for details if you need this on an older Tomcat version:

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.UUID;

@MultipartConfig // So you can call getPart(...) in doPost(...)
public class SupportFileUpload extends HttpServlet {

    private String uploadDirectory;

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        // Configure location with <init-param> in web.xml
        uploadDirectory = config.getInitParameter("upload_directory");
        if (uploadDirectory == null) {
            uploadDirectory = System.getProperty("java.io.tmpdir");
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String token = request.getHeader("token");
        if (!isValid(token)) {
            response.setStatus(403);
            response.getWriter().println("Rejected");
            return;
        }
        Part filePart = request.getPart("file");
        String fileName = filePart.getSubmittedFileName();
        UUID uuid = UUID.randomUUID();
        filePart.write(Paths.get(uploadDirectory, "support_" + uuid + "_" + fileName).toString());
        response.getWriter().println("Uploaded: " + uuid);
    }

    private boolean isValid(String token) {
        return "plzhalp".equals(token); // Implement tight security here
    }
}

Part.write(String) is a convenience method to write an uploaded part to disk.

On the client side, you would use Commons HttpClient to upload the file.

Hugues M.
  • 19,846
  • 6
  • 37
  • 65