merge remove credential changes

This commit is contained in:
Efstratios Giannopoulos 2024-01-15 13:57:33 +02:00
parent 0e61925f8d
commit 4da8c2a6a9
26 changed files with 639 additions and 272 deletions

View File

@ -24,6 +24,11 @@
<artifactId>commons-csv</artifactId> <artifactId>commons-csv</artifactId>
<version>1.10.0</version> <version>1.10.0</version>
</dependency> </dependency>
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>1.8.0</version>
</dependency>
<dependency> <dependency>
<groupId>gr.cite</groupId> <groupId>gr.cite</groupId>
<artifactId>validation</artifactId> <artifactId>validation</artifactId>

View File

@ -5,9 +5,9 @@ import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlAttribute; import jakarta.xml.bind.annotation.XmlAttribute;
import jakarta.xml.bind.annotation.XmlRootElement; import jakarta.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "email-confirmation") @XmlRootElement(name = "merge-account-confirmation")
@XmlAccessorType(XmlAccessType.FIELD) @XmlAccessorType(XmlAccessType.FIELD)
public class EmailConfirmationEntity { public class MergeAccountConfirmationEntity {
@XmlAttribute(name = "email") @XmlAttribute(name = "email")
private String email; private String email;

View File

@ -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;
}
}

View File

