diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetWizardController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetWizardController.java deleted file mode 100644 index c2b9abc43..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetWizardController.java +++ /dev/null @@ -1,224 +0,0 @@ -package eu.eudat.controllers; - -import eu.eudat.data.entities.Dataset; -import eu.eudat.data.query.items.item.dataset.DatasetWizardAutocompleteRequest; -import eu.eudat.data.query.items.item.datasetprofile.DatasetProfileWizardAutocompleteRequest; -import eu.eudat.exceptions.datasetwizard.DatasetWizardCannotUnlockException; -import eu.eudat.exceptions.security.UnauthorisedException; -import eu.eudat.logic.managers.DatasetManager; -import eu.eudat.logic.managers.DatasetWizardManager; -import eu.eudat.logic.managers.UserManager; -import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; -import eu.eudat.logic.security.claims.ClaimedAuthorities; -import eu.eudat.logic.services.ApiContext; -import eu.eudat.logic.services.forms.VisibilityRuleService; -import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; -import eu.eudat.models.data.datasetwizard.DataManagentPlanListingModel; -import eu.eudat.models.data.datasetwizard.DatasetWizardModel; -import eu.eudat.models.data.dmp.AssociatedProfile; -import eu.eudat.models.data.helpers.responses.ResponseItem; -import eu.eudat.models.data.listingmodels.DataManagementPlanOverviewModel; -import eu.eudat.models.data.security.Principal; -import eu.eudat.models.data.user.composite.PagedDatasetProfile; -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.persistence.NoResultException; -import javax.transaction.Transactional; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Files; -import java.util.List; -import java.util.UUID; - -import static eu.eudat.types.Authorities.ANONYMOUS; - - -@RestController -@CrossOrigin -@RequestMapping(value = {"api/datasetwizard"}) -public class DatasetWizardController extends BaseController { - private static final Logger logger = LoggerFactory.getLogger(DatasetWizardController.class); - - private Environment environment; - private DatasetManager datasetManager; - private UserManager userManager; - private ConfigLoader configLoader; - - @Autowired - public DatasetWizardController(ApiContext apiContext, Environment environment, DatasetManager datasetManager, UserManager userManager, ConfigLoader configLoader) { - super(apiContext); - this.environment = environment; - this.datasetManager = datasetManager; - this.userManager = userManager; - this.configLoader = configLoader; - } - - @RequestMapping(method = RequestMethod.POST, value = {"/userDmps"}, produces = "application/json") - public @ResponseBody - ResponseEntity>> getUserDmps(@RequestBody DatasetWizardAutocompleteRequest datasetWizardAutocompleteRequest, Principal principal) throws IllegalAccessException, InstantiationException { - List dataManagementPlans = DatasetWizardManager.getUserDmps(this.getApiContext().getOperationsContext().getDatabaseRepository().getDmpDao(), datasetWizardAutocompleteRequest, principal); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlans)); - } - - @RequestMapping(method = RequestMethod.POST, value = {"/getAvailableProfiles"}, produces = "application/json") - public @ResponseBody - ResponseEntity>> getAvailableProfiles(@RequestBody DatasetProfileWizardAutocompleteRequest datasetProfileWizardAutocompleteRequest, @ClaimedAuthorities(claims = {ANONYMOUS}) Principal principal) throws IllegalAccessException, InstantiationException { - List dataManagementPlans = DatasetWizardManager.getAvailableProfiles(this.getApiContext().getOperationsContext().getDatabaseRepository().getDmpDao(), datasetProfileWizardAutocompleteRequest); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlans)); - } - - @Transactional - @RequestMapping(method = RequestMethod.GET, value = {"{id}"}, produces = "application/json") - public @ResponseBody - ResponseEntity getSingle(@PathVariable String id, @RequestHeader("Content-Type") String contentType, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws IllegalAccessException, IOException, InstantiationException { - try { - if (contentType.equals("application/xml")) { - VisibilityRuleService visibilityRuleService = this.getApiContext().getUtilitiesService().getVisibilityRuleService(); - return this.datasetManager.getDocument(id, visibilityRuleService, contentType, principal); - } else if (contentType.equals("application/msword")) { - FileEnvelope file = datasetManager.getWordDocumentFile(this.configLoader, id, this.getApiContext().getUtilitiesService().getVisibilityRuleService(), principal); - InputStream resource = new FileInputStream(file.getFile()); - HttpHeaders responseHeaders = new HttpHeaders(); - responseHeaders.setContentLength(file.getFile().length()); - responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); - responseHeaders.set("Content-Disposition", "attachment;filename=" + file.getFilename()); - responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); - responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); - - byte[] content = IOUtils.toByteArray(resource); - resource.close(); - Files.deleteIfExists(file.getFile().toPath()); - return new ResponseEntity<>(content, - responseHeaders, - HttpStatus.OK); - } else { - DatasetWizardModel dataset = this.datasetManager.getSingle(id, principal); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataset)); - } - } catch (Exception e) { - if (e instanceof UnauthorisedException) { - if (e instanceof UnauthorisedException) { - return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE)); - } else if (e instanceof NoResultException) { - return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE)); - } else { - throw e; - } - } - } - return null; // ???? - } - - @RequestMapping(method = RequestMethod.GET, value = {"/public/{id}"}, produces = "application/json") - public @ResponseBody - ResponseEntity getSinglePublic(@PathVariable String id) throws Exception { - try { - DatasetWizardModel dataset = this.datasetManager.getSinglePublic(id); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataset)); - } - catch (Exception ex) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).message(ex.getMessage())); - } - } - - @Transactional - @RequestMapping(method = RequestMethod.DELETE, value = {"{id}"}, produces = "application/json") - public @ResponseBody - ResponseEntity> delete(@PathVariable(value = "id") UUID id, Principal principal) throws Exception { - new DatasetWizardManager().delete(this.getApiContext(), id); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Deleted")); - } - - @Transactional - @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") - public @ResponseBody - ResponseEntity> createOrUpdate(@RequestBody DatasetWizardModel profile, Principal principal) throws Exception { - this.datasetManager.createOrUpdate(profile, principal); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload(null)); - } - - @RequestMapping(method = RequestMethod.GET, value = {"/getPDF/{id}"}) - public @ResponseBody - ResponseEntity getPDFDocument(@PathVariable String id, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws IllegalAccessException, IOException, InstantiationException, InterruptedException { - FileEnvelope file = datasetManager.getWordDocumentFile(this.configLoader, id, this.getApiContext().getUtilitiesService().getVisibilityRuleService(), principal); - String fileName = file.getFilename(); - if (fileName.endsWith(".docx")){ - fileName = fileName.substring(0, fileName.length() - 5); - } - File pdffile = datasetManager.convertToPDF(file, environment); - InputStream resource = new FileInputStream(pdffile); - - HttpHeaders responseHeaders = new HttpHeaders(); - responseHeaders.setContentLength(pdffile.length()); - responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); - responseHeaders.set("Content-Disposition", "attachment;filename=" + fileName + ".pdf"); - responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); - responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); - - byte[] content = IOUtils.toByteArray(resource); - resource.close(); - Files.deleteIfExists(file.getFile().toPath()); - Files.deleteIfExists(pdffile.toPath()); - return new ResponseEntity<>(content, - responseHeaders, - HttpStatus.OK); - } - - @RequestMapping(method = RequestMethod.GET, value = {"/get/{id}"}, produces = "application/json") - public ResponseEntity> getSingle(@PathVariable String id) { - eu.eudat.data.entities.DatasetProfile profile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); - eu.eudat.models.data.user.composite.DatasetProfile datasetprofile = userManager.generateDatasetProfileModel(profile); - PagedDatasetProfile pagedDatasetProfile = new PagedDatasetProfile(); - pagedDatasetProfile.buildPagedDatasetProfile(datasetprofile); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(pagedDatasetProfile)); - } - - @Transactional - @RequestMapping(method = RequestMethod.GET, value = {"/{id}/unlock"}, produces = "application/json") - public @ResponseBody - ResponseEntity> unlock(@PathVariable(value = "id") UUID id, Principal principal) throws Exception { - try { - new DatasetWizardManager().unlock(this.getApiContext(), id); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Unlocked")); - } catch (DatasetWizardCannotUnlockException datasetWizardCannotUnlockException) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message(datasetWizardCannotUnlockException.getMessage())); - } - } - - @RequestMapping(method = RequestMethod.POST, value = {"/upload"}) - public ResponseEntity datasetXmlImport(@RequestParam("file") MultipartFile file, @RequestParam("dmpId") String dmpId, @RequestParam("datasetProfileId") String datasetProfileId, Principal principal) { - try { - Dataset dataset = this.datasetManager.createDatasetFromXml(file, dmpId, datasetProfileId, principal); - if (dataset != null){ - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE)); - } - else { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).message("Import was unsuccessful.")); - } - } catch (Exception e) { - logger.error(e.getMessage(), e); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).message("Import was unsuccessful.")); - } - } - - @RequestMapping(method = RequestMethod.GET, value = {"profile/{id}"}, produces = "application/json") - public @ResponseBody - ResponseEntity getSingleProfileUpdate(@PathVariable String id, @ClaimedAuthorities(claims = {ANONYMOUS}) Principal principal) throws IllegalAccessException, IOException, InstantiationException { - DatasetWizardModel dataset = this.datasetManager.datasetUpdateProfile(id); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataset)); - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java index 781237cab..00a7431b9 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java @@ -1,45 +1,84 @@ package eu.eudat.controllers; import eu.eudat.data.entities.Dataset; +import eu.eudat.data.query.items.item.dataset.DatasetWizardAutocompleteRequest; +import eu.eudat.data.query.items.item.datasetprofile.DatasetProfileWizardAutocompleteRequest; import eu.eudat.data.query.items.table.dataset.DatasetPublicTableRequest; import eu.eudat.data.query.items.table.dataset.DatasetTableRequest; import eu.eudat.data.query.items.table.datasetprofile.DatasetProfileTableRequestItem; +import eu.eudat.exceptions.datasetwizard.DatasetWizardCannotUnlockException; import eu.eudat.exceptions.security.UnauthorisedException; import eu.eudat.logic.managers.DatasetManager; import eu.eudat.logic.managers.DatasetWizardManager; +import eu.eudat.logic.managers.UserManager; +import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.security.claims.ClaimedAuthorities; import eu.eudat.logic.services.ApiContext; +import eu.eudat.logic.services.forms.VisibilityRuleService; +import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; import eu.eudat.models.data.dataset.DatasetOverviewModel; import eu.eudat.models.data.datasetprofile.DatasetProfileListingModel; +import eu.eudat.models.data.datasetwizard.DataManagentPlanListingModel; +import eu.eudat.models.data.datasetwizard.DatasetWizardModel; +import eu.eudat.models.data.dmp.AssociatedProfile; import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.models.data.helpers.responses.ResponseItem; +import eu.eudat.models.data.listingmodels.DataManagementPlanOverviewModel; import eu.eudat.models.data.listingmodels.DatasetListingModel; import eu.eudat.models.data.security.Principal; +import eu.eudat.models.data.user.composite.PagedDatasetProfile; 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.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import javax.persistence.NoResultException; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.util.List; import java.util.Locale; import java.util.UUID; +import static eu.eudat.types.Authorities.ANONYMOUS; + @RestController @CrossOrigin @RequestMapping(value = {"/api/datasets/"}) public class Datasets extends BaseController { + private static final Logger logger = LoggerFactory.getLogger(Datasets.class); + private Environment environment; private DatasetManager datasetManager; + private ConfigLoader configLoader; + private UserManager userManager; @Autowired - public Datasets(ApiContext apiContext, DatasetManager datasetManager) { + public Datasets(ApiContext apiContext, Environment environment, DatasetManager datasetManager, ConfigLoader configLoader, UserManager userManager) { super(apiContext); + this.environment = environment; this.datasetManager = datasetManager; + this.configLoader = configLoader; + this.userManager = userManager; } + /* + * Data Retrieval + * */ + @RequestMapping(method = RequestMethod.POST, value = {"paged"}, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity>> getPaged(@RequestBody DatasetTableRequest datasetTableRequest, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { @@ -81,12 +120,46 @@ public class Datasets extends BaseController { // } } - @Transactional - @RequestMapping(method = RequestMethod.GET, value = {"/makepublic/{id}"}, produces = "application/json") + @javax.transaction.Transactional + @RequestMapping(method = RequestMethod.GET, value = {"{id}"}, produces = "application/json") public @ResponseBody - ResponseEntity> makePublic(@PathVariable UUID id, Principal principal, Locale locale) throws Exception { - this.datasetManager.makePublic(this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetDao(), id); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message(this.getApiContext().getHelpersService().getMessageSource().getMessage("dataset.public", new Object[]{}, locale))); + ResponseEntity getSingle(@PathVariable String id, @RequestHeader("Content-Type") String contentType, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws IllegalAccessException, IOException, InstantiationException { + try { + if (contentType.equals("application/xml")) { + VisibilityRuleService visibilityRuleService = this.getApiContext().getUtilitiesService().getVisibilityRuleService(); + return this.datasetManager.getDocument(id, visibilityRuleService, contentType, principal); + } else if (contentType.equals("application/msword")) { + FileEnvelope file = datasetManager.getWordDocumentFile(this.configLoader, id, this.getApiContext().getUtilitiesService().getVisibilityRuleService(), principal); + InputStream resource = new FileInputStream(file.getFile()); + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.setContentLength(file.getFile().length()); + responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); + responseHeaders.set("Content-Disposition", "attachment;filename=" + file.getFilename()); + responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); + responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); + + byte[] content = IOUtils.toByteArray(resource); + resource.close(); + Files.deleteIfExists(file.getFile().toPath()); + return new ResponseEntity<>(content, + responseHeaders, + HttpStatus.OK); + } else { + DatasetWizardModel dataset = this.datasetManager.getSingle(id, principal); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataset)); + } + } catch (Exception e) { + if (e instanceof UnauthorisedException) { + if (e instanceof UnauthorisedException) { + return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE)); + } else if (e instanceof NoResultException) { + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE)); + } else { + throw e; + } + } + } + return null; // ???? } @RequestMapping(method = RequestMethod.POST, value = {"/datasetProfilesUsedByDatasets/paged"}, produces = "application/json") @@ -96,6 +169,143 @@ public class Datasets extends BaseController { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(datasetProfileTableData)); } + @RequestMapping(method = RequestMethod.POST, value = {"/userDmps"}, produces = "application/json") + public @ResponseBody + ResponseEntity>> getUserDmps(@RequestBody DatasetWizardAutocompleteRequest datasetWizardAutocompleteRequest, Principal principal) throws IllegalAccessException, InstantiationException { + List dataManagementPlans = DatasetWizardManager.getUserDmps(this.getApiContext().getOperationsContext().getDatabaseRepository().getDmpDao(), datasetWizardAutocompleteRequest, principal); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlans)); + } + + @RequestMapping(method = RequestMethod.POST, value = {"/getAvailableProfiles"}, produces = "application/json") + public @ResponseBody + ResponseEntity>> getAvailableProfiles(@RequestBody DatasetProfileWizardAutocompleteRequest datasetProfileWizardAutocompleteRequest, @ClaimedAuthorities(claims = {ANONYMOUS}) Principal principal) throws IllegalAccessException, InstantiationException { + List dataManagementPlans = DatasetWizardManager.getAvailableProfiles(this.getApiContext().getOperationsContext().getDatabaseRepository().getDmpDao(), datasetProfileWizardAutocompleteRequest); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlans)); + } + + @RequestMapping(method = RequestMethod.GET, value = {"/public/{id}"}, produces = "application/json") + public @ResponseBody + ResponseEntity getSinglePublic(@PathVariable String id) throws Exception { + try { + DatasetWizardModel dataset = this.datasetManager.getSinglePublic(id); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataset)); + } + catch (Exception ex) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).message(ex.getMessage())); + } + } + + @RequestMapping(method = RequestMethod.GET, value = {"/get/{id}"}, produces = "application/json") + public ResponseEntity> getSingle(@PathVariable String id) { + eu.eudat.data.entities.DatasetProfile profile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); + eu.eudat.models.data.user.composite.DatasetProfile datasetprofile = userManager.generateDatasetProfileModel(profile); + PagedDatasetProfile pagedDatasetProfile = new PagedDatasetProfile(); + pagedDatasetProfile.buildPagedDatasetProfile(datasetprofile); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(pagedDatasetProfile)); + } + + @RequestMapping(method = RequestMethod.GET, value = {"profile/{id}"}, produces = "application/json") + public @ResponseBody + ResponseEntity getSingleProfileUpdate(@PathVariable String id, @ClaimedAuthorities(claims = {ANONYMOUS}) Principal principal) throws IllegalAccessException, IOException, InstantiationException { + DatasetWizardModel dataset = this.datasetManager.datasetUpdateProfile(id); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataset)); + } + + /* + * Data Export + * */ + + @RequestMapping(method = RequestMethod.GET, value = {"/getPDF/{id}"}) + public @ResponseBody + ResponseEntity getPDFDocument(@PathVariable String id, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws IllegalAccessException, IOException, InstantiationException, InterruptedException { + FileEnvelope file = datasetManager.getWordDocumentFile(this.configLoader, id, this.getApiContext().getUtilitiesService().getVisibilityRuleService(), principal); + String fileName = file.getFilename(); + if (fileName.endsWith(".docx")){ + fileName = fileName.substring(0, fileName.length() - 5); + } + File pdffile = datasetManager.convertToPDF(file, environment); + InputStream resource = new FileInputStream(pdffile); + + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.setContentLength(pdffile.length()); + responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); + responseHeaders.set("Content-Disposition", "attachment;filename=" + fileName + ".pdf"); + responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); + responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); + + byte[] content = IOUtils.toByteArray(resource); + resource.close(); + Files.deleteIfExists(file.getFile().toPath()); + Files.deleteIfExists(pdffile.toPath()); + return new ResponseEntity<>(content, + responseHeaders, + HttpStatus.OK); + } + + /* + * Data Management + * */ + + @javax.transaction.Transactional + @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") + public @ResponseBody + ResponseEntity> createOrUpdate(@RequestBody DatasetWizardModel profile, Principal principal) throws Exception { + this.datasetManager.createOrUpdate(profile, principal); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload(null)); + } + + @Transactional + @RequestMapping(method = RequestMethod.GET, value = {"/makepublic/{id}"}, produces = "application/json") + public @ResponseBody + ResponseEntity> makePublic(@PathVariable UUID id, Principal principal, Locale locale) throws Exception { + this.datasetManager.makePublic(this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetDao(), id); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message(this.getApiContext().getHelpersService().getMessageSource().getMessage("dataset.public", new Object[]{}, locale))); + } + + @javax.transaction.Transactional + @RequestMapping(method = RequestMethod.DELETE, value = {"/delete/{id}"}, produces = "application/json") + public @ResponseBody + ResponseEntity> delete(@PathVariable(value = "id") UUID id, Principal principal) throws Exception { + new DatasetWizardManager().delete(this.getApiContext(), id); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Deleted")); + } + + @javax.transaction.Transactional + @RequestMapping(method = RequestMethod.GET, value = {"/{id}/unlock"}, produces = "application/json") + public @ResponseBody + ResponseEntity> unlock(@PathVariable(value = "id") UUID id, Principal principal) throws Exception { + try { + new DatasetWizardManager().unlock(this.getApiContext(), id); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Unlocked")); + } catch (DatasetWizardCannotUnlockException datasetWizardCannotUnlockException) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message(datasetWizardCannotUnlockException.getMessage())); + } + } + + /* + * Data Import + * */ + + @RequestMapping(method = RequestMethod.POST, value = {"/upload"}) + public ResponseEntity datasetXmlImport(@RequestParam("file") MultipartFile file, @RequestParam("dmpId") String dmpId, @RequestParam("datasetProfileId") String datasetProfileId, Principal principal) { + try { + Dataset dataset = this.datasetManager.createDatasetFromXml(file, dmpId, datasetProfileId, principal); + if (dataset != null){ + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE)); + } + else { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).message("Import was unsuccessful.")); + } + } catch (Exception e) { + logger.error(e.getMessage(), e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).message("Import was unsuccessful.")); + } + } + + /* + * Data Index + * */ + @javax.transaction.Transactional @RequestMapping(method = RequestMethod.POST, value = {"/index"}) public @ResponseBody @@ -112,12 +322,6 @@ public class Datasets extends BaseController { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Cleared").payload(null)); } - @javax.transaction.Transactional - @RequestMapping(method = RequestMethod.DELETE, value = {"/delete/{id}"}, produces = "application/json") - public @ResponseBody - ResponseEntity> delete(@PathVariable(value = "id") UUID id, Principal principal) throws Exception { - new DatasetWizardManager().delete(this.getApiContext(), id); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Deleted")); - } + } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Login.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Login.java index d0591ded6..ff6ddfe92 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Login.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Login.java @@ -31,6 +31,7 @@ import eu.eudat.logic.services.operations.authentication.AuthenticationService; import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.models.data.login.Credentials; import eu.eudat.models.data.login.LoginInfo; +import eu.eudat.models.data.principal.PrincipalModel; import eu.eudat.models.data.security.Principal; import eu.eudat.types.ApiMessageCode; import org.slf4j.Logger; @@ -91,17 +92,17 @@ public class Login { @Transactional @RequestMapping(method = RequestMethod.POST, value = {"/externallogin"}, consumes = "application/json", produces = "application/json") public @ResponseBody - ResponseEntity> externallogin(@RequestBody LoginInfo credentials) throws GeneralSecurityException, NullEmailException { + ResponseEntity> externallogin(@RequestBody LoginInfo credentials) throws GeneralSecurityException, NullEmailException { logger.info("Trying To Login With " + credentials.getProvider()); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(customAuthenticationProvider.authenticate(credentials)).status(ApiMessageCode.SUCCESS_MESSAGE)); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(customAuthenticationProvider.authenticate(credentials)).status(ApiMessageCode.SUCCESS_MESSAGE)); } @Transactional @RequestMapping(method = RequestMethod.POST, value = {"/nativelogin"}, consumes = "application/json", produces = "application/json") public @ResponseBody - ResponseEntity> nativelogin(@RequestBody Credentials credentials) throws NullEmailException { + ResponseEntity> nativelogin(@RequestBody Credentials credentials) throws NullEmailException { logger.info(credentials.getUsername() + " Trying To Login"); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(userManager.authenticate(this.nonVerifiedUserAuthenticationService, credentials)).status(ApiMessageCode.SUCCESS_MESSAGE)); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(userManager.authenticate(this.nonVerifiedUserAuthenticationService, credentials)).status(ApiMessageCode.SUCCESS_MESSAGE)); } @RequestMapping(method = RequestMethod.GET, value = {"/twitterRequestToken"}, produces = "application/json") @@ -148,9 +149,11 @@ public class Login { @RequestMapping(method = RequestMethod.POST, value = {"/me"}, consumes = "application/json", produces = "application/json") public @ResponseBody - ResponseEntity> authMe(Principal principal) throws NullEmailException { + ResponseEntity> authMe(Principal principal) throws NullEmailException { logger.info(principal + " Getting Me"); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(this.nonVerifiedUserAuthenticationService.Touch(principal.getToken())).status(ApiMessageCode.NO_MESSAGE)); + Principal principal1 = this.nonVerifiedUserAuthenticationService.Touch(principal.getToken()); + PrincipalModel principalModel = PrincipalModel.fromEntity(principal1); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(principalModel).status(ApiMessageCode.NO_MESSAGE)); } @Transactional diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/model/models/PrincipalBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/model/models/PrincipalBuilder.java index 74ca6607b..bc5cce484 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/model/models/PrincipalBuilder.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/model/models/PrincipalBuilder.java @@ -17,6 +17,7 @@ public class PrincipalBuilder extends Builder { private UUID id; private UUID token; private String name; + private String email; private Date expiresAt; private String avatarUrl; private Set authorities; @@ -43,6 +44,11 @@ public class PrincipalBuilder extends Builder { return this; } + public PrincipalBuilder email(String email) { + this.email = email; + return this; + } + public PrincipalBuilder expiresAt(Date expiresAt) { this.expiresAt = expiresAt; return this; @@ -98,6 +104,7 @@ public class PrincipalBuilder extends Builder { Principal principal = new Principal(); principal.setAuthorities(authorities); principal.setName(name); + principal.setEmail(email); principal.setExpiresAt(expiresAt); principal.setToken(token); principal.setId(id); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java index dd47937b0..572f8e64b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java @@ -24,6 +24,7 @@ import eu.eudat.models.data.dmp.DataManagementPlan; import eu.eudat.models.data.doi.DOIRequest; import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.models.data.login.Credentials; +import eu.eudat.models.data.principal.PrincipalModel; import eu.eudat.models.data.security.Principal; import eu.eudat.models.data.userinfo.UserListingModel; import eu.eudat.models.data.userinfo.UserProfile; @@ -105,10 +106,11 @@ public class UserManager { .createOrUpdate(userInfo); } - public Principal authenticate(AuthenticationService authenticationServiceImpl, Credentials credentials) throws NullEmailException { + public PrincipalModel authenticate(AuthenticationService authenticationServiceImpl, Credentials credentials) throws NullEmailException { Principal principal = authenticationServiceImpl.Touch(credentials); if (principal == null) throw new UnauthorisedException("Could not Sign In User"); - return principal; + PrincipalModel principalModel = PrincipalModel.fromEntity(principal); + return principalModel; } public DataTableData getCollaboratorsPaged(UserInfoTableRequestItem userInfoTableRequestItem, Principal principal) throws Exception { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/CustomAuthenticationProvider.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/CustomAuthenticationProvider.java index f002d93d7..a068a5dcb 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/CustomAuthenticationProvider.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/CustomAuthenticationProvider.java @@ -4,6 +4,7 @@ import eu.eudat.exceptions.security.NonValidTokenException; import eu.eudat.exceptions.security.NullEmailException; import eu.eudat.exceptions.security.UnauthorisedException; import eu.eudat.models.data.login.LoginInfo; +import eu.eudat.models.data.principal.PrincipalModel; import eu.eudat.models.data.security.Principal; import eu.eudat.logic.security.validators.TokenValidatorFactory; import org.slf4j.Logger; @@ -22,11 +23,11 @@ public class CustomAuthenticationProvider { @Autowired private TokenValidatorFactory tokenValidatorFactory; - public Principal authenticate(LoginInfo credentials) throws GeneralSecurityException, NullEmailException { + public PrincipalModel authenticate(LoginInfo credentials) throws GeneralSecurityException, NullEmailException { String token = credentials.getTicket(); try { Principal principal = this.tokenValidatorFactory.getProvider(credentials.getProvider()).validateToken(credentials); - return principal; + return PrincipalModel.fromEntity(principal); } catch (NonValidTokenException e) { logger.error("Could not validate a user by his token! Reason: " + e.getMessage(), e); throw new UnauthorisedException("Token validation failed - Not a valid token"); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java index 4d849a51c..34fa80dc9 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java @@ -78,7 +78,9 @@ public class NonVerifiedUserEmailAuthenticationService extends AbstractAuthentic } Principal principal = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(PrincipalBuilder.class) .id(user.getId()).token(token.getToken()) - .expiresAt(token.getExpiresAt()).name(user.getName()) + .expiresAt(token.getExpiresAt()) + .name(user.getName()) + .email(user.getEmail()) .avatarUrl(avatarUrl) .culture(culture) .language(language) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java index d613b2b47..dfaca0d7a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java @@ -87,7 +87,9 @@ public class VerifiedUserAuthenticationService extends AbstractAuthenticationSer } Principal principal = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(PrincipalBuilder.class) .id(user.getId()).token(token.getToken()) - .expiresAt(token.getExpiresAt()).name(user.getName()) + .expiresAt(token.getExpiresAt()) + .name(user.getName()) + .email(user.getEmail()) .avatarUrl(avatarUrl) .culture(culture) .language(language) diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/principal/PrincipalModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/principal/PrincipalModel.java new file mode 100644 index 000000000..e5604dfb3 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/principal/PrincipalModel.java @@ -0,0 +1,131 @@ +package eu.eudat.models.data.principal; + +import eu.eudat.models.data.security.Principal; +import eu.eudat.types.Authorities; + +import java.util.Date; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +public class PrincipalModel { + private UUID id; + private UUID token; + private String name; + private String email; + private Date expiresAt; + private String avatarUrl; + private Set authorities; + private String culture; + private String language; + private String timezone; + private String zenodoEmail; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public UUID getToken() { + return token; + } + + public void setToken(UUID token) { + this.token = token; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public Date getExpiresAt() { + return expiresAt; + } + + public void setExpiresAt(Date expiresAt) { + this.expiresAt = expiresAt; + } + + public String getAvatarUrl() { + return avatarUrl; + } + + public void setAvatarUrl(String avatarUrl) { + this.avatarUrl = avatarUrl; + } + + public Set getAuthz() { + return authorities; + } + + public Set getAuthorities() { + return authorities.stream().map(authz -> authz.getValue()).collect(Collectors.toSet()); + } + + public void setAuthorities(Set authorities) { + this.authorities = authorities; + } + + public String getCulture() { + return culture; + } + + public void setCulture(String culture) { + this.culture = culture; + } + + public String getLanguage() { + return language; + } + + public void setLanguage(String language) { + this.language = language; + } + + public String getTimezone() { + return timezone; + } + + public void setTimezone(String timezone) { + this.timezone = timezone; + } + + public String getZenodoEmail() { + return zenodoEmail; + } + + public void setZenodoEmail(String zenodoEmail) { + this.zenodoEmail = zenodoEmail; + } + + public static PrincipalModel fromEntity(Principal principal) { + PrincipalModel model = new PrincipalModel(); + model.setId(principal.getId()); + model.setToken(principal.getToken()); + model.setAuthorities(principal.getAuthz()); + model.setAvatarUrl(principal.getAvatarUrl()); + model.setCulture(principal.getCulture()); + model.setEmail(principal.getEmail()); + model.setExpiresAt(principal.getExpiresAt()); + model.setLanguage(principal.getLanguage()); + model.setName(principal.getName()); + model.setTimezone(principal.getTimezone()); + model.setZenodoEmail(principal.getZenodoEmail()); + return model; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/security/Principal.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/security/Principal.java index 7f2992194..b7231ca78 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/security/Principal.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/security/Principal.java @@ -12,6 +12,7 @@ public class Principal { private UUID id; private UUID token; private String name; + private String email; private Date expiresAt; private String avatarUrl; private Set authorities; @@ -47,6 +48,14 @@ public class Principal { this.name = name; } + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + public Date getExpiresAt() { return expiresAt; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserInfo.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserInfo.java index bd757846e..5143c404b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserInfo.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserInfo.java @@ -22,7 +22,7 @@ public class UserInfo implements DataModel appRoles; public UUID getId() { @@ -69,12 +69,12 @@ public class UserListingModel implements DataModel getAppRoles() { return appRoles; @@ -92,7 +92,7 @@ public class UserListingModel implements DataModel item.getRole()).collect(Collectors.toList()); return this; } @@ -107,7 +107,7 @@ public class UserListingModel implements DataModel { + private static final Logger logger = LoggerFactory.getLogger(UserProfile.class); private UUID id; private String email; private Short usertype; private String name; private Date lastloggedin; - private String additionalinfo; + //private String additionalinfo; private List associatedDmps; + private String zenodoEmail; + private Map language; + private String timezone; + private Map culture; + private String avatarUrl; public UUID getId() { return id; @@ -63,13 +73,13 @@ public class UserProfile implements DataModel getAssociatedDmps() { return associatedDmps; @@ -79,6 +89,46 @@ public class UserProfile implements DataModel getLanguage() { + return language; + } + + public void setLanguage(Map language) { + this.language = language; + } + + public String getTimezone() { + return timezone; + } + + public void setTimezone(String timezone) { + this.timezone = timezone; + } + + public Map getCulture() { + return culture; + } + + public void setCulture(Map culture) { + this.culture = culture; + } + + public String getAvatarUrl() { + return avatarUrl; + } + + public void setAvatarUrl(String avatarUrl) { + this.avatarUrl = avatarUrl; + } + @Override public UserProfile fromDataModel(UserInfo entity) { this.id = entity.getId(); @@ -86,7 +136,17 @@ public class UserProfile implements DataModel additionalInfo = new ObjectMapper().readValue(entity.getAdditionalinfo(), HashMap.class); + this.language = (Map)additionalInfo.get("language"); + this.culture = (Map) additionalInfo.get("culture"); + this.timezone = (String) additionalInfo.get("timezone"); + this.zenodoEmail = (String) additionalInfo.get("zenodoEmail"); + this.avatarUrl = (String) additionalInfo.get("avatarUrl"); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } return this; } diff --git a/dmp-backend/web/src/main/resources/config/application-devel.properties b/dmp-backend/web/src/main/resources/config/application-devel.properties index 706a740f7..3f5eb5dfa 100644 --- a/dmp-backend/web/src/main/resources/config/application-devel.properties +++ b/dmp-backend/web/src/main/resources/config/application-devel.properties @@ -18,7 +18,7 @@ http-logger.server-address = http://localhost:31311 pdf.converter.url=http://localhost:88/ ####################CONFIGURATION FILES OVERRIDES CONFIGURATIONS########## -configuration.externalUrls=ExternalUrls.xml +configuration.externalUrls=externalUrls/ExternalUrls.xml configuration.rda=RDACommonStandards.txt configuration.h2020template=documents/h2020.docx configuration.configurable_login_providers=configurableLoginProviders.json diff --git a/dmp-frontend/src/app/app-routing.module.ts b/dmp-frontend/src/app/app-routing.module.ts index d847ca441..078f3a7bc 100644 --- a/dmp-frontend/src/app/app-routing.module.ts +++ b/dmp-frontend/src/app/app-routing.module.ts @@ -139,6 +139,14 @@ const appRoutes: Routes = [ title: 'GENERAL.TITLES.PRIVACY' } }, + { + path: 'opensource-licences', + loadChildren: () => import('./ui/sidebar/sidebar-footer/opensource-licences/opensource-licenses.module').then(m => m.OpensourceLicencesModule), + data: { + breadcrumb: true, + title: 'GENERAL.TITLES.OPENSOURCE-LICENCES' + } + }, { path: 'terms-and-conditions', loadChildren: () => import('./ui/sidebar/sidebar-footer/terms/terms.module').then(m => m.TermsModule), diff --git a/dmp-frontend/src/app/core/model/auth/principal.ts b/dmp-frontend/src/app/core/model/auth/principal.ts index e5131a436..9307d33ea 100644 --- a/dmp-frontend/src/app/core/model/auth/principal.ts +++ b/dmp-frontend/src/app/core/model/auth/principal.ts @@ -4,6 +4,7 @@ export interface Principal { id: string; token: string; name: string; + email: string; expiresAt: Date; authorities: AppRole[]; avatarUrl: string; diff --git a/dmp-frontend/src/app/core/model/dataset/dataset-overview.ts b/dmp-frontend/src/app/core/model/dataset/dataset-overview.ts index 3080a1548..3c4cdbb6d 100644 --- a/dmp-frontend/src/app/core/model/dataset/dataset-overview.ts +++ b/dmp-frontend/src/app/core/model/dataset/dataset-overview.ts @@ -5,7 +5,7 @@ import { DmpOverviewModel } from '../dmp/dmp-overview'; export interface DatasetOverviewModel { id: string; label: string; - status: any; + status: number; datasetTemplate: DatasetProfileModel; users: any[]; diff --git a/dmp-frontend/src/app/core/model/user/user-listing.ts b/dmp-frontend/src/app/core/model/user/user-listing.ts index 1abc5383b..fde223cb0 100644 --- a/dmp-frontend/src/app/core/model/user/user-listing.ts +++ b/dmp-frontend/src/app/core/model/user/user-listing.ts @@ -5,6 +5,10 @@ export interface UserListingModel { name: String; email: string; appRoles: AppRole[]; - additionalinfo: any; associatedDmps: any[]; + language: any; + culture: any; + timezone: String; + zenodoEmail: String; + avatarUrl: String; } diff --git a/dmp-frontend/src/app/core/services/dataset-wizard/dataset-wizard.service.ts b/dmp-frontend/src/app/core/services/dataset-wizard/dataset-wizard.service.ts index 3f1b65a33..4db5fc2ee 100644 --- a/dmp-frontend/src/app/core/services/dataset-wizard/dataset-wizard.service.ts +++ b/dmp-frontend/src/app/core/services/dataset-wizard/dataset-wizard.service.ts @@ -19,7 +19,7 @@ export class DatasetWizardService { private headers = new HttpHeaders(); constructor(private http: BaseHttpService, private httpClient: HttpClient, private configurationService: ConfigurationService) { - this.actionUrl = configurationService.server + 'datasetwizard/'; + this.actionUrl = configurationService.server + 'datasets/'; } // public userDmps(criteria: RequestItem): Observable { @@ -39,7 +39,7 @@ export class DatasetWizardService { } public delete(id: string): Observable { - return this.http.delete(this.actionUrl + id, { headers: this.headers }); + return this.http.delete(this.actionUrl + 'delete/' + id, { headers: this.headers }); } createDataset(datasetModel: DatasetWizardModel): Observable { diff --git a/dmp-frontend/src/app/core/services/dataset/dataset-external-autocomplete.service.ts b/dmp-frontend/src/app/core/services/dataset/dataset-external-autocomplete.service.ts index 21d3f814a..35ee12a6f 100644 --- a/dmp-frontend/src/app/core/services/dataset/dataset-external-autocomplete.service.ts +++ b/dmp-frontend/src/app/core/services/dataset/dataset-external-autocomplete.service.ts @@ -16,7 +16,7 @@ export class DatasetExternalAutocompleteService { private httpClient: HttpClient, private datasetProfileService: DatasetProfileService, private configurationService: ConfigurationService) { - this.actionUrl = configurationService.server + 'datasetwizard/'; + this.actionUrl = configurationService.server + 'datasets/'; } getDatasetProfileById(datasetProfileID) { diff --git a/dmp-frontend/src/app/core/services/dataset/dataset.service.ts b/dmp-frontend/src/app/core/services/dataset/dataset.service.ts index e7306d139..b56e3b19c 100644 --- a/dmp-frontend/src/app/core/services/dataset/dataset.service.ts +++ b/dmp-frontend/src/app/core/services/dataset/dataset.service.ts @@ -90,7 +90,8 @@ export class DatasetService { return this.httpClient.get(this.actionUrl + 'getPDF/' + id, { responseType: 'blob', observe: 'response', headers: headerPdf }); } - public downloadJson(id: string): Observable> { - return this.httpClient.get(this.actionUrl + 'rda/' + id, { responseType: 'blob', observe: 'response' }); - } + //GK: NO + // public downloadJson(id: string): Observable> { + // return this.httpClient.get(this.actionUrl + 'rda/' + id, { responseType: 'blob', observe: 'response' }); + // } } diff --git a/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.html b/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.html index 26ed8b1a1..e5664fe44 100644 --- a/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.html +++ b/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.html @@ -12,8 +12,8 @@

