diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserInfo.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserInfo.java index a2451c3e5..da52ab2eb 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserInfo.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserInfo.java @@ -165,6 +165,14 @@ public class UserInfo implements DataEntity { this.userRoles = userRoles; } + public Set getLocks() { + return locks; + } + + public void setLocks(Set locks) { + this.locks = locks; + } + @Override public void update(UserInfo entity) { this.name = entity.getName(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index d4aef39e0..f4ac98b30 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -481,6 +481,9 @@ public class DataManagementPlanManager { if (!isUserOwnerOfDmp(dmp1, principal)) { throw new Exception("User not being the creator is not authorized to edit this DMP."); } + if (dmp1.getModified().getTime() != dataManagementPlan.getModified().getTime()) { + throw new Exception("Another user have already edit that DMP."); + } List datasetList = new ArrayList<>(dmp1.getDataset()); for (Dataset dataset : datasetList) { if (dataManagementPlan.getProfiles().stream().filter(associatedProfile -> dataset.getProfile().getId().equals(associatedProfile.getId())).findAny().orElse(null) == null) @@ -573,7 +576,7 @@ public class DataManagementPlanManager { UserDMP userDMP = new UserDMP(); userDMP.setDmp(dmp); userDMP.setUser(userInfo); - userDMP.setRole(UserDMP.UserDMPRoles.OWNER.getValue()); + userDMP.setRole(UserDMP.UserDMPRoles.CREATOR.getValue()); databaseRepository.getUserDmpDao().createOrUpdate(userDMP); } @@ -1175,7 +1178,7 @@ public class DataManagementPlanManager { } private boolean isUserOwnerOfDmp(DMP dmp, Principal principal) { - return (dmp.getUsers().stream().filter(userDMP -> userDMP.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue())).findFirst().get().getUser().getId()).equals(principal.getId()); + return (dmp.getUsers().stream().filter(userDMP -> userDMP.getRole().equals(UserDMP.UserDMPRoles.CREATOR.getValue()) || userDMP.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue())).findFirst().get().getUser().getId()).equals(principal.getId()); } public String createZenodoDoi(UUID id, Principal principal, ConfigLoader configLoader) throws Exception { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java index ee76ea42c..bf4b7b7a8 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java @@ -401,6 +401,12 @@ public class DatasetManager { public eu.eudat.data.entities.Dataset createOrUpdate(DatasetWizardModel datasetWizardModel, Principal principal) throws Exception { DMP dmp = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().find(datasetWizardModel.getDmp().getId()); + Dataset tempDataset = apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao().find(datasetWizardModel.getId()); + if (tempDataset != null) { + if (datasetWizardModel.getModified().getTime() != tempDataset.getModified().getTime()) { + throw new Exception("Dataset has been modified already by another user."); + } + } if (dmp.getStatus().equals(DMP.DMPStatus.FINALISED.getValue()) && datasetWizardModel.getId() != null) throw new Exception("DMP is finalized, therefore Dataset cannot be edited."); eu.eudat.data.entities.Dataset dataset = datasetWizardModel.toDataModel(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetwizard/DatasetWizardModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetwizard/DatasetWizardModel.java index 39eb11553..8e967a1cc 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetwizard/DatasetWizardModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetwizard/DatasetWizardModel.java @@ -34,6 +34,7 @@ public class DatasetWizardModel implements DataModel externalDatasets; private UUID profile; private Boolean isProfileLatestVersion; + private Date modified; public UUID getId() { return id; @@ -147,6 +148,13 @@ public class DatasetWizardModel implements DataModel; + modified: Date; } diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard-editor.model.ts b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard-editor.model.ts index 341e5e2bb..e26947c50 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard-editor.model.ts +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard-editor.model.ts @@ -29,6 +29,7 @@ export class DatasetWizardEditorModel { public datasetProfileDefinition: DatasetDescriptionFormEditorModel; public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); public isProfileLatestVersion: Boolean; + public modified: Date; fromModel(item: DatasetWizardModel): DatasetWizardEditorModel { this.id = item.id; @@ -45,6 +46,7 @@ export class DatasetWizardEditorModel { if (item.datasetProfileDefinition) { this.datasetProfileDefinition = new DatasetDescriptionFormEditorModel().fromModel(item.datasetProfileDefinition); } if (item.tags) { this.tags = item.tags.map(x => new ExternalTagEditorModel().fromModel(x)); } this.isProfileLatestVersion = item.isProfileLatestVersion; + this.modified = new Date(item.modified); return this; } @@ -64,6 +66,7 @@ export class DatasetWizardEditorModel { //dataRepositories: [{ value: this.dataRepositories, disabled: disabled }, context.getValidation('dataRepositories').validators], //services: [{ value: this.services, disabled: disabled }, context.getValidation('services').validators], profile: [{ value: this.profile, disabled: disabled }, context.getValidation('profile').validators], + modified: [{value: this.modified, disabled: disabled}, context.getValidation('modified').validators] }); const externalDatasetsFormArray = new Array(); @@ -142,6 +145,7 @@ export class DatasetWizardEditorModel { baseContext.validation.push({ key: 'dmp', validators: [BackendErrorValidator(this.validationErrorModel, 'dmp')] }); baseContext.validation.push({ key: 'datasetProfileDefinition', validators: [BackendErrorValidator(this.validationErrorModel, 'datasetProfileDefinition')] }); baseContext.validation.push({ key: 'tags', validators: [BackendErrorValidator(this.validationErrorModel, 'datasetProfileDefinition')] }); + baseContext.validation.push({ key: 'modified', validators: [Validators.required]}); return baseContext; } } diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.model.ts b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.model.ts index 372ca7250..fc48cec5a 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.model.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.model.ts @@ -44,6 +44,7 @@ export class DmpEditorModel { public definition: DmpProfileDefinition; public dynamicFields: Array = []; public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); + public modified: Date; fromModel(item: DmpModel): DmpEditorModel { this.id = item.id; @@ -67,6 +68,7 @@ export class DmpEditorModel { if (item.definition) { this.definition = item.definition; } if (item.dynamicFields) { item.dynamicFields.map(x => this.dynamicFields.push(new DmpDynamicFieldEditorModel().fromModel(x))); } this.creator = item.creator; + this.modified = new Date(item.modified); return this; } @@ -90,7 +92,8 @@ export class DmpEditorModel { datasets: [{ value: this.datasets, disabled: disabled }, context.getValidation('datasets').validators], datasetsToBeFinalized: [{ value: this.datasetsToBeFinalized, disabled: disabled }, context.getValidation('datasetsToBeFinalized').validators], associatedUsers: [{ value: this.associatedUsers, disabled: disabled }, context.getValidation('associatedUsers').validators], - users: [{ value: this.users, disabled: disabled }, context.getValidation('users').validators] + users: [{ value: this.users, disabled: disabled }, context.getValidation('users').validators], + modified: [{value: this.modified, disabled: disabled}, context.getValidation('modified').validators] }); const dynamicFields = new Array(); @@ -128,7 +131,7 @@ export class DmpEditorModel { baseContext.validation.push({ key: 'datasetsToBeFinalized', validators: [BackendErrorValidator(this.validationErrorModel, 'datasetsToBeFinalized')] }); baseContext.validation.push({ key: 'associatedUsers', validators: [BackendErrorValidator(this.validationErrorModel, 'associatedUsers')] }); baseContext.validation.push({ key: 'users', validators: [BackendErrorValidator(this.validationErrorModel, 'users')] }); - + baseContext.validation.push({ key: 'modified', validators: [Validators.required] }); return baseContext; } }