package eu.eudat.controllers; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.entities.FileUpload; import eu.eudat.exceptions.security.UnauthorisedException; import eu.eudat.logic.managers.DatasetProfileManager; import eu.eudat.logic.security.claims.ClaimedAuthorities; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.operations.DatabaseRepository; import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; import eu.eudat.logic.utilities.json.JsonSearcher; import eu.eudat.models.HintedModelFactory; import eu.eudat.models.data.components.commons.datafield.UploadData; import eu.eudat.models.data.datasetwizard.DatasetWizardModel; import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.models.data.security.Principal; import eu.eudat.types.ApiMessageCode; import eu.eudat.types.Authorities; import org.apache.poi.util.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.transaction.Transactional; import java.io.*; import java.nio.file.Files; import java.util.HashSet; import java.util.NoSuchElementException; import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; @RestController @CrossOrigin @RequestMapping(value = {"/api/file/"}) public class FileController { private static final Logger logger = LoggerFactory.getLogger(FileController.class); private DatasetProfileManager datasetProfileManager; private final Environment environment; private DatabaseRepository databaseRepository; private final ObjectMapper objectMapper; @Autowired public FileController(DatasetProfileManager datasetProfileManager, Environment environment, ApiContext apiContext) { this.datasetProfileManager = datasetProfileManager; this.environment = environment; this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository(); this.objectMapper = apiContext.getUtilitiesService().getGenericObjectMapper(); } @RequestMapping(method = RequestMethod.POST, value = {"/upload"}) public ResponseEntity> upload( @RequestParam("file") MultipartFile file, @RequestParam("datasetProfileId") String datasetProfileId, @RequestParam("fieldId") String fieldId, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER}) Principal principal) throws IllegalAccessException, IOException { String uuid = UUID.randomUUID().toString(); eu.eudat.models.data.admin.composite.DatasetProfile datasetprofile = this.datasetProfileManager.getDatasetProfile(datasetProfileId); String json = objectMapper.writeValueAsString(datasetprofile.getSections()); JsonNode propertiesJson = objectMapper.readTree(json); Set fieldNodes = new HashSet<>(); fieldNodes.addAll(JsonSearcher.findNodes(propertiesJson, "id", fieldId, false)); // AtomicReference exceptionMessage = null; Boolean acceptedFile = false; for (JsonNode node : fieldNodes) { JsonNode data = node.get("data"); try { UploadData uploadData = objectMapper.treeToValue(data, UploadData.class); if (uploadData != null) { if (uploadData.getMaxFileSizeInMB() != null) { if (file.getSize() <= (uploadData.getMaxFileSizeInMB() * Math.pow(1024, 2))) { acceptedFile = true; } } if (acceptedFile && uploadData.getTypes() != null && !uploadData.getTypes().isEmpty()) { acceptedFile = false; for (UploadData.Option option : uploadData.getTypes()) { if (option.getValue() != null) { if (file.getContentType().equals(option.getValue())) { acceptedFile = true; } } } } } } catch (JsonProcessingException e) { logger.error(e.getLocalizedMessage(), e); } } // if(!acceptedFile.get()) { // exceptionMessage.set("The file type is not accepted."); // } if (!acceptedFile) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message("The uploaded file is too large or has an unaccepted type")); } File convFile = new File(this.environment.getProperty("temp.temp") + uuid); FileOutputStream fos = new FileOutputStream(convFile); fos.write(file.getBytes()); fos.close(); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(uuid) .status(ApiMessageCode.SUCCESS_MESSAGE).message("")); } @RequestMapping(method = RequestMethod.POST, value = {"/delete-temp"}) public ResponseEntity> upload(@RequestBody String filename) throws IllegalAccessException, IOException { File convFile = new File(this.environment.getProperty("temp.temp") + filename); // Boolean deleted = convFile.delete(); Boolean deleted = Files.deleteIfExists(convFile.toPath()); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(deleted.toString()) .status(ApiMessageCode.SUCCESS_MESSAGE).message("")); } @Transactional @RequestMapping(method = RequestMethod.GET, value = {"{id}"}, produces = "application/json") public @ResponseBody ResponseEntity download(@PathVariable String id ,@ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal ) throws IOException { FileUpload fileUpload = databaseRepository.getFileUploadDao().find(UUID.fromString(id)); if(fileUpload == null) { throw new NoSuchElementException("File with id "+id+" not found"); } if(fileUpload.getEntityType().name().equals(FileUpload.EntityType.DATASET.name())) { eu.eudat.data.entities.Dataset datasetEntity = databaseRepository.getDatasetDao().find(fileUpload.getEntityId(), HintedModelFactory.getHint(DatasetWizardModel.class)); if (datasetEntity == null) { throw new NoSuchElementException("No dataset with id " + fileUpload.getEntityId() + " found. This dataset was related to the file with id " + id); } if (!datasetEntity.getDmp().isPublic() && datasetEntity.getDmp().getUsers() .stream().filter(userInfo -> userInfo.getUser().getId() == principal.getId()) .collect(Collectors.toList()).size() == 0) throw new UnauthorisedException(); } FileEnvelope fileEnvelope = new FileEnvelope(); fileEnvelope.setFilename(fileUpload.getName()); File exportFile = new File(this.environment.getProperty("file.storage") + id); fileEnvelope.setFile(exportFile); InputStream resource = new FileInputStream(fileEnvelope.getFile()); HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.setContentLength(fileEnvelope.getFile().length()); responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); String fileName = fileEnvelope.getFilename().replace(" ", "_").replace(",", "_"); responseHeaders.set("Content-Disposition", "attachment;filename=" + fileName); responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); responseHeaders.set("Cache-Control", "no-store"); responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); byte[] content = IOUtils.toByteArray(resource); resource.close(); return new ResponseEntity<>(content, responseHeaders, HttpStatus.OK); } }