{{ dataset.label }}

-
-

+

+

{{ roleDisplayFromList(dataset.users) }}

@@ -33,12 +33,12 @@ lock_outline {{'DMP-OVERVIEW.LOCKED' | translate}}
-
{{'GENERAL.STATUSES.EDIT' | translate}} : +
{{'GENERAL.STATUSES.EDIT' | translate}} : {{dataset.modified | date:"longDate"}}
- check + check {{'TYPES.DATASET-STATUS.FINALISED' | translate}}
@@ -49,12 +49,12 @@ matTooltipPosition="above"> content_copy - -
- +
+
+ +

{{ 'DMP-LISTING.ACTIONS.MAKE-PUBLIC' | translate }}

+
-
diff --git a/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.scss b/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.scss index 6ab4cd95a..d3d816948 100644 --- a/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.scss +++ b/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.scss @@ -29,6 +29,10 @@ color: #A7A7A7; } +.check-icon { + font-weight: bold; +} + .account-icon { font-size: 2.5em; } @@ -52,7 +56,7 @@ .dmp-btn { width: 35em; - height: 2.3em; + min-height: 2.3em; background-color: #129D99; border-radius: 4px; flex-direction: row; @@ -76,15 +80,15 @@ .frame-btn { border: 1px solid #212121; color: black; + background: #FFFFFF; } .finalize-btn { - border: 1px solid #129D99; - color: #129D99; + border: 1px solid #F7DD72; + background: #F5DB71; } .frame-btn, .finalize-btn { - background: #FFFFFF; box-shadow: 0px 2px 6px #00000029; } @@ -177,6 +181,7 @@ overflow: hidden; color: #FFFFFF; opacity: 0.8; + text-align: left; } .doi-label { @@ -221,10 +226,6 @@ color: #000000; } -.finalize-txt { - color: #129D99; -} - .frame-txt, .finalize-txt { font-size: 0.75em; font-weight: bold; diff --git a/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.ts b/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.ts index 602fb0e0f..de0678940 100644 --- a/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.ts +++ b/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.ts @@ -28,6 +28,9 @@ import { DatasetCopyDialogueComponent } from '../dataset-wizard/dataset-copy-dia import { DmpService } from '@app/core/services/dmp/dmp.service'; import { ResearcherModel } from '@app/core/model/researcher/researcher'; import { LockService } from '@app/core/services/lock/lock.service'; +import { DatasetsToBeFinalized } from '@app/core/model/dataset/datasets-toBeFinalized'; +import { DatasetModel } from '@app/core/model/dataset/dataset'; +import { DatasetWizardModel } from '@app/core/model/dataset/dataset-wizard'; @Component({ @@ -38,7 +41,8 @@ import { LockService } from '@app/core/services/lock/lock.service'; export class DatasetOverviewComponent extends BaseComponent implements OnInit { dataset: DatasetOverviewModel; - datasetWizardModel: DatasetWizardEditorModel; + datasetWizardEditorModel: DatasetWizardEditorModel; + datasetWizardModel: DatasetWizardModel; isNew = true; isFinalized = false; isPublicView = true; @@ -87,10 +91,7 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { this.dataset = data; this.getDmpResearchers(); this.getDmpUsers(); - this.datasetWizardService.getSingle(this.dataset.id).pipe(takeUntil(this._destroyed)) - .subscribe(data => { - this.datasetWizardModel = new DatasetWizardEditorModel().fromModel(data); - }); + this.getDatasetWizardModel(this.dataset.id); this.checkLockStatus(this.dataset.id); this.setIsUserOwner(); const breadCrumbs = []; @@ -116,10 +117,7 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { this.dataset = data; this.getDmpResearchers(); this.getDmpUsers(); - this.datasetWizardService.getSingle(this.dataset.id).pipe(takeUntil(this._destroyed)) - .subscribe(data => { - this.datasetWizardModel = new DatasetWizardEditorModel().fromModel(data); - }); + this.getDatasetWizardModel(this.dataset.id); this.checkLockStatus(this.dataset.id); this.setIsUserOwner(); const breadCrumbs = []; @@ -138,6 +136,14 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { }); } + getDatasetWizardModel(id: string) { + this.datasetWizardService.getSingle(id).pipe(takeUntil(this._destroyed)) + .subscribe(data => { + this.datasetWizardEditorModel = new DatasetWizardEditorModel().fromModel(data); + this.datasetWizardModel = data; + }); + } + checkLockStatus(id: string) { this.lockService.checkLockStatus(id).pipe(takeUntil(this._destroyed)) .subscribe(lockStatus => this.lockStatus = lockStatus); @@ -278,8 +284,7 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { .pipe(takeUntil(this._destroyed)) .subscribe( complete => { - this.onCallbackSuccess(); - this.router.navigate(['/datasets']); + this.onDeleteCallbackSuccess(); }, error => this.onDeleteCallbackError(error) ); @@ -291,23 +296,33 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { this.router.navigate(['/plans/overview/' + dmpId]); } - onCallbackSuccess(): void { - this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); + onDeleteCallbackSuccess(): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Success); + this.router.navigate(['/datasets']); + } + + onUpdateCallbackSuccess(): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); + this.reloadPage(); } onDeleteCallbackError(error) { this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error); } + onUpdateCallbackError(error) { + this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('DATASET-UPLOAD.SNACK-BAR.UNSUCCESSFUL'), SnackBarNotificationLevel.Error); + } + public getOrcidPath(): string { return this.configurationService.orcidPath; } getOrcidPathForResearcher(reference: string): string { - const path = this.getOrcidPath(); - const userId = reference.split(':')[1]; - return path + userId; - } + const path = this.getOrcidPath(); + const userId = reference.split(':')[1]; + return path + userId; + } downloadPDF(id: string) { this.datasetService.downloadPDF(id) @@ -342,15 +357,16 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { }); } - downloadJson(id: string) { - this.datasetService.downloadJson(id) - .pipe(takeUntil(this._destroyed)) - .subscribe(response => { - const blob = new Blob([response.body], { type: 'application/json' }); - const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); - FileSaver.saveAs(blob, filename); - }) - } + //GK: NO +// downloadJson(id: string) { +// this.datasetService.downloadJson(id) +// .pipe(takeUntil(this._destroyed)) +// .subscribe(response => { +// const blob = new Blob([response.body], { type: 'application/json' }); +// const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); +// FileSaver.saveAs(blob, filename); +// }) +// } getFilenameFromContentDispositionHeader(header: string): string { const regex: RegExp = new RegExp(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/g); @@ -378,7 +394,7 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { data: { formControl: formControl, datasetId: this.dataset.id, - datasetProfileId: this.datasetWizardModel.profile, + datasetProfileId: this.datasetWizardEditorModel.profile, datasetProfileExist: false, confirmButton: this.language.instant('DATASET-WIZARD.DIALOGUE.COPY'), cancelButton: this.language.instant('DATASET-WIZARD.DIALOGUE.CANCEL') @@ -398,10 +414,9 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { return this.dmpService.updateUsers(this.dataset.dmp.id, this.users).pipe(takeUntil(this._destroyed)) .subscribe( complete => { - this.onCallbackSuccess(); - this.reloadPage(); + this.onUpdateCallbackSuccess(); }, - error => this.onDeleteCallbackError(error) + error => this.onUpdateCallbackError(error) ); } @@ -418,12 +433,63 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { if (result) { const index = this.users.findIndex(x => x.id === user.id); if (index > -1) { - this.users.splice(index, 1); + this.users.splice(index, 1); } this.updateUsers(); } }); } + showPublishButton(dataset: DatasetOverviewModel) { + return this.isFinalizedDataset(dataset) && !dataset.public && this.hasPublishButton; + } + + publish(id: String) { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '500px', + restoreFocus: false, + data: { + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.PUBLISH-ITEM'), + privacyPolicyNames: this.language.instant('GENERAL.CONFIRMATION-DIALOG.PRIVACY-POLICY-NAMES'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), + isDeleteConfirmation: false + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + this.datasetService.publish(id) + .pipe(takeUntil(this._destroyed)) + .subscribe(() => { + this.hasPublishButton = false; + this.reloadPage(); + }); + } + }); + } + + finalize(dataset: DatasetOverviewModel) { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + restoreFocus: false, + data: { + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.FINALIZE-ITEM'), + confirmButton: this.language.instant('QUICKWIZARD.SAVE-DIALOG.ACTIONS.AFFIRMATIVE'), + cancelButton: this.language.instant('QUICKWIZARD.SAVE-DIALOG.ACTIONS.NEGATIVE'), + isDeleteConfirmation: false + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + this.getDatasetWizardModel(this.dataset.id); + this.datasetWizardModel.status = DatasetStatus.Finalized; + this.datasetWizardService.createDataset(this.datasetWizardModel) + .pipe(takeUntil(this._destroyed)) + .subscribe( + data => this.onUpdateCallbackSuccess(), + error => this.onUpdateCallbackError(error) + ); + } + }); + } } diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html index 24337384c..89f80ea81 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html @@ -54,7 +54,7 @@ -
@@ -132,7 +132,7 @@
-
+
@@ -145,7 +145,7 @@