@ -3,6 +3,8 @@ package eu.eudat.commons.validation;
import eu.eudat.convention.ConventionService; import eu.eudat.convention.ConventionService;
import eu.eudat.errorcode.ErrorThesaurusProperties; import eu.eudat.errorcode.ErrorThesaurusProperties;
import gr.cite.tools.exception.MyValidationException; import gr.cite.tools.exception.MyValidationException;
import org.apache.commons.validator.routines.EmailValidator;
import java.util.*; import java.util.*;
public abstract class BaseValidator<T> extends AbstractValidator<T> { public abstract class BaseValidator<T> extends AbstractValidator<T> {
@ -27,6 +29,9 @@ public abstract class BaseValidator<T> extends AbstractValidator<T> {
protected Boolean isValidGuid(UUID guid) { protected Boolean isValidGuid(UUID guid) {
return this.conventionService.isValidGuid(guid); return this.conventionService.isValidGuid(guid);
} }
protected Boolean isValidEmail(String value) {
return EmailValidator.getInstance().isValid(value);
}
protected Boolean isValidHash(String hash) { protected Boolean isValidHash(String hash) {
return this.conventionService.isValidHash(hash); return this.conventionService.isValidHash(hash);

View File

@ -20,9 +20,6 @@ public class ActionConfirmation {
private ActionConfirmationStatus status; private ActionConfirmationStatus status;
public static final String _status = "status"; public static final String _status = "status";
private String token;
public static final String _token = "token";
private EmailConfirmation emailConfirmation; private EmailConfirmation emailConfirmation;
public static final String _emailConfirmation = "emailConfirmation"; public static final String _emailConfirmation = "emailConfirmation";
@ -75,14 +72,6 @@ public class ActionConfirmation {
this.status = status; this.status = status;
} }
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public EmailConfirmation getEmailConfirmation() { public EmailConfirmation getEmailConfirmation() {
return emailConfirmation; return emailConfirmation;
} }

View File

@ -4,7 +4,7 @@ import eu.eudat.authorization.AuthorizationFlags;
import eu.eudat.commons.XmlHandlingService; import eu.eudat.commons.XmlHandlingService;
import eu.eudat.commons.enums.ActionConfirmationType; import eu.eudat.commons.enums.ActionConfirmationType;
import eu.eudat.commons.types.actionconfirmation.DmpInvitationEntity; 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.convention.ConventionService;
import eu.eudat.data.ActionConfirmationEntity; import eu.eudat.data.ActionConfirmationEntity;
import eu.eudat.model.ActionConfirmation; import eu.eudat.model.ActionConfirmation;
@ -71,12 +71,11 @@ public class ActionConfirmationBuilder extends BaseBuilder<ActionConfirmation, A
if(fields.hasField(this.asIndexer(ActionConfirmation._id))) m.setId(d.getId()); if(fields.hasField(this.asIndexer(ActionConfirmation._id))) m.setId(d.getId());
if(fields.hasField(this.asIndexer(ActionConfirmation._type))) m.setType(d.getType()); if(fields.hasField(this.asIndexer(ActionConfirmation._type))) m.setType(d.getType());
if(fields.hasField(this.asIndexer(ActionConfirmation._status))) m.setStatus(d.getStatus()); if(fields.hasField(this.asIndexer(ActionConfirmation._status))) m.setStatus(d.getStatus());
if(fields.hasField(this.asIndexer(ActionConfirmation._token))) m.setToken(d.getToken());
if(fields.hasField(this.asIndexer(ActionConfirmation._isActive))) m.setIsActive(d.getIsActive()); if(fields.hasField(this.asIndexer(ActionConfirmation._isActive))) m.setIsActive(d.getIsActive());
if(fields.hasField(this.asIndexer(ActionConfirmation._expiresAt))) m.setExpiresAt(d.getExpiresAt()); if(fields.hasField(this.asIndexer(ActionConfirmation._expiresAt))) m.setExpiresAt(d.getExpiresAt());
if (!emailConfirmationFields.isEmpty() && d.getData() != null){ if (!emailConfirmationFields.isEmpty() && d.getData() != null){
if (d.getType().equals(ActionConfirmationType.MergeAccount) || d.getType().equals(ActionConfirmationType.RemoveCredential)){ if (d.getType().equals(ActionConfirmationType.MergeAccount) || d.getType().equals(ActionConfirmationType.RemoveCredential)){
EmailConfirmationEntity emailConfirmation = this.xmlHandlingService.fromXmlSafe(EmailConfirmationEntity.class, d.getData()); MergeAccountConfirmationEntity emailConfirmation = this.xmlHandlingService.fromXmlSafe(MergeAccountConfirmationEntity.class, d.getData());
m.setEmailConfirmation(this.builderFactory.builder(EmailConfirmationBuilder.class).authorize(this.authorize).build(emailConfirmationFields, emailConfirmation)); m.setEmailConfirmation(this.builderFactory.builder(EmailConfirmationBuilder.class).authorize(this.authorize).build(emailConfirmationFields, emailConfirmation));
}else{ }else{
DmpInvitationEntity dmpInvitation = this.xmlHandlingService.fromXmlSafe(DmpInvitationEntity.class, d.getData()); DmpInvitationEntity dmpInvitation = this.xmlHandlingService.fromXmlSafe(DmpInvitationEntity.class, d.getData());

View File

@ -1,7 +1,7 @@
package eu.eudat.model.builder.actionconfirmation; package eu.eudat.model.builder.actionconfirmation;
import eu.eudat.authorization.AuthorizationFlags; import eu.eudat.authorization.AuthorizationFlags;
import eu.eudat.commons.types.actionconfirmation.EmailConfirmationEntity; import eu.eudat.commons.types.actionconfirmation.MergeAccountConfirmationEntity;
import eu.eudat.convention.ConventionService; import eu.eudat.convention.ConventionService;
import eu.eudat.model.actionconfirmation.EmailConfirmation; import eu.eudat.model.actionconfirmation.EmailConfirmation;
import eu.eudat.model.builder.BaseBuilder; import eu.eudat.model.builder.BaseBuilder;
@ -20,7 +20,7 @@ import java.util.*;
@Component @Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class EmailConfirmationBuilder extends BaseBuilder<EmailConfirmation, EmailConfirmationEntity> { public class EmailConfirmationBuilder extends BaseBuilder<EmailConfirmation, MergeAccountConfirmationEntity> {
private final BuilderFactory builderFactory; private final BuilderFactory builderFactory;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None); private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
@ -38,7 +38,7 @@ public class EmailConfirmationBuilder extends BaseBuilder<EmailConfirmation, Ema
} }
@Override @Override
public List<EmailConfirmation> build(FieldSet fields, List<EmailConfirmationEntity> data) throws MyApplicationException { public List<EmailConfirmation> build(FieldSet fields, List<MergeAccountConfirmationEntity> 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.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)); this.logger.trace(new DataLogEntry("requested fields", fields));
if (fields == null || data == null || fields.isEmpty()) if (fields == null || data == null || fields.isEmpty())
@ -46,7 +46,7 @@ public class EmailConfirmationBuilder extends BaseBuilder<EmailConfirmation, Ema
List<EmailConfirmation> models = new ArrayList<>(); List<EmailConfirmation> models = new ArrayList<>();
for (EmailConfirmationEntity d : data) { for (MergeAccountConfirmationEntity d : data) {
EmailConfirmation m = new EmailConfirmation(); EmailConfirmation m = new EmailConfirmation();
if (fields.hasField(this.asIndexer(EmailConfirmation._email))) m.setEmail(d.getEmail()); if (fields.hasField(this.asIndexer(EmailConfirmation._email))) m.setEmail(d.getEmail());

View File

@ -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<UUID> ids) throws InvalidApplicationException {
logger.debug(new MapLogEntry("collecting to delete").And("count", Optional.ofNullable(ids).map(List::size).orElse(0)).And("ids", ids));
List<UserSettingsEntity> 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<UserSettingsEntity> 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<UserSettingsEntity> 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");
}
}
}

View File

@ -8,7 +8,7 @@ import eu.eudat.commons.validation.specification.Specification;
import eu.eudat.convention.ConventionService; import eu.eudat.convention.ConventionService;
import eu.eudat.errorcode.ErrorThesaurusProperties; import eu.eudat.errorcode.ErrorThesaurusProperties;
import eu.eudat.model.persist.actionconfirmation.DmpInvitationPersist; 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.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.MessageSource; import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
@ -40,18 +40,18 @@ public class ActionConfirmationPersist {
private static final String _dmpInvitation = "dmpInvitation"; 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 Instant expiresAt;
private static final String _expiresAt = "expiresAt"; private static final String _expiresAt = "expiresAt";
private UUID createdById;
private static final String _createdById = "createdById";
private String hash; private String hash;
private static final String _hash = "hash"; private static final String _hash = "hash";
@ -80,14 +80,6 @@ public class ActionConfirmationPersist {
this.status = status; this.status = status;
} }
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public DmpInvitationPersist getDmpInvitation() { public DmpInvitationPersist getDmpInvitation() {
return dmpInvitation; return dmpInvitation;
} }
@ -96,12 +88,28 @@ public class ActionConfirmationPersist {
this.dmpInvitation = dmpInvitation; this.dmpInvitation = dmpInvitation;
} }
public EmailConfirmationPersist getEmailConfirmation() { public MergeAccountConfirmationPersist getMergeAccountConfirmation() {
return emailConfirmation; return mergeAccountConfirmation;
} }
public void setEmailConfirmation(EmailConfirmationPersist emailConfirmation) { public void setMergeAccountConfirmation(MergeAccountConfirmationPersist mergeAccountConfirmation) {
this.emailConfirmation = emailConfirmation; 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() { public Instant getExpiresAt() {
@ -112,13 +120,6 @@ public class ActionConfirmationPersist {
this.expiresAt = expiresAt; this.expiresAt = expiresAt;
} }
public UUID getCreatedById() {
return createdById;
}
public void setCreatedById(UUID createdById) {
this.createdById = createdById;
}
public String getHash() { public String getHash() {
return hash; return hash;
@ -173,8 +174,18 @@ public class ActionConfirmationPersist {
.must(() -> !this.isNull(item.getExpiresAt())) .must(() -> !this.isNull(item.getExpiresAt()))
.failOn(ActionConfirmationPersist._expiresAt).failWith(messageSource.getMessage("Validation_Required", new Object[]{ActionConfirmationPersist._expiresAt}, LocaleContextHolder.getLocale())), .failOn(ActionConfirmationPersist._expiresAt).failWith(messageSource.getMessage("Validation_Required", new Object[]{ActionConfirmationPersist._expiresAt}, LocaleContextHolder.getLocale())),
this.spec() this.spec()
.must(() -> !this.isNull(item.getCreatedById())) .iff(() -> ActionConfirmationType.MergeAccount.equals(item.getType()))
.failOn(ActionConfirmationPersist._createdById).failWith(messageSource.getMessage("Validation_Required", new Object[]{ActionConfirmationPersist._createdById}, LocaleContextHolder.getLocale())), .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() this.refSpec()
.iff(() -> !this.isNull(item.getDmpInvitation())) .iff(() -> !this.isNull(item.getDmpInvitation()))
@ -182,10 +193,16 @@ public class ActionConfirmationPersist {
.over(item.getDmpInvitation()) .over(item.getDmpInvitation())
.using(() -> this.validatorFactory.validator(DmpInvitationPersist.DmpInvitationPersistValidator.class)), .using(() -> this.validatorFactory.validator(DmpInvitationPersist.DmpInvitationPersistValidator.class)),
this.refSpec() this.refSpec()
.iff(() -> !this.isNull(item.getEmailConfirmation())) .iff(() -> !this.isNull(item.getMergeAccountConfirmation()))
.on(ActionConfirmationPersist._emailConfirmation) .on(ActionConfirmationPersist._mergeAccountConfirmation)
.over(item.getEmailConfirmation()) .over(item.getMergeAccountConfirmation())
.using(() -> this.validatorFactory.validator(EmailConfirmationPersist.EmailConfirmationPersistValidator.class)) .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))
); );
} }

View File

@ -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<RemoveCredentialRequestPersist> {
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<RemoveCredentialRequestPersist> modelClass() {
return RemoveCredentialRequestPersist.class;
}
@Override
protected List<Specification> 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()))
);
}
}
}

View File

@ -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<UserMergeRequestPersist> {
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<UserMergeRequestPersist> modelClass() {
return UserMergeRequestPersist.class;
}
@Override
protected List<Specification> 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()))
);
}
}
}

