Add additional checkups when editing DMPs and Datasets in order to ensure that no other user has edit them. (ref #240)

This commit is contained in:
George Kalampokis 2020-02-10 18:21:06 +02:00
parent c515d3ddf6
commit 4e5a48e6c4
8 changed files with 39 additions and 4 deletions

View File

@ -165,6 +165,14 @@ public class UserInfo implements DataEntity<UserInfo, UUID> {
this.userRoles = userRoles; this.userRoles = userRoles;
} }
public Set<Lock> getLocks() {
return locks;
}
public void setLocks(Set<Lock> locks) {
this.locks = locks;
}
@Override @Override
public void update(UserInfo entity) { public void update(UserInfo entity) {
this.name = entity.getName(); this.name = entity.getName();

View File

@ -481,6 +481,9 @@ public class DataManagementPlanManager {
if (!isUserOwnerOfDmp(dmp1, principal)) { if (!isUserOwnerOfDmp(dmp1, principal)) {
throw new Exception("User not being the creator is not authorized to edit this DMP."); 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<Dataset> datasetList = new ArrayList<>(dmp1.getDataset()); List<Dataset> datasetList = new ArrayList<>(dmp1.getDataset());
for (Dataset dataset : datasetList) { for (Dataset dataset : datasetList) {
if (dataManagementPlan.getProfiles().stream().filter(associatedProfile -> dataset.getProfile().getId().equals(associatedProfile.getId())).findAny().orElse(null) == null) 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 userDMP = new UserDMP();
userDMP.setDmp(dmp); userDMP.setDmp(dmp);
userDMP.setUser(userInfo); userDMP.setUser(userInfo);
userDMP.setRole(UserDMP.UserDMPRoles.OWNER.getValue()); userDMP.setRole(UserDMP.UserDMPRoles.CREATOR.getValue());
databaseRepository.getUserDmpDao().createOrUpdate(userDMP); databaseRepository.getUserDmpDao().createOrUpdate(userDMP);
} }
@ -1175,7 +1178,7 @@ public class DataManagementPlanManager {
} }
private boolean isUserOwnerOfDmp(DMP dmp, Principal principal) { 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 { public String createZenodoDoi(UUID id, Principal principal, ConfigLoader configLoader) throws Exception {

View File

@ -401,6 +401,12 @@ public class DatasetManager {
public eu.eudat.data.entities.Dataset createOrUpdate(DatasetWizardModel datasetWizardModel, Principal principal) throws Exception { public eu.eudat.data.entities.Dataset createOrUpdate(DatasetWizardModel datasetWizardModel, Principal principal) throws Exception {
DMP dmp = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().find(datasetWizardModel.getDmp().getId()); 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) if (dmp.getStatus().equals(DMP.DMPStatus.FINALISED.getValue()) && datasetWizardModel.getId() != null)
throw new Exception("DMP is finalized, therefore Dataset cannot be edited."); throw new Exception("DMP is finalized, therefore Dataset cannot be edited.");
eu.eudat.data.entities.Dataset dataset = datasetWizardModel.toDataModel(); eu.eudat.data.entities.Dataset dataset = datasetWizardModel.toDataModel();

View File

@ -34,6 +34,7 @@ public class DatasetWizardModel implements DataModel<Dataset, DatasetWizardModel
private List<ExternalDatasetListingModel> externalDatasets; private List<ExternalDatasetListingModel> externalDatasets;
private UUID profile; private UUID profile;
private Boolean isProfileLatestVersion; private Boolean isProfileLatestVersion;
private Date modified;
public UUID getId() { public UUID getId() {
return id; return id;
@ -147,6 +148,13 @@ public class DatasetWizardModel implements DataModel<Dataset, DatasetWizardModel
isProfileLatestVersion = profileLatestVersion; isProfileLatestVersion = profileLatestVersion;
} }
public Date getModified() {
return modified;
}
public void setModified(Date modified) {
this.modified = modified;
}
@Override @Override
public DatasetWizardModel fromDataModel(Dataset entity) { public DatasetWizardModel fromDataModel(Dataset entity) {
this.id = entity.getId(); this.id = entity.getId();
@ -179,6 +187,7 @@ public class DatasetWizardModel implements DataModel<Dataset, DatasetWizardModel
} }
return externalDatasetListingModel; return externalDatasetListingModel;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
this.modified = entity.getModified();
return this; return this;
} }

View File

@ -22,4 +22,5 @@ export interface DatasetWizardModel {
externalDatasets?: ExternalDatasetModel[]; externalDatasets?: ExternalDatasetModel[];
profile?: DatasetProfileModel; profile?: DatasetProfileModel;
isProfileLatestVersion?: Boolean; isProfileLatestVersion?: Boolean;
modified?: Date;
} }

View File

@ -33,4 +33,5 @@ export interface DmpModel {
creator: UserModel; creator: UserModel;
definition: DmpProfileDefinition; definition: DmpProfileDefinition;
dynamicFields: Array<DmpDynamicField>; dynamicFields: Array<DmpDynamicField>;
modified: Date;
} }

View File

@ -29,6 +29,7 @@ export class DatasetWizardEditorModel {
public datasetProfileDefinition: DatasetDescriptionFormEditorModel; public datasetProfileDefinition: DatasetDescriptionFormEditorModel;
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); public validationErrorModel: ValidationErrorModel = new ValidationErrorModel();
public isProfileLatestVersion: Boolean; public isProfileLatestVersion: Boolean;
public modified: Date;
fromModel(item: DatasetWizardModel): DatasetWizardEditorModel { fromModel(item: DatasetWizardModel): DatasetWizardEditorModel {
this.id = item.id; this.id = item.id;
@ -45,6 +46,7 @@ export class DatasetWizardEditorModel {
if (item.datasetProfileDefinition) { this.datasetProfileDefinition = new DatasetDescriptionFormEditorModel().fromModel(item.datasetProfileDefinition); } if (item.datasetProfileDefinition) { this.datasetProfileDefinition = new DatasetDescriptionFormEditorModel().fromModel(item.datasetProfileDefinition); }
if (item.tags) { this.tags = item.tags.map(x => new ExternalTagEditorModel().fromModel(x)); } if (item.tags) { this.tags = item.tags.map(x => new ExternalTagEditorModel().fromModel(x)); }
this.isProfileLatestVersion = item.isProfileLatestVersion; this.isProfileLatestVersion = item.isProfileLatestVersion;
this.modified = new Date(item.modified);
return this; return this;
} }
@ -64,6 +66,7 @@ export class DatasetWizardEditorModel {
//dataRepositories: [{ value: this.dataRepositories, disabled: disabled }, context.getValidation('dataRepositories').validators], //dataRepositories: [{ value: this.dataRepositories, disabled: disabled }, context.getValidation('dataRepositories').validators],
//services: [{ value: this.services, disabled: disabled }, context.getValidation('services').validators], //services: [{ value: this.services, disabled: disabled }, context.getValidation('services').validators],
profile: [{ value: this.profile, disabled: disabled }, context.getValidation('profile').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<FormGroup>(); const externalDatasetsFormArray = new Array<FormGroup>();
@ -142,6 +145,7 @@ export class DatasetWizardEditorModel {
baseContext.validation.push({ key: 'dmp', validators: [BackendErrorValidator(this.validationErrorModel, 'dmp')] }); baseContext.validation.push({ key: 'dmp', validators: [BackendErrorValidator(this.validationErrorModel, 'dmp')] });
baseContext.validation.push({ key: 'datasetProfileDefinition', validators: [BackendErrorValidator(this.validationErrorModel, 'datasetProfileDefinition')] }); baseContext.validation.push({ key: 'datasetProfileDefinition', validators: [BackendErrorValidator(this.validationErrorModel, 'datasetProfileDefinition')] });
baseContext.validation.push({ key: 'tags', 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; return baseContext;
} }
} }

View File

@ -44,6 +44,7 @@ export class DmpEditorModel {
public definition: DmpProfileDefinition; public definition: DmpProfileDefinition;
public dynamicFields: Array<DmpDynamicFieldEditorModel> = []; public dynamicFields: Array<DmpDynamicFieldEditorModel> = [];
public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); public validationErrorModel: ValidationErrorModel = new ValidationErrorModel();
public modified: Date;
fromModel(item: DmpModel): DmpEditorModel { fromModel(item: DmpModel): DmpEditorModel {
this.id = item.id; this.id = item.id;
@ -67,6 +68,7 @@ export class DmpEditorModel {
if (item.definition) { this.definition = item.definition; } if (item.definition) { this.definition = item.definition; }
if (item.dynamicFields) { item.dynamicFields.map(x => this.dynamicFields.push(new DmpDynamicFieldEditorModel().fromModel(x))); } if (item.dynamicFields) { item.dynamicFields.map(x => this.dynamicFields.push(new DmpDynamicFieldEditorModel().fromModel(x))); }
this.creator = item.creator; this.creator = item.creator;
this.modified = new Date(item.modified);
return this; return this;
} }
@ -90,7 +92,8 @@ export class DmpEditorModel {
datasets: [{ value: this.datasets, disabled: disabled }, context.getValidation('datasets').validators], datasets: [{ value: this.datasets, disabled: disabled }, context.getValidation('datasets').validators],
datasetsToBeFinalized: [{ value: this.datasetsToBeFinalized, disabled: disabled }, context.getValidation('datasetsToBeFinalized').validators], datasetsToBeFinalized: [{ value: this.datasetsToBeFinalized, disabled: disabled }, context.getValidation('datasetsToBeFinalized').validators],
associatedUsers: [{ value: this.associatedUsers, disabled: disabled }, context.getValidation('associatedUsers').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<FormGroup>(); const dynamicFields = new Array<FormGroup>();
@ -128,7 +131,7 @@ export class DmpEditorModel {
baseContext.validation.push({ key: 'datasetsToBeFinalized', validators: [BackendErrorValidator(this.validationErrorModel, 'datasetsToBeFinalized')] }); baseContext.validation.push({ key: 'datasetsToBeFinalized', validators: [BackendErrorValidator(this.validationErrorModel, 'datasetsToBeFinalized')] });
baseContext.validation.push({ key: 'associatedUsers', validators: [BackendErrorValidator(this.validationErrorModel, 'associatedUsers')] }); baseContext.validation.push({ key: 'associatedUsers', validators: [BackendErrorValidator(this.validationErrorModel, 'associatedUsers')] });
baseContext.validation.push({ key: 'users', validators: [BackendErrorValidator(this.validationErrorModel, 'users')] }); baseContext.validation.push({ key: 'users', validators: [BackendErrorValidator(this.validationErrorModel, 'users')] });
baseContext.validation.push({ key: 'modified', validators: [Validators.required] });
return baseContext; return baseContext;
} }
} }