/** * {@code id}에 해당하는 첨부파일을 지운다. * * <p>게시물, 이슈, 댓글들의 첨부파일을 지울때 사용한다. * * <p>폼의 필드에 {@code _method}가 존재하고 값이 delete로 지정되어 있지 않으면 Bad Request로 응답한다. 파일을 못 찾으면 Not Found * 삭제 권한이 없으면 Forbidden * * <p>첨부내용을 삭제한 후 해당 첨부의 origin 파일 유효검증 * * @param id 첨부파일 id * @return attachment 삭제 결과 (하지만 해당 메시지를 쓰고 있지는 않다. 아까운 네크워크 자원..) * @throws NoSuchAlgorithmException * @throws IOException */ public static Result deleteFile(Long id) throws NoSuchAlgorithmException, IOException { // _method must be 'delete' Map<String, String[]> data = request().body().asMultipartFormData().asFormUrlEncoded(); if (!HttpUtil.getFirstValueFromQuery(data, "_method").toLowerCase().equals("delete")) { return badRequest("_method must be 'delete'."); } // Remove the attachment. Attachment attach = Attachment.find.byId(id); if (attach == null) { return notFound(); } if (!AccessControl.isAllowed(UserApp.currentUser(), attach.asResource(), Operation.DELETE)) { return forbidden(); } attach.delete(); logIfOriginFileIsNotValid(attach.hash); if (Attachment.fileExists(attach.hash)) { return ok("The attachment is removed successfully, but its origin file still exists."); } else { return ok("Both the attachment and its origin file are removed successfully."); } }
/** * origin file의 유효성을 검증하고, 유효하지 않다면 로그를 남긴다. * * <p>origin file이 존재하지 않지만 그 파일을 참조하는 첨부가 존재하는 경우엔 에러 로그를 남긴다. origin file이 존재하지만 그 파일을 참조하는 첨부가 * 존재하지 않는 경우엔 경고 로그를 남긴다. * * @param hash origin file의 hash */ private static void logIfOriginFileIsNotValid(String hash) { if (!Attachment.fileExists(hash) && Attachment.exists(hash)) { Logger.error( "The origin file '" + hash + "' cannot be " + "found even if the file is still referred by some" + "attachments."); } if (Attachment.fileExists(hash) && !Attachment.exists(hash)) { Logger.warn( "The attachment is removed successfully, but its " + "origin file '" + hash + "' still exists abnormally even if the file " + "referred by nowhere."); } }