View File

@ -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<UserRequestPersist> {
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<UserRequestPersist> modelClass() {
return UserRequestPersist.class;
}
@Override
protected List<Specification> 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()))
);
}
}
}

View File

@ -13,15 +13,12 @@ import org.springframework.stereotype.Component;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
public class EmailConfirmationPersist { public class MergeAccountConfirmationPersist {
private String email; private String email;
public static final String _email = "email"; public static final String _email = "email";
public EmailConfirmationPersist(String email) {
this.email = email;
}
public String getEmail() { public String getEmail() {
return email; return email;
@ -31,30 +28,30 @@ public class EmailConfirmationPersist {
this.email = email; this.email = email;
} }
@Component(EmailConfirmationPersistValidator.ValidatorName) @Component(MergeAccountConfirmationPersistValidator.ValidatorName)
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public static class EmailConfirmationPersistValidator extends BaseValidator<EmailConfirmationPersist> { public static class MergeAccountConfirmationPersistValidator extends BaseValidator<MergeAccountConfirmationPersist> {
public static final String ValidatorName = "EmailConfirmationPersistValidator"; public static final String ValidatorName = "MergeAccountConfirmationPersistValidator";
private final MessageSource messageSource; private final MessageSource messageSource;
protected EmailConfirmationPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) { protected MergeAccountConfirmationPersistValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource) {
super(conventionService, errors); super(conventionService, errors);
this.messageSource = messageSource; this.messageSource = messageSource;
} }
@Override @Override
protected Class<EmailConfirmationPersist> modelClass() { protected Class<MergeAccountConfirmationPersist> modelClass() {
return EmailConfirmationPersist.class; return MergeAccountConfirmationPersist.class;
} }
@Override @Override
protected List<Specification> specifications(EmailConfirmationPersist item) { protected List<Specification> specifications(MergeAccountConfirmationPersist item) {
return Collections.singletonList( return Collections.singletonList(
this.spec() this.spec()
.must(() -> !this.isEmpty(item.getEmail())) .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()))
); );
} }
} }

View File

@ -237,7 +237,7 @@ public class ActionConfirmationQuery extends QueryBase<ActionConfirmationEntity>
if (item.match(ActionConfirmation._id)) return ActionConfirmationEntity._id; if (item.match(ActionConfirmation._id)) return ActionConfirmationEntity._id;
else if (item.match(ActionConfirmation._type)) return ActionConfirmationEntity._type; else if (item.match(ActionConfirmation._type)) return ActionConfirmationEntity._type;
else if (item.match(ActionConfirmation._status)) return ActionConfirmationEntity._status; 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.match(ActionConfirmation._expiresAt)) return ActionConfirmationEntity._expiresAt;
else if (item.prefix(ActionConfirmation._emailConfirmation)) return ActionConfirmationEntity._data; else if (item.prefix(ActionConfirmation._emailConfirmation)) return ActionConfirmationEntity._data;
else if (item.prefix(ActionConfirmation._dmpInvitation)) return ActionConfirmationEntity._data; else if (item.prefix(ActionConfirmation._dmpInvitation)) return ActionConfirmationEntity._data;

View File

