Пример #1
0
  /**
   * Deletes a file.
   *
   * @param id File ID
   * @return Response
   * @throws JSONException
   */
  @DELETE
  @Path("{id: [a-z0-9\\-]+}")
  @Produces(MediaType.APPLICATION_JSON)
  public Response delete(@PathParam("id") String id) throws JSONException {
    if (!authenticate()) {
      throw new ForbiddenClientException();
    }

    // Get the file
    FileDao fileDao = new FileDao();
    DocumentDao documentDao = new DocumentDao();
    File file;
    try {
      file = fileDao.getFile(id);
      documentDao.getDocument(file.getDocumentId(), principal.getId());
    } catch (NoResultException e) {
      throw new ClientException("FileNotFound", MessageFormat.format("File not found: {0}", id));
    }

    // Delete the file
    fileDao.delete(file.getId());

    // Raise a new file deleted event
    FileDeletedAsyncEvent fileDeletedAsyncEvent = new FileDeletedAsyncEvent();
    fileDeletedAsyncEvent.setFile(file);
    AppContext.getInstance().getAsyncEventBus().post(fileDeletedAsyncEvent);

    // Always return ok
    JSONObject response = new JSONObject();
    response.put("status", "ok");
    return Response.ok().entity(response).build();
  }
Пример #2
0
  /**
   * Build Lucene document from file.
   *
   * @param file File
   * @param document Document linked to the file
   * @return Document
   */
  private org.apache.lucene.document.Document getDocumentFromFile(File file, Document document) {
    org.apache.lucene.document.Document luceneDocument = new org.apache.lucene.document.Document();
    luceneDocument.add(new StringField("id", file.getId(), Field.Store.YES));
    luceneDocument.add(new StringField("user_id", document.getUserId(), Field.Store.YES));
    luceneDocument.add(new StringField("type", "file", Field.Store.YES));
    luceneDocument.add(new StringField("document_id", file.getDocumentId(), Field.Store.YES));
    if (file.getContent() != null) {
      luceneDocument.add(new TextField("content", file.getContent(), Field.Store.NO));
    }

    return luceneDocument;
  }
Пример #3
0
  /**
   * Returns files linked to a document.
   *
   * @param documentId Document ID
   * @return Response
   * @throws JSONException
   */
  @GET
  @Path("list")
  @Produces(MediaType.APPLICATION_JSON)
  public Response list(@QueryParam("id") String documentId, @QueryParam("share") String shareId)
      throws JSONException {
    authenticate();

    // Check document visibility
    try {
      DocumentDao documentDao = new DocumentDao();
      Document document = documentDao.getDocument(documentId);
      ShareDao shareDao = new ShareDao();
      if (!shareDao.checkVisibility(document, principal.getId(), shareId)) {
        throw new ForbiddenClientException();
      }
    } catch (NoResultException e) {
      throw new ClientException(
          "DocumentNotFound", MessageFormat.format("Document not found: {0}", documentId));
    }

    FileDao fileDao = new FileDao();
    List<File> fileList = fileDao.getByDocumentId(documentId);

    JSONObject response = new JSONObject();
    List<JSONObject> files = new ArrayList<>();

    for (File fileDb : fileList) {
      JSONObject file = new JSONObject();
      file.put("id", fileDb.getId());
      file.put("mimetype", fileDb.getMimeType());
      file.put("document_id", fileDb.getDocumentId());
      file.put("create_date", fileDb.getCreateDate().getTime());
      files.add(file);
    }

    response.put("files", files);
    return Response.ok().entity(response).build();
  }
Пример #4
0
  /**
   * Reorder files.
   *
   * @param documentId Document ID
   * @param idList List of files ID in the new order
   * @return Response
   * @throws JSONException
   */
  @POST
  @Path("reorder")
  @Produces(MediaType.APPLICATION_JSON)
  public Response reorder(
      @FormParam("id") String documentId, @FormParam("order") List<String> idList)
      throws JSONException {
    if (!authenticate()) {
      throw new ForbiddenClientException();
    }

    // Validate input data
    ValidationUtil.validateRequired(documentId, "id");
    ValidationUtil.validateRequired(idList, "order");

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

    // Reorder files
    FileDao fileDao = new FileDao();
    for (File file : fileDao.getByDocumentId(documentId)) {
      int order = idList.lastIndexOf(file.getId());
      if (order != -1) {
        file.setOrder(order);
      }
    }

    // Always return ok
    JSONObject response = new JSONObject();
    response.put("status", "ok");
    return Response.ok().entity(response).build();
  }
Пример #5
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);
    }
  }
Пример #6
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();
  }