{{ 'DMP-LISTING.ACTIONS.EXPORT' | translate }}

-
+
diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss index 1923ad102..f68c825f8 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss @@ -30,14 +30,6 @@ // ********BUTTONS******** -.version-btn { - // width: 6.7em; - height: 1.8em; - border: 1px solid #707070; - border-radius: 4px; - background-color: transparent; -} - .id-btn { background: url("../../../../assets/images/NoPath.png") no-repeat center; width: 1em; @@ -194,7 +186,7 @@ } .doi-txt { - font-size: 0.8em; + font-size: 1em; letter-spacing: 0.009em; color: #7d7d7d; width: 12em; @@ -202,6 +194,7 @@ overflow: hidden; border: none; padding: 0px; + background-color: transparent; } .doi-panel { @@ -303,6 +296,17 @@ ::ng-deep .versions-select .mat-form-field-wrapper { background-color: transparent !important; padding-bottom: 0 !important; + width: 6.5rem; +} + +::ng-deep .versions-select .mat-form-field-wrapper .mat-form-field-flex { + padding: 0 0.5rem 0 0.625rem; + margin-bottom: 0.2rem; + font-weight: 500; +} + +::ng-deep mat-select .mat-select-arrow-wrapper { + vertical-align: bottom; } ::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix { diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts index ab89088c8..506537218 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts @@ -478,7 +478,10 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { if (result) { this.dmpService.publish(dmpId) .pipe(takeUntil(this._destroyed)) - .subscribe(() => { this.hasPublishButton = false }); + .subscribe(() => { + this.hasPublishButton = false; + this.reloadPage(); + }); } }); } diff --git a/dmp-frontend/src/app/ui/misc/navigation/user-dialog/user-dialog.component.html b/dmp-frontend/src/app/ui/misc/navigation/user-dialog/user-dialog.component.html index 689af7f41..f9aa116ea 100644 --- a/dmp-frontend/src/app/ui/misc/navigation/user-dialog/user-dialog.component.html +++ b/dmp-frontend/src/app/ui/misc/navigation/user-dialog/user-dialog.component.html @@ -3,8 +3,8 @@ @@ -67,7 +68,7 @@
Contact us to learn more
-
+
* Required fields
@@ -104,7 +105,7 @@
-
@@ -124,15 +125,16 @@
Unless otherwise indicated, all materials created by OpenAIRE are licenced under
  - +
