예제 #1
0
  /**
   * Add a file to a document.
   *
   * @param documentId Document ID
   * @param fileBodyPart File to add
   * @return Response
   * @throws JSONException
   */
  @PUT
  @Consumes("multipart/form-data")
  @Produces(MediaType.APPLICATION_JSON)
  public Response add(
      @FormDataParam("id") String documentId, @FormDataParam("file") FormDataBodyPart fileBodyPart)
      throws JSONException {
    if (!authenticate()) {
      throw new ForbiddenClientException();
    }

    // Validate input data
    ValidationUtil.validateRequired(documentId, "id");
    ValidationUtil.validateRequired(fileBodyPart, "file");

    // Get the document
    DocumentDao documentDao = new DocumentDao();
    FileDao fileDao = new FileDao();
    UserDao userDao = new UserDao();
    Document document;
    User user;
    try {
      document = documentDao.getDocument(documentId, principal.getId());
      user = userDao.getById(principal.getId());
    } catch (NoResultException e) {
      throw new ClientException(
          "DocumentNotFound", MessageFormat.format("Document not found: {0}", documentId));
    }

    // Keep unencrypted data in memory, because we will need it two times
    byte[] fileData;
    try {
      fileData = ByteStreams.toByteArray(fileBodyPart.getValueAs(InputStream.class));
    } catch (IOException e) {
      throw new ServerException("StreamError", "Error reading the input file", e);
    }
    InputStream fileInputStream = new ByteArrayInputStream(fileData);

    // Validate mime type
    String mimeType;
    try {
      mimeType = MimeTypeUtil.guessMimeType(fileInputStream);
    } catch (Exception e) {
      throw new ServerException("ErrorGuessMime", "Error guessing mime type", e);
    }
    if (mimeType == null) {
      throw new ClientException("InvalidFileType", "File type not recognized");
    }

    try {
      // Get files of this document
      int order = 0;
      for (File file : fileDao.getByDocumentId(documentId)) {
        file.setOrder(order++);
      }

      // Create the file
      File file = new File();
      file.setOrder(order);
      file.setDocumentId(document.getId());
      file.setMimeType(mimeType);
      String fileId = fileDao.create(file);

      // Save the file
      FileUtil.save(fileInputStream, file, user.getPrivateKey());

      // Raise a new file created event
      FileCreatedAsyncEvent fileCreatedAsyncEvent = new FileCreatedAsyncEvent();
      fileCreatedAsyncEvent.setDocument(document);
      fileCreatedAsyncEvent.setFile(file);
      fileCreatedAsyncEvent.setInputStream(fileInputStream);
      AppContext.getInstance().getAsyncEventBus().post(fileCreatedAsyncEvent);

      // Always return ok
      JSONObject response = new JSONObject();
      response.put("status", "ok");
      response.put("id", fileId);
      return Response.ok().entity(response).build();
    } catch (Exception e) {
      throw new ServerException("FileError", "Error adding a file", e);
    }
  }
예제 #2
0
  /**
   * Returns a file.
   *
   * @param fileId File ID
   * @return Response
   * @throws JSONException
   */
  @GET
  @Path("{id: [a-z0-9\\-]+}/data")
  @Produces(MediaType.APPLICATION_OCTET_STREAM)
  public Response data(
      @PathParam("id") final String fileId,
      @QueryParam("share") String shareId,
      @QueryParam("size") String size)
      throws JSONException {
    authenticate();

    if (size != null) {
      if (!Lists.newArrayList("web", "thumb").contains(size)) {
        throw new ClientException("SizeError", "Size must be web or thumb");
      }
    }

    // Get the file
    FileDao fileDao = new FileDao();
    DocumentDao documentDao = new DocumentDao();
    UserDao userDao = new UserDao();
    File file;
    Document document;
    try {
      file = fileDao.getFile(fileId);
      document = documentDao.getDocument(file.getDocumentId());

      // Check document visibility
      ShareDao shareDao = new ShareDao();
      if (!shareDao.checkVisibility(document, principal.getId(), shareId)) {
        throw new ForbiddenClientException();
      }
    } catch (NoResultException e) {
      throw new ClientException(
          "FileNotFound", MessageFormat.format("File not found: {0}", fileId));
    }

    // Get the stored file
    java.io.File storedfile;
    String mimeType;
    boolean decrypt = false;
    if (size != null) {
      storedfile =
          Paths.get(DirectoryUtil.getStorageDirectory().getPath(), fileId + "_" + size).toFile();
      mimeType = MimeType.IMAGE_JPEG; // Thumbnails are JPEG
      decrypt = true; // Thumbnails are encrypted
      if (!storedfile.exists()) {
        storedfile = new java.io.File(getClass().getResource("/image/file.png").getFile());
        mimeType = MimeType.IMAGE_PNG;
        decrypt = false;
      }
    } else {
      storedfile = Paths.get(DirectoryUtil.getStorageDirectory().getPath(), fileId).toFile();
      mimeType = file.getMimeType();
      decrypt = true; // Original files are encrypted
    }

    // Stream the output and decrypt it if necessary
    StreamingOutput stream;
    User user = userDao.getById(document.getUserId());
    try {
      InputStream fileInputStream = new FileInputStream(storedfile);
      final InputStream responseInputStream =
          decrypt
              ? EncryptionUtil.decryptInputStream(fileInputStream, user.getPrivateKey())
              : fileInputStream;

      stream =
          new StreamingOutput() {
            @Override
            public void write(OutputStream outputStream)
                throws IOException, WebApplicationException {
              try {
                ByteStreams.copy(responseInputStream, outputStream);
              } finally {
                responseInputStream.close();
                outputStream.close();
              }
            }
          };
    } catch (Exception e) {
      throw new ServerException("FileError", "Error while reading the file", e);
    }

    return Response.ok(stream)
        .header("Content-Type", mimeType)
        .header(
            "Expires",
            new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z")
                .format(new Date().getTime() + 3600000 * 24))
        .build();
  }