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

184 lines
9.3 KiB
Java
Raw Normal View History

package eu.eudat.controllers;
2023-11-03 13:53:10 +01:00
import eu.eudat.authorization.AuthorizationFlags;
import eu.eudat.authorization.Permission;
2023-11-03 13:53:10 +01:00
import eu.eudat.commons.XmlHandlingService;
2023-11-16 13:01:39 +01:00
import eu.eudat.commons.enums.DmpAccessType;
2023-11-03 13:53:10 +01:00
import eu.eudat.commons.enums.FieldType;
2023-11-07 13:53:36 +01:00
import eu.eudat.commons.enums.IsActive;
import eu.eudat.commons.scope.user.UserScope;
2023-11-03 13:53:10 +01:00
import eu.eudat.commons.types.descriptiontemplate.DefinitionEntity;
import eu.eudat.commons.types.descriptiontemplate.FieldEntity;
import eu.eudat.commons.types.descriptiontemplate.fielddata.UploadDataEntity;
2023-11-06 15:17:57 +01:00
import eu.eudat.data.DescriptionEntity;
2023-11-03 13:53:10 +01:00
import eu.eudat.data.DescriptionTemplateEntity;
2023-11-16 13:01:39 +01:00
import eu.eudat.data.DmpEntity;
import eu.eudat.data.old.FileUpload;
import eu.eudat.exceptions.security.UnauthorisedException;
import eu.eudat.logic.managers.DatasetProfileManager;
import eu.eudat.logic.services.ApiContext;
import eu.eudat.logic.services.operations.DatabaseRepository;
import eu.eudat.model.file.FileEnvelope;
import eu.eudat.models.HintedModelFactory;
import eu.eudat.models.data.helpers.responses.ResponseItem;
2024-02-01 16:46:28 +01:00
import eu.eudat.query.DescriptionQuery;
2023-11-03 13:53:10 +01:00
import eu.eudat.query.DescriptionTemplateQuery;
2023-11-07 13:53:36 +01:00
import eu.eudat.query.DmpDescriptionTemplateQuery;
2024-02-01 16:29:04 +01:00
import eu.eudat.query.DmpQuery;
import eu.eudat.types.ApiMessageCode;
import gr.cite.commons.web.authz.service.AuthorizationService;
2023-11-03 13:53:10 +01:00
import gr.cite.tools.data.query.QueryFactory;
import jakarta.transaction.Transactional;
2023-11-03 13:53:10 +01:00
import jakarta.xml.bind.JAXBException;
import org.apache.poi.util.IOUtils;
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;
2023-11-03 13:53:10 +01:00
import org.springframework.util.unit.DataSize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
2023-11-03 13:53:10 +01:00
import org.xml.sax.SAXException;
import javax.management.InvalidApplicationException;
2023-11-03 13:53:10 +01:00
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.nio.file.Files;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
@RestController
@CrossOrigin
@RequestMapping(value = {"/api/file/"})
public class FileController {
private DatasetProfileManager datasetProfileManager;
private final Environment environment;
private DatabaseRepository databaseRepository;
private final AuthorizationService authorizationService;
private final UserScope userScope;
2023-11-03 13:53:10 +01:00
private final QueryFactory queryFactory;
private final XmlHandlingService xmlHandlingService;
@Autowired
2023-11-03 13:53:10 +01:00
public FileController(DatasetProfileManager datasetProfileManager, Environment environment, ApiContext apiContext, AuthorizationService authorizationService, UserScope userScope, QueryFactory queryFactory, XmlHandlingService xmlHandlingService) {
this.datasetProfileManager = datasetProfileManager;
this.environment = environment;
this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository();
this.authorizationService = authorizationService;
this.userScope = userScope;
2023-11-03 13:53:10 +01:00
this.queryFactory = queryFactory;
this.xmlHandlingService = xmlHandlingService;
}
@RequestMapping(method = RequestMethod.POST, value = {"/upload"})
public ResponseEntity<ResponseItem<String>> upload(
@RequestParam("file") MultipartFile file, @RequestParam("datasetProfileId") String datasetProfileId, @RequestParam("fieldId") String fieldId)
2023-11-03 13:53:10 +01:00
throws IllegalAccessException, IOException, InvalidApplicationException, JAXBException, ParserConfigurationException, InstantiationException, SAXException {
this.authorizationService.authorizeForce(Permission.AdminRole, Permission.ManagerRole, Permission.UserRole);
String uuid = UUID.randomUUID().toString();
2023-11-17 18:01:44 +01:00
DescriptionTemplateEntity descriptionTemplate = this.queryFactory.query(DescriptionTemplateQuery.class).ids(UUID.fromString(datasetProfileId)).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).first();
2023-11-03 13:53:10 +01:00
DefinitionEntity definition = descriptionTemplate == null ? null : this.xmlHandlingService.fromXml(DefinitionEntity.class, descriptionTemplate.getDefinition());
AtomicBoolean acceptedFile = new AtomicBoolean(false);
2023-11-03 13:53:10 +01:00
List<FieldEntity> fieldEntities = definition != null ? definition.getFieldById(fieldId).stream().filter(x -> x != null && x.getData() != null && x.getData().getFieldType().equals(FieldType.UPLOAD)).toList() : new ArrayList<>();
fieldEntities.forEach(x-> {
UploadDataEntity uploadDataEntity = (UploadDataEntity)x.getData();
if (DataSize.ofBytes(file.getSize()).equals(DataSize.ofMegabytes(uploadDataEntity.getMaxFileSizeInMB()))) {
acceptedFile.set(true);
}
if(acceptedFile.get() && uploadDataEntity.getTypes() != null && !uploadDataEntity.getTypes().isEmpty()) {
acceptedFile.set(false);
2024-01-30 15:31:03 +01:00
for (UploadDataEntity.UploadDataOptionEntity option: uploadDataEntity.getTypes()) {
2023-11-03 13:53:10 +01:00
if(Objects.equals(file.getContentType(), option.getValue())) {
acceptedFile.set(true);
}
}
}
});
if(!acceptedFile.get()) {
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);
convFile.createNewFile();
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) throws IOException, InvalidApplicationException {
this.authorizationService.authorizeForce(Permission.AdminRole, Permission.ManagerRole, Permission.UserRole, Permission.AnonymousRole);
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())) {
2024-02-01 16:46:28 +01:00
DescriptionEntity descriptionEntityEntity = this.queryFactory.query(DescriptionQuery.class).ids(fileUpload.getEntityId()).first();
2023-11-06 15:17:57 +01:00
if (descriptionEntityEntity == null) {
throw new NoSuchElementException("No dataset with id " + fileUpload.getEntityId() + " found. This dataset was related to the file with id " + id);
}
2023-11-06 15:17:57 +01:00
2024-02-01 16:29:04 +01:00
DmpEntity dmp = this.queryFactory.query(DmpQuery.class).ids(this.queryFactory.query(DmpDescriptionTemplateQuery.class).ids(descriptionEntityEntity.getDmpDescriptionTemplateId()).isActive(IsActive.Active).first().getDmpId()).first();
2023-11-06 15:17:57 +01:00
2023-11-16 13:01:39 +01:00
if (!dmp.getAccessType().equals(DmpAccessType.Public)
//TODO
// && dmp.getUsers()
// .stream().filter(userInfo -> this.userScope.getUserIdSafe().equals(userInfo.getUser().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);
}
}