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>
<version>1.10.0</version>
</dependency>
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>1.8.0</version>
</dependency>
<dependency>
<groupId>gr.cite</groupId>
<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.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;

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.errorcode.ErrorThesaurusProperties;
import gr.cite.tools.exception.MyValidationException;
import org.apache.commons.validator.routines.EmailValidator;
import java.util.*;
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) {
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);

View File

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

View File

@ -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<ActionConfirmation, A
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._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._expiresAt))) m.setExpiresAt(d.getExpiresAt());
if (!emailConfirmationFields.isEmpty() && d.getData() != null){
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));
}else{
DmpInvitationEntity dmpInvitation = this.xmlHandlingService.fromXmlSafe(DmpInvitationEntity.class, d.getData());

View File

@ -1,7 +1,7 @@
package eu.eudat.model.builder.actionconfirmation;
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.model.actionconfirmation.EmailConfirmation;
import eu.eudat.model.builder.BaseBuilder;
@ -20,7 +20,7 @@ import java.util.*;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class EmailConfirmationBuilder extends BaseBuilder<EmailConfirmation, EmailConfirmationEntity> {
public class EmailConfirmationBuilder extends BaseBuilder<EmailConfirmation, MergeAccountConfirmationEntity> {
private final BuilderFactory builderFactory;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
@ -38,7 +38,7 @@ public class EmailConfirmationBuilder extends BaseBuilder<EmailConfirmation, Ema
}
@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.trace(new DataLogEntry("requested fields", fields));
if (fields == null || data == null || fields.isEmpty())
@ -46,7 +46,7 @@ public class EmailConfirmationBuilder extends BaseBuilder<EmailConfirmation, Ema
List<EmailConfirmation> 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());

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.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))
);
}

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.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<EmailConfirmationPersist> {
public static class MergeAccountConfirmationPersistValidator extends BaseValidator<MergeAccountConfirmationPersist> {
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<EmailConfirmationPersist> modelClass() {
return EmailConfirmationPersist.class;
protected Class<MergeAccountConfirmationPersist> modelClass() {
return MergeAccountConfirmationPersist.class;
}
@Override
protected List<Specification> specifications(EmailConfirmationPersist item) {
protected List<Specification> 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()))
);
}
}

View File

@ -237,7 +237,7 @@ public class ActionConfirmationQuery extends QueryBase<ActionConfirmationEntity>
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;

View File

@ -35,6 +35,8 @@ import java.util.*;
public class DescriptionQuery extends QueryBase<DescriptionEntity> {
private String like;
private Collection<UUID> ids;
private Collection<UUID> createdByIds;
private DmpDescriptionTemplateQuery dmpDescriptionTemplateQuery;
private DmpQuery dmpQuery;
private Instant createdAfter;
@ -78,6 +80,21 @@ public class DescriptionQuery extends QueryBase<DescriptionEntity> {
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) {
this.dmpDescriptionTemplateQuery = subQuery;
return this;
@ -174,7 +191,7 @@ public class DescriptionQuery extends QueryBase<DescriptionEntity> {
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<DescriptionEntity> {
inClause.value(item);
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) {
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 Collection<UUID> ids;
private Collection<UUID> creatorIds;
private Collection<UUID> excludedIds;
@ -79,6 +80,21 @@ public class DmpQuery extends QueryBase<DmpEntity> {
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) {
this.excludedIds = values;
return this;
@ -201,7 +217,7 @@ public class DmpQuery extends QueryBase<DmpEntity> {
@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<DmpEntity> {
inClause.value(item);
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) {
CriteriaBuilder.In<UUID> notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(DmpEntity._id));
for (UUID item : this.excludedIds)

View File

@ -24,6 +24,7 @@ public class LockQuery extends QueryBase<LockEntity> {
private Collection<UUID> ids;
private Collection<UUID> targetIds;
private Collection<UUID> lockedByIds;
private Collection<LockTargetType> targetTypes;
@ -46,6 +47,21 @@ public class LockQuery extends QueryBase<LockEntity> {
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) {
this.targetIds = List.of(value);
return this;
@ -106,7 +122,7 @@ public class LockQuery extends QueryBase<LockEntity> {
@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<LockEntity> {
inClause.value(item);
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) {
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(LockEntity._target));
for (UUID item : this.targetIds)

View File

@ -25,6 +25,7 @@ import java.util.*;
public class StorageFileQuery extends QueryBase<StorageFileEntity> {
private String like;
private Collection<UUID> ids;
private Collection<UUID> ownerIds;
private Boolean canPurge;
private Boolean isPurged;
private Instant createdAfter;
@ -58,6 +59,21 @@ public class StorageFileQuery extends QueryBase<StorageFileEntity> {
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) {
this.createdAfter = value;
return this;
@ -97,6 +113,7 @@ public class StorageFileQuery extends QueryBase<StorageFileEntity> {
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<StorageFileEntity> {
inClause.value(item);
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) {
predicates.add(queryContext.CriteriaBuilder.greaterThan(queryContext.Root.get(StorageFileEntity._createdAt), this.createdAfter));
}

View File

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

View File

@ -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) {
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);

View File

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

View File

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

View File

@ -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,6 +104,8 @@ public class UserServiceImpl implements UserService {
private final ValidatorFactory validatorFactory;
private final ElasticService elasticService;
@Autowired
public UserServiceImpl(
EntityManager entityManager,
@ -111,7 +118,7 @@ public class UserServiceImpl implements UserService {
EventBroker eventBroker,
JsonHandlingService jsonHandlingService,
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.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.createRemoveConfirmation(data.getId());
this.createRemoveCredentialNotificationEvent(token, data.getUserId(), NotificationContactType.EMAIL);
this.createRemoveCredentialNotificationEvent(token, data.getUserId(), NotificationContactType.IN_APP);
}
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);
}
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<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.setNotificationType(notificationProperties.getRemoveCredentialConfirmationType());
NotificationFieldData data = new NotificationFieldData();
List<FieldInfo> 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();
}
//TODO merge
// this.entityManager.merge(action);
private void mergeNewUserToOld(UserEntity newUser, UserEntity oldUser) throws IOException, InvalidApplicationException {
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);
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 {

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.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<String, Object>("id", id),
new AbstractMap.SimpleEntry<String, Object>("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);

View File

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