argos/dmp-backend/web/src/main/java/eu/eudat/controllers/FileController.java

177 lines
8.4 KiB
Java

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<ResponseItem<String>> 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<JsonNode> fieldNodes = new HashSet<>();
fieldNodes.addAll(JsonSearcher.findNodes(propertiesJson, "id", fieldId, false));
// AtomicReference<String> 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<String>().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<String>().payload(uuid)
.status(ApiMessageCode.SUCCESS_MESSAGE).message(""));
}
@RequestMapping(method = RequestMethod.POST, value = {"/delete-temp"})
public ResponseEntity<ResponseItem<String>> 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<String>().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);
}
}