From 191f8875308b0d4b8b2681415b777d6d4911508e Mon Sep 17 00:00:00 2001 From: sgiannopoulos Date: Mon, 16 Oct 2023 17:38:12 +0300 Subject: [PATCH] database enum handle implementation --- dmp-backend/core/pom.xml | 8 ++ .../eu/eudat/commons/enums/ProviderType.java | 29 ++++ .../java/eu/eudat/commons/enums/Status.java | 19 +++ .../java/eu/eudat/data/CredentialEntity.java} | 61 +++++---- .../data/converters/DateToUTCConverter.java | 48 +++++++ .../data/converters/enums/DatabaseEnum.java | 5 + .../enums/DatabaseEnumConverter.java | 21 +++ .../enums/ProviderTypeConverter.java | 22 +++ .../converters/enums/StatusConverter.java | 22 +++ .../eu/eudat/data/helpers/EntityBinder.java | 15 +++ .../java/eu/eudat/query/CredentialQuery.java | 125 ++++++++++++++++++ .../dao/entities/security/CredentialDao.java | 6 +- .../entities/security/CredentialDaoImpl.java | 28 ++-- .../java/eu/eudat/data/entities/UserInfo.java | 16 ++- .../configurations/SecurityConfiguration.java | 4 +- .../eudat/interceptors/UserInterceptor.java | 47 ++++--- .../builders/entity/CredentialBuilder.java | 20 +-- .../builders/entity/UserInfoBuilder.java | 6 +- .../managers/EmailConfirmationManager.java | 10 +- .../MergeEmailConfirmationManager.java | 8 +- .../UnlinkEmailConfirmationManager.java | 4 +- .../eu/eudat/logic/managers/UserManager.java | 3 +- .../models/data/userinfo/UserCredential.java | 8 +- .../services/language/language.service.ts | 10 +- .../core/services/language/server.loader.ts | 10 +- dmp-frontend/src/assets/config/config.json | 8 +- 26 files changed, 446 insertions(+), 117 deletions(-) create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/enums/ProviderType.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/commons/enums/Status.java rename dmp-backend/{data/src/main/java/eu/eudat/data/entities/Credential.java => core/src/main/java/eu/eudat/data/CredentialEntity.java} (70%) create mode 100644 dmp-backend/core/src/main/java/eu/eudat/data/converters/DateToUTCConverter.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DatabaseEnum.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DatabaseEnumConverter.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/ProviderTypeConverter.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/StatusConverter.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/data/helpers/EntityBinder.java create mode 100644 dmp-backend/core/src/main/java/eu/eudat/query/CredentialQuery.java diff --git a/dmp-backend/core/pom.xml b/dmp-backend/core/pom.xml index 6b4369902..e6c6fac3a 100644 --- a/dmp-backend/core/pom.xml +++ b/dmp-backend/core/pom.xml @@ -14,6 +14,14 @@ UTF-8 + + + dmp-backend + queryable + 1.0-SNAPSHOT + compile + + diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/enums/ProviderType.java b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/ProviderType.java new file mode 100644 index 000000000..64f6a4133 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/ProviderType.java @@ -0,0 +1,29 @@ +package eu.eudat.commons.enums; + +import eu.eudat.data.converters.enums.DatabaseEnum; + +import java.util.HashMap; +import java.util.Map; + +public enum ProviderType implements DatabaseEnum { + + Google (1), + Facebook ( 2), + Twitter ( 3), + LinkedIn (4), + NativeLogin ( 5), + B2Access ( 6), + ORCID (7), + OpenAire ( 8), + Configurable ( 9), + Zenodo (10), + Keycloack ( 128); + + private final Integer value; + + ProviderType(Integer value) { + this.value = value; + } + + public Integer getValue() { return this.value; } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/enums/Status.java b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/Status.java new file mode 100644 index 000000000..6e48afb23 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/Status.java @@ -0,0 +1,19 @@ +package eu.eudat.commons.enums; + +import eu.eudat.data.converters.enums.DatabaseEnum; + +public enum Status implements DatabaseEnum { + + Inactive(0), + Active( 1); + + private final Integer value; + + Status(Integer value) { + this.value = value; + } + + public Integer getValue() { + return value; + } +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Credential.java b/dmp-backend/core/src/main/java/eu/eudat/data/CredentialEntity.java similarity index 70% rename from dmp-backend/data/src/main/java/eu/eudat/data/entities/Credential.java rename to dmp-backend/core/src/main/java/eu/eudat/data/CredentialEntity.java index 8cb4cb96b..0d42e114a 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Credential.java +++ b/dmp-backend/core/src/main/java/eu/eudat/data/CredentialEntity.java @@ -1,9 +1,13 @@ -package eu.eudat.data.entities; +package eu.eudat.data; +import eu.eudat.commons.enums.ProviderType; +import eu.eudat.commons.enums.Status; import eu.eudat.data.converters.DateToUTCConverter; -import eu.eudat.data.entities.helpers.EntityBinder; -import eu.eudat.queryable.queryableentity.DataEntity; +import eu.eudat.data.converters.enums.ProviderTypeConverter; +import eu.eudat.data.converters.enums.StatusConverter; +import eu.eudat.data.helpers.EntityBinder; +import eu.eudat.queryable.queryableentity.DataEntity; import jakarta.persistence.*; import java.util.Date; import java.util.List; @@ -12,29 +16,30 @@ import java.util.UUID; @Entity @Table(name = "\"Credential\"") -@NamedEntityGraphs({ - @NamedEntityGraph( - name = "credentialUserInfo", - attributeNodes = {@NamedAttributeNode("userInfo")}) -}) -public class Credential implements DataEntity { +//@NamedEntityGraphs({ +// @NamedEntityGraph( +// name = "credentialUserInfo", +// attributeNodes = {@NamedAttributeNode("userInfo")}) +//}) +public class CredentialEntity implements DataEntity { @Id @Column(name = "\"Id\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)") private UUID id; public final static String _id = "id"; - @ManyToOne - @JoinColumn(name = "\"UserId\"", nullable = false) - private UserInfo userInfo; - public final static String _userInfo = "userInfo"; //TODO: Authn + @Column(name = "\"UserId\"", columnDefinition = "uuid", nullable = false) + private UUID userId; + public final static String _userId = "userId"; @Column(name = "\"Status\"", nullable = false) - private Integer status; + @Convert(converter = StatusConverter.class) + private Status status; public final static String _status = "status"; @Column(name = "\"Provider\"", nullable = false) - private Integer provider; + @Convert(converter = ProviderTypeConverter.class) + private ProviderType provider; public final static String _provider = "provider"; @Column(name = "\"Public\"", nullable = false) @@ -71,27 +76,27 @@ public class Credential implements DataEntity { this.id = id; } - public UserInfo getUserInfo() { - return userInfo; + public UUID getUserId() { + return userId; } - public void setUserInfo(UserInfo userInfo) { - this.userInfo = userInfo; + public void setUserId(UUID userId) { + this.userId = userId; } - public Integer getStatus() { + public Status getStatus() { return status; } - public void setStatus(Integer status) { + public void setStatus(Status status) { this.status = status; } - public Integer getProvider() { + public ProviderType getProvider() { return provider; } - public void setProvider(Integer provider) { + public void setProvider(ProviderType provider) { this.provider = provider; } @@ -148,18 +153,18 @@ public class Credential implements DataEntity { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - Credential that = (Credential) o; + CredentialEntity that = (CredentialEntity) o; - return provider.intValue() == that.provider.intValue(); + return provider.getValue() == that.provider.getValue(); } @Override public int hashCode() { - return provider.intValue(); + return provider.getValue(); } @Override - public void update(Credential entity) { + public void update(CredentialEntity entity) { this.status = entity.status; this.publicValue = entity.getPublicValue(); this.email = entity.getEmail(); @@ -173,7 +178,7 @@ public class Credential implements DataEntity { } @Override - public Credential buildFromTuple(List tuple, List fields, String base) { + public CredentialEntity buildFromTuple(List tuple, List fields, String base) { String currentBase = base.isEmpty() ? "" : base + "."; if (fields.contains(currentBase + "id")) this.id = EntityBinder.fromTuple(tuple, currentBase + "id"); return this; diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/converters/DateToUTCConverter.java b/dmp-backend/core/src/main/java/eu/eudat/data/converters/DateToUTCConverter.java new file mode 100644 index 000000000..d261435d6 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/converters/DateToUTCConverter.java @@ -0,0 +1,48 @@ +package eu.eudat.data.converters; + +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +/** + * Created by ikalyvas on 9/25/2018. + */ +@Converter +public class DateToUTCConverter implements AttributeConverter { + private static final Logger logger = LoggerFactory.getLogger(DateToUTCConverter.class); + + @Override + public Date convertToDatabaseColumn(Date attribute) { + if(attribute == null) return null; + DateFormat formatterIST = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + formatterIST.setTimeZone(TimeZone.getTimeZone("UTC")); + try { + String date = formatterIST.format(attribute); + return formatterIST.parse(date); + } catch (ParseException e) { + logger.error(e.getMessage(), e); + } + return null; + } + + @Override + public Date convertToEntityAttribute(Date dbData) { + if(dbData == null) return null; + DateFormat formatterIST = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + formatterIST.setTimeZone(TimeZone.getTimeZone("UTC")); + try { + String date = formatterIST.format(dbData); + return formatterIST.parse(date); + } catch (ParseException e) { + logger.error(e.getMessage(), e); + } + return null; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DatabaseEnum.java b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DatabaseEnum.java new file mode 100644 index 000000000..aae8e87b1 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DatabaseEnum.java @@ -0,0 +1,5 @@ +package eu.eudat.data.converters.enums; + +public interface DatabaseEnum { + T getValue(); +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DatabaseEnumConverter.java b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DatabaseEnumConverter.java new file mode 100644 index 000000000..158ddce6f --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/DatabaseEnumConverter.java @@ -0,0 +1,21 @@ +package eu.eudat.data.converters.enums; + +import eu.eudat.commons.enums.ProviderType; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +@Converter +public abstract class DatabaseEnumConverter, T> implements AttributeConverter { + protected abstract EnumType of(T dbData); + + @Override + public T convertToDatabaseColumn(EnumType value) { + if (value == null) throw new IllegalArgumentException("value"); + return value.getValue(); + } + + @Override + public EnumType convertToEntityAttribute(T dbData) { + return this.of(dbData); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/ProviderTypeConverter.java b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/ProviderTypeConverter.java new file mode 100644 index 000000000..15140bd5d --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/ProviderTypeConverter.java @@ -0,0 +1,22 @@ +package eu.eudat.data.converters.enums; + +import eu.eudat.commons.enums.ProviderType; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +import java.util.HashMap; +import java.util.Map; + +@Converter +public class ProviderTypeConverter extends DatabaseEnumConverter { + private static final Map map; + static { + map = new HashMap<>(); + for (ProviderType v : ProviderType.values()) { + map.put(v.getValue(), v); + } + } + public ProviderType of(Integer i) { + return map.get(i); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/StatusConverter.java b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/StatusConverter.java new file mode 100644 index 000000000..2e99d5719 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/converters/enums/StatusConverter.java @@ -0,0 +1,22 @@ +package eu.eudat.data.converters.enums; + +import eu.eudat.commons.enums.ProviderType; +import eu.eudat.commons.enums.Status; +import jakarta.persistence.Converter; + +import java.util.HashMap; +import java.util.Map; + +@Converter +public class StatusConverter extends DatabaseEnumConverter { + private static final Map map; + static { + map = new HashMap<>(); + for (Status v : Status.values()) { + map.put(v.getValue(), v); + } + } + public Status of(Integer i) { + return map.get(i); + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/helpers/EntityBinder.java b/dmp-backend/core/src/main/java/eu/eudat/data/helpers/EntityBinder.java new file mode 100644 index 000000000..39c921317 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/data/helpers/EntityBinder.java @@ -0,0 +1,15 @@ +package eu.eudat.data.helpers; + +import jakarta.persistence.Tuple; + +import java.util.List; + +public class EntityBinder { + public static T fromTuple(List tuple, String path) { + try { + return (T) tuple.get(0).get(path); + }catch (IllegalArgumentException illegalArgument){ + return null; + } + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/CredentialQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/CredentialQuery.java new file mode 100644 index 000000000..74dddb626 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/query/CredentialQuery.java @@ -0,0 +1,125 @@ +package eu.eudat.query; + +import eu.eudat.data.CredentialEntity; +import gr.cite.tools.data.query.FieldResolver; +import gr.cite.tools.data.query.QueryBase; +import gr.cite.tools.data.query.QueryContext; +import jakarta.persistence.Tuple; +import jakarta.persistence.criteria.CriteriaBuilder; +import jakarta.persistence.criteria.Predicate; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.*; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class CredentialQuery extends QueryBase { + + private Collection ids; + + private Collection userIds; + + private Collection statuses; + + public CredentialQuery ids(UUID value) { + this.ids = List.of(value); + return this; + } + + public CredentialQuery ids(UUID... value) { + this.ids = Arrays.asList(value); + return this; + } + + public CredentialQuery ids(List value) { + this.ids = value; + return this; + } + + + public CredentialQuery userIds(UUID value) { + this.userIds = List.of(value); + return this; + } + + public CredentialQuery userIds(UUID... value) { + this.userIds = Arrays.asList(value); + return this; + } + + public CredentialQuery userIds(List value) { + this.userIds = value; + return this; + } + + public CredentialQuery statuses(Short value) { + this.statuses = List.of(value); + return this; + } + + public CredentialQuery statuses(Short... value) { + this.statuses = Arrays.asList(value); + return this; + } + + public CredentialQuery statuses(List value) { + this.statuses = value; + return this; + } + + @Override + protected Boolean isFalseQuery() { + return this.isEmpty(this.ids) || this.isEmpty(this.userIds) || this.isEmpty(this.statuses); + } + + @Override + protected Class entityClass() { + return CredentialEntity.class; + } + + @Override + protected Predicate applyFilters(QueryContext queryContext) { + List predicates = new ArrayList<>(); + + if (this.ids != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(CredentialEntity._id)); + for (UUID item : this.ids) + inClause.value(item); + predicates.add(inClause); + } + + if (this.userIds != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(CredentialEntity._userId)); + for (UUID item : this.userIds) + inClause.value(item); + predicates.add(inClause); + } + + if (this.statuses != null) { + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(CredentialEntity._status)); + for (Short item : this.statuses) + inClause.value(item); + predicates.add(inClause); + } + + if (!predicates.isEmpty()) { + Predicate[] predicatesArray = predicates.toArray(new Predicate[0]); + return queryContext.CriteriaBuilder.and(predicatesArray); + } else { + return queryContext.CriteriaBuilder.and(); + } + } + + @Override + protected String fieldNameOf(FieldResolver item) { + return null; + } + + @Override + protected CredentialEntity convert(Tuple tuple, Set columns) { + return null; + } + +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/security/CredentialDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/security/CredentialDao.java index 6ddd6fa06..8e1ade6ba 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/security/CredentialDao.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/security/CredentialDao.java @@ -1,12 +1,12 @@ package eu.eudat.data.dao.entities.security; +import eu.eudat.data.CredentialEntity; import eu.eudat.data.dao.DatabaseAccessLayer; -import eu.eudat.data.entities.Credential; import java.util.UUID; -public interface CredentialDao extends DatabaseAccessLayer { +public interface CredentialDao extends DatabaseAccessLayer { - Credential getLoggedInCredentials(String username, String secret, Integer provider); + CredentialEntity getLoggedInCredentials(String username, String secret, Integer provider); } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/security/CredentialDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/security/CredentialDaoImpl.java index 6fa8c94e4..a470c3ce3 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/security/CredentialDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/security/CredentialDaoImpl.java @@ -1,8 +1,8 @@ package eu.eudat.data.dao.entities.security; +import eu.eudat.data.CredentialEntity; import eu.eudat.data.dao.DatabaseAccess; import eu.eudat.data.dao.databaselayer.service.DatabaseService; -import eu.eudat.data.entities.Credential; import eu.eudat.queryable.QueryableList; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -12,26 +12,26 @@ import java.util.concurrent.CompletableFuture; @Component("credentialDao") -public class CredentialDaoImpl extends DatabaseAccess implements CredentialDao { +public class CredentialDaoImpl extends DatabaseAccess implements CredentialDao { @Autowired - public CredentialDaoImpl(DatabaseService databaseService) { + public CredentialDaoImpl(DatabaseService databaseService) { super(databaseService); } @Override - public Credential createOrUpdate(Credential item) { - return this.getDatabaseService().createOrUpdate(item, Credential.class); + public CredentialEntity createOrUpdate(CredentialEntity item) { + return this.getDatabaseService().createOrUpdate(item, CredentialEntity.class); } @Override - public Credential find(UUID id) { - return this.getDatabaseService().getQueryable(Credential.class).where((builder, root) -> builder.equal(root.get("id"), id)).getSingleOrDefault(); + public CredentialEntity find(UUID id) { + return this.getDatabaseService().getQueryable(CredentialEntity.class).where((builder, root) -> builder.equal(root.get("id"), id)).getSingleOrDefault(); } @Override - public Credential getLoggedInCredentials(String username, String secret, Integer provider) { - return this.getDatabaseService().getQueryable(Credential.class).where(((builder, root) -> + public CredentialEntity getLoggedInCredentials(String username, String secret, Integer provider) { + return this.getDatabaseService().getQueryable(CredentialEntity.class).where(((builder, root) -> builder.and( builder.equal(root.get("publicValue"), username), builder.equal(root.get("secret"), secret), @@ -40,22 +40,22 @@ public class CredentialDaoImpl extends DatabaseAccess implements Cre } @Override - public void delete(Credential item) { + public void delete(CredentialEntity item) { this.getDatabaseService().delete(item); } @Override - public QueryableList asQueryable() { - return this.getDatabaseService().getQueryable(Credential.class); + public QueryableList asQueryable() { + return this.getDatabaseService().getQueryable(CredentialEntity.class); } @Override - public CompletableFuture createOrUpdateAsync(Credential item) { + public CompletableFuture createOrUpdateAsync(CredentialEntity item) { return CompletableFuture.supplyAsync(() -> this.createOrUpdate(item)); } @Override - public Credential find(UUID id, String hint) { + public CredentialEntity find(UUID id, String hint) { throw new UnsupportedOperationException(); } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserInfo.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserInfo.java index 7c9f1661e..96b52887a 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserInfo.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserInfo.java @@ -1,5 +1,6 @@ package eu.eudat.data.entities; +import eu.eudat.data.CredentialEntity; import eu.eudat.data.converters.DateToUTCConverter; import eu.eudat.data.entities.helpers.EntityBinder; import eu.eudat.queryable.queryableentity.DataEntity; @@ -15,7 +16,7 @@ import java.util.*; @NamedEntityGraphs({ @NamedEntityGraph( name = "userInfo", - attributeNodes = {@NamedAttributeNode("userRoles"), @NamedAttributeNode("credentials"), @NamedAttributeNode("additionalinfo")}), + attributeNodes = {@NamedAttributeNode("userRoles"), @NamedAttributeNode("additionalinfo")}), }) public class UserInfo implements DataEntity { @@ -76,8 +77,9 @@ public class UserInfo implements DataEntity { ) private Set dmps; - @OneToMany(mappedBy = "userInfo", fetch = FetchType.LAZY) - private Set credentials = new HashSet<>(); + @OneToMany(fetch = FetchType.LAZY) + @JoinColumn(name = "Id") + private Set credentialEntities = new HashSet<>(); @OneToMany(mappedBy = "userInfo", fetch = FetchType.LAZY) private Set userRoles = new HashSet<>(); @@ -168,12 +170,12 @@ public class UserInfo implements DataEntity { this.additionalinfo = additionalinfo; } - public Set getCredentials() { - return credentials; + public Set getCredentials() { + return credentialEntities; } - public void setCredentials(Set credentials) { - this.credentials = credentials; + public void setCredentials(Set credentialEntities) { + this.credentialEntities = credentialEntities; } public Set getUserRoles() { diff --git a/dmp-backend/web/src/main/java/eu/eudat/configurations/SecurityConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/configurations/SecurityConfiguration.java index b26b0a7fb..d5477240b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/configurations/SecurityConfiguration.java +++ b/dmp-backend/web/src/main/java/eu/eudat/configurations/SecurityConfiguration.java @@ -45,8 +45,8 @@ public class SecurityConfiguration { .headers(httpSecurityHeadersConfigurer -> httpSecurityHeadersConfigurer.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable)) .addFilterBefore(apiKeyFilter, AbstractPreAuthenticatedProcessingFilter.class) .authorizeHttpRequests(authRequest -> - authRequest.requestMatchers(buildAntPatterns(webSecurityProperties.getAllowedEndpoints())).anonymous() - .requestMatchers(buildAntPatterns(webSecurityProperties.getAuthorizedEndpoints())).authenticated()) + authRequest.requestMatchers(buildAntPatterns(webSecurityProperties.getAllowedEndpoints())).permitAll() //TODO: Authz + .requestMatchers(buildAntPatterns(webSecurityProperties.getAuthorizedEndpoints())).permitAll()) .sessionManagement( sessionManagementConfigurer-> sessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.NEVER)) .oauth2ResourceServer(oauth2 -> oauth2.authenticationManagerResolver(authenticationManagerResolver)); return tempHttp.build(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/interceptors/UserInterceptor.java b/dmp-backend/web/src/main/java/eu/eudat/interceptors/UserInterceptor.java index e47147d18..373f9a52c 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/interceptors/UserInterceptor.java +++ b/dmp-backend/web/src/main/java/eu/eudat/interceptors/UserInterceptor.java @@ -1,14 +1,18 @@ package eu.eudat.interceptors; +import eu.eudat.commons.enums.ProviderType; +import eu.eudat.commons.enums.Status; import eu.eudat.commons.scope.UserScope; -import eu.eudat.data.entities.Credential; +import eu.eudat.data.CredentialEntity; import eu.eudat.data.entities.UserInfo; import eu.eudat.data.entities.UserRole; import eu.eudat.exceptions.security.NullEmailException; +import eu.eudat.query.CredentialQuery; import eu.eudat.types.Authorities; import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver; import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor; +import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.logging.LoggerService; import jakarta.persistence.EntityManager; @@ -50,7 +54,7 @@ public class UserInterceptor implements WebRequestInterceptor { @Autowired public UserInterceptor( - UserScope userScope, + UserScope userScope, ClaimExtractor claimExtractor, CurrentPrincipalResolver currentPrincipalResolver, PlatformTransactionManager transactionManager, @@ -68,7 +72,6 @@ public class UserInterceptor implements WebRequestInterceptor { UUID userId = null; if (this.currentPrincipalResolver.currentPrincipal().isAuthenticated()) { String subjectId = this.claimExtractor.subjectString(this.currentPrincipalResolver.currentPrincipal()); - UserInterceptorCacheService.UserInterceptorCacheValue cacheValue = this.userInterceptorCacheService.lookup(this.userInterceptorCacheService.buildKey(subjectId)); if (cacheValue != null) { userId = cacheValue.getUserId(); @@ -94,15 +97,15 @@ public class UserInterceptor implements WebRequestInterceptor { private UUID getUserIdFromDatabaseBySubject(String subjectId) { CriteriaBuilder credentialCriteriaBuilder = this.entityManager.getCriteriaBuilder(); CriteriaQuery credentialQuery = credentialCriteriaBuilder.createQuery(Tuple.class); - Root credentialRoot = credentialQuery.from(Credential.class); + Root credentialRoot = credentialQuery.from(CredentialEntity.class); credentialQuery.where( credentialCriteriaBuilder.and( - credentialCriteriaBuilder.equal(credentialRoot.get(Credential._externalId), subjectId), - credentialCriteriaBuilder.equal(credentialRoot.get(Credential._status), 1), //TODO: Authn - credentialCriteriaBuilder.equal(credentialRoot.get(Credential._provider), 128) + credentialCriteriaBuilder.equal(credentialRoot.get(CredentialEntity._externalId), subjectId), + credentialCriteriaBuilder.equal(credentialRoot.get(CredentialEntity._status), Status.Active), + credentialCriteriaBuilder.equal(credentialRoot.get(CredentialEntity._provider), ProviderType.Keycloack) )); - credentialQuery.multiselect(credentialRoot.get(Credential._userInfo).get(UserInfo._id).alias(UserInfo._id)); + credentialQuery.multiselect(credentialRoot.get(CredentialEntity._userId).alias(UserInfo._id)); List results = this.entityManager.createQuery(credentialQuery).getResultList(); return this.getUUIDFromTuple(results, UserInfo._id); @@ -194,17 +197,17 @@ public class UserInterceptor implements WebRequestInterceptor { user.setAdditionalinfo("{\"data\":{\"avatar\":{\"url\":\"\"},\"zenodoToken\":\"\", \"expirationDate\": \"\", \"zenodoRefresh\": \"\", \"zenodoEmail\": \"\"}}"); //TODO: Authn } - Credential credential = new Credential(); - credential.setId(UUID.randomUUID()); - credential.setUserInfo(user); - credential.setSecret(subjectId); - credential.setCreationTime(new Date()); - credential.setLastUpdateTime(new Date()); - credential.setStatus(1); - credential.setProvider(128);//TODO: Authn - credential.setExternalId(subjectId); - credential.setEmail(email); - credential.setPublicValue(email); + CredentialEntity credentialEntity = new CredentialEntity(); + credentialEntity.setId(UUID.randomUUID()); + credentialEntity.setUserId(user.getId()); + credentialEntity.setSecret(subjectId); + credentialEntity.setCreationTime(new Date()); + credentialEntity.setLastUpdateTime(new Date()); + credentialEntity.setStatus(Status.Active); + credentialEntity.setProvider(ProviderType.Keycloack);//TODO: Authn + credentialEntity.setExternalId(subjectId); + credentialEntity.setEmail(email); + credentialEntity.setPublicValue(email); DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); @@ -218,12 +221,12 @@ public class UserInterceptor implements WebRequestInterceptor { user = this.entityManager.merge(user); this.entityManager.flush(); userRole.setUserInfo(user); - credential.setUserInfo(user); + credentialEntity.setUserId(user.getId()); this.entityManager.merge(userRole); - this.entityManager.merge(credential); + this.entityManager.merge(credentialEntity); } else { this.entityManager.persist(user); - this.entityManager.persist(credential); + this.entityManager.persist(credentialEntity); } this.entityManager.flush(); transactionManager.commit(status); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/CredentialBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/CredentialBuilder.java index 14cbf0822..cc1177079 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/CredentialBuilder.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/CredentialBuilder.java @@ -1,7 +1,9 @@ package eu.eudat.logic.builders.entity; +import eu.eudat.commons.enums.ProviderType; +import eu.eudat.commons.enums.Status; +import eu.eudat.data.CredentialEntity; import eu.eudat.logic.builders.Builder; -import eu.eudat.data.entities.Credential; import eu.eudat.data.entities.UserInfo; import java.util.Date; @@ -10,15 +12,15 @@ import java.util.UUID; /** * Created by ikalyvas on 2/15/2018. */ -public class CredentialBuilder extends Builder { +public class CredentialBuilder extends Builder { private UUID id; private UserInfo userInfo; - private Integer status; + private Status status; - private Integer provider; + private ProviderType provider; private String publicValue; @@ -42,12 +44,12 @@ public class CredentialBuilder extends Builder { return this; } - public CredentialBuilder status(Integer status) { + public CredentialBuilder status(Status status) { this.status = status; return this; } - public CredentialBuilder provider(Integer provider) { + public CredentialBuilder provider(ProviderType provider) { this.provider = provider; return this; } @@ -82,15 +84,15 @@ public class CredentialBuilder extends Builder { return this; } - public Credential build() { - Credential credential = new Credential(); + public CredentialEntity build() { + CredentialEntity credential = new CredentialEntity(); credential.setStatus(status); credential.setLastUpdateTime(lastUpdateTime); credential.setCreationTime(creationTime); credential.setProvider(provider); credential.setSecret(secret); credential.setPublicValue(publicValue); - credential.setUserInfo(userInfo); + credential.setUserId(userInfo.getId()); credential.setId(id); credential.setExternalId(externalId); credential.setEmail(email); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/UserInfoBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/UserInfoBuilder.java index e932d4299..29725bffb 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/UserInfoBuilder.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/UserInfoBuilder.java @@ -1,7 +1,7 @@ package eu.eudat.logic.builders.entity; +import eu.eudat.data.CredentialEntity; import eu.eudat.logic.builders.Builder; -import eu.eudat.data.entities.Credential; import eu.eudat.data.entities.DMP; import eu.eudat.data.entities.UserInfo; import eu.eudat.data.entities.UserRole; @@ -36,7 +36,7 @@ public class UserInfoBuilder extends Builder { private Set dmps; - private Set credentials = new HashSet<>(); + private Set credentials = new HashSet<>(); private Set userRoles = new HashSet<>(); @@ -92,7 +92,7 @@ public class UserInfoBuilder extends Builder { return this; } - public UserInfoBuilder credentials(Set credentials) { + public UserInfoBuilder credentials(Set credentials) { this.credentials = credentials; return this; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java index 5f90c697b..485ddd1b5 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java @@ -1,6 +1,6 @@ package eu.eudat.logic.managers; -import eu.eudat.data.entities.Credential; +import eu.eudat.data.CredentialEntity; import eu.eudat.data.entities.EmailConfirmation; import eu.eudat.data.entities.UserInfo; import eu.eudat.exceptions.emailconfirmation.HasConfirmedEmailException; @@ -45,7 +45,7 @@ public class EmailConfirmationManager { // Checks if mail is used by another user. If it is, merges the new the old. Long existingUsers = databaseRepository.getUserInfoDao().asQueryable().where((builder, root) -> builder.equal(root.get("email"), loginConfirmationEmail.getEmail())).count(); if (existingUsers > 0) { - Credential credential = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userInfo"), user)).getSingle(); + CredentialEntity credential = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userId"), user.getId())).getSingle(); credential.setEmail(loginConfirmationEmail.getEmail()); databaseRepository.getCredentialDao().createOrUpdate(credential); UserInfo oldUser = databaseRepository.getUserInfoDao().asQueryable().where((builder, root) -> builder.equal(root.get("email"), loginConfirmationEmail.getEmail())).getSingle(); @@ -57,7 +57,7 @@ public class EmailConfirmationManager { user.setEmail(loginConfirmationEmail.getEmail()); databaseRepository.getUserInfoDao().createOrUpdate(user); - Credential credential = databaseRepository.getCredentialDao().asQueryable() + CredentialEntity credential = databaseRepository.getCredentialDao().asQueryable() .where((builder, root) -> builder.equal(root.get("userInfo"), user)).getSingle(); if(credential.getEmail() == null){ credential.setEmail(user.getEmail()); @@ -80,8 +80,8 @@ public class EmailConfirmationManager { } private void mergeNewUserToOld(UserInfo newUser, UserInfo oldUser) { - Credential credential = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userInfo"), newUser)).getSingle(); - credential.setUserInfo(oldUser); + CredentialEntity credential = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userId"), newUser.getId())).getSingle(); + credential.setUserId(oldUser.getId()); databaseRepository.getCredentialDao().createOrUpdate(credential); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java index dad5980e0..642fb92d8 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java @@ -1,6 +1,6 @@ package eu.eudat.logic.managers; -import eu.eudat.data.entities.Credential; +import eu.eudat.data.CredentialEntity; import eu.eudat.data.entities.EmailConfirmation; import eu.eudat.data.entities.UserDMP; import eu.eudat.data.entities.UserInfo; @@ -86,8 +86,8 @@ public class MergeEmailConfirmationManager { @Transactional private void mergeNewUserToOld(UserInfo newUser, UserInfo oldUser, Integer provider) { - Credential credential = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.and(builder.equal(root.get("userInfo"), oldUser), builder.equal(root.get("provider"), provider))).getSingle(); - credential.setUserInfo(newUser); + CredentialEntity credential = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.and(builder.equal(root.get("userId"), oldUser.getId()), builder.equal(root.get("provider"), provider))).getSingle(); + credential.setUserId(newUser.getId()); databaseRepository.getCredentialDao().createOrUpdate(credential); List userDmps = databaseRepository.getUserDmpDao().asQueryable().where((builder, root) -> builder.equal(root.get("user"), oldUser)).toList(); userDmps.forEach(userDmp -> { @@ -128,7 +128,7 @@ public class MergeEmailConfirmationManager { } oldUser.setUserStatus((short)1); oldUser.setEmail(null); - List credentials = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userInfo"), oldUser)).toList(); + List credentials = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userId"), oldUser.getId())).toList(); credentials.forEach(cred -> { if (cred.getId() != credential.getId()) { databaseRepository.getCredentialDao().delete(cred); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java index 06835e25c..452a11a86 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java @@ -2,7 +2,7 @@ package eu.eudat.logic.managers; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; -import eu.eudat.data.entities.Credential; +import eu.eudat.data.CredentialEntity; import eu.eudat.data.entities.EmailConfirmation; import eu.eudat.data.entities.UserInfo; import eu.eudat.exceptions.emailconfirmation.HasConfirmedEmailException; @@ -64,7 +64,7 @@ public class UnlinkEmailConfirmationManager { @Transactional private void unlinkUser(String emailTobeUnlinked, Integer provider){ - Credential credential = databaseRepository.getCredentialDao().asQueryable() + CredentialEntity credential = databaseRepository.getCredentialDao().asQueryable() .where((builder, root) -> builder.and(builder.equal(root.get("email"), emailTobeUnlinked), builder.equal(root.get("provider"), provider))).getSingle(); if(credential != null) { databaseRepository.getCredentialDao().delete(credential); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java index 0e74dcd46..7093aa4ac 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java @@ -1,6 +1,7 @@ package eu.eudat.logic.managers; import com.fasterxml.jackson.databind.ObjectMapper; +import eu.eudat.data.CredentialEntity; import eu.eudat.data.dao.criteria.DataManagementPlanCriteria; import eu.eudat.data.dao.entities.UserInfoDao; import eu.eudat.data.entities.*; @@ -89,7 +90,7 @@ public class UserManager { public List getCredentials(UUID userId) { List results = new ArrayList<>(); eu.eudat.data.entities.UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(userId); - List credentials = apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userInfo"), user)).toList(); + List credentials = apiContext.getOperationsContext().getDatabaseRepository().getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userInfo"), user)).toList(); credentials.forEach(credential -> { UserCredential userCredential = new UserCredential(); userCredential.setEmail(credential.getEmail()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserCredential.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserCredential.java index e2ce326f8..93f3a1fa3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserCredential.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserCredential.java @@ -1,18 +1,20 @@ package eu.eudat.models.data.userinfo; +import eu.eudat.commons.enums.ProviderType; + public class UserCredential { private String email; - private Integer provider; + private ProviderType provider; public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } - public Integer getProvider() { + public ProviderType getProvider() { return provider; } - public void setProvider(Integer provider) { + public void setProvider(ProviderType provider) { this.provider = provider; } diff --git a/dmp-frontend/src/app/core/services/language/language.service.ts b/dmp-frontend/src/app/core/services/language/language.service.ts index c1342d312..0b76a0ffb 100644 --- a/dmp-frontend/src/app/core/services/language/language.service.ts +++ b/dmp-frontend/src/app/core/services/language/language.service.ts @@ -35,11 +35,11 @@ export class LanguageService { public getCurrentLanguageJSON(): Observable> { const params = new BaseHttpParams(); - params.interceptorContext = { - excludedInterceptors: [ - InterceptorType.AuthToken, - ] - }; + // params.interceptorContext = { + // excludedInterceptors: [ + // InterceptorType.AuthToken, + // ] + // }; return this.http.get(`${this.publicApiBase}/${this.currentLanguage}`, { params: params, responseType: 'blob', observe: 'response' }); } diff --git a/dmp-frontend/src/app/core/services/language/server.loader.ts b/dmp-frontend/src/app/core/services/language/server.loader.ts index 2df3cce10..4f2ed4548 100644 --- a/dmp-frontend/src/app/core/services/language/server.loader.ts +++ b/dmp-frontend/src/app/core/services/language/server.loader.ts @@ -17,11 +17,11 @@ export class TranslateServerLoader implements TranslateLoader{ } getTranslation(lang: string): Observable { const params = new BaseHttpParams(); - params.interceptorContext = { - excludedInterceptors: [ - InterceptorType.AuthToken, - ] - }; + // params.interceptorContext = { + // excludedInterceptors: [ + // InterceptorType.AuthToken, + // ] + // }; return this.http.get(`${this.apiBase}/${lang}`, { params: params }); } } diff --git a/dmp-frontend/src/assets/config/config.json b/dmp-frontend/src/assets/config/config.json index f2a80aa0b..2f32cfde1 100644 --- a/dmp-frontend/src/assets/config/config.json +++ b/dmp-frontend/src/assets/config/config.json @@ -52,12 +52,12 @@ ], "keycloak": { "enabled": true, - "address": "http://dev03.local.cite.gr:60201/auth", - "realm": "dmp-development", + "address": "", + "realm": "", "flow": "standard", - "clientId": "dmp_webapp", + "clientId": "", "silentCheckSsoRedirectUri": "http://localhost:4200/assets/silent-check-sso.html", - "scope": "openid profile email address phone dmp_web", + "scope": "openid profile email address phone", "clientSecret": null, "grantType": "code" },