From ea2503917ee63f02d6c92083046a8f2f4808b6e0 Mon Sep 17 00:00:00 2001 From: gaetanbrl Date: Fri, 4 Oct 2024 13:05:33 +0200 Subject: [PATCH] Can return opened docs --- docs-manager-back/.vscode/launch.json | 3 +- .../controller/FilesController.java | 210 ++++++++++++++---- .../docsmanager/helper/FileEntityHelper.java | 29 +++ .../docsmanager/model/FileEntity.java | 10 + .../docsmanager/model/FileResponse.java | 9 + .../repository/FileRepository.java | 12 +- .../docsmanager/service/FileService.java | 46 +++- .../src/main/resources/application.properties | 2 + 8 files changed, 269 insertions(+), 52 deletions(-) diff --git a/docs-manager-back/.vscode/launch.json b/docs-manager-back/.vscode/launch.json index 8978920..7120df7 100644 --- a/docs-manager-back/.vscode/launch.json +++ b/docs-manager-back/.vscode/launch.json @@ -15,7 +15,8 @@ "name": "Application", "request": "launch", "mainClass": "org.georchestra.docsmanager.Application", - "projectName": "docsmanager" + "projectName": "docsmanager", + "args": "--spring.devtools.restart.enabled=true --spring.config.location=/srv/docs-manager/application.properties" } ] } \ No newline at end of file diff --git a/docs-manager-back/src/main/java/org/georchestra/docsmanager/controller/FilesController.java b/docs-manager-back/src/main/java/org/georchestra/docsmanager/controller/FilesController.java index 7283b4d..2bab770 100644 --- a/docs-manager-back/src/main/java/org/georchestra/docsmanager/controller/FilesController.java +++ b/docs-manager-back/src/main/java/org/georchestra/docsmanager/controller/FilesController.java @@ -14,13 +14,14 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.servlet.support.ServletUriComponentsBuilder; import org.springframework.beans.factory.annotation.Value; import jakarta.servlet.http.HttpServletRequest; +import jakarta.websocket.server.PathParam; import org.georchestra.docsmanager.helper.FileEntityHelper; import org.georchestra.docsmanager.helper.RoleHelper; import org.georchestra.docsmanager.model.FileEntity; @@ -43,24 +44,43 @@ public class FilesController { String additionalRoles; @Value("${docs.roles.admin}") List adminRoles; + @Value("${docs.public.value}") + String publicValue; + @Value("${docs.context.path:}") + String contextPath; @Autowired public FilesController(FileService fileService) { this.fileService = fileService; } + /** + * [protected] - Upload a file + * + * @param request + * @param file - blob + * @param comment + * @param label + * @param dateDoc + * @param plugin - code or id plugin + * @param status - e.g public + * @param entity - id feature + * @return + */ @PostMapping(value = "/plugin/{plugin}") public ResponseEntity upload(HttpServletRequest request, @RequestParam("file") MultipartFile file, - @RequestParam("comment") String comment, + @RequestParam(value = "comment", required = false) String comment, @RequestParam("label") String label, @RequestParam("dateDoc") String dateDoc, - @RequestParam("status") String status, - @RequestParam("entity") String entity, @PathVariable String plugin) { + @RequestParam(value = "status", required = false) String status, + @RequestParam("entity") String entity, + @RequestParam(value = "opened", defaultValue = "false", + required = false) Boolean opened, + @PathVariable String plugin) { try { String roles = request.getHeader(HEADER_ROLE); String username = request.getHeader(HEADER_USERNAME); - String org = request.getHeader(HEADER_ORG); List defaultWriteRoles = RoleHelper.getFullAuthorizedRoles(plugin, "edit", adminRoles, additionalRoles); @@ -72,7 +92,7 @@ public ResponseEntity upload(HttpServletRequest request, file.getOriginalFilename())); } fileService.save(file, plugin, comment, username, label, dateDoc, status, - entity); + entity, opened); return ResponseEntity.status(HttpStatus.OK) .body(String.format("File uploaded successfully: %s", file.getOriginalFilename())); @@ -84,6 +104,70 @@ public ResponseEntity upload(HttpServletRequest request, } } + /** + * + * @param request + * @param comment + * @param label + * @param dateDoc + * @param status + * @param entity - id feature + * @param opened + * @param id - file + * @param plugin + * @return + */ + @PutMapping("/plugin/{plugin}/{id}") + public ResponseEntity update(HttpServletRequest request, + @RequestParam("comment") String comment, + @RequestParam("label") String label, + @RequestParam("dateDoc") String dateDoc, + @RequestParam("status") String status, + @RequestParam("entity") String entity, + @RequestParam("opened") Boolean opened, @PathVariable String id, + @PathVariable String plugin) { + try { + String roles = request.getHeader(HEADER_ROLE); + + List defaultWriteRoles = RoleHelper.getFullAuthorizedRoles(plugin, + "edit", adminRoles, additionalRoles); + + if (!RoleHelper.isWriter(plugin, roles, defaultWriteRoles)) { + logger.info("Upload failed : check user ROLES (header sec-roles)"); + return ResponseEntity.status(HttpStatus.FORBIDDEN).body(String + .format("Not authorized to upload the file with id: %s", + id)); + } + // chek if exists + Optional optionalFileToUp = fileService.getFile(id); + if (!optionalFileToUp.isPresent()) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body( + String.format("File with id %s not found !", id)); + } + + // change + fileService.update(id, comment, label, dateDoc, status, entity, opened); + + return ResponseEntity.status(HttpStatus.OK) + .body(String.format("File successfully updated: %s", id)); + } catch (Exception e) { + logger.error("Upload failed due to Unknown error", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(String + .format("Could not update the file with id : %s!", id)); + } + } + + + /** + * [protected] - List all files + * + * @param request + * @param plugin - code or id plugin + * @param status - e.g public + * @param entity - id feature + * @param label + * @return + */ @GetMapping("/all") public List list(HttpServletRequest request, @RequestParam(required = false) String status, @@ -103,28 +187,58 @@ public List list(HttpServletRequest request, .collect(Collectors.toList()); } + /** + * [protected] - Get all files by plugin value + * + * @param request + * @param plugin - code or id plugin + * @param status - e.g public + * @param entity - id feature + * @param label + * @return + */ @GetMapping(value = "/plugin/{plugin}") - public List listByPlugin(HttpServletRequest request, + public List listFilesByPlugin(HttpServletRequest request, @PathVariable String plugin, @RequestParam(required = false) String status, @RequestParam(required = false) String entity, @RequestParam(required = false) String label) { String roles = request.getHeader(HEADER_ROLE); List defaultReadersRoles = RoleHelper.getFullAuthorizedRoles(plugin, "read", adminRoles, additionalRoles); - if (!RoleHelper.isReader(plugin, roles, defaultReadersRoles)) { - logger.info("GET /plugin/{plugin} : Not autorized roles [%s]" - .formatted(roles)); - return Collections.emptyList(); - } + + List responseFiles; FileEntity searchFile = FileEntityHelper.getFileExample(status, plugin, entity, label); - return fileService.getAllFilesFromExample(searchFile).stream() - .map(this::mapToFileResponse).collect(Collectors.toList()); + + Boolean onlyReadOpenFiles = roles == null + || !RoleHelper.isReader(plugin, roles, defaultReadersRoles); + if (onlyReadOpenFiles) { + searchFile.setOpened(onlyReadOpenFiles); + } else { + searchFile.setOpened(null); + } + + responseFiles = fileService.getAllFilesFromExample(searchFile); + return responseFiles.stream().map(this::mapToFileResponse) + .collect(Collectors.toList()); + } + + /** + * Utility func to create a file response. + * + * @param fileEntity + * @return + */ private FileResponse mapToFileResponse(FileEntity fileEntity) { - String downloadURL = ServletUriComponentsBuilder.fromCurrentContextPath() - .path("/files/").path(fileEntity.getId()).toUriString(); + String downloadURL = "/plugin/" + fileEntity.getPlugin() + "/" + fileEntity.getId(); + + if (contextPath != null) { + downloadURL = contextPath + downloadURL; + } else { + downloadURL = "files" + downloadURL; + } FileResponse fileResponse = new FileResponse(); fileResponse.setId(fileEntity.getId()); fileResponse.setName(fileEntity.getName()); @@ -137,10 +251,18 @@ private FileResponse mapToFileResponse(FileEntity fileEntity) { fileResponse.setStatus(fileEntity.getStatus()); fileResponse.setComment(fileEntity.getComment()); fileResponse.setEntity(fileEntity.getEntity()); + fileResponse.setOpened(fileEntity.getOpened()); return fileResponse; } + /** + * Check if a label exist + * + * @param request + * @param label + * @return + */ @GetMapping("/label/exists/{label}") public ResponseEntity labelExists(HttpServletRequest request, @PathVariable String label) { @@ -148,6 +270,14 @@ public ResponseEntity labelExists(HttpServletRequest request, return ResponseEntity.status(HttpStatus.OK).body(test); } + /** + * [protected] - Delete file + * + * @param request + * @param id - file ID + * @param plugin - plugin name or code + * @return + */ @DeleteMapping("/plugin/{plugin}/{id}") public ResponseEntity deleteFile(HttpServletRequest request, @PathVariable String id, @PathVariable String plugin) { @@ -174,26 +304,42 @@ public ResponseEntity deleteFile(HttpServletRequest request, .body(String.format("File successfully deleted !")); } + /** + * [Protected] - Get file by ID + * + * @param request + * @param id - file ID + * @param plugin - plugin name or code + * @return + */ @GetMapping("/plugin/{plugin}/{id}") public ResponseEntity getFile(HttpServletRequest request, @PathVariable String id, @PathVariable String plugin) { String roles = request.getHeader(HEADER_ROLE); - Optional fileEntityOptional = fileService.getFile(id); + List defaultReaders = RoleHelper.getFullAuthorizedRoles(plugin, "read", + adminRoles, additionalRoles); - if (!fileEntityOptional.isPresent()) { + // check if exists + Boolean idExists = fileService.existsByIdLike(id); + if (!idExists) { logger.info("GET /plugin/{plugin}/{id} : No document exists with this ID -> Check ID."); return ResponseEntity.notFound().build(); } - List defaultReaders = RoleHelper.getFullAuthorizedRoles(plugin, "read", - adminRoles, additionalRoles); - if (!RoleHelper.isReader(plugin, roles, defaultReaders)) { + + // read file + Optional fileEntityOptional = fileService.getFile(id); + + FileEntity fileEntity = fileEntityOptional.get(); + + // fobid if not opened file + if (!fileEntity.getOpened() + && !RoleHelper.isReader(plugin, roles, defaultReaders)) { logger.info("GET /plugin/{plugin}/{id} : Not autorized roles [%s]" .formatted(roles)); return ResponseEntity.notFound().build(); } - FileEntity fileEntity = fileEntityOptional.get(); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileEntity.getName() @@ -201,24 +347,4 @@ public ResponseEntity getFile(HttpServletRequest request, @PathVariable .contentType(MediaType.valueOf(fileEntity.getContentType())) .body(fileEntity.getData()); } - - @GetMapping("/plugin/{plugin}/public/{id}") - public List getPublicFilesByPluginAndFeature(HttpServletRequest request, @PathVariable String id, - @PathVariable String plugin) { - List responseFiles; - - responseFiles = fileService.getPublicFilesByPluginAndEntity(plugin, "public", id); - return responseFiles.stream().map(this::mapToFileResponse) - .collect(Collectors.toList()); - } - - @GetMapping("/plugin/public/{id}") - public List getPublicFilesByFeature(HttpServletRequest request, @PathVariable String id, - @PathVariable String plugin) { - List responseFiles; - - responseFiles = fileService.getPublicFilesByIdFeature("public", id); - return responseFiles.stream().map(this::mapToFileResponse) - .collect(Collectors.toList()); - } } diff --git a/docs-manager-back/src/main/java/org/georchestra/docsmanager/helper/FileEntityHelper.java b/docs-manager-back/src/main/java/org/georchestra/docsmanager/helper/FileEntityHelper.java index c5d2f8e..3e9f67c 100644 --- a/docs-manager-back/src/main/java/org/georchestra/docsmanager/helper/FileEntityHelper.java +++ b/docs-manager-back/src/main/java/org/georchestra/docsmanager/helper/FileEntityHelper.java @@ -20,4 +20,33 @@ public static FileEntity getFileExample(String status, String plugin, String ent } return fileAsExample; } + + public static FileEntity getOpenedFileExample(String status, String plugin, String entity, + String label) { + FileEntity fileAsExample = new FileEntity(); + if (entity != null) { + fileAsExample.setEntity(entity); + } + if (status != null) { + fileAsExample.setStatus(status); + } + if (plugin != null) { + fileAsExample.setPlugin(plugin); + } + if (label != null) { + fileAsExample.setLabel(label); + } + + fileAsExample.setOpened(true); + + return fileAsExample; + } + + public static FileEntity getFileExample(Boolean opened) { + FileEntity fileAsExample = new FileEntity(); + if (opened != null) { + fileAsExample.setOpened(opened); + } + return fileAsExample; + } } diff --git a/docs-manager-back/src/main/java/org/georchestra/docsmanager/model/FileEntity.java b/docs-manager-back/src/main/java/org/georchestra/docsmanager/model/FileEntity.java index 6b2d5e4..d4938ec 100644 --- a/docs-manager-back/src/main/java/org/georchestra/docsmanager/model/FileEntity.java +++ b/docs-manager-back/src/main/java/org/georchestra/docsmanager/model/FileEntity.java @@ -32,6 +32,8 @@ public class FileEntity { private String createDate; private String userInfos; + private Boolean opened; + private String dateDoc; private Long size; @@ -158,4 +160,12 @@ public void setDateDoc(String dateDoc) { LocalDate date = LocalDate.parse(dateDoc, formatter); this.dateDoc = date.toString(); } + + public void setOpened(Boolean opened) { + this.opened = opened; + } + + public Boolean getOpened() { + return this.opened; + } } diff --git a/docs-manager-back/src/main/java/org/georchestra/docsmanager/model/FileResponse.java b/docs-manager-back/src/main/java/org/georchestra/docsmanager/model/FileResponse.java index 4df9c5c..efed224 100644 --- a/docs-manager-back/src/main/java/org/georchestra/docsmanager/model/FileResponse.java +++ b/docs-manager-back/src/main/java/org/georchestra/docsmanager/model/FileResponse.java @@ -13,6 +13,7 @@ public class FileResponse { private String status; private String comment; private String entity; + private Boolean opened; public String getId() { return id; @@ -98,7 +99,15 @@ public void setEntity(String entity) { this.entity = entity; } + public void setOpened(Boolean opened) { + this.opened = opened; + } + public String getEntity() { return entity; } + + public Boolean getOpened() { + return opened; + } } diff --git a/docs-manager-back/src/main/java/org/georchestra/docsmanager/repository/FileRepository.java b/docs-manager-back/src/main/java/org/georchestra/docsmanager/repository/FileRepository.java index d4a6f30..209f54e 100644 --- a/docs-manager-back/src/main/java/org/georchestra/docsmanager/repository/FileRepository.java +++ b/docs-manager-back/src/main/java/org/georchestra/docsmanager/repository/FileRepository.java @@ -12,9 +12,17 @@ public interface FileRepository extends JpaRepository { Boolean existsByIdLike(String id); - List findByStatusAndEntity(String status, String entity, Sort sort); + List findByOpenedAndEntity(Boolean opened, String entity, Sort sort); + + List findByEntityLike(String entity, Sort sort); + + List findByEntityAndPlugin(String entity, String plugin, Sort sort); List findByStatusAndPlugin(String status, String plugin, Sort sort); - List findByStatusAndPluginAndEntity(String status, String plugin, String entity, Sort sort); + List findByOpenedAndPlugin(Boolean opened, String plugin, Sort sort); + + List findByOpenedAndStatusAndPlugin(Boolean opened, String status, String plugin, Sort sort); + + List findByOpenedAndPluginAndEntity(Boolean opened, String plugin, String entity, Sort sort); } diff --git a/docs-manager-back/src/main/java/org/georchestra/docsmanager/service/FileService.java b/docs-manager-back/src/main/java/org/georchestra/docsmanager/service/FileService.java index 270296f..7b33544 100644 --- a/docs-manager-back/src/main/java/org/georchestra/docsmanager/service/FileService.java +++ b/docs-manager-back/src/main/java/org/georchestra/docsmanager/service/FileService.java @@ -23,7 +23,7 @@ public FileService(FileRepository fileRepository) { } public void save(MultipartFile file, String plugin, String comment, String userInfos, - String label, String dateDoc, String status, String entity) throws IOException { + String label, String dateDoc, String status, String entity, Boolean opened) throws IOException { FileEntity fileEntity = new FileEntity(); fileEntity.setName(StringUtils.cleanPath(file.getOriginalFilename())); fileEntity.setContentType(file.getContentType()); @@ -37,10 +37,27 @@ public void save(MultipartFile file, String plugin, String comment, String userI fileEntity.setDateDoc(dateDoc); fileEntity.setStatus(status); fileEntity.setEntity(entity); + fileEntity.setOpened(opened); fileRepository.save(fileEntity); } + public void update(String id, String comment, String label, String dateDoc, String status, String entity, + Boolean opened) throws IOException { + Optional findFile = fileRepository.findById(id); + if(findFile.isPresent()) { + FileEntity fileEntity = findFile.get(); + fileEntity.setComment(comment); + fileEntity.setLabel(label); + fileEntity.setDateDoc(dateDoc); + fileEntity.setStatus(status); + fileEntity.setEntity(entity); + fileEntity.setOpened(opened); + + fileRepository.save(fileEntity); + } + } + public void delete(String id) { fileRepository.deleteById(id); } @@ -57,22 +74,37 @@ public List getAllFiles() { return fileRepository.findAll(Sort.by("plugin")); } + public List getAllFilesByPlugin() { + return fileRepository.findAll(Sort.by("plugin")); + } + public List getAllFilesFromExample(FileEntity file) { return fileRepository.findAll(Example.of(file)); } - public List getPublicFilesByIdFeature(String idFeature, String status) { - return fileRepository.findByStatusAndEntity(status, idFeature, Sort.by("label")); + public List getPublicFilesByEntity(String entity) { + return fileRepository.findByOpenedAndEntity(true, entity, Sort.by("label")); } - public List getPublicFilesByPlugin(String plugin, String status) { - return fileRepository.findByStatusAndPlugin(status, plugin, Sort.by("label")); + public List getAllFilesByEntity(String entity) { + return fileRepository.findByEntityLike(entity, Sort.by("label")); } - public List getPublicFilesByPluginAndEntity(String plugin, String status, String entity) { - return fileRepository.findByStatusAndPluginAndEntity(status, plugin, entity, Sort.by("label")); + public List getAllFilesByEntityAndPlugin(String entity, String plugin) { + return fileRepository.findByEntityAndPlugin(entity, plugin, Sort.by("label")); } + public List getPublicFilesByPlugin(String plugin) { + return fileRepository.findByOpenedAndPlugin(true, plugin, Sort.by("label")); + } + + public List getPublicFilesByPluginAndStatus(String plugin, String status) { + return fileRepository.findByOpenedAndStatusAndPlugin(true, status, plugin, Sort.by("label")); + } + + public List getPublicFilesByPluginAndEntity(String plugin, String entity) { + return fileRepository.findByOpenedAndPluginAndEntity(true, plugin, entity, Sort.by("label")); + } public Boolean existsByLabel(String label) { return fileRepository.existsByLabelLike(label); diff --git a/docs-manager-back/src/main/resources/application.properties b/docs-manager-back/src/main/resources/application.properties index 45ae3c5..06636cb 100644 --- a/docs-manager-back/src/main/resources/application.properties +++ b/docs-manager-back/src/main/resources/application.properties @@ -23,6 +23,8 @@ docs.roles.admin = MAPSTORE_ADMIN,SUPERUSER,ROLE_MAPSTORE_ADMIN,ROLE_SUPERUSER,D # {'ID_PLUGIN':{'edit':['ROLE_A','ROLE_B'], 'read':['ROLE_X']}} docs.roles.additionnal = {} +docs.public.value = "public"; + logging.level.root=info logging.level.org.springframework.web=info #logging.level.org.hibernate.SQL=debug