From 4da8c2a6a9a889cd35ad9fbcbed9dc26a9b07cd6 Mon Sep 17 00:00:00 2001 From: sgiannopoulos Date: Mon, 15 Jan 2024 13:57:33 +0200 Subject: [PATCH] merge remove credential changes --- dmp-backend/core/pom.xml | 5 + ...va => MergeAccountConfirmationEntity.java} | 4 +- .../RemoveCredentialConfirmationEntity.java | 24 ++ .../commons/validation/BaseValidator.java | 5 + .../eu/eudat/model/ActionConfirmation.java | 11 - .../builder/ActionConfirmationBuilder.java | 5 +- .../EmailConfirmationBuilder.java | 8 +- .../deleter/UserSettingsSettingsDeleter.java | 68 +++++ .../persist/ActionConfirmationPersist.java | 81 +++--- .../RemoveCredentialRequestPersist.java | 60 +++++ .../persist/UserMergeRequestPersist.java | 65 +++++ .../model/persist/UserRequestPersist.java | 78 ------ ...a => MergeAccountConfirmationPersist.java} | 21 +- .../eudat/query/ActionConfirmationQuery.java | 2 +- .../java/eu/eudat/query/DescriptionQuery.java | 25 +- .../main/java/eu/eudat/query/DmpQuery.java | 24 +- .../main/java/eu/eudat/query/LockQuery.java | 24 +- .../java/eu/eudat/query/StorageFileQuery.java | 23 ++ .../ActionConfirmationService.java | 3 +- .../ActionConfirmationServiceImpl.java | 54 ++-- .../eu/eudat/service/dmp/DmpServiceImpl.java | 1 - .../eu/eudat/service/user/UserService.java | 9 +- .../eudat/service/user/UserServiceImpl.java | 245 ++++++++++++++---- .../configurations/JacksonConfiguration.java | 30 --- .../eudat/controllers/v2/UserController.java | 29 +-- .../src/main/resources/config/permissions.yml | 7 +- 26 files changed, 639 insertions(+), 272 deletions(-) rename dmp-backend/core/src/main/java/eu/eudat/commons/types/actionconfirmation/{EmailConfirmationEntity.java => MergeAccountConfirmationEntity.java} (83%) create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/types/actionconfirmation/RemoveCredentialConfirmationEntity.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/model/deleter/UserSettingsSettingsDeleter.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/model/persist/RemoveCredentialRequestPersist.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/model/persist/UserMergeRequestPersist.java delete mode 100644 dmp-backend/core/src/main/java/eu/eudat/model/persist/UserRequestPersist.java rename dmp-backend/core/src/main/java/eu/eudat/model/persist/actionconfirmation/{EmailConfirmationPersist.java => MergeAccountConfirmationPersist.java} (57%) delete mode 100644 dmp-backend/web/src/main/java/eu/eudat/configurations/JacksonConfiguration.java diff --git a/dmp-backend/core/pom.xml b/dmp-backend/core/pom.xml index 1122942a9..f2486c905 100644 --- a/dmp-backend/core/pom.xml +++ b/dmp-backend/core/pom.xml @@ -24,6 +24,11 @@ commons-csv 1.10.0 + + commons-validator + commons-validator + 1.8.0 + gr.cite validation diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/actionconfirmation/EmailConfirmationEntity.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/actionconfirmation/MergeAccountConfirmationEntity.java similarity index 83% rename from dmp-backend/core/src/main/java/eu/eudat/commons/types/actionconfirmation/EmailConfirmationEntity.java rename to dmp-backend/core/src/main/java/eu/eudat/commons/types/actionconfirmation/MergeAccountConfirmationEntity.java index 72c74869a..d158f1b22 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/types/actionconfirmation/EmailConfirmationEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/actionconfirmation/MergeAccountConfirmationEntity.java @@ -5,9 +5,9 @@ import jakarta.xml.bind.annotation.XmlAccessorType; import jakarta.xml.bind.annotation.XmlAttribute; import jakarta.xml.bind.annotation.XmlRootElement; -@XmlRootElement(name = "email-confirmation") +@XmlRootElement(name = "merge-account-confirmation") @XmlAccessorType(XmlAccessType.FIELD) -public class EmailConfirmationEntity { +public class MergeAccountConfirmationEntity { @XmlAttribute(name = "email") private String email; diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/actionconfirmation/RemoveCredentialConfirmationEntity.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/actionconfirmation/RemoveCredentialConfirmationEntity.java new file mode 100644 index 000000000..a7e58c98e --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/actionconfirmation/RemoveCredentialConfirmationEntity.java @@ -0,0 +1,24 @@ +package eu.eudat.commons.types.actionconfirmation; + +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlRootElement; + +import java.util.UUID; + +@XmlRootElement(name = "remove-credential-confirmation") +@XmlAccessorType(XmlAccessType.FIELD) +public class RemoveCredentialConfirmationEntity { + + @XmlAttribute(name = "credential-id") + private UUID credentialId; + + public UUID getCredentialId() { + return credentialId; + } + + public void setCredentialId(UUID credentialId) { + this.credentialId = credentialId; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/BaseValidator.java b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/BaseValidator.java index c1cbab41b..5992c55e3 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/validation/BaseValidator.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/validation/BaseValidator.java @@ -3,6 +3,8 @@ package eu.eudat.commons.validation; import eu.eudat.convention.ConventionService; import eu.eudat.errorcode.ErrorThesaurusProperties; import gr.cite.tools.exception.MyValidationException; +import org.apache.commons.validator.routines.EmailValidator; + import java.util.*; public abstract class BaseValidator extends AbstractValidator { @@ -27,6 +29,9 @@ public abstract class BaseValidator extends AbstractValidator { protected Boolean isValidGuid(UUID guid) { return this.conventionService.isValidGuid(guid); } + protected Boolean isValidEmail(String value) { + return EmailValidator.getInstance().isValid(value); + } protected Boolean isValidHash(String hash) { return this.conventionService.isValidHash(hash); diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/ActionConfirmation.java b/dmp-backend/core/src/main/java/eu/eudat/model/ActionConfirmation.java index 67e7c6d3b..a26bb22d0 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/ActionConfirmation.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/ActionConfirmation.java @@ -20,9 +20,6 @@ public class ActionConfirmation { private ActionConfirmationStatus status; public static final String _status = "status"; - private String token; - public static final String _token = "token"; - private EmailConfirmation emailConfirmation; public static final String _emailConfirmation = "emailConfirmation"; @@ -75,14 +72,6 @@ public class ActionConfirmation { this.status = status; } - public String getToken() { - return token; - } - - public void setToken(String token) { - this.token = token; - } - public EmailConfirmation getEmailConfirmation() { return emailConfirmation; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/ActionConfirmationBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/ActionConfirmationBuilder.java index 90ce82f24..8a7fe7e2e 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/ActionConfirmationBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/ActionConfirmationBuilder.java @@ -4,7 +4,7 @@ import eu.eudat.authorization.AuthorizationFlags; import eu.eudat.commons.XmlHandlingService; import eu.eudat.commons.enums.ActionConfirmationType; import eu.eudat.commons.types.actionconfirmation.DmpInvitationEntity; -import eu.eudat.commons.types.actionconfirmation.EmailConfirmationEntity; +import eu.eudat.commons.types.actionconfirmation.MergeAccountConfirmationEntity; import eu.eudat.convention.ConventionService; import eu.eudat.data.ActionConfirmationEntity; import eu.eudat.model.ActionConfirmation; @@ -71,12 +71,11 @@ public class ActionConfirmationBuilder extends BaseBuilder { +public class EmailConfirmationBuilder extends BaseBuilder { private final BuilderFactory builderFactory; private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); @@ -38,7 +38,7 @@ public class EmailConfirmationBuilder extends BaseBuilder build(FieldSet fields, List data) throws MyApplicationException { + public List build(FieldSet fields, List data) throws MyApplicationException { this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0)); this.logger.trace(new DataLogEntry("requested fields", fields)); if (fields == null || data == null || fields.isEmpty()) @@ -46,7 +46,7 @@ public class EmailConfirmationBuilder extends BaseBuilder models = new ArrayList<>(); - for (EmailConfirmationEntity d : data) { + for (MergeAccountConfirmationEntity d : data) { EmailConfirmation m = new EmailConfirmation(); if (fields.hasField(this.asIndexer(EmailConfirmation._email))) m.setEmail(d.getEmail()); diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/deleter/UserSettingsSettingsDeleter.java b/dmp-backend/core/src/main/java/eu/eudat/model/deleter/UserSettingsSettingsDeleter.java new file mode 100644 index 000000000..b312f05c9 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/deleter/UserSettingsSettingsDeleter.java @@ -0,0 +1,68 @@ +package eu.eudat.model.deleter; + +import eu.eudat.data.UserSettingsEntity; +import eu.eudat.query.UserSettingsQuery; +import gr.cite.tools.data.deleter.Deleter; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.logging.LoggerService; +import gr.cite.tools.logging.MapLogEntry; +import jakarta.persistence.EntityManager; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import javax.management.InvalidApplicationException; +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class UserSettingsSettingsDeleter implements Deleter { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UserSettingsSettingsDeleter.class)); + private final EntityManager entityManager; + + protected final QueryFactory queryFactory; + + + @Autowired + public UserSettingsSettingsDeleter( + EntityManager entityManager, + QueryFactory queryFactory + ) { + this.entityManager = entityManager; + this.queryFactory = queryFactory; + } + + public void deleteAndSaveByIds(List ids) throws InvalidApplicationException { + logger.debug(new MapLogEntry("collecting to delete").And("count", Optional.ofNullable(ids).map(List::size).orElse(0)).And("ids", ids)); + List data = this.queryFactory.query(UserSettingsQuery.class).ids(ids).collect(); + logger.trace("retrieved {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + this.deleteAndSave(data); + } + + public void deleteAndSave(List data) throws InvalidApplicationException { + logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + this.delete(data); + logger.trace("saving changes"); + this.entityManager.flush(); + logger.trace("changes saved"); + } + + public void delete(List data) throws InvalidApplicationException { + logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0)); + if (data == null || data.isEmpty()) + return; + + for (UserSettingsEntity item : data) { + logger.trace("deleting item {}", item.getId()); + logger.trace("deleting item"); + this.entityManager.remove(item); + logger.trace("deleted item"); + } + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/ActionConfirmationPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/ActionConfirmationPersist.java index 08bf4058c..7877940a8 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/ActionConfirmationPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/ActionConfirmationPersist.java @@ -8,7 +8,7 @@ import eu.eudat.commons.validation.specification.Specification; import eu.eudat.convention.ConventionService; import eu.eudat.errorcode.ErrorThesaurusProperties; import eu.eudat.model.persist.actionconfirmation.DmpInvitationPersist; -import eu.eudat.model.persist.actionconfirmation.EmailConfirmationPersist; +import eu.eudat.model.persist.actionconfirmation.MergeAccountConfirmationPersist; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.MessageSource; import org.springframework.context.annotation.Scope; @@ -40,18 +40,18 @@ public class ActionConfirmationPersist { private static final String _dmpInvitation = "dmpInvitation"; - private EmailConfirmationPersist emailConfirmation; + private MergeAccountConfirmationPersist mergeAccountConfirmation; - private static final String _emailConfirmation = "emailConfirmation"; + private static final String _mergeAccountConfirmation = "mergeAccountConfirmation"; + + private RemoveCredentialRequestPersist removeCredentialRequest; + + private static final String _removeCredentialRequest = "removeCredentialRequest"; private Instant expiresAt; private static final String _expiresAt = "expiresAt"; - private UUID createdById; - - private static final String _createdById = "createdById"; - private String hash; private static final String _hash = "hash"; @@ -80,14 +80,6 @@ public class ActionConfirmationPersist { this.status = status; } - public String getToken() { - return token; - } - - public void setToken(String token) { - this.token = token; - } - public DmpInvitationPersist getDmpInvitation() { return dmpInvitation; } @@ -96,12 +88,28 @@ public class ActionConfirmationPersist { this.dmpInvitation = dmpInvitation; } - public EmailConfirmationPersist getEmailConfirmation() { - return emailConfirmation; + public MergeAccountConfirmationPersist getMergeAccountConfirmation() { + return mergeAccountConfirmation; } - public void setEmailConfirmation(EmailConfirmationPersist emailConfirmation) { - this.emailConfirmation = emailConfirmation; + public void setMergeAccountConfirmation(MergeAccountConfirmationPersist mergeAccountConfirmation) { + this.mergeAccountConfirmation = mergeAccountConfirmation; + } + + public RemoveCredentialRequestPersist getRemoveCredentialRequest() { + return removeCredentialRequest; + } + + public void setRemoveCredentialRequest(RemoveCredentialRequestPersist removeCredentialRequest) { + this.removeCredentialRequest = removeCredentialRequest; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; } public Instant getExpiresAt() { @@ -112,13 +120,6 @@ public class ActionConfirmationPersist { this.expiresAt = expiresAt; } - public UUID getCreatedById() { - return createdById; - } - - public void setCreatedById(UUID createdById) { - this.createdById = createdById; - } public String getHash() { return hash; @@ -173,8 +174,18 @@ public class ActionConfirmationPersist { .must(() -> !this.isNull(item.getExpiresAt())) .failOn(ActionConfirmationPersist._expiresAt).failWith(messageSource.getMessage("Validation_Required", new Object[]{ActionConfirmationPersist._expiresAt}, LocaleContextHolder.getLocale())), this.spec() - .must(() -> !this.isNull(item.getCreatedById())) - .failOn(ActionConfirmationPersist._createdById).failWith(messageSource.getMessage("Validation_Required", new Object[]{ActionConfirmationPersist._createdById}, LocaleContextHolder.getLocale())), + .iff(() -> ActionConfirmationType.MergeAccount.equals(item.getType())) + .must(() -> !this.isNull(item.getMergeAccountConfirmation())) + .failOn(ActionConfirmationPersist._mergeAccountConfirmation).failWith(messageSource.getMessage("Validation_Required", new Object[]{ActionConfirmationPersist._mergeAccountConfirmation}, LocaleContextHolder.getLocale())), + this.spec() + .iff(() -> ActionConfirmationType.DmpInvitation.equals(item.getType())) + .must(() -> !this.isNull(item.getDmpInvitation())) + .failOn(ActionConfirmationPersist._dmpInvitation).failWith(messageSource.getMessage("Validation_Required", new Object[]{ActionConfirmationPersist._dmpInvitation}, LocaleContextHolder.getLocale())), + + this.spec() + .iff(() -> ActionConfirmationType.RemoveCredential.equals(item.getType())) + .must(() -> !this.isNull(item.getRemoveCredentialRequest())) + .failOn(ActionConfirmationPersist._removeCredentialRequest).failWith(messageSource.getMessage("Validation_Required", new Object[]{ActionConfirmationPersist._removeCredentialRequest}, LocaleContextHolder.getLocale())), this.refSpec() .iff(() -> !this.isNull(item.getDmpInvitation())) @@ -182,10 +193,16 @@ public class ActionConfirmationPersist { .over(item.getDmpInvitation()) .using(() -> this.validatorFactory.validator(DmpInvitationPersist.DmpInvitationPersistValidator.class)), this.refSpec() - .iff(() -> !this.isNull(item.getEmailConfirmation())) - .on(ActionConfirmationPersist._emailConfirmation) - .over(item.getEmailConfirmation()) - .using(() -> this.validatorFactory.validator(EmailConfirmationPersist.EmailConfirmationPersistValidator.class)) + .iff(() -> !this.isNull(item.getMergeAccountConfirmation())) + .on(ActionConfirmationPersist._mergeAccountConfirmation) + .over(item.getMergeAccountConfirmation()) + .using(() -> this.validatorFactory.validator(MergeAccountConfirmationPersist.MergeAccountConfirmationPersistValidator.class)), + + this.refSpec() + .iff(() -> !this.isNull(item.getRemoveCredentialRequest())) + .on(ActionConfirmationPersist._removeCredentialRequest) + .over(item.getRemoveCredentialRequest()) + .using(() -> this.validatorFactory.validator(RemoveCredentialRequestPersist.RemoveCredentialRequestPersistValidator.class)) ); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/RemoveCredentialRequestPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/RemoveCredentialRequestPersist.java new file mode 100644 index 000000000..51ff4893d --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/RemoveCredentialRequestPersist.java @@ -0,0 +1,60 @@ +package eu.eudat.model.persist; + +import eu.eudat.commons.validation.BaseValidator; +import eu.eudat.commons.validation.specification.Specification; +import eu.eudat.convention.ConventionService; +import eu.eudat.errorcode.ErrorThesaurusProperties; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Scope; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +public class RemoveCredentialRequestPersist { + + private UUID credentialId; + public static final String _credentialId = "credentialId"; + + public UUID getCredentialId() { + return credentialId; + } + + public void setCredentialId(UUID credentialId) { + this.credentialId = credentialId; + } + + @Component(RemoveCredentialRequestPersistValidator.ValidatorName) + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public static class RemoveCredentialRequestPersistValidator extends BaseValidator { + + public static final String ValidatorName = "RemoveCredentialRequestPersistValidator"; + + private final MessageSource messageSource; + + + protected RemoveCredentialRequestPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) { + super(conventionService, errors); + this.messageSource = messageSource; + } + + @Override + protected Class modelClass() { + return RemoveCredentialRequestPersist.class; + } + + @Override + protected List specifications(RemoveCredentialRequestPersist item) { + return Arrays.asList( + this.spec() + .must(() -> !this.isValidGuid(item.getCredentialId())) + .failOn(RemoveCredentialRequestPersist._credentialId).failWith(messageSource.getMessage("Validation_Required", new Object[]{RemoveCredentialRequestPersist._credentialId}, LocaleContextHolder.getLocale())) + ); + } + } + +} + diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserMergeRequestPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserMergeRequestPersist.java new file mode 100644 index 000000000..41bac0869 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserMergeRequestPersist.java @@ -0,0 +1,65 @@ +package eu.eudat.model.persist; + +import eu.eudat.commons.validation.BaseValidator; +import eu.eudat.commons.validation.ValidatorFactory; +import eu.eudat.commons.validation.specification.Specification; +import eu.eudat.convention.ConventionService; +import eu.eudat.errorcode.ErrorThesaurusProperties; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Scope; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; + +public class UserMergeRequestPersist { + + + private String email; + public static final String _email = "email"; + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + @Component(UserMergeRequestPersistValidator.ValidatorName) + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public static class UserMergeRequestPersistValidator extends BaseValidator { + + public static final String ValidatorName = "UserMergeRequestPersistValidator"; + + private final MessageSource messageSource; + + + protected UserMergeRequestPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) { + super(conventionService, errors); + this.messageSource = messageSource; + } + + @Override + protected Class modelClass() { + return UserMergeRequestPersist.class; + } + + @Override + protected List specifications(UserMergeRequestPersist item) { + return Arrays.asList( + this.spec() + .must(() -> !this.isEmpty(item.getEmail())) + .failOn(UserMergeRequestPersist._email).failWith(messageSource.getMessage("Validation_Required", new Object[]{UserMergeRequestPersist._email}, LocaleContextHolder.getLocale())), + this.spec() + .iff(() -> !this.isEmpty(item.getEmail())) + .must(() -> this.isValidEmail(item.getEmail())) + .failOn(UserMergeRequestPersist._email).failWith(messageSource.getMessage("Validation_UnexpectedValue", new Object[]{UserMergeRequestPersist._email}, LocaleContextHolder.getLocale())) + ); + } + } + +} + diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserRequestPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserRequestPersist.java deleted file mode 100644 index 5c3b4dbd0..000000000 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/UserRequestPersist.java +++ /dev/null @@ -1,78 +0,0 @@ -package eu.eudat.model.persist; - -import eu.eudat.commons.validation.BaseValidator; -import eu.eudat.commons.validation.ValidatorFactory; -import eu.eudat.commons.validation.specification.Specification; -import eu.eudat.convention.ConventionService; -import eu.eudat.errorcode.ErrorThesaurusProperties; -import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.MessageSource; -import org.springframework.context.annotation.Scope; -import org.springframework.context.i18n.LocaleContextHolder; -import org.springframework.stereotype.Component; - -import java.util.Arrays; -import java.util.List; -import java.util.UUID; - -public class UserRequestPersist { - - private UUID userId; - public static final String _userId = "userId"; - - private String email; - public static final String _email = "email"; - - public UUID getUserId() { - return userId; - } - - public void setUserId(UUID userId) { - this.userId = userId; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - @Component(UserRequestPersistValidator.ValidatorName) - @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public static class UserRequestPersistValidator extends BaseValidator { - - public static final String ValidatorName = "UserRequestPersistValidator"; - - private final MessageSource messageSource; - - private final ValidatorFactory validatorFactory; - - protected UserRequestPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) { - super(conventionService, errors); - this.messageSource = messageSource; - this.validatorFactory = validatorFactory; - } - - @Override - protected Class modelClass() { - return UserRequestPersist.class; - } - - @Override - protected List specifications(UserRequestPersist item) { - return Arrays.asList( - this.spec() - .must(() -> this.isValidGuid(item.getUserId())) - .failOn(UserRequestPersist._userId).failWith(messageSource.getMessage("Validation_Required", new Object[]{UserRequestPersist._userId}, LocaleContextHolder.getLocale())), - - this.spec() - .must(() -> !this.isEmpty(item.getEmail())) - .failOn(UserRequestPersist._email).failWith(messageSource.getMessage("Validation_Required", new Object[]{UserRequestPersist._email}, LocaleContextHolder.getLocale())) - ); - } - } - -} - diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/actionconfirmation/EmailConfirmationPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/actionconfirmation/MergeAccountConfirmationPersist.java similarity index 57% rename from dmp-backend/core/src/main/java/eu/eudat/model/persist/actionconfirmation/EmailConfirmationPersist.java rename to dmp-backend/core/src/main/java/eu/eudat/model/persist/actionconfirmation/MergeAccountConfirmationPersist.java index 302d5d256..768253c8f 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/actionconfirmation/EmailConfirmationPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/actionconfirmation/MergeAccountConfirmationPersist.java @@ -13,15 +13,12 @@ import org.springframework.stereotype.Component; import java.util.Collections; import java.util.List; -public class EmailConfirmationPersist { +public class MergeAccountConfirmationPersist { private String email; public static final String _email = "email"; - public EmailConfirmationPersist(String email) { - this.email = email; - } public String getEmail() { return email; @@ -31,30 +28,30 @@ public class EmailConfirmationPersist { this.email = email; } - @Component(EmailConfirmationPersistValidator.ValidatorName) + @Component(MergeAccountConfirmationPersistValidator.ValidatorName) @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) - public static class EmailConfirmationPersistValidator extends BaseValidator { + public static class MergeAccountConfirmationPersistValidator extends BaseValidator { - public static final String ValidatorName = "EmailConfirmationPersistValidator"; + public static final String ValidatorName = "MergeAccountConfirmationPersistValidator"; private final MessageSource messageSource; - protected EmailConfirmationPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) { + protected MergeAccountConfirmationPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) { super(conventionService, errors); this.messageSource = messageSource; } @Override - protected Class modelClass() { - return EmailConfirmationPersist.class; + protected Class modelClass() { + return MergeAccountConfirmationPersist.class; } @Override - protected List specifications(EmailConfirmationPersist item) { + protected List specifications(MergeAccountConfirmationPersist item) { return Collections.singletonList( this.spec() .must(() -> !this.isEmpty(item.getEmail())) - .failOn(EmailConfirmationPersist._email).failWith(messageSource.getMessage("Validation_Required", new Object[]{EmailConfirmationPersist._email}, LocaleContextHolder.getLocale())) + .failOn(MergeAccountConfirmationPersist._email).failWith(messageSource.getMessage("Validation_Required", new Object[]{MergeAccountConfirmationPersist._email}, LocaleContextHolder.getLocale())) ); } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/ActionConfirmationQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/ActionConfirmationQuery.java index e5c114090..6fc7c985d 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/ActionConfirmationQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/ActionConfirmationQuery.java @@ -237,7 +237,7 @@ public class ActionConfirmationQuery extends QueryBase if (item.match(ActionConfirmation._id)) return ActionConfirmationEntity._id; else if (item.match(ActionConfirmation._type)) return ActionConfirmationEntity._type; else if (item.match(ActionConfirmation._status)) return ActionConfirmationEntity._status; - else if (item.match(ActionConfirmation._token)) return ActionConfirmationEntity._token; + else if (item.match(ActionConfirmationEntity._token)) return ActionConfirmationEntity._token; else if (item.match(ActionConfirmation._expiresAt)) return ActionConfirmationEntity._expiresAt; else if (item.prefix(ActionConfirmation._emailConfirmation)) return ActionConfirmationEntity._data; else if (item.prefix(ActionConfirmation._dmpInvitation)) return ActionConfirmationEntity._data; diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/DescriptionQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/DescriptionQuery.java index d1cd0eb99..200c9684a 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/DescriptionQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/DescriptionQuery.java @@ -35,6 +35,8 @@ import java.util.*; public class DescriptionQuery extends QueryBase { private String like; private Collection ids; + private Collection createdByIds; + private DmpDescriptionTemplateQuery dmpDescriptionTemplateQuery; private DmpQuery dmpQuery; private Instant createdAfter; @@ -78,6 +80,21 @@ public class DescriptionQuery extends QueryBase { return this; } + public DescriptionQuery createdByIds(UUID value) { + this.createdByIds = List.of(value); + return this; + } + + public DescriptionQuery createdByIds(UUID... value) { + this.createdByIds = Arrays.asList(value); + return this; + } + + public DescriptionQuery createdByIds(Collection values) { + this.createdByIds = values; + return this; + } + public DescriptionQuery dmpDescriptionTemplateSubQuery(DmpDescriptionTemplateQuery subQuery) { this.dmpDescriptionTemplateQuery = subQuery; return this; @@ -174,7 +191,7 @@ public class DescriptionQuery extends QueryBase { protected Boolean isFalseQuery() { return this.isEmpty(this.ids) || - this.isEmpty(this.isActives) || + this.isEmpty(this.isActives) || this.isEmpty(this.createdByIds) || this.isEmpty(this.excludedIds) || this.isFalseQuery(this.dmpQuery) || this.isEmpty(this.statuses) || this.isFalseQuery(this.dmpDescriptionTemplateQuery); } @@ -220,6 +237,12 @@ public class DescriptionQuery extends QueryBase { inClause.value(item); predicates.add(inClause); } + if (this.createdByIds != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionEntity._createdById)); + for (UUID item : this.createdByIds) + inClause.value(item); + predicates.add(inClause); + } if (this.createdAfter != null) { predicates.add(queryContext.CriteriaBuilder.greaterThan(queryContext.Root.get(DescriptionEntity._createdAt), this.createdAfter)); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/DmpQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/DmpQuery.java index 22dc650b6..a85e9eb74 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/DmpQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/DmpQuery.java @@ -31,6 +31,7 @@ public class DmpQuery extends QueryBase { private String like; private Collection ids; + private Collection creatorIds; private Collection excludedIds; @@ -79,6 +80,21 @@ public class DmpQuery extends QueryBase { return this; } + public DmpQuery creatorIds(UUID value) { + this.creatorIds = List.of(value); + return this; + } + + public DmpQuery creatorIds(UUID... value) { + this.creatorIds = Arrays.asList(value); + return this; + } + + public DmpQuery creatorIds(Collection values) { + this.creatorIds = values; + return this; + } + public DmpQuery excludedIds(Collection values) { this.excludedIds = values; return this; @@ -201,7 +217,7 @@ public class DmpQuery extends QueryBase { @Override protected Boolean isFalseQuery() { - return this.isEmpty(this.ids) || this.isEmpty(this.isActives) || this.isEmpty(this.versionStatuses) || this.isEmpty(this.excludedIds) || this.isEmpty(this.accessTypes)|| this.isEmpty(this.statuses)|| this.isFalseQuery(this.dmpDescriptionTemplateQuery)|| this.isFalseQuery(this.dmpUserQuery); + return this.isEmpty(this.ids) || this.isEmpty(this.creatorIds) ||this.isEmpty(this.isActives) || this.isEmpty(this.versionStatuses) || this.isEmpty(this.excludedIds) || this.isEmpty(this.accessTypes)|| this.isEmpty(this.statuses)|| this.isFalseQuery(this.dmpDescriptionTemplateQuery)|| this.isFalseQuery(this.dmpUserQuery); } @Override @@ -248,6 +264,12 @@ public class DmpQuery extends QueryBase { inClause.value(item); predicates.add(inClause); } + if (this.creatorIds != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpEntity._creatorId)); + for (UUID item : this.creatorIds) + inClause.value(item); + predicates.add(inClause); + } if (this.excludedIds != null) { CriteriaBuilder.In notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpEntity._id)); for (UUID item : this.excludedIds) diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/LockQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/LockQuery.java index d78d6ff2f..05f179793 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/LockQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/LockQuery.java @@ -24,6 +24,7 @@ public class LockQuery extends QueryBase { private Collection ids; private Collection targetIds; + private Collection lockedByIds; private Collection targetTypes; @@ -45,6 +46,21 @@ public class LockQuery extends QueryBase { this.ids = values; return this; } + + public LockQuery lockedByIds(UUID value) { + this.lockedByIds = List.of(value); + return this; + } + + public LockQuery lockedByIds(UUID... value) { + this.lockedByIds = Arrays.asList(value); + return this; + } + + public LockQuery lockedByIds(Collection values) { + this.lockedByIds = values; + return this; + } public LockQuery targetIds(UUID value) { this.targetIds = List.of(value); @@ -106,7 +122,7 @@ public class LockQuery extends QueryBase { @Override protected Boolean isFalseQuery() { - return this.isEmpty(this.ids) || this.isEmpty(this.targetIds) || this.isEmpty(this.excludedIds) || this.isEmpty(this.targetTypes); + return this.isEmpty(this.ids) || this.isEmpty(this.lockedByIds) || this.isEmpty(this.targetIds) || this.isEmpty(this.excludedIds) || this.isEmpty(this.targetTypes); } @Override @@ -118,6 +134,12 @@ public class LockQuery extends QueryBase { inClause.value(item); predicates.add(inClause); } + if (this.lockedByIds != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(LockEntity._lockedBy)); + for (UUID item : this.lockedByIds) + inClause.value(item); + predicates.add(inClause); + } if (this.targetIds != null) { CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(LockEntity._target)); for (UUID item : this.targetIds) diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/StorageFileQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/StorageFileQuery.java index 2aef9ced3..d536d38f7 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/StorageFileQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/StorageFileQuery.java @@ -25,6 +25,7 @@ import java.util.*; public class StorageFileQuery extends QueryBase { private String like; private Collection ids; + private Collection ownerIds; private Boolean canPurge; private Boolean isPurged; private Instant createdAfter; @@ -58,6 +59,21 @@ public class StorageFileQuery extends QueryBase { return this; } + public StorageFileQuery ownerIds(UUID value) { + this.ownerIds = List.of(value); + return this; + } + + public StorageFileQuery ownerIds(UUID... value) { + this.ownerIds = Arrays.asList(value); + return this; + } + + public StorageFileQuery ownerIds(Collection values) { + this.ownerIds = values; + return this; + } + public StorageFileQuery createdAfter(Instant value) { this.createdAfter = value; return this; @@ -97,6 +113,7 @@ public class StorageFileQuery extends QueryBase { protected Boolean isFalseQuery() { return this.isEmpty(this.ids) || + this.isEmpty(this.ownerIds) || this.isEmpty(this.excludedIds) ; } @@ -137,6 +154,12 @@ public class StorageFileQuery extends QueryBase { inClause.value(item); predicates.add(inClause); } + if (this.ownerIds != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(StorageFileEntity._ownerId)); + for (UUID item : this.ownerIds) + inClause.value(item); + predicates.add(inClause); + } if (this.createdAfter != null) { predicates.add(queryContext.CriteriaBuilder.greaterThan(queryContext.Root.get(StorageFileEntity._createdAt), this.createdAfter)); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/actionconfirmation/ActionConfirmationService.java b/dmp-backend/core/src/main/java/eu/eudat/service/actionconfirmation/ActionConfirmationService.java index f3352c9b8..757cfb4b2 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/actionconfirmation/ActionConfirmationService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/actionconfirmation/ActionConfirmationService.java @@ -1,5 +1,6 @@ package eu.eudat.service.actionconfirmation; +import eu.eudat.model.ActionConfirmation; import eu.eudat.model.persist.ActionConfirmationPersist; import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.exception.MyForbiddenException; @@ -14,7 +15,7 @@ import java.util.UUID; public interface ActionConfirmationService { - void persist(ActionConfirmationPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JAXBException; + ActionConfirmation persist(ActionConfirmationPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JAXBException; void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException, IOException; diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/actionconfirmation/ActionConfirmationServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/actionconfirmation/ActionConfirmationServiceImpl.java index dbbf94db6..4119cc442 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/actionconfirmation/ActionConfirmationServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/actionconfirmation/ActionConfirmationServiceImpl.java @@ -1,19 +1,26 @@ package eu.eudat.service.actionconfirmation; +import eu.eudat.authorization.OwnedResource; import eu.eudat.authorization.Permission; import eu.eudat.commons.XmlHandlingService; -import eu.eudat.commons.enums.ActionConfirmationType; import eu.eudat.commons.enums.IsActive; +import eu.eudat.commons.scope.user.UserScope; import eu.eudat.commons.types.actionconfirmation.DmpInvitationEntity; -import eu.eudat.commons.types.actionconfirmation.EmailConfirmationEntity; +import eu.eudat.commons.types.actionconfirmation.MergeAccountConfirmationEntity; +import eu.eudat.commons.types.actionconfirmation.RemoveCredentialConfirmationEntity; import eu.eudat.convention.ConventionService; import eu.eudat.data.ActionConfirmationEntity; import eu.eudat.errorcode.ErrorThesaurusProperties; +import eu.eudat.model.ActionConfirmation; +import eu.eudat.model.Dmp; import eu.eudat.model.ReferenceType; +import eu.eudat.model.builder.ActionConfirmationBuilder; +import eu.eudat.model.builder.DmpBuilder; import eu.eudat.model.deleter.ActionConfirmationDeleter; import eu.eudat.model.persist.ActionConfirmationPersist; +import eu.eudat.model.persist.RemoveCredentialRequestPersist; import eu.eudat.model.persist.actionconfirmation.DmpInvitationPersist; -import eu.eudat.model.persist.actionconfirmation.EmailConfirmationPersist; +import eu.eudat.model.persist.actionconfirmation.MergeAccountConfirmationPersist; import eu.eudat.service.dmpblueprint.DmpBlueprintServiceImpl; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.builder.BuilderFactory; @@ -22,6 +29,7 @@ import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.exception.MyForbiddenException; import gr.cite.tools.exception.MyNotFoundException; import gr.cite.tools.exception.MyValidationException; +import gr.cite.tools.fieldset.BaseFieldSet; import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.MapLogEntry; @@ -51,12 +59,12 @@ public class ActionConfirmationServiceImpl implements ActionConfirmationService private final MessageSource messageSource; private final XmlHandlingService xmlHandlingService; private final ErrorThesaurusProperties errors; - + private final UserScope userScope; public ActionConfirmationServiceImpl( - EntityManager entityManager, AuthorizationService authorizationService, DeleterFactory deleterFactory, BuilderFactory builderFactory, - ConventionService conventionService, MessageSource messageSource, - XmlHandlingService xmlHandlingService, ErrorThesaurusProperties errors) { + EntityManager entityManager, AuthorizationService authorizationService, DeleterFactory deleterFactory, BuilderFactory builderFactory, + ConventionService conventionService, MessageSource messageSource, + XmlHandlingService xmlHandlingService, ErrorThesaurusProperties errors, UserScope userScope) { this.entityManager = entityManager; this.authorizationService = authorizationService; this.deleterFactory = deleterFactory; @@ -65,13 +73,13 @@ public class ActionConfirmationServiceImpl implements ActionConfirmationService this.messageSource = messageSource; this.xmlHandlingService = xmlHandlingService; this.errors = errors; + this.userScope = userScope; } - public void persist(ActionConfirmationPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JAXBException{ + public ActionConfirmation persist(ActionConfirmationPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JAXBException{ logger.debug(new MapLogEntry("persisting data").And("model", model).And("fields", fields)); -// this.authorizationService.authorizeForce(Permission.EditActionConfirmation); //TODO Boolean isUpdate = this.conventionService.isValidGuid(model.getId()); @@ -86,17 +94,19 @@ public class ActionConfirmationServiceImpl implements ActionConfirmationService data.setId(UUID.randomUUID()); data.setIsActive(IsActive.Active); data.setCreatedAt(Instant.now()); + data.setCreatedById(userScope.getUserId()); } - + this.authorizationService.authorizeAtLeastOneForce(List.of(new OwnedResource(data.getCreatedById())), Permission.EditActionConfirmation); + data.setToken(model.getToken()); - data.setCreatedById(model.getCreatedById()); data.setType(model.getType()); data.setStatus(model.getStatus()); data.setExpiresAt(model.getExpiresAt()); - if (model.getType().equals(ActionConfirmationType.MergeAccount) || model.getType().equals(ActionConfirmationType.RemoveCredential)){ - data.setData(this.xmlHandlingService.toXmlSafe(this.buildEmailConfirmationEntity(model.getEmailConfirmation()))); - }else{ - data.setData(this.xmlHandlingService.toXmlSafe(this.buildDmpInvitationEntity(model.getDmpInvitation()))); + switch (model.getType()){ + case MergeAccount -> data.setData(this.xmlHandlingService.toXmlSafe(this.buildMergeAccountConfirmationEntity(model.getMergeAccountConfirmation()))); + case DmpInvitation -> data.setData(this.xmlHandlingService.toXmlSafe(this.buildDmpInvitationEntity(model.getDmpInvitation()))); + case RemoveCredential -> data.setData(this.xmlHandlingService.toXmlSafe(this.buildMergeAccountConfirmationEntity(model.getRemoveCredentialRequest()))); + default -> throw new InternalError("unknown type: " + model.getType()); } data.setUpdatedAt(Instant.now()); @@ -105,6 +115,7 @@ public class ActionConfirmationServiceImpl implements ActionConfirmationService this.entityManager.flush(); + return this.builderFactory.builder(ActionConfirmationBuilder.class).build(BaseFieldSet.build(fields, ActionConfirmation._id), data); } private @NotNull DmpInvitationEntity buildDmpInvitationEntity(DmpInvitationPersist persist){ @@ -118,8 +129,8 @@ public class ActionConfirmationServiceImpl implements ActionConfirmationService return data; } - private @NotNull EmailConfirmationEntity buildEmailConfirmationEntity(EmailConfirmationPersist persist){ - EmailConfirmationEntity data = new EmailConfirmationEntity(); + private @NotNull MergeAccountConfirmationEntity buildMergeAccountConfirmationEntity(MergeAccountConfirmationPersist persist){ + MergeAccountConfirmationEntity data = new MergeAccountConfirmationEntity(); if (persist == null) return data; data.setEmail(persist.getEmail()); @@ -127,6 +138,15 @@ public class ActionConfirmationServiceImpl implements ActionConfirmationService return data; } + private @NotNull RemoveCredentialConfirmationEntity buildMergeAccountConfirmationEntity(RemoveCredentialRequestPersist persist){ + RemoveCredentialConfirmationEntity data = new RemoveCredentialConfirmationEntity(); + if (persist == null) return data; + + data.setCredentialId(persist.getCredentialId()); + + return data; + } + public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException { logger.debug("deleting : {}", id); diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java index 9bc67e78f..39c89957a 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java @@ -833,7 +833,6 @@ public class DmpServiceImpl implements DmpService { persist.setStatus(ActionConfirmationStatus.Requested); persist.setToken(UUID.randomUUID().toString()); persist.setDmpInvitation(new DmpInvitationPersist(email, dmp.getId(), role)); - persist.setCreatedById(this.userScope.getUserIdSafe()); persist.setExpiresAt(Instant.now().plusSeconds(this.notificationProperties.getEmailExpirationTimeSeconds())); validatorFactory.validator(ActionConfirmationPersist.ActionConfirmationPersistValidator.class).validateForce(persist); this.actionConfirmationService.persist(persist, null); diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/user/UserService.java b/dmp-backend/core/src/main/java/eu/eudat/service/user/UserService.java index 3abb979ba..09517cc7d 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/user/UserService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/user/UserService.java @@ -2,7 +2,8 @@ package eu.eudat.service.user; import com.fasterxml.jackson.core.JsonProcessingException; import eu.eudat.model.User; -import eu.eudat.model.persist.UserRequestPersist; +import eu.eudat.model.persist.RemoveCredentialRequestPersist; +import eu.eudat.model.persist.UserMergeRequestPersist; import eu.eudat.model.persist.UserPersist; import eu.eudat.model.persist.UserRolePatchPersist; import gr.cite.tools.exception.MyApplicationException; @@ -32,11 +33,11 @@ public interface UserService { User patchRoles(UserRolePatchPersist model, FieldSet fields) throws InvalidApplicationException; - void sendMergeAccountConfirmation(UserRequestPersist model) throws InvalidApplicationException, JAXBException; + void sendMergeAccountConfirmation(UserMergeRequestPersist model) throws InvalidApplicationException, JAXBException; - void sendRemoveCredentialConfirmation(UserRequestPersist model) throws InvalidApplicationException, JAXBException; + void sendRemoveCredentialConfirmation(RemoveCredentialRequestPersist model) throws InvalidApplicationException, JAXBException; - void confirmMergeAccount(String token) throws InvalidApplicationException; + void confirmMergeAccount(String token) throws InvalidApplicationException, IOException; void confirmRemoveCredential(String token) throws InvalidApplicationException; diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/user/UserServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/user/UserServiceImpl.java index bf3427072..2bd5dec5f 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/user/UserServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/user/UserServiceImpl.java @@ -12,7 +12,8 @@ import eu.eudat.commons.enums.ContactInfoType; import eu.eudat.commons.enums.IsActive; import eu.eudat.commons.enums.notification.NotificationContactType; import eu.eudat.commons.scope.user.UserScope; -import eu.eudat.commons.types.actionconfirmation.EmailConfirmationEntity; +import eu.eudat.commons.types.actionconfirmation.MergeAccountConfirmationEntity; +import eu.eudat.commons.types.actionconfirmation.RemoveCredentialConfirmationEntity; import eu.eudat.commons.types.notification.*; import eu.eudat.commons.types.user.AdditionalInfoEntity; import eu.eudat.commons.validation.ValidatorFactory; @@ -26,19 +27,23 @@ import eu.eudat.integrationevent.outbox.notification.NotificationIntegrationEven import eu.eudat.integrationevent.outbox.notification.NotificationIntegrationEventHandler; import eu.eudat.model.User; import eu.eudat.model.UserContactInfo; +import eu.eudat.model.UserCredential; import eu.eudat.model.builder.UserBuilder; import eu.eudat.model.deleter.UserCredentialDeleter; import eu.eudat.model.deleter.UserDeleter; import eu.eudat.model.deleter.UserRoleDeleter; +import eu.eudat.model.deleter.UserSettingsSettingsDeleter; import eu.eudat.model.persist.*; -import eu.eudat.model.persist.actionconfirmation.EmailConfirmationPersist; +import eu.eudat.model.persist.actionconfirmation.MergeAccountConfirmationPersist; import eu.eudat.query.*; import eu.eudat.service.actionconfirmation.ActionConfirmationService; +import eu.eudat.service.elastic.ElasticService; import eu.eudat.service.keycloak.KeycloakRole; import eu.eudat.service.keycloak.KeycloakService; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.data.deleter.DeleterFactory; +import gr.cite.tools.data.query.Ordering; import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.exception.MyForbiddenException; @@ -99,19 +104,21 @@ public class UserServiceImpl implements UserService { private final ValidatorFactory validatorFactory; + private final ElasticService elasticService; + @Autowired public UserServiceImpl( - EntityManager entityManager, - AuthorizationService authorizationService, - DeleterFactory deleterFactory, - BuilderFactory builderFactory, - ConventionService conventionService, - ErrorThesaurusProperties errors, - MessageSource messageSource, - EventBroker eventBroker, - JsonHandlingService jsonHandlingService, - XmlHandlingService xmlHandlingService, QueryFactory queryFactory, - UserScope userScope, KeycloakService keycloakService, ActionConfirmationService actionConfirmationService, NotificationProperties notificationProperties, NotificationIntegrationEventHandler eventHandler, ValidatorFactory validatorFactory) { + EntityManager entityManager, + AuthorizationService authorizationService, + DeleterFactory deleterFactory, + BuilderFactory builderFactory, + ConventionService conventionService, + ErrorThesaurusProperties errors, + MessageSource messageSource, + EventBroker eventBroker, + JsonHandlingService jsonHandlingService, + XmlHandlingService xmlHandlingService, QueryFactory queryFactory, + UserScope userScope, KeycloakService keycloakService, ActionConfirmationService actionConfirmationService, NotificationProperties notificationProperties, NotificationIntegrationEventHandler eventHandler, ValidatorFactory validatorFactory, ElasticService elasticService) { this.entityManager = entityManager; this.authorizationService = authorizationService; this.deleterFactory = deleterFactory; @@ -129,6 +136,7 @@ public class UserServiceImpl implements UserService { this.notificationProperties = notificationProperties; this.eventHandler = eventHandler; this.validatorFactory = validatorFactory; + this.elasticService = elasticService; } //region persist @@ -343,12 +351,14 @@ public class UserServiceImpl implements UserService { //endregion //notifications - public void sendMergeAccountConfirmation(UserRequestPersist model) throws InvalidApplicationException, JAXBException { - UserEntity user = this.queryFactory.query(UserQuery.class).ids(model.getUserId()).isActive(IsActive.Active).first(); - if (user == null){ - throw new MyApplicationException("User don't exist"); - } - String token = this.createActionConfirmation(model.getEmail(), ActionConfirmationType.MergeAccount); + public void sendMergeAccountConfirmation(UserMergeRequestPersist model) throws InvalidApplicationException, JAXBException { + UserContactInfoEntity userContactInfoEntity = this.queryFactory.query(UserContactInfoQuery.class).values(model.getEmail()).types(ContactInfoType.Email).first(); + if (userContactInfoEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getEmail(), User.class.getSimpleName()}, LocaleContextHolder.getLocale())); + + UserEntity user = this.queryFactory.query(UserQuery.class).ids(userContactInfoEntity.getUserId()).isActive(IsActive.Active).first(); + if (user == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{userContactInfoEntity.getUserId(), User.class.getSimpleName()}, LocaleContextHolder.getLocale())); + + String token = this.createMergeAccountConfirmation(model.getEmail()); createMergeNotificationEvent(token, user, model.getEmail(), NotificationContactType.EMAIL); createMergeNotificationEvent(token, user, model.getEmail(), NotificationContactType.IN_APP); } @@ -372,52 +382,54 @@ public class UserServiceImpl implements UserService { eventHandler.handle(event); } - public void sendRemoveCredentialConfirmation(UserRequestPersist model) throws InvalidApplicationException, JAXBException { + public void sendRemoveCredentialConfirmation(RemoveCredentialRequestPersist model) throws InvalidApplicationException, JAXBException { + UserCredentialEntity data = this.entityManager.find(UserCredentialEntity.class, model.getCredentialId()); + if (data == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getCredentialId(), UserCredentialEntity.class.getSimpleName()}, LocaleContextHolder.getLocale())); + if (!data.getUserId().equals(this.userScope.getUserId())) throw new MyForbiddenException(this.errors.getForbidden().getCode(), this.errors.getForbidden().getMessage()); - UserQuery userQuery = this.queryFactory.query(UserQuery.class).ids(model.getUserId()).isActive(IsActive.Active); - if (userQuery == null || userQuery.count() == 0){ - throw new MyApplicationException("User don't exist"); - } - UserContactInfoEntity userContactInfo = this.queryFactory.query(UserContactInfoQuery.class).types(ContactInfoType.Email).userIds(model.getUserId()).values(model.getEmail()).first(); - if(userContactInfo == null){ - throw new MyApplicationException("Email does not exist in this user!"); - } - UserCredentialQuery query = this.queryFactory.query(UserCredentialQuery.class).userIds(model.getUserId()); - if (query == null || query.count() == 0){ - throw new MyApplicationException("This user don't have credential!"); - } - String token = this.createActionConfirmation(model.getEmail(), ActionConfirmationType.RemoveCredential); - this.createRemoveCredentialNotificationEvent(token, model.getEmail(), model.getUserId(), NotificationContactType.EMAIL); - this.createRemoveCredentialNotificationEvent(token, model.getEmail(), model.getUserId(), NotificationContactType.IN_APP); + String token = this.createRemoveConfirmation(data.getId()); + this.createRemoveCredentialNotificationEvent(token, data.getUserId(), NotificationContactType.EMAIL); + this.createRemoveCredentialNotificationEvent(token, data.getUserId(), NotificationContactType.IN_APP); } - private void createRemoveCredentialNotificationEvent(String token, String email, UUID userId, NotificationContactType type) throws InvalidApplicationException { + private void createRemoveCredentialNotificationEvent(String token, UUID userId, NotificationContactType type) throws InvalidApplicationException { NotificationIntegrationEvent event = new NotificationIntegrationEvent(); event.setUserId(userId); - List contactPairs = new ArrayList<>(); - contactPairs.add(new ContactPair(ContactInfoType.Email, email)); - NotificationContactData contactData = new NotificationContactData(contactPairs, null, null); - event.setContactHint(jsonHandlingService.toJsonSafe(contactData)); event.setContactTypeHint(type); event.setNotificationType(notificationProperties.getRemoveCredentialConfirmationType()); NotificationFieldData data = new NotificationFieldData(); List fieldInfoList = new ArrayList<>(); fieldInfoList.add(new FieldInfo("{confirmationToken}", DataType.String, token)); - fieldInfoList.add(new FieldInfo("{email}", DataType.String, email)); fieldInfoList.add(new FieldInfo("{expiration_time}", DataType.String, this.secondsToTime(this.notificationProperties.getEmailExpirationTimeSeconds()))); data.setFields(fieldInfoList); event.setData(jsonHandlingService.toJsonSafe(data)); eventHandler.handle(event); } - private String createActionConfirmation(String email, ActionConfirmationType type) throws JAXBException, InvalidApplicationException { + private String createMergeAccountConfirmation(String email) throws JAXBException, InvalidApplicationException { ActionConfirmationPersist persist = new ActionConfirmationPersist(); - persist.setType(type); + persist.setType(ActionConfirmationType.MergeAccount); persist.setStatus(ActionConfirmationStatus.Requested); persist.setToken(UUID.randomUUID().toString()); - persist.setEmailConfirmation(new EmailConfirmationPersist(email)); - persist.setCreatedById(this.userScope.getUserId()); + persist.setMergeAccountConfirmation(new MergeAccountConfirmationPersist()); + persist.getMergeAccountConfirmation().setEmail(email); + persist.setExpiresAt(Instant.now().plusSeconds(this.notificationProperties.getEmailExpirationTimeSeconds())); + validatorFactory.validator(ActionConfirmationPersist.ActionConfirmationPersistValidator.class).validateForce(persist); + this.actionConfirmationService.persist(persist, null); + + return persist.getToken(); + } + + + + private String createRemoveConfirmation(UUID credentialId) throws JAXBException, InvalidApplicationException { + ActionConfirmationPersist persist = new ActionConfirmationPersist(); + persist.setType(ActionConfirmationType.RemoveCredential); + persist.setStatus(ActionConfirmationStatus.Requested); + persist.setToken(UUID.randomUUID().toString()); + persist.setRemoveCredentialRequest(new RemoveCredentialRequestPersist()); + persist.getRemoveCredentialRequest().setCredentialId(credentialId); persist.setExpiresAt(Instant.now().plusSeconds(this.notificationProperties.getEmailExpirationTimeSeconds())); validatorFactory.validator(ActionConfirmationPersist.ActionConfirmationPersistValidator.class).validateForce(persist); this.actionConfirmationService.persist(persist, null); @@ -433,19 +445,137 @@ public class UserServiceImpl implements UserService { return (hour + ":" + min + ":" + sec); } - public void confirmMergeAccount(String token) throws InvalidApplicationException { + public void confirmMergeAccount(String token) throws IOException, InvalidApplicationException { ActionConfirmationEntity action = this.queryFactory.query(ActionConfirmationQuery.class).tokens(token).types(ActionConfirmationType.MergeAccount).isActive(IsActive.Active).first(); if (action == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{token, ActionConfirmationEntity.class.getSimpleName()}, LocaleContextHolder.getLocale())); this.checkActionState(action); - EmailConfirmationEntity emailConfirmation = this.xmlHandlingService.fromXmlSafe(EmailConfirmationEntity.class, action.getData()); + MergeAccountConfirmationEntity mergeAccountConfirmationEntity = this.xmlHandlingService.fromXmlSafe(MergeAccountConfirmationEntity.class, action.getData()); + if (mergeAccountConfirmationEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{mergeAccountConfirmationEntity, MergeAccountConfirmationEntity.class.getSimpleName()}, LocaleContextHolder.getLocale())); + + UserContactInfoEntity userContactInfoEntity = this.queryFactory.query(UserContactInfoQuery.class).values(mergeAccountConfirmationEntity.getEmail()).types(ContactInfoType.Email).first(); + if (userContactInfoEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{mergeAccountConfirmationEntity.getEmail(), User.class.getSimpleName()}, LocaleContextHolder.getLocale())); + UserEntity userToBeMerge = this.queryFactory.query(UserQuery.class).ids(userContactInfoEntity.getUserId()).isActive(IsActive.Active).first(); + if (userToBeMerge == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{userContactInfoEntity.getUserId(), User.class.getSimpleName()}, LocaleContextHolder.getLocale())); + + if (!this.userScope.getUserIdSafe().equals(userToBeMerge.getId())) throw new MyForbiddenException("Only requested user can approve"); + + UserEntity newUser = this.queryFactory.query(UserQuery.class).ids(action.getCreatedById()).isActive(IsActive.Active).first(); + if (newUser == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{action.getCreatedById(), User.class.getSimpleName()}, LocaleContextHolder.getLocale())); + + if (!newUser.getId().equals(userToBeMerge.getId())){ + this.mergeNewUserToOld(newUser, userToBeMerge); + } + + action.setUpdatedAt(Instant.now()); action.setStatus(ActionConfirmationStatus.Accepted); + this.entityManager.merge(action); + this.entityManager.flush(); + } + + private void mergeNewUserToOld(UserEntity newUser, UserEntity oldUser) throws IOException, InvalidApplicationException { + List userCredentials = this.queryFactory.query(UserCredentialQuery.class).userIds(oldUser.getId()).collect(); + for (UserCredentialEntity userCredential : userCredentials){ + userCredential.setUserId(newUser.getId()); + this.entityManager.merge(userCredential); + } + + List userContactInfos = this.queryFactory.query(UserContactInfoQuery.class).userIds(oldUser.getId()).collect(); + UserContactInfoQuery newUserContactInfoQuery = this.queryFactory.query(UserContactInfoQuery.class).userIds(newUser.getId()); + newUserContactInfoQuery.setOrder(new Ordering().addDescending(UserContactInfo._ordinal)); + UserContactInfoEntity newUserContactInfo = newUserContactInfoQuery.first(); + int ordinal = newUserContactInfo == null ? 0 : newUserContactInfo.getOrdinal() + 1; + for (UserContactInfoEntity userContactInfo : userContactInfos){ + userContactInfo.setUserId(newUser.getId()); + userContactInfo.setOrdinal(ordinal); + this.entityManager.merge(userContactInfo); + ordinal++; + } + + List userRoles = this.queryFactory.query(UserRoleQuery.class).userIds(oldUser.getId()).collect(); + List newUserRoles = this.queryFactory.query(UserRoleQuery.class).userIds(newUser.getId()).collect(); + List rolesToDelete = new ArrayList<>(); + for (UserRoleEntity userRole : userRoles){ + if (newUserRoles.stream().anyMatch(x-> x.getRole().equals(userRole.getRole()))) { + rolesToDelete.add(userRole); + } else { + userRole.setUserId(newUser.getId()); + this.entityManager.merge(userRole); + } + } + this.deleterFactory.deleter(UserRoleDeleter.class).delete(rolesToDelete); + + List userSettings = this.queryFactory.query(UserSettingsQuery.class).entityIds(oldUser.getId()).collect(); + List newUserSettings = this.queryFactory.query(UserSettingsQuery.class).entityIds(newUser.getId()).collect(); + List userSettingsToDelete = new ArrayList<>(); + for (UserSettingsEntity userSetting : userSettings){ + if (newUserSettings.stream().anyMatch(x-> x.getKey().equals(userSetting.getKey()))) { + userSettingsToDelete.add(userSetting); + } else { + userSetting.setEntityId(newUser.getId()); + this.entityManager.merge(userSetting); + } + } + this.deleterFactory.deleter(UserSettingsSettingsDeleter.class).delete(userSettingsToDelete); + + List tags = this.queryFactory.query(TagQuery.class).createdByIds(oldUser.getId()).collect(); + for (TagEntity tag : tags){ + tag.setCreatedById(newUser.getId()); + this.entityManager.merge(tag); + } + + List storageFiles = this.queryFactory.query(StorageFileQuery.class).ownerIds(oldUser.getId()).collect(); + for (StorageFileEntity storageFile : storageFiles){ + storageFile.setOwnerId(newUser.getId()); + this.entityManager.merge(storageFile); + } + + List locks = this.queryFactory.query(LockQuery.class).lockedByIds(oldUser.getId()).collect(); + for (LockEntity lock : locks){ + lock.setLockedBy(newUser.getId()); + this.entityManager.merge(lock); + } + + List dmpUsers = this.queryFactory.query(DmpUserQuery.class).userIds(oldUser.getId()).collect(); + for (DmpUserEntity dmpUser : dmpUsers){ + dmpUser.setUserId(newUser.getId()); + this.entityManager.merge(dmpUser); + } + + List userDescriptionTemplates = this.queryFactory.query(UserDescriptionTemplateQuery.class).userIds(oldUser.getId()).collect(); + for (UserDescriptionTemplateEntity userDescriptionTemplate : userDescriptionTemplates){ + userDescriptionTemplate.setUserId(newUser.getId()); + this.entityManager.merge(userDescriptionTemplate); + } + + List dmps = this.queryFactory.query(DmpQuery.class).creatorIds(oldUser.getId()).collect(); + for (DmpEntity dmp : dmps){ + dmp.setCreatorId(newUser.getId()); + this.entityManager.merge(dmp); + } + + List descriptions = this.queryFactory.query(DescriptionQuery.class).createdByIds(oldUser.getId()).collect(); + for (DescriptionEntity description : descriptions){ + description.setCreatedById(newUser.getId()); + this.entityManager.merge(description); + } - //TODO merge -// this.entityManager.merge(action); + oldUser.setIsActive(IsActive.Inactive); + + this.entityManager.merge(oldUser); + + this.entityManager.flush(); + + for (DmpEntity dmp : dmps){ + this.elasticService.persistDmp(dmp); + } + + for (DescriptionEntity description : descriptions){ + this.elasticService.persistDescription(description); + } } @@ -456,14 +586,21 @@ public class UserServiceImpl implements UserService { this.checkActionState(action); - UserCredentialEntity userCredential = this.queryFactory.query(UserCredentialQuery.class).userIds(this.userScope.getUserIdSafe()).first(); - if (userCredential == null){ - throw new MyApplicationException("This user does not have credential"); - } - this.deleterFactory.deleter(UserCredentialDeleter.class).deleteAndSaveByIds(List.of(userCredential.getId())); + RemoveCredentialConfirmationEntity removeCredentialConfirmationEntity = this.xmlHandlingService.fromXmlSafe(RemoveCredentialConfirmationEntity.class, action.getData()); + if (removeCredentialConfirmationEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{removeCredentialConfirmationEntity, RemoveCredentialConfirmationEntity.class.getSimpleName()}, LocaleContextHolder.getLocale())); + UserCredentialEntity userCredentialEntity = this.queryFactory.query(UserCredentialQuery.class).ids(removeCredentialConfirmationEntity.getCredentialId()).first(); + if (userCredentialEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{removeCredentialConfirmationEntity.getCredentialId(), UserCredential.class.getSimpleName()}, LocaleContextHolder.getLocale())); + + if (!this.userScope.getUserIdSafe().equals(userCredentialEntity.getId())) throw new MyForbiddenException("Only requested user can approve"); + + this.deleterFactory.deleter(UserCredentialDeleter.class).delete(List.of(userCredentialEntity)); + + action.setUpdatedAt(Instant.now()); action.setStatus(ActionConfirmationStatus.Accepted); this.entityManager.merge(action); + + this.entityManager.flush(); } private void checkActionState(ActionConfirmationEntity action) throws MyApplicationException { diff --git a/dmp-backend/web/src/main/java/eu/eudat/configurations/JacksonConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/configurations/JacksonConfiguration.java deleted file mode 100644 index 266c23ede..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/configurations/JacksonConfiguration.java +++ /dev/null @@ -1,30 +0,0 @@ -package eu.eudat.configurations; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.Module; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.databind.module.SimpleModule; -import eu.eudat.criteria.entities.Criteria; -import eu.eudat.criteria.serialzier.CriteriaSerializer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import java.util.ArrayList; - -@Configuration -public class JacksonConfiguration { - @Bean - public ObjectMapper buildObjectMapper() { - - ArrayList modules = new ArrayList<>(); - SimpleModule criteriaSerializerModule = new SimpleModule(); - criteriaSerializerModule.addDeserializer(Criteria.class, new CriteriaSerializer()); - modules.add(criteriaSerializerModule); - - return new ObjectMapper() - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) - .registerModules(modules); - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/UserController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/UserController.java index ee2862f16..fdee9959a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/UserController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/v2/UserController.java @@ -14,16 +14,15 @@ import eu.eudat.model.builder.DmpAssociatedUserBuilder; import eu.eudat.model.builder.UserBuilder; import eu.eudat.model.censorship.DmpAssociatedUserCensor; import eu.eudat.model.censorship.UserCensor; -import eu.eudat.model.persist.UserRequestPersist; +import eu.eudat.model.persist.RemoveCredentialRequestPersist; +import eu.eudat.model.persist.UserMergeRequestPersist; import eu.eudat.model.persist.UserPersist; import eu.eudat.model.persist.UserRolePatchPersist; import eu.eudat.model.result.QueryResult; -import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.query.UserQuery; import eu.eudat.query.lookup.UserLookup; import eu.eudat.service.responseutils.ResponseUtilsService; import eu.eudat.service.user.UserService; -import eu.eudat.types.ApiMessageCode; import gr.cite.tools.auditing.AuditService; import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.data.censor.CensorFactory; @@ -38,7 +37,6 @@ import jakarta.xml.bind.JAXBException; import org.slf4j.LoggerFactory; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; @@ -132,7 +130,7 @@ public class UserController { public User get(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException { logger.debug(new MapLogEntry("retrieving" + User.class.getSimpleName()).And("id", id).And("fields", fieldSet)); - this.censorFactory.censor(UserCensor.class).censor(fieldSet, null); + this.censorFactory.censor(UserCensor.class).censor(fieldSet, id); UserQuery query = this.queryFactory.query(UserQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).ids(id); User model = this.builderFactory.builder(UserBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(fieldSet, query.firstAs(fieldSet)); @@ -180,18 +178,17 @@ public class UserController { } @GetMapping("mine") - public User getMine(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException { - logger.debug(new MapLogEntry("retrieving" + User.class.getSimpleName()).And("id", id).And("fields", fieldSet)); + public User getMine(FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException { + logger.debug(new MapLogEntry("retrieving me" + User.class.getSimpleName()).And("fields", fieldSet)); this.censorFactory.censor(UserCensor.class).censor(fieldSet, this.userScope.getUserId()); UserQuery query = this.queryFactory.query(UserQuery.class).ids(this.userScope.getUserId()).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic); User model = this.builderFactory.builder(UserBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(fieldSet, query.firstAs(fieldSet)); if (model == null) - throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, User.class.getSimpleName()}, LocaleContextHolder.getLocale())); + throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{this.userScope.getUserId(), User.class.getSimpleName()}, LocaleContextHolder.getLocale())); this.auditService.track(AuditableAction.User_Lookup, Map.ofEntries( - new AbstractMap.SimpleEntry("id", id), new AbstractMap.SimpleEntry("fields", fieldSet) )); @@ -271,10 +268,10 @@ public class UserController { this.auditService.track(AuditableAction.User_Delete, "id", id); } - @PostMapping("mine/merge-account-request/{email}") + @PostMapping("mine/merge-account-request") @Transactional - @ValidationFilterAnnotation(validator = UserRequestPersist.UserRequestPersistValidator.ValidatorName, argumentName = "model") - public Boolean mergeAccount(@RequestBody UserRequestPersist model) throws InvalidApplicationException, JAXBException { + @ValidationFilterAnnotation(validator = UserMergeRequestPersist.UserMergeRequestPersistValidator.ValidatorName, argumentName = "model") + public Boolean mergeAccount(@RequestBody UserMergeRequestPersist model) throws InvalidApplicationException, JAXBException { logger.debug(new MapLogEntry("merge account to user").And("email", model)); this.userTypeService.sendMergeAccountConfirmation(model); @@ -288,7 +285,7 @@ public class UserController { @GetMapping("mine/confirm-merge-account/token/{token}") @Transactional - public Boolean confirmMergeAccount(@PathVariable("token") String token) throws InvalidApplicationException, JAXBException { + public Boolean confirmMergeAccount(@PathVariable("token") String token) throws InvalidApplicationException, IOException { logger.debug(new MapLogEntry("confirm merge account to user").And("token", token)); this.userTypeService.confirmMergeAccount(token); @@ -300,10 +297,10 @@ public class UserController { return true; } - @PostMapping("mine/remove-credential-request/{email}") + @PostMapping("mine/remove-credential-request") @Transactional - @ValidationFilterAnnotation(validator = UserRequestPersist.UserRequestPersistValidator.ValidatorName, argumentName = "model") - public Boolean removeCredentialAccount(@RequestBody UserRequestPersist model) throws InvalidApplicationException, JAXBException { + @ValidationFilterAnnotation(validator = RemoveCredentialRequestPersist.RemoveCredentialRequestPersistValidator.ValidatorName, argumentName = "model") + public Boolean removeCredentialAccount(@RequestBody RemoveCredentialRequestPersist model) throws InvalidApplicationException, JAXBException { logger.debug(new MapLogEntry("remove credential request to user").And("model", model)); this.userTypeService.sendRemoveCredentialConfirmation(model); diff --git a/dmp-backend/web/src/main/resources/config/permissions.yml b/dmp-backend/web/src/main/resources/config/permissions.yml index eb3d23375..00bb8f25e 100644 --- a/dmp-backend/web/src/main/resources/config/permissions.yml +++ b/dmp-backend/web/src/main/resources/config/permissions.yml @@ -457,6 +457,7 @@ permissions: BrowseReference: roles: - Admin + - User clients: [ ] allowAnonymous: false allowAuthenticated: false @@ -711,19 +712,19 @@ permissions: # ActionConfirmation Permissions BrowseActionConfirmation: roles: - - User + - Admin clients: [ ] allowAnonymous: false allowAuthenticated: false EditActionConfirmation: roles: - - User + - Admin clients: [ ] allowAnonymous: false allowAuthenticated: false DeleteActionConfirmation: roles: - - User + - Admin claims: [ ] clients: [ ] allowAnonymous: false