@ -35,6 +35,8 @@ import java.util.*;
public class DescriptionQuery extends QueryBase<DescriptionEntity> { public class DescriptionQuery extends QueryBase<DescriptionEntity> {
private String like; private String like;
private Collection<UUID> ids; private Collection<UUID> ids;
private Collection<UUID> createdByIds;
private DmpDescriptionTemplateQuery dmpDescriptionTemplateQuery; private DmpDescriptionTemplateQuery dmpDescriptionTemplateQuery;
private DmpQuery dmpQuery; private DmpQuery dmpQuery;
private Instant createdAfter; private Instant createdAfter;
@ -78,6 +80,21 @@ public class DescriptionQuery extends QueryBase<DescriptionEntity> {
return this; 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<UUID> values) {
this.createdByIds = values;
return this;
}
public DescriptionQuery dmpDescriptionTemplateSubQuery(DmpDescriptionTemplateQuery subQuery) { public DescriptionQuery dmpDescriptionTemplateSubQuery(DmpDescriptionTemplateQuery subQuery) {
this.dmpDescriptionTemplateQuery = subQuery; this.dmpDescriptionTemplateQuery = subQuery;
return this; return this;
@ -174,7 +191,7 @@ public class DescriptionQuery extends QueryBase<DescriptionEntity> {
protected Boolean isFalseQuery() { protected Boolean isFalseQuery() {
return return
this.isEmpty(this.ids) || 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.excludedIds) || this.isFalseQuery(this.dmpQuery) ||
this.isEmpty(this.statuses) || this.isFalseQuery(this.dmpDescriptionTemplateQuery); this.isEmpty(this.statuses) || this.isFalseQuery(this.dmpDescriptionTemplateQuery);
} }
@ -220,6 +237,12 @@ public class DescriptionQuery extends QueryBase<DescriptionEntity> {
inClause.value(item); inClause.value(item);
predicates.add(inClause); predicates.add(inClause);
} }
if (this.createdByIds != null) {
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DescriptionEntity._createdById));
for (UUID item : this.createdByIds)
inClause.value(item);
predicates.add(inClause);
}
if (this.createdAfter != null) { if (this.createdAfter != null) {
predicates.add(queryContext.CriteriaBuilder.greaterThan(queryContext.Root.get(DescriptionEntity._createdAt), this.createdAfter)); predicates.add(queryContext.CriteriaBuilder.greaterThan(queryContext.Root.get(DescriptionEntity._createdAt), this.createdAfter));
} }

View File

@ -31,6 +31,7 @@ public class DmpQuery extends QueryBase<DmpEntity> {
private String like; private String like;
private Collection<UUID> ids; private Collection<UUID> ids;
private Collection<UUID> creatorIds;
private Collection<UUID> excludedIds; private Collection<UUID> excludedIds;
@ -79,6 +80,21 @@ public class DmpQuery extends QueryBase<DmpEntity> {
return this; 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<UUID> values) {
this.creatorIds = values;
return this;
}
public DmpQuery excludedIds(Collection<UUID> values) { public DmpQuery excludedIds(Collection<UUID> values) {
this.excludedIds = values; this.excludedIds = values;
return this; return this;
@ -201,7 +217,7 @@ public class DmpQuery extends QueryBase<DmpEntity> {
@Override @Override
protected Boolean isFalseQuery() { 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 @Override
@ -248,6 +264,12 @@ public class DmpQuery extends QueryBase<DmpEntity> {
inClause.value(item); inClause.value(item);
predicates.add(inClause); predicates.add(inClause);
} }
if (this.creatorIds != null) {
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpEntity._creatorId));
for (UUID item : this.creatorIds)
inClause.value(item);
predicates.add(inClause);
}
if (this.excludedIds != null) { if (this.excludedIds != null) {
CriteriaBuilder.In<UUID> notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpEntity._id)); CriteriaBuilder.In<UUID> notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpEntity._id));
for (UUID item : this.excludedIds) for (UUID item : this.excludedIds)

View File

@ -24,6 +24,7 @@ public class LockQuery extends QueryBase<LockEntity> {
private Collection<UUID> ids; private Collection<UUID> ids;
private Collection<UUID> targetIds; private Collection<UUID> targetIds;
private Collection<UUID> lockedByIds;
private Collection<LockTargetType> targetTypes; private Collection<LockTargetType> targetTypes;
@ -46,6 +47,21 @@ public class LockQuery extends QueryBase<LockEntity> {
return this; 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<UUID> values) {
this.lockedByIds = values;
return this;
}
public LockQuery targetIds(UUID value) { public LockQuery targetIds(UUID value) {
this.targetIds = List.of(value); this.targetIds = List.of(value);
return this; return this;
@ -106,7 +122,7 @@ public class LockQuery extends QueryBase<LockEntity> {
@Override @Override
protected Boolean isFalseQuery() { 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 @Override
@ -118,6 +134,12 @@ public class LockQuery extends QueryBase<LockEntity> {
inClause.value(item); inClause.value(item);
predicates.add(inClause); predicates.add(inClause);
} }
if (this.lockedByIds != null) {
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(LockEntity._lockedBy));
for (UUID item : this.lockedByIds)
inClause.value(item);
predicates.add(inClause);
}
if (this.targetIds != null) { if (this.targetIds != null) {
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(LockEntity._target)); CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(LockEntity._target));
for (UUID item : this.targetIds) for (UUID item : this.targetIds)

View File

@ -25,6 +25,7 @@ import java.util.*;
public class StorageFileQuery extends QueryBase<StorageFileEntity> { public class StorageFileQuery extends QueryBase<StorageFileEntity> {
private String like; private String like;
private Collection<UUID> ids; private Collection<UUID> ids;
private Collection<UUID> ownerIds;
private Boolean canPurge; private Boolean canPurge;
private Boolean isPurged; private Boolean isPurged;
private Instant createdAfter; private Instant createdAfter;
@ -58,6 +59,21 @@ public class StorageFileQuery extends QueryBase<StorageFileEntity> {
return this; 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<UUID> values) {
this.ownerIds = values;
return this;
}
public StorageFileQuery createdAfter(Instant value) { public StorageFileQuery createdAfter(Instant value) {
this.createdAfter = value; this.createdAfter = value;
return this; return this;
@ -97,6 +113,7 @@ public class StorageFileQuery extends QueryBase<StorageFileEntity> {
protected Boolean isFalseQuery() { protected Boolean isFalseQuery() {
return return
this.isEmpty(this.ids) || this.isEmpty(this.ids) ||
this.isEmpty(this.ownerIds) ||
this.isEmpty(this.excludedIds) ; this.isEmpty(this.excludedIds) ;
} }
@ -137,6 +154,12 @@ public class StorageFileQuery extends QueryBase<StorageFileEntity> {
inClause.value(item); inClause.value(item);
predicates.add(inClause); predicates.add(inClause);
} }
if (this.ownerIds != null) {
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(StorageFileEntity._ownerId));
for (UUID item : this.ownerIds)
inClause.value(item);
predicates.add(inClause);
}
if (this.createdAfter != null) { if (this.createdAfter != null) {
predicates.add(queryContext.CriteriaBuilder.greaterThan(queryContext.Root.get(StorageFileEntity._createdAt), this.createdAfter)); predicates.add(queryContext.CriteriaBuilder.greaterThan(queryContext.Root.get(StorageFileEntity._createdAt), this.createdAfter));
} }

View File

@ -1,5 +1,6 @@
package eu.eudat.service.actionconfirmation; package eu.eudat.service.actionconfirmation;
import eu.eudat.model.ActionConfirmation;
import eu.eudat.model.persist.ActionConfirmationPersist; import eu.eudat.model.persist.ActionConfirmationPersist;
import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.exception.MyForbiddenException; import gr.cite.tools.exception.MyForbiddenException;
@ -14,7 +15,7 @@ import java.util.UUID;
public interface ActionConfirmationService { 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; void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException, IOException;

View File

@ -1,19 +1,26 @@
package eu.eudat.service.actionconfirmation; package eu.eudat.service.actionconfirmation;
import eu.eudat.authorization.OwnedResource;
import eu.eudat.authorization.Permission; import eu.eudat.authorization.Permission;
import eu.eudat.commons.XmlHandlingService; import eu.eudat.commons.XmlHandlingService;
import eu.eudat.commons.enums.ActionConfirmationType;
import eu.eudat.commons.enums.IsActive; 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.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.convention.ConventionService;
import eu.eudat.data.ActionConfirmationEntity; import eu.eudat.data.ActionConfirmationEntity;
import eu.eudat.errorcode.ErrorThesaurusProperties; import eu.eudat.errorcode.ErrorThesaurusProperties;
import eu.eudat.model.ActionConfirmation;
import eu.eudat.model.Dmp;
import eu.eudat.model.ReferenceType; 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.deleter.ActionConfirmationDeleter;
import eu.eudat.model.persist.ActionConfirmationPersist; 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.DmpInvitationPersist;
import eu.eudat.model.persist.actionconfirmation.EmailConfirmationPersist; import eu.eudat.model.persist.actionconfirmation.MergeAccountConfirmationPersist;
import eu.eudat.service.dmpblueprint.DmpBlueprintServiceImpl; import eu.eudat.service.dmpblueprint.DmpBlueprintServiceImpl;
import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.tools.data.builder.BuilderFactory; 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.MyForbiddenException;
import gr.cite.tools.exception.MyNotFoundException; import gr.cite.tools.exception.MyNotFoundException;
import gr.cite.tools.exception.MyValidationException; import gr.cite.tools.exception.MyValidationException;
import gr.cite.tools.fieldset.BaseFieldSet;
import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.LoggerService;
import gr.cite.tools.logging.MapLogEntry; import gr.cite.tools.logging.MapLogEntry;
@ -51,12 +59,12 @@ public class ActionConfirmationServiceImpl implements ActionConfirmationService
private final MessageSource messageSource; private final MessageSource messageSource;
private final XmlHandlingService xmlHandlingService; private final XmlHandlingService xmlHandlingService;
private final ErrorThesaurusProperties errors; private final ErrorThesaurusProperties errors;
private final UserScope userScope;
public ActionConfirmationServiceImpl( public ActionConfirmationServiceImpl(
EntityManager entityManager, AuthorizationService authorizationService, DeleterFactory deleterFactory, BuilderFactory builderFactory, EntityManager entityManager, AuthorizationService authorizationService, DeleterFactory deleterFactory, BuilderFactory builderFactory,
ConventionService conventionService, MessageSource messageSource, ConventionService conventionService, MessageSource messageSource,
XmlHandlingService xmlHandlingService, ErrorThesaurusProperties errors) { XmlHandlingService xmlHandlingService, ErrorThesaurusProperties errors, UserScope userScope) {
this.entityManager = entityManager; this.entityManager = entityManager;
this.authorizationService = authorizationService; this.authorizationService = authorizationService;
this.deleterFactory = deleterFactory; this.deleterFactory = deleterFactory;
@ -65,13 +73,13 @@ public class ActionConfirmationServiceImpl implements ActionConfirmationService
this.messageSource = messageSource; this.messageSource = messageSource;
this.xmlHandlingService = xmlHandlingService; this.xmlHandlingService = xmlHandlingService;
this.errors = errors; 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)); 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()); Boolean isUpdate = this.conventionService.isValidGuid(model.getId());
@ -86,17 +94,19 @@ public class ActionConfirmationServiceImpl implements ActionConfirmationService
data.setId(UUID.randomUUID()); data.setId(UUID.randomUUID());
data.setIsActive(IsActive.Active); data.setIsActive(IsActive.Active);
data.setCreatedAt(Instant.now()); data.setCreatedAt(Instant.now());
data.setCreatedById(userScope.getUserId());
} }
this.authorizationService.authorizeAtLeastOneForce(List.of(new OwnedResource(data.getCreatedById())), Permission.EditActionConfirmation);
data.setToken(model.getToken()); data.setToken(model.getToken());
data.setCreatedById(model.getCreatedById());
data.setType(model.getType()); data.setType(model.getType());
data.setStatus(model.getStatus()); data.setStatus(model.getStatus());
data.setExpiresAt(model.getExpiresAt()); data.setExpiresAt(model.getExpiresAt());
if (model.getType().equals(ActionConfirmationType.MergeAccount) || model.getType().equals(ActionConfirmationType.RemoveCredential)){ switch (model.getType()){
data.setData(this.xmlHandlingService.toXmlSafe(this.buildEmailConfirmationEntity(model.getEmailConfirmation()))); case MergeAccount -> data.setData(this.xmlHandlingService.toXmlSafe(this.buildMergeAccountConfirmationEntity(model.getMergeAccountConfirmation())));
}else{ case DmpInvitation -> data.setData(this.xmlHandlingService.toXmlSafe(this.buildDmpInvitationEntity(model.getDmpInvitation())));
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()); data.setUpdatedAt(Instant.now());
@ -105,6 +115,7 @@ public class ActionConfirmationServiceImpl implements ActionConfirmationService
this.entityManager.flush(); this.entityManager.flush();
return this.builderFactory.builder(ActionConfirmationBuilder.class).build(BaseFieldSet.build(fields, ActionConfirmation._id), data);
} }
private @NotNull DmpInvitationEntity buildDmpInvitationEntity(DmpInvitationPersist persist){ private @NotNull DmpInvitationEntity buildDmpInvitationEntity(DmpInvitationPersist persist){
@ -118,8 +129,8 @@ public class ActionConfirmationServiceImpl implements ActionConfirmationService
return data; return data;
} }
private @NotNull EmailConfirmationEntity buildEmailConfirmationEntity(EmailConfirmationPersist persist){ private @NotNull MergeAccountConfirmationEntity buildMergeAccountConfirmationEntity(MergeAccountConfirmationPersist persist){
EmailConfirmationEntity data = new EmailConfirmationEntity(); MergeAccountConfirmationEntity data = new MergeAccountConfirmationEntity();
if (persist == null) return data; if (persist == null) return data;
data.setEmail(persist.getEmail()); data.setEmail(persist.getEmail());
@ -127,6 +138,15 @@ public class ActionConfirmationServiceImpl implements ActionConfirmationService
return data; 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 { public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException {
logger.debug("deleting : {}", id); logger.debug("deleting : {}", id);

View File

@ -833,7 +833,6 @@ public class DmpServiceImpl implements DmpService {
persist.setStatus(ActionConfirmationStatus.Requested); persist.setStatus(ActionConfirmationStatus.Requested);
persist.setToken(UUID.randomUUID().toString()); persist.setToken(UUID.randomUUID().toString());
persist.setDmpInvitation(new DmpInvitationPersist(email, dmp.getId(), role)); persist.setDmpInvitation(new DmpInvitationPersist(email, dmp.getId(), role));
persist.setCreatedById(this.userScope.getUserIdSafe());
persist.setExpiresAt(Instant.now().plusSeconds(this.notificationProperties.getEmailExpirationTimeSeconds())); persist.setExpiresAt(Instant.now().plusSeconds(this.notificationProperties.getEmailExpirationTimeSeconds()));
validatorFactory.validator(ActionConfirmationPersist.ActionConfirmationPersistValidator.class).validateForce(persist); validatorFactory.validator(ActionConfirmationPersist.ActionConfirmationPersistValidator.class).validateForce(persist);
this.actionConfirmationService.persist(persist, null); this.actionConfirmationService.persist(persist, null);

View File

@ -2,7 +2,8 @@ package eu.eudat.service.user;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import eu.eudat.model.User; 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.UserPersist;
import eu.eudat.model.persist.UserRolePatchPersist; import eu.eudat.model.persist.UserRolePatchPersist;
import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.exception.MyApplicationException;
@ -32,11 +33,11 @@ public interface UserService {
User patchRoles(UserRolePatchPersist model, FieldSet fields) throws InvalidApplicationException; 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; void confirmRemoveCredential(String token) throws InvalidApplicationException;

View File

@ -12,7 +12,8 @@ import eu.eudat.commons.enums.ContactInfoType;
import eu.eudat.commons.enums.IsActive; import eu.eudat.commons.enums.IsActive;
import eu.eudat.commons.enums.notification.NotificationContactType; import eu.eudat.commons.enums.notification.NotificationContactType;
import eu.eudat.commons.scope.user.UserScope; 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.notification.*;
import eu.eudat.commons.types.user.AdditionalInfoEntity; import eu.eudat.commons.types.user.AdditionalInfoEntity;
import eu.eudat.commons.validation.ValidatorFactory; 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.integrationevent.outbox.notification.NotificationIntegrationEventHandler;
import eu.eudat.model.User; import eu.eudat.model.User;
import eu.eudat.model.UserContactInfo; import eu.eudat.model.UserContactInfo;
import eu.eudat.model.UserCredential;
import eu.eudat.model.builder.UserBuilder; import eu.eudat.model.builder.UserBuilder;
import eu.eudat.model.deleter.UserCredentialDeleter; import eu.eudat.model.deleter.UserCredentialDeleter;
import eu.eudat.model.deleter.UserDeleter; import eu.eudat.model.deleter.UserDeleter;
import eu.eudat.model.deleter.UserRoleDeleter; import eu.eudat.model.deleter.UserRoleDeleter;
import eu.eudat.model.deleter.UserSettingsSettingsDeleter;
import eu.eudat.model.persist.*; 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.query.*;
import eu.eudat.service.actionconfirmation.ActionConfirmationService; import eu.eudat.service.actionconfirmation.ActionConfirmationService;
import eu.eudat.service.elastic.ElasticService;
import eu.eudat.service.keycloak.KeycloakRole; import eu.eudat.service.keycloak.KeycloakRole;
import eu.eudat.service.keycloak.KeycloakService; import eu.eudat.service.keycloak.KeycloakService;
import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.data.builder.BuilderFactory;
import gr.cite.tools.data.deleter.DeleterFactory; 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.data.query.QueryFactory;
import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.exception.MyForbiddenException; import gr.cite.tools.exception.MyForbiddenException;
@ -99,6 +104,8 @@ public class UserServiceImpl implements UserService {
private final ValidatorFactory validatorFactory; private final ValidatorFactory validatorFactory;
private final ElasticService elasticService;
@Autowired @Autowired
public UserServiceImpl( public UserServiceImpl(
EntityManager entityManager, EntityManager entityManager,
@ -111,7 +118,7 @@ public class UserServiceImpl implements UserService {
EventBroker eventBroker, EventBroker eventBroker,
JsonHandlingService jsonHandlingService, JsonHandlingService jsonHandlingService,
XmlHandlingService xmlHandlingService, QueryFactory queryFactory, XmlHandlingService xmlHandlingService, QueryFactory queryFactory,
UserScope userScope, KeycloakService keycloakService, ActionConfirmationService actionConfirmationService, NotificationProperties notificationProperties, NotificationIntegrationEventHandler eventHandler, ValidatorFactory validatorFactory) { UserScope userScope, KeycloakService keycloakService, ActionConfirmationService actionConfirmationService, NotificationProperties notificationProperties, NotificationIntegrationEventHandler eventHandler, ValidatorFactory validatorFactory, ElasticService elasticService) {
this.entityManager = entityManager; this.entityManager = entityManager;
this.authorizationService = authorizationService; this.authorizationService = authorizationService;
this.deleterFactory = deleterFactory; this.deleterFactory = deleterFactory;
@ -129,6 +136,7 @@ public class UserServiceImpl implements UserService {
this.notificationProperties = notificationProperties; this.notificationProperties = notificationProperties;
this.eventHandler = eventHandler; this.eventHandler = eventHandler;
this.validatorFactory = validatorFactory; this.validatorFactory = validatorFactory;
this.elasticService = elasticService;
} }
//region persist //region persist
@ -343,12 +351,14 @@ public class UserServiceImpl implements UserService {
//endregion //endregion
//notifications //notifications
public void sendMergeAccountConfirmation(UserRequestPersist model) throws InvalidApplicationException, JAXBException { public void sendMergeAccountConfirmation(UserMergeRequestPersist model) throws InvalidApplicationException, JAXBException {
UserEntity user = this.queryFactory.query(UserQuery.class).ids(model.getUserId()).isActive(IsActive.Active).first(); UserContactInfoEntity userContactInfoEntity = this.queryFactory.query(UserContactInfoQuery.class).values(model.getEmail()).types(ContactInfoType.Email).first();
if (user == null){ if (userContactInfoEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getEmail(), User.class.getSimpleName()}, LocaleContextHolder.getLocale()));
throw new MyApplicationException("User don't exist");
} UserEntity user = this.queryFactory.query(UserQuery.class).ids(userContactInfoEntity.getUserId()).isActive(IsActive.Active).first();
String token = this.createActionConfirmation(model.getEmail(), ActionConfirmationType.MergeAccount); 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.EMAIL);
createMergeNotificationEvent(token, user, model.getEmail(), NotificationContactType.IN_APP); createMergeNotificationEvent(token, user, model.getEmail(), NotificationContactType.IN_APP);
} }
@ -372,52 +382,54 @@ public class UserServiceImpl implements UserService {
eventHandler.handle(event); 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){ String token = this.createRemoveConfirmation(data.getId());
throw new MyApplicationException("User don't exist"); this.createRemoveCredentialNotificationEvent(token, data.getUserId(), NotificationContactType.EMAIL);
} this.createRemoveCredentialNotificationEvent(token, data.getUserId(), NotificationContactType.IN_APP);
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); private void createRemoveCredentialNotificationEvent(String token, UUID userId, NotificationContactType type) throws InvalidApplicationException {
this.createRemoveCredentialNotificationEvent(token, model.getEmail(), model.getUserId(), NotificationContactType.EMAIL);
this.createRemoveCredentialNotificationEvent(token, model.getEmail(), model.getUserId(), NotificationContactType.IN_APP);
}
private void createRemoveCredentialNotificationEvent(String token, String email, UUID userId, NotificationContactType type) throws InvalidApplicationException {
NotificationIntegrationEvent event = new NotificationIntegrationEvent(); NotificationIntegrationEvent event = new NotificationIntegrationEvent();
event.setUserId(userId); event.setUserId(userId);
List<ContactPair> 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.setContactTypeHint(type);
event.setNotificationType(notificationProperties.getRemoveCredentialConfirmationType()); event.setNotificationType(notificationProperties.getRemoveCredentialConfirmationType());
NotificationFieldData data = new NotificationFieldData(); NotificationFieldData data = new NotificationFieldData();
List<FieldInfo> fieldInfoList = new ArrayList<>(); List<FieldInfo> fieldInfoList = new ArrayList<>();
fieldInfoList.add(new FieldInfo("{confirmationToken}", DataType.String, token)); 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()))); fieldInfoList.add(new FieldInfo("{expiration_time}", DataType.String, this.secondsToTime(this.notificationProperties.getEmailExpirationTimeSeconds())));
data.setFields(fieldInfoList); data.setFields(fieldInfoList);
event.setData(jsonHandlingService.toJsonSafe(data)); event.setData(jsonHandlingService.toJsonSafe(data));
eventHandler.handle(event); 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(); ActionConfirmationPersist persist = new ActionConfirmationPersist();
persist.setType(type); persist.setType(ActionConfirmationType.MergeAccount);
persist.setStatus(ActionConfirmationStatus.Requested); persist.setStatus(ActionConfirmationStatus.Requested);
persist.setToken(UUID.randomUUID().toString()); persist.setToken(UUID.randomUUID().toString());
persist.setEmailConfirmation(new EmailConfirmationPersist(email)); persist.setMergeAccountConfirmation(new MergeAccountConfirmationPersist());
persist.setCreatedById(this.userScope.getUserId()); 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())); persist.setExpiresAt(Instant.now().plusSeconds(this.notificationProperties.getEmailExpirationTimeSeconds()));
validatorFactory.validator(ActionConfirmationPersist.ActionConfirmationPersistValidator.class).validateForce(persist); validatorFactory.validator(ActionConfirmationPersist.ActionConfirmationPersistValidator.class).validateForce(persist);
this.actionConfirmationService.persist(persist, null); this.actionConfirmationService.persist(persist, null);
@ -433,19 +445,137 @@ public class UserServiceImpl implements UserService {
return (hour + ":" + min + ":" + sec); 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(); 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())); if (action == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{token, ActionConfirmationEntity.class.getSimpleName()}, LocaleContextHolder.getLocale()));
this.checkActionState(action); 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); action.setStatus(ActionConfirmationStatus.Accepted);
this.entityManager.merge(action);
this.entityManager.flush();
}
//TODO merge private void mergeNewUserToOld(UserEntity newUser, UserEntity oldUser) throws IOException, InvalidApplicationException {
// this.entityManager.merge(action); List<UserCredentialEntity> userCredentials = this.queryFactory.query(UserCredentialQuery.class).userIds(oldUser.getId()).collect();
for (UserCredentialEntity userCredential : userCredentials){
userCredential.setUserId(newUser.getId());
this.entityManager.merge(userCredential);
}
List<UserContactInfoEntity> 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<UserRoleEntity> userRoles = this.queryFactory.query(UserRoleQuery.class).userIds(oldUser.getId()).collect();
List<UserRoleEntity> newUserRoles = this.queryFactory.query(UserRoleQuery.class).userIds(newUser.getId()).collect();
List<UserRoleEntity> 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<UserSettingsEntity> userSettings = this.queryFactory.query(UserSettingsQuery.class).entityIds(oldUser.getId()).collect();
List<UserSettingsEntity> newUserSettings = this.queryFactory.query(UserSettingsQuery.class).entityIds(newUser.getId()).collect();
List<UserSettingsEntity> 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<TagEntity> tags = this.queryFactory.query(TagQuery.class).createdByIds(oldUser.getId()).collect();
for (TagEntity tag : tags){
tag.setCreatedById(newUser.getId());
this.entityManager.merge(tag);
}
List<StorageFileEntity> storageFiles = this.queryFactory.query(StorageFileQuery.class).ownerIds(oldUser.getId()).collect();
for (StorageFileEntity storageFile : storageFiles){
storageFile.setOwnerId(newUser.getId());
this.entityManager.merge(storageFile);
}
List<LockEntity> locks = this.queryFactory.query(LockQuery.class).lockedByIds(oldUser.getId()).collect();
for (LockEntity lock : locks){
lock.setLockedBy(newUser.getId());
this.entityManager.merge(lock);
}
List<DmpUserEntity> dmpUsers = this.queryFactory.query(DmpUserQuery.class).userIds(oldUser.getId()).collect();
for (DmpUserEntity dmpUser : dmpUsers){
dmpUser.setUserId(newUser.getId());
this.entityManager.merge(dmpUser);
}
List<UserDescriptionTemplateEntity> userDescriptionTemplates = this.queryFactory.query(UserDescriptionTemplateQuery.class).userIds(oldUser.getId()).collect();
for (UserDescriptionTemplateEntity userDescriptionTemplate : userDescriptionTemplates){
userDescriptionTemplate.setUserId(newUser.getId());
this.entityManager.merge(userDescriptionTemplate);
}
List<DmpEntity> dmps = this.queryFactory.query(DmpQuery.class).creatorIds(oldUser.getId()).collect();
for (DmpEntity dmp : dmps){
dmp.setCreatorId(newUser.getId());
this.entityManager.merge(dmp);
}
List<DescriptionEntity> descriptions = this.queryFactory.query(DescriptionQuery.class).createdByIds(oldUser.getId()).collect();
for (DescriptionEntity description : descriptions){
description.setCreatedById(newUser.getId());
this.entityManager.merge(description);
}
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); this.checkActionState(action);
UserCredentialEntity userCredential = this.queryFactory.query(UserCredentialQuery.class).userIds(this.userScope.getUserIdSafe()).first(); RemoveCredentialConfirmationEntity removeCredentialConfirmationEntity = this.xmlHandlingService.fromXmlSafe(RemoveCredentialConfirmationEntity.class, action.getData());
if (userCredential == null){ if (removeCredentialConfirmationEntity == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{removeCredentialConfirmationEntity, RemoveCredentialConfirmationEntity.class.getSimpleName()}, LocaleContextHolder.getLocale()));
throw new MyApplicationException("This user does not have credential");
}
this.deleterFactory.deleter(UserCredentialDeleter.class).deleteAndSaveByIds(List.of(userCredential.getId()));
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); action.setStatus(ActionConfirmationStatus.Accepted);
this.entityManager.merge(action); this.entityManager.merge(action);
this.entityManager.flush();
} }
private void checkActionState(ActionConfirmationEntity action) throws MyApplicationException { private void checkActionState(ActionConfirmationEntity action) throws MyApplicationException {

View File

@ -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<Module> 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);
}
}