diff --git a/dmp-frontend/src/assets/splash/css/footer.css b/dmp-frontend/src/assets/splash/css/footer.css index 28cf11a9f..9a8a5b312 100644 --- a/dmp-frontend/src/assets/splash/css/footer.css +++ b/dmp-frontend/src/assets/splash/css/footer.css @@ -41,7 +41,7 @@ .conditions-policy { text-align: left; - text-decoration: underline; + text-decoration: underline !important; font-weight: 400; font-family: 'Roboto',sans-serif; font-size: 1rem; diff --git a/dmp-frontend/src/assets/splash/css/section.css b/dmp-frontend/src/assets/splash/css/section.css index 0f0ab10fc..f43025fb5 100644 --- a/dmp-frontend/src/assets/splash/css/section.css +++ b/dmp-frontend/src/assets/splash/css/section.css @@ -124,6 +124,7 @@ section.benefits { box-shadow: 0px 6px 15px #0000001A; border-radius: 36px; opacity: 1; + margin-bottom: 0.5rem; } .benefit-card-title { @@ -216,6 +217,12 @@ section.benefits { padding: 2rem 0rem; } +.list { + font-size: 0.87rem; + color: #212121; + opacity: 0.8; +} + section.media-kit-logo { background: #F3F3F3; opacity: 1; diff --git a/dmp-frontend/src/assets/splash/css/styles.css b/dmp-frontend/src/assets/splash/css/styles.css index 5bfb49ccf..02cacc8d5 100644 --- a/dmp-frontend/src/assets/splash/css/styles.css +++ b/dmp-frontend/src/assets/splash/css/styles.css @@ -130,30 +130,30 @@ p a { } .title-1 { - text-align: left; - font-size: 2.37rem; line-height: 2.75rem; - font-family: 'Roboto', sans-serif; font-weight: 300; color: #FFFFFF; } .title-2 { - text-align: left; - font-size: 2.37rem; line-height: 2.75rem; - font-family: 'Roboto', sans-serif; font-weight: 700; color: #FFFFFF; } .title-3 { + opacity: 0.95; +} + +.title-3, .title-4 { + font-weight: 300; + color: #212121; +} + +.title-1, .title-2, .title-3, .title-4 { text-align: left; font-size: 2.37rem; font-family: 'Roboto', sans-serif; - font-weight: 300; - color: #212121; - opacity: 0.95; } .page-title { @@ -323,3 +323,41 @@ hr { max-width: 900px; } } + +.card { + min-height: 14rem; + margin-bottom: 1.875rem; + box-shadow: 0px 3px 6px #00000029; +} + +.card-img { + transform: scale(0.5); +} + +.card-body { + display: flex; + flex-direction: column; + align-items: left; + justify-content: center; + padding: 1rem 1.25rem !important; +} + +.card-text-1 { + font-size: 1.125rem; + font-weight: bold; + text-transform: uppercase; +} + +.card-text-2 { + font-size: 1rem; + font-weight: 400; + opacity: 0.6; +} + +.flag { + border: 10px solid #EEEEEE; + border-radius: 50% !important; + padding-right: 0px !important; + padding-left: 0px !important; + transform: scale(0.45); +} diff --git a/dmp-frontend/src/assets/splash/index.html b/dmp-frontend/src/assets/splash/index.html index 626561f25..b5df09f6f 100644 --- a/dmp-frontend/src/assets/splash/index.html +++ b/dmp-frontend/src/assets/splash/index.html @@ -36,6 +36,7 @@ How it works Roadmap faqs + Contributors
@@ -350,7 +351,7 @@
-
@@ -371,15 +372,16 @@
Unless otherwise indicated, all materials created by OpenAIRE are licenced under
  - +
diff --git a/dmp-frontend/src/assets/splash/resources/co-branding.html b/dmp-frontend/src/assets/splash/resources/co-branding.html index ba37601ad..e3a8c5269 100644 --- a/dmp-frontend/src/assets/splash/resources/co-branding.html +++ b/dmp-frontend/src/assets/splash/resources/co-branding.html @@ -9,14 +9,17 @@ - + - + @@ -24,7 +27,9 @@