2022-03-16 11:14:08 +01:00
package eu.eudat.controllers ;
2023-11-03 13:53:10 +01:00
import eu.eudat.authorization.AuthorizationFlags ;
2023-10-18 17:52:03 +02:00
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 ;
2023-10-18 17:52:03 +02:00
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 ;
2023-10-18 12:04:53 +02:00
import eu.eudat.data.old.FileUpload ;
2022-03-16 11:14:08 +01:00
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 ;
2023-11-03 16:54:26 +01:00
import eu.eudat.model.file.FileEnvelope ;
2022-03-16 11:14:08 +01:00
import eu.eudat.models.HintedModelFactory ;
import eu.eudat.models.data.datasetwizard.DatasetWizardModel ;
import eu.eudat.models.data.helpers.responses.ResponseItem ;
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 ;
2022-03-16 11:14:08 +01:00
import eu.eudat.types.ApiMessageCode ;
2023-10-18 17:52:03 +02:00
import gr.cite.commons.web.authz.service.AuthorizationService ;
2023-11-03 13:53:10 +01:00
import gr.cite.tools.data.query.QueryFactory ;
2023-11-06 15:19:06 +01:00
import jakarta.transaction.Transactional ;
2023-11-03 13:53:10 +01:00
import jakarta.xml.bind.JAXBException ;
2022-03-16 11:14:08 +01:00
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 ;
2022-03-16 11:14:08 +01:00
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 ;
2023-10-18 17:52:03 +02:00
import javax.management.InvalidApplicationException ;
2023-11-03 13:53:10 +01:00
import javax.xml.parsers.ParserConfigurationException ;
2022-03-16 11:14:08 +01:00
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 ;
2023-10-18 17:52:03 +02:00
private final AuthorizationService authorizationService ;
private final UserScope userScope ;
2023-11-03 13:53:10 +01:00
private final QueryFactory queryFactory ;
private final XmlHandlingService xmlHandlingService ;
2022-03-16 11:14:08 +01:00
@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 ) {
2022-03-16 11:14:08 +01:00
this . datasetProfileManager = datasetProfileManager ;
this . environment = environment ;
this . databaseRepository = apiContext . getOperationsContext ( ) . getDatabaseRepository ( ) ;
2023-10-18 17:52:03 +02:00
this . authorizationService = authorizationService ;
this . userScope = userScope ;
2023-11-03 13:53:10 +01:00
this . queryFactory = queryFactory ;
this . xmlHandlingService = xmlHandlingService ;
2022-03-16 11:14:08 +01:00
}
@RequestMapping ( method = RequestMethod . POST , value = { " /upload " } )
public ResponseEntity < ResponseItem < String > > upload (
2023-10-18 17:52:03 +02:00
@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 {
2023-10-18 17:52:03 +02:00
this . authorizationService . authorizeForce ( Permission . AdminRole , Permission . ManagerRole , Permission . UserRole ) ;
2022-03-16 11:14:08 +01:00
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 ( ) ) ;
2022-03-16 11:14:08 +01:00
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 ) ;
for ( UploadDataEntity . Option option : uploadDataEntity . getTypes ( ) ) {
if ( Objects . equals ( file . getContentType ( ) , option . getValue ( ) ) ) {
2022-03-16 11:14:08 +01:00
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
2023-10-18 17:52:03 +02:00
ResponseEntity download ( @PathVariable String id ) throws IOException , InvalidApplicationException {
this . authorizationService . authorizeForce ( Permission . AdminRole , Permission . ManagerRole , Permission . UserRole , Permission . AnonymousRole ) ;
2022-03-16 11:14:08 +01:00
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 ( ) ) ) {
2023-11-06 15:17:57 +01:00
DescriptionEntity descriptionEntityEntity = databaseRepository . getDatasetDao ( ) . find ( fileUpload . getEntityId ( ) , HintedModelFactory . getHint ( DatasetWizardModel . class ) ) ;
if ( descriptionEntityEntity = = null ) {
2022-03-16 11:14:08 +01:00
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
2023-11-16 13:01:39 +01:00
DmpEntity dmp = databaseRepository . getDmpDao ( ) . find ( this . queryFactory . query ( DmpDescriptionTemplateQuery . class ) . ids ( descriptionEntityEntity . getDmpDescriptionTemplateId ( ) ) . isActive ( IsActive . Active ) . first ( ) . getDmpId ( ) ) ;
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
)
2022-03-16 11:14:08 +01:00
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 ) ;
}
}