View File

@ -14,16 +14,15 @@ import eu.eudat.model.builder.DmpAssociatedUserBuilder;
import eu.eudat.model.builder.UserBuilder; import eu.eudat.model.builder.UserBuilder;
import eu.eudat.model.censorship.DmpAssociatedUserCensor; import eu.eudat.model.censorship.DmpAssociatedUserCensor;
import eu.eudat.model.censorship.UserCensor; 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.UserPersist;
import eu.eudat.model.persist.UserRolePatchPersist; import eu.eudat.model.persist.UserRolePatchPersist;
import eu.eudat.model.result.QueryResult; import eu.eudat.model.result.QueryResult;
import eu.eudat.models.data.helpers.responses.ResponseItem;
import eu.eudat.query.UserQuery; import eu.eudat.query.UserQuery;
import eu.eudat.query.lookup.UserLookup; import eu.eudat.query.lookup.UserLookup;
import eu.eudat.service.responseutils.ResponseUtilsService; import eu.eudat.service.responseutils.ResponseUtilsService;
import eu.eudat.service.user.UserService; import eu.eudat.service.user.UserService;
import eu.eudat.types.ApiMessageCode;
import gr.cite.tools.auditing.AuditService; import gr.cite.tools.auditing.AuditService;
import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.data.builder.BuilderFactory;
import gr.cite.tools.data.censor.CensorFactory; import gr.cite.tools.data.censor.CensorFactory;
@ -38,7 +37,6 @@ import jakarta.xml.bind.JAXBException;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.context.MessageSource; import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*; 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 { 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)); 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); 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)); User model = this.builderFactory.builder(UserBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(fieldSet, query.firstAs(fieldSet));
@ -180,18 +178,17 @@ public class UserController {
} }
@GetMapping("mine") @GetMapping("mine")
public User getMine(@PathVariable("id") UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException { public User getMine(FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException {
logger.debug(new MapLogEntry("retrieving" + User.class.getSimpleName()).And("id", id).And("fields", fieldSet)); logger.debug(new MapLogEntry("retrieving me" + User.class.getSimpleName()).And("fields", fieldSet));
this.censorFactory.censor(UserCensor.class).censor(fieldSet, this.userScope.getUserId()); this.censorFactory.censor(UserCensor.class).censor(fieldSet, this.userScope.getUserId());
UserQuery query = this.queryFactory.query(UserQuery.class).ids(this.userScope.getUserId()).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic); 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)); User model = this.builderFactory.builder(UserBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(fieldSet, query.firstAs(fieldSet));
if (model == null) 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( this.auditService.track(AuditableAction.User_Lookup, Map.ofEntries(
new AbstractMap.SimpleEntry<String, Object>("id", id),
new AbstractMap.SimpleEntry<String, Object>("fields", fieldSet) new AbstractMap.SimpleEntry<String, Object>("fields", fieldSet)
)); ));
@ -271,10 +268,10 @@ public class UserController {
this.auditService.track(AuditableAction.User_Delete, "id", id); this.auditService.track(AuditableAction.User_Delete, "id", id);
} }
@PostMapping("mine/merge-account-request/{email}") @PostMapping("mine/merge-account-request")
@Transactional @Transactional
@ValidationFilterAnnotation(validator = UserRequestPersist.UserRequestPersistValidator.ValidatorName, argumentName = "model") @ValidationFilterAnnotation(validator = UserMergeRequestPersist.UserMergeRequestPersistValidator.ValidatorName, argumentName = "model")
public Boolean mergeAccount(@RequestBody UserRequestPersist model) throws InvalidApplicationException, JAXBException { public Boolean mergeAccount(@RequestBody UserMergeRequestPersist model) throws InvalidApplicationException, JAXBException {
logger.debug(new MapLogEntry("merge account to user").And("email", model)); logger.debug(new MapLogEntry("merge account to user").And("email", model));
this.userTypeService.sendMergeAccountConfirmation(model); this.userTypeService.sendMergeAccountConfirmation(model);
@ -288,7 +285,7 @@ public class UserController {
@GetMapping("mine/confirm-merge-account/token/{token}") @GetMapping("mine/confirm-merge-account/token/{token}")
@Transactional @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)); logger.debug(new MapLogEntry("confirm merge account to user").And("token", token));
this.userTypeService.confirmMergeAccount(token); this.userTypeService.confirmMergeAccount(token);
@ -300,10 +297,10 @@ public class UserController {
return true; return true;
} }
@PostMapping("mine/remove-credential-request/{email}") @PostMapping("mine/remove-credential-request")
@Transactional @Transactional
@ValidationFilterAnnotation(validator = UserRequestPersist.UserRequestPersistValidator.ValidatorName, argumentName = "model") @ValidationFilterAnnotation(validator = RemoveCredentialRequestPersist.RemoveCredentialRequestPersistValidator.ValidatorName, argumentName = "model")
public Boolean removeCredentialAccount(@RequestBody UserRequestPersist model) throws InvalidApplicationException, JAXBException { public Boolean removeCredentialAccount(@RequestBody RemoveCredentialRequestPersist model) throws InvalidApplicationException, JAXBException {
logger.debug(new MapLogEntry("remove credential request to user").And("model", model)); logger.debug(new MapLogEntry("remove credential request to user").And("model", model));
this.userTypeService.sendRemoveCredentialConfirmation(model); this.userTypeService.sendRemoveCredentialConfirmation(model);

View File

@ -457,6 +457,7 @@ permissions:
BrowseReference: BrowseReference:
roles: roles:
- Admin - Admin
- User
clients: [ ] clients: [ ]
allowAnonymous: false allowAnonymous: false
allowAuthenticated: false allowAuthenticated: false
@ -711,19 +712,19 @@ permissions:
# ActionConfirmation Permissions # ActionConfirmation Permissions
BrowseActionConfirmation: BrowseActionConfirmation:
roles: roles:
- User - Admin
clients: [ ] clients: [ ]
allowAnonymous: false allowAnonymous: false
allowAuthenticated: false allowAuthenticated: false
EditActionConfirmation: EditActionConfirmation:
roles: roles:
- User - Admin
clients: [ ] clients: [ ]
allowAnonymous: false allowAnonymous: false
allowAuthenticated: false allowAuthenticated: false
DeleteActionConfirmation: DeleteActionConfirmation:
roles: roles:
- User - Admin
claims: [ ] claims: [ ]
clients: [ ] clients: [ ]
allowAnonymous: false allowAnonymous: false