Merge branch 'dmp-refactoring' of https://code-repo.d4science.org/MaDgiK-CITE/argos into dmp-refactoring

This commit is contained in:
Diamantis Tziotzios 2024-04-16 16:21:51 +03:00
commit 0fa4c58363
16 changed files with 88 additions and 621 deletions

View File

@ -11,8 +11,6 @@ import javax.management.InvalidApplicationException;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
@Component
@RequestScope
public class TenantScope { public class TenantScope {
public static final String TenantReplaceParameter = "::TenantCode::"; public static final String TenantReplaceParameter = "::TenantCode::";
private final MultitenancyProperties multitenancy; private final MultitenancyProperties multitenancy;
@ -66,7 +64,14 @@ public class TenantScope {
this.tenant.set(tenant); this.tenant.set(tenant);
this.tenantCode.set(tenantCode); this.tenantCode.set(tenantCode);
if (this.tenant.get() != null && !this.isDefaultTenant()) { entityManager
.unwrap(Session.class)
.disableFilter(TenantScopedBaseEntity.TENANT_FILTER);
entityManager
.unwrap(Session.class)
.disableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER);
if (this.tenant.get() != null || this.isDefaultTenant()) {
if(!this.isDefaultTenant()) { if(!this.isDefaultTenant()) {
entityManager entityManager
.unwrap(Session.class) .unwrap(Session.class)
@ -83,7 +88,16 @@ public class TenantScope {
public void removeTempTenant(EntityManager entityManager) { public void removeTempTenant(EntityManager entityManager) {
this.tenant.set(this.initialTenant.get()); this.tenant.set(this.initialTenant.get());
this.tenantCode.set(this.initialTenantCode.get()); this.tenantCode.set(this.initialTenantCode.get());
if (this.initialTenant.get() != null && !this.isDefaultTenant()) {
entityManager
.unwrap(Session.class)
.disableFilter(TenantScopedBaseEntity.TENANT_FILTER);
entityManager
.unwrap(Session.class)
.disableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER);
if (this.initialTenant.get() != null || this.isDefaultTenant()) {
if(!this.isDefaultTenant()) { if(!this.isDefaultTenant()) {
entityManager entityManager
.unwrap(Session.class) .unwrap(Session.class)

View File

@ -1,125 +0,0 @@
package gr.cite.annotation.data;
import gr.cite.annotation.common.enums.ContactInfoType;
import gr.cite.annotation.common.enums.IsActive;
import gr.cite.annotation.data.conventers.ContactInfoTypeConverter;
import gr.cite.annotation.data.conventers.IsActiveConverter;
import gr.cite.annotation.data.tenant.TenantScopedBaseEntity;
import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;
@Entity
@Table(name = "\"UserContactInfo\"")
public class UserContactInfoEntity {
@Id
@Column(name = "id", columnDefinition = "uuid", updatable = false, nullable = false)
private UUID id;
public static final String _id = "id";
@Column(name = "\"user\"", nullable = false)
private UUID userId;
public static final String _userId = "userId";
@Column(name = "\"ordinal\"", nullable = false)
private Integer ordinal;
public static final String _ordinal = "ordinal";
@Column(name = "type", length = 100, nullable = false)
@Convert(converter = ContactInfoTypeConverter.class)
private ContactInfoType type;
public static final String _type = "type";
@Column(name = "value", nullable = false)
private String value;
public static final String _value = "value";
@Column(name = "created_at", nullable = false)
private Instant createdAt;
public static final String _createdAt = "createdAt";
@Column(name = "updated_at", nullable = false)
private Instant updatedAt;
public static final String _updatedAt = "updatedAt";
@Column(name = "\"is_active\"", nullable = false)
@Convert(converter = IsActiveConverter.class)
private IsActive isActive;
public static final String _isActive = "isActive";
public UUID getUserId() {
return userId;
}
public void setUserId(UUID userId) {
this.userId = userId;
}
public ContactInfoType getType() {
return type;
}
public void setType(ContactInfoType type) {
this.type = type;
}
public String getValue() {
return value;
}
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public Integer getOrdinal() {
return ordinal;
}
public void setOrdinal(Integer ordinal) {
this.ordinal = ordinal;
}
public void setValue(String value) {
this.value = value;
}
public Instant getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Instant createdAt) {
this.createdAt = createdAt;
}
public Instant getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(Instant updatedAt) {
this.updatedAt = updatedAt;
}
public IsActive getIsActive() {
return isActive;
}
public void setIsActive(IsActive isActive) {
this.isActive = isActive;
}
}

View File

@ -1,76 +0,0 @@
package gr.cite.annotation.model;
import gr.cite.annotation.common.enums.ContactInfoType;
import java.time.Instant;
import java.util.UUID;
public class UserContactInfo {
private UUID id;
public static final String _id = "id";
private String value;
public static final String _value = "value";
private ContactInfoType type;
public static final String _type = "type";
private int ordinal;
public static final String _ordinal = "ordinal";
private User user;
public static final String _user = "user";
private Instant createdAt;
public static final String _createdAt = "createdAt";
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public ContactInfoType getType() {
return type;
}
public void setType(ContactInfoType type) {
this.type = type;
}
public int getOrdinal() {
return ordinal;
}
public void setOrdinal(int ordinal) {
this.ordinal = ordinal;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Instant getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Instant createdAt) {
this.createdAt = createdAt;
}
}

View File

@ -1,68 +0,0 @@
package gr.cite.annotation.model.deleter;
import gr.cite.annotation.data.TenantEntityManager;
import gr.cite.annotation.data.UserContactInfoEntity;
import gr.cite.annotation.query.UserContactInfoQuery;
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 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 UserContactInfoDeleter implements Deleter {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(UserContactInfoDeleter.class));
private final TenantEntityManager entityManager;
protected final QueryFactory queryFactory;
@Autowired
public UserContactInfoDeleter(
TenantEntityManager 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<UserContactInfoEntity> data = this.queryFactory.query(UserContactInfoQuery.class).ids(ids).collect();
logger.trace("retrieved {} items", Optional.ofNullable(data).map(List::size).orElse(0));
this.deleteAndSave(data);
}
public void deleteAndSave(List<UserContactInfoEntity> 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<UserContactInfoEntity> data) throws InvalidApplicationException {
logger.debug("will delete {} items", Optional.ofNullable(data).map(List::size).orElse(0));
if (data == null || data.isEmpty())
return;
for (UserContactInfoEntity item : data) {
logger.trace("deleting item {}", item.getId());
logger.trace("deleting item");
this.entityManager.remove(item);
logger.trace("deleted item");
}
}
}

View File

@ -3,7 +3,6 @@ package gr.cite.annotation.model.deleter;
import gr.cite.annotation.common.enums.IsActive; import gr.cite.annotation.common.enums.IsActive;
import gr.cite.annotation.data.*; import gr.cite.annotation.data.*;
import gr.cite.annotation.query.TenantUserQuery; import gr.cite.annotation.query.TenantUserQuery;
import gr.cite.annotation.query.UserContactInfoQuery;
import gr.cite.annotation.query.UserCredentialQuery; import gr.cite.annotation.query.UserCredentialQuery;
import gr.cite.annotation.query.UserQuery; import gr.cite.annotation.query.UserQuery;
import gr.cite.tools.data.deleter.Deleter; import gr.cite.tools.data.deleter.Deleter;
@ -76,12 +75,6 @@ public class UserDeleter implements Deleter {
deleter.delete(items); deleter.delete(items);
} }
{
logger.debug("checking related - {}", UserContactInfoEntity.class.getSimpleName());
List<UserContactInfoEntity> items = this.queryFactory.query(UserContactInfoQuery.class).userIds(ids).collect();
UserContactInfoDeleter deleter = this.deleterFactory.deleter(UserContactInfoDeleter.class);
deleter.delete(items);
}
{ {
logger.debug("checking related - {}", TenantUserEntity.class.getSimpleName()); logger.debug("checking related - {}", TenantUserEntity.class.getSimpleName());
List<TenantUserEntity> items = this.queryFactory.query(TenantUserQuery.class).userIds(ids).collect(); List<TenantUserEntity> items = this.queryFactory.query(TenantUserQuery.class).userIds(ids).collect();

View File

@ -1,236 +0,0 @@
package gr.cite.annotation.query;
import gr.cite.annotation.authorization.AuthorizationFlags;
import gr.cite.annotation.authorization.Permission;
import gr.cite.annotation.common.enums.ContactInfoType;
import gr.cite.annotation.common.scope.user.UserScope;
import gr.cite.annotation.data.UserContactInfoEntity;
import gr.cite.annotation.model.UserContactInfo;
import gr.cite.commons.web.authz.service.AuthorizationService;
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.time.Instant;
import java.util.*;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class UserContactInfoQuery extends QueryBase<UserContactInfoEntity> {
private Collection<UUID> ids;
private Collection<UUID> excludedIds;
private Collection<UUID> excludedUserIds;
private Collection<UUID> userIds;
private Collection<String> values;
private Collection<ContactInfoType> types;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
private final UserScope userScope;
private final AuthorizationService authService;
public UserContactInfoQuery(UserScope userScope, AuthorizationService authService) {
this.userScope = userScope;
this.authService = authService;
}
public UserContactInfoQuery ids(UUID value) {
this.ids = List.of(value);
return this;
}
public UserContactInfoQuery ids(UUID... value) {
this.ids = Arrays.asList(value);
return this;
}
public UserContactInfoQuery ids(Collection<UUID> values) {
this.ids = values;
return this;
}
public UserContactInfoQuery excludedIds(Collection<UUID> values) {
this.excludedIds = values;
return this;
}
public UserContactInfoQuery excludedIds(UUID value) {
this.excludedIds = List.of(value);
return this;
}
public UserContactInfoQuery excludedIds(UUID... value) {
this.excludedIds = Arrays.asList(value);
return this;
}
public UserContactInfoQuery excludedUserIds(Collection<UUID> values) {
this.excludedUserIds = values;
return this;
}
public UserContactInfoQuery excludedUserIds(UUID value) {
this.excludedUserIds = List.of(value);
return this;
}
public UserContactInfoQuery excludedUserIds(UUID... value) {
this.excludedUserIds = Arrays.asList(value);
return this;
}
public UserContactInfoQuery userIds(UUID value) {
this.userIds = List.of(value);
return this;
}
public UserContactInfoQuery userIds(UUID... value) {
this.userIds = Arrays.asList(value);
return this;
}
public UserContactInfoQuery userIds(Collection<UUID> values) {
this.userIds = values;
return this;
}
public UserContactInfoQuery values(String value) {
this.values = List.of(value);
return this;
}
public UserContactInfoQuery values(String... value) {
this.values = Arrays.asList(value);
return this;
}
public UserContactInfoQuery values(Collection<String> values) {
this.values = values;
return this;
}
public UserContactInfoQuery types(ContactInfoType value) {
this.types = List.of(value);
return this;
}
public UserContactInfoQuery types(ContactInfoType... value) {
this.types = Arrays.asList(value);
return this;
}
public UserContactInfoQuery types(Collection<ContactInfoType> values) {
this.types = values;
return this;
}
public UserContactInfoQuery authorize(EnumSet<AuthorizationFlags> values) {
this.authorize = values;
return this;
}
@Override
protected Boolean isFalseQuery() {
return
this.isEmpty(this.ids) ||
this.isEmpty(this.userIds) ||
this.isEmpty(this.excludedIds) ||
this.isEmpty(this.values) ||
this.isEmpty(this.excludedIds);
}
@Override
protected Class<UserContactInfoEntity> entityClass() {
return UserContactInfoEntity.class;
}
@Override
protected <X, Y> Predicate applyAuthZ(QueryContext<X, Y> queryContext) {
if (this.authorize.contains(AuthorizationFlags.None)) return null;
if (this.authorize.contains(AuthorizationFlags.Permission) && this.authService.authorize(Permission.BrowseUser)) return null;
UUID userId;
if (this.authorize.contains(AuthorizationFlags.Owner)) userId = this.userScope.getUserIdSafe();
else userId = null;
List<Predicate> predicates = new ArrayList<>();
if (userId != null) {
predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(UserContactInfoEntity._userId)).value(userId));
}
if (!predicates.isEmpty()) {
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
return queryContext.CriteriaBuilder.and(predicatesArray);
} else {
return queryContext.CriteriaBuilder.or(); //Creates a false query
}
}
@Override
protected <X, Y> Predicate applyFilters(QueryContext<X, Y> queryContext) {
List<Predicate> predicates = new ArrayList<>();
if (this.ids != null) {
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UserContactInfoEntity._id));
for (UUID item : this.ids)
inClause.value(item);
predicates.add(inClause);
}
if (this.userIds != null) {
CriteriaBuilder.In<UUID> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UserContactInfoEntity._userId));
for (UUID item : this.userIds)
inClause.value(item);
predicates.add(inClause);
}
if (this.excludedIds != null) {
CriteriaBuilder.In<UUID> notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UserContactInfoEntity._id));
for (UUID item : this.excludedIds)
notInClause.value(item);
predicates.add(notInClause.not());
}
if (this.excludedUserIds != null) {
CriteriaBuilder.In<UUID> notInClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UserContactInfoEntity._userId));
for (UUID item : this.excludedUserIds)
notInClause.value(item);
predicates.add(notInClause.not());
}
if (this.values != null) {
CriteriaBuilder.In<String> inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(UserContactInfoEntity._value));
for (String item : this.values)
inClause.value(item);
predicates.add(inClause);
}
if (!predicates.isEmpty()) {
Predicate[] predicatesArray = predicates.toArray(new Predicate[0]);
return queryContext.CriteriaBuilder.and(predicatesArray);
} else {
return null;
}
}
@Override
protected String fieldNameOf(FieldResolver item) {
if (item.match(UserContactInfo._id)) return UserContactInfoEntity._id;
else if (item.match(UserContactInfo._value)) return UserContactInfoEntity._value;
else if (item.match(UserContactInfo._ordinal)) return UserContactInfoEntity._ordinal;
else if (item.prefix(UserContactInfo._user)) return UserContactInfoEntity._userId;
else if (item.match(UserContactInfo._user)) return UserContactInfoEntity._userId;
else if (item.match(UserContactInfo._type)) return UserContactInfoEntity._type;
else if (item.match(UserContactInfo._createdAt) ) return UserContactInfoEntity._createdAt;
else return null;
}
@Override
protected UserContactInfoEntity convert(Tuple tuple, Set<String> columns) {
UserContactInfoEntity item = new UserContactInfoEntity();
item.setId(QueryBase.convertSafe(tuple, columns, UserContactInfoEntity._id, UUID.class));
item.setValue(QueryBase.convertSafe(tuple, columns, UserContactInfoEntity._value, String.class));
item.setType(QueryBase.convertSafe(tuple, columns, UserContactInfoEntity._type, ContactInfoType.class));
item.setOrdinal(QueryBase.convertSafe(tuple, columns, UserContactInfoEntity._ordinal, Integer.class));
item.setUserId(QueryBase.convertSafe(tuple, columns, UserContactInfoEntity._userId, UUID.class));
item.setCreatedAt(QueryBase.convertSafe(tuple, columns, UserContactInfoEntity._createdAt, Instant.class));
return item;
}
}

View File

@ -9,17 +9,14 @@ import gr.cite.annotation.common.scope.tenant.TenantScope;
import gr.cite.annotation.convention.ConventionService; import gr.cite.annotation.convention.ConventionService;
import gr.cite.annotation.data.*; import gr.cite.annotation.data.*;
import gr.cite.annotation.integrationevent.inbox.usertouch.UserTouchedIntegrationEvent; import gr.cite.annotation.integrationevent.inbox.usertouch.UserTouchedIntegrationEvent;
import gr.cite.annotation.model.Annotation;
import gr.cite.annotation.model.Tenant; import gr.cite.annotation.model.Tenant;
import gr.cite.annotation.model.User; import gr.cite.annotation.model.User;
import gr.cite.annotation.model.builder.UserBuilder; import gr.cite.annotation.model.builder.UserBuilder;
import gr.cite.annotation.model.deleter.TenantUserDeleter; import gr.cite.annotation.model.deleter.TenantUserDeleter;
import gr.cite.annotation.model.deleter.UserContactInfoDeleter;
import gr.cite.annotation.model.deleter.UserCredentialDeleter; import gr.cite.annotation.model.deleter.UserCredentialDeleter;
import gr.cite.annotation.model.deleter.UserDeleter; import gr.cite.annotation.model.deleter.UserDeleter;
import gr.cite.annotation.query.TenantQuery; import gr.cite.annotation.query.TenantQuery;
import gr.cite.annotation.query.TenantUserQuery; import gr.cite.annotation.query.TenantUserQuery;
import gr.cite.annotation.query.UserContactInfoQuery;
import gr.cite.annotation.query.UserCredentialQuery; import gr.cite.annotation.query.UserCredentialQuery;
import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.data.builder.BuilderFactory;
@ -125,7 +122,6 @@ public class UserServiceImpl implements UserService {
this.entityManager.flush(); this.entityManager.flush();
this.persistContactInfo(model.getUserContactInfo(), data.getId());
this.persistUserCredential(model.getCredentials(), data.getId()); this.persistUserCredential(model.getCredentials(), data.getId());
this.persistTenantUser(model.getTenantUsers(), data.getId()); this.persistTenantUser(model.getTenantUsers(), data.getId());
@ -143,38 +139,6 @@ public class UserServiceImpl implements UserService {
this.deleterFactory.deleter(UserDeleter.class).deleteAndSaveByIds(List.of(id)); this.deleterFactory.deleter(UserDeleter.class).deleteAndSaveByIds(List.of(id));
} }
private void persistContactInfo(List<UserTouchedIntegrationEvent.UserContactInfo> models, UUID userId) throws InvalidApplicationException {
List<UserContactInfoEntity> items = this.queryFactory.query(UserContactInfoQuery.class)
.userIds(userId)
.collect();
List<UUID> updatedCreatedIds = new ArrayList<>();
if (models != null) {
for (UserTouchedIntegrationEvent.UserContactInfo model : models) {
UserContactInfoEntity data = items.stream().filter(x -> x.getType().equals(model.getType()) && x.getValue().equals(model.getValue())).findFirst().orElse(null);
if (data == null) {
data = new UserContactInfoEntity();
data.setId(UUID.randomUUID());
data.setUserId(userId);
data.setType(model.getType());
data.setValue(model.getValue());
data.setOrdinal(model.getOrdinal());
data.setCreatedAt(Instant.now());
data.setUpdatedAt(Instant.now());
data.setIsActive(IsActive.Active);
entityManager.persist(data);
} else {
data.setOrdinal(model.getOrdinal());
entityManager.merge(data);
}
updatedCreatedIds.add(data.getId());
}
}
List<UserContactInfoEntity> toDelete = items.stream().filter(x -> updatedCreatedIds.stream().noneMatch(y -> y.equals(x.getId()))).collect(Collectors.toList());
deleterFactory.deleter(UserContactInfoDeleter.class).delete(toDelete);
entityManager.flush();
}
private void persistUserCredential(List<UserTouchedIntegrationEvent.UserCredential> models, UUID userId) throws InvalidApplicationException { private void persistUserCredential(List<UserTouchedIntegrationEvent.UserCredential> models, UUID userId) throws InvalidApplicationException {
List<UserCredentialEntity> items = this.queryFactory.query(UserCredentialQuery.class) List<UserCredentialEntity> items = this.queryFactory.query(UserCredentialQuery.class)
.userIds(userId) .userIds(userId)

View File

@ -88,7 +88,7 @@
<dependency> <dependency>
<groupId>gr.cite</groupId> <groupId>gr.cite</groupId>
<artifactId>keycloak-api</artifactId> <artifactId>keycloak-api</artifactId>
<version>2.2.0</version> <version>2.3.0</version>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -24,8 +24,8 @@ public class KeycloakResourcesConfiguration {
.replace("{tenantCode}", tenantCode); .replace("{tenantCode}", tenantCode);
} }
public String getTenantRoleAttributeValue(String tenantCode, String key) { public String getTenantRoleAttributeValue(String tenantCode, KeycloakTenantAuthorityProperties properties) {
return properties.getTenantAuthorities().get(key).getRoleAttributeValueStrategy() return properties.getRoleAttributeValueStrategy()
.replace("{tenantCode}", tenantCode); .replace("{tenantCode}", tenantCode);
} }

View File

@ -1,5 +1,6 @@
package eu.eudat.service.keycloak; package eu.eudat.service.keycloak;
import eu.eudat.convention.ConventionService;
import gr.cite.commons.web.keycloak.api.configuration.KeycloakClientConfiguration; import gr.cite.commons.web.keycloak.api.configuration.KeycloakClientConfiguration;
import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.LoggerService;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -16,13 +17,13 @@ public class KeycloakServiceImpl implements KeycloakService {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(KeycloakServiceImpl.class)); private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(KeycloakServiceImpl.class));
private final MyKeycloakAdminRestApi api; private final MyKeycloakAdminRestApi api;
private final KeycloakResourcesConfiguration configuration; private final KeycloakResourcesConfiguration configuration;
private final KeycloakClientConfiguration clientConfiguration; private final ConventionService conventionService;
@Autowired @Autowired
public KeycloakServiceImpl(MyKeycloakAdminRestApi api, KeycloakResourcesConfiguration configuration, KeycloakClientConfiguration clientConfiguration) { public KeycloakServiceImpl(MyKeycloakAdminRestApi api, KeycloakResourcesConfiguration configuration, ConventionService conventionService) {
this.api = api; this.api = api;
this.configuration = configuration; this.configuration = configuration;
this.clientConfiguration = clientConfiguration; this.conventionService = conventionService;
} }
@Override @Override
@ -37,72 +38,50 @@ public class KeycloakServiceImpl implements KeycloakService {
@Override @Override
public void addUserToGlobalRoleGroup(String subjectId, String role) { public void addUserToGlobalRoleGroup(String subjectId, String role) {
KeycloakAuthorityProperties properties = this.configuration.getProperties().getAuthorities().get(role); if (this.configuration.getProperties().getAuthorities() == null) return;
KeycloakAuthorityProperties properties = this.configuration.getProperties().getAuthorities().getOrDefault(role, null);
if (properties != null) addUserToGroup(subjectId, properties.getGroupId()); if (properties != null) addUserToGroup(subjectId, properties.getGroupId());
} }
@Override @Override
public void removeUserGlobalRoleGroup(@NotNull String subjectId, String role) { public void removeUserGlobalRoleGroup(@NotNull String subjectId, String role) {
KeycloakAuthorityProperties properties = this.configuration.getProperties().getAuthorities().get(role); if (this.configuration.getProperties().getAuthorities() == null) return;
if (properties != null) KeycloakAuthorityProperties properties = this.configuration.getProperties().getAuthorities().getOrDefault(role, null);
removeUserFromGroup(subjectId, properties.getGroupId()); if (properties != null) removeUserFromGroup(subjectId, properties.getGroupId());
} }
//
// @Override
// public void assignClientRoleToUser(UUID subjectId, String clientId, KeycloakRole role) {
// if (clientId == null)
// clientId = clientConfiguration.getProperties().getClientId();
// UserRepresentation user = api.users().findUserById(subjectId.toString());
// user.getClientRoles().computeIfAbsent(clientId, k -> new ArrayList<>());
// Set<String> clientRoles = new HashSet<>(Set.copyOf(user.getClientRoles().get(clientId)));
// clientRoles.add(role.name());
// user.getClientRoles().get(clientId).clear();
// user.getClientRoles().get(clientId).addAll(clientRoles);
// api.users().updateUser(subjectId.toString(), user);
// }
//
// @Override
// public void removeClientRoleFromUser(UUID subjectId, String clientId, KeycloakRole role) {
// if (clientId == null) clientId = clientConfiguration.getProperties().getClientId();
// UserRepresentation user = api.users().findUserById(subjectId.toString());
// user.getClientRoles().computeIfAbsent(clientId, k -> new ArrayList<>());
// Set<String> clientRoles = new HashSet<>(Set.copyOf(user.getClientRoles().get(clientId)));
// clientRoles.remove(role.name());
// user.getClientRoles().get(clientId).clear();
// user.getClientRoles().get(clientId).addAll(clientRoles);
// api.users().updateUser(subjectId.toString(), user);
// }
//
// public List<GroupRepresentation> getUserGroups(UUID subjectId) {
// return api.users().getGroups(subjectId.toString());
// }
@Override @Override
public void addUserToTenantRoleGroup(String subjectId, String tenantCode, String tenantRole) { public void addUserToTenantRoleGroup(String subjectId, String tenantCode, String tenantRole) {
GroupRepresentation group = api.groups().findGroupByPath(getTenantAuthorityParentPath(tenantRole) + "/" + configuration.getTenantGroupName(tenantCode)); if (this.configuration.getProperties().getAuthorities() == null) return;
addUserToGroup(subjectId, group.getId()); KeycloakTenantAuthorityProperties properties = this.configuration.getProperties().getTenantAuthorities().getOrDefault(tenantRole, null);
if (properties == null) return;
GroupRepresentation group = api.groups().findGroupByPath(getTenantAuthorityParentPath(properties) + "/" + configuration.getTenantGroupName(tenantCode));
if (group != null) addUserToGroup(subjectId, group.getId());
} }
@Override @Override
public void removeUserTenantRoleGroup(String subjectId, String tenantCode, String tenantRole) { public void removeUserTenantRoleGroup(String subjectId, String tenantCode, String tenantRole) {
GroupRepresentation group = api.groups().findGroupByPath(getTenantAuthorityParentPath(tenantRole) + "/" + configuration.getTenantGroupName(tenantCode)); KeycloakTenantAuthorityProperties properties = this.configuration.getProperties().getTenantAuthorities().getOrDefault(tenantRole, null);
removeUserFromGroup(subjectId, group.getId()); if (properties == null) return;
GroupRepresentation group = api.groups().findGroupByPath(getTenantAuthorityParentPath(properties) + "/" + configuration.getTenantGroupName(tenantCode));
if (group != null) removeUserFromGroup(subjectId, group.getId());
} }
private String getTenantAuthorityParentPath(String tenantRole) { private String getTenantAuthorityParentPath(KeycloakTenantAuthorityProperties keycloakTenantAuthorityProperties) {
GroupRepresentation parent = api.groups().findGroupById(configuration.getProperties().getTenantAuthorities().get(tenantRole).getParent()); GroupRepresentation parent = api.groups().findGroupById(keycloakTenantAuthorityProperties.getParent());
return parent.getPath(); return parent.getPath();
} }
@Override @Override
public void createTenantGroups(String tenantCode) { public void createTenantGroups(String tenantCode) {
if (this.configuration.getProperties().getTenantAuthorities() == null) return;
for (Map.Entry<String,KeycloakTenantAuthorityProperties> entry :configuration.getProperties().getTenantAuthorities().entrySet()){ for (Map.Entry<String,KeycloakTenantAuthorityProperties> entry :configuration.getProperties().getTenantAuthorities().entrySet()){
GroupRepresentation group = new GroupRepresentation(); GroupRepresentation group = new GroupRepresentation();
group.setName(configuration.getTenantGroupName(tenantCode)); group.setName(configuration.getTenantGroupName(tenantCode));
HashMap<String, List<String>> user_attributes = new HashMap<>(); HashMap<String, List<String>> user_attributes = new HashMap<>();
user_attributes.put(this.configuration.getProperties().getTenantRoleAttributeName(), List.of(configuration.getTenantRoleAttributeValue(tenantCode, entry.getKey()))); if (!this.conventionService.isNullOrEmpty(this.configuration.getProperties().getTenantRoleAttributeName())) user_attributes.put(this.configuration.getProperties().getTenantRoleAttributeName(), List.of(configuration.getTenantRoleAttributeValue(tenantCode, entry.getValue())));
group.setAttributes(user_attributes); group.setAttributes(user_attributes);
api.groups().addGroupWithParent(group, configuration.getProperties().getTenantAuthorities().get(entry.getKey()).getParent()); api.groups().addGroupWithParent(group, entry.getValue().getParent());
} }
} }
} }

View File

@ -242,7 +242,7 @@
<dependency> <dependency>
<groupId>gr.cite</groupId> <groupId>gr.cite</groupId>
<artifactId>keycloak-api</artifactId> <artifactId>keycloak-api</artifactId>
<version>2.2.0</version> <version>2.3.0</version>
</dependency> </dependency>

View File

@ -9,7 +9,7 @@ CREATE TABLE IF NOT EXISTS public."ant_EntityUser"
"id" uuid NOT NULL, "id" uuid NOT NULL,
"entity_id" uuid NOT NULL, "entity_id" uuid NOT NULL,
"user_id" uuid NOT NULL, "user_id" uuid NOT NULL,
"tenant" uuid NOT NULL, "tenant" uuid NULL,
"created_at" timestamp without time zone NOT NULL, "created_at" timestamp without time zone NOT NULL,
"updated_at" timestamp without time zone NOT NULL, "updated_at" timestamp without time zone NOT NULL,
"is_active" smallint NOT NULL, "is_active" smallint NOT NULL,

View File

@ -39,11 +39,15 @@
</p> </p>
<div class="row d-flex align-items-center"> <div class="row d-flex align-items-center">
<div *ngIf="!this.hasDmps()" class="col-auto add-dataset-btn d-flex"> <div *ngIf="!this.hasDmps()" class="col-auto p-0 add-dataset-btn d-flex">
<button type="button" class="col-auto align-self-center normal-btn" (click)="openNewDmpDialog()">{{'DASHBOARD.START-YOUR-FIRST-DMP' | translate}}</button> <div class="pr-2">
<button type="button" class="align-self-center normal-btn" (click)="openNewDmpDialog()">{{'DASHBOARD.START-YOUR-FIRST-DMP' | translate}}</button>
</div>
</div>
<div *ngIf="this.hasDmps()" class="col-auto p-0 new-dataset-tour add-dataset-btn col-auto d-flex">
<div class="pr-2">
<button mat-raised-button type="button" class="align-self-center yellow-btn" (click)="addNewDescription()">{{'DASHBOARD.ACTIONS.ADD-DESCRIPTION' | translate}}</button>
</div> </div>
<div *ngIf="this.hasDmps()" class="new-dataset-tour add-dataset-btn col-auto d-flex">
<button mat-raised-button type="button" class="col-auto align-self-center yellow-btn" (click)="addNewDescription()">{{'DASHBOARD.ACTIONS.ADD-DESCRIPTION' | translate}}</button>
</div> </div>
<span class="col-auto ml-auto"> <span class="col-auto ml-auto">
<img class="laptop-img\6" src="../../../assets/images/dashboard-popup.png"> <img class="laptop-img\6" src="../../../assets/images/dashboard-popup.png">

View File

@ -186,7 +186,7 @@ export class DashboardComponent extends BaseComponent implements OnInit {
closeAction: () => this.dialog.closeAll() closeAction: () => this.dialog.closeAll()
}, },
{ {
selector: '.new-description-tour', selector: '.new-dataset-tour',
content: 'Step 4', content: 'Step 4',
orientation: Orientation.BottomLeft, orientation: Orientation.BottomLeft,
isStepUnique: false, isStepUnique: false,

View File

@ -15,16 +15,19 @@
</div> </div>
<div class="col-12"> <div class="col-12">
<div class="d-flex justify-content-between align-items-center"> <div class="d-flex justify-content-between align-items-center">
<div class="col-auto p-0"> <div class="import-file col-auto p-0">
<div class="pr-2">
<button type="button" class="normal-btn upload-btn d-flex flex-row align-items-center" (click)="uploadFile($event)"> <button type="button" class="normal-btn upload-btn d-flex flex-row align-items-center" (click)="uploadFile($event)">
<mat-icon class="pr-2">file_upload</mat-icon> <mat-icon class="pr-2">file_upload</mat-icon>
{{ 'START-NEW-PLAN-DIALOG.IMPORT-FROM-FILE' | translate }} {{ 'START-NEW-PLAN-DIALOG.IMPORT-FROM-FILE' | translate }}
</button> </button>
</div> </div>
<div class="col-auto p-0"> </div>
<div class="col-auto">
<p class="m-0">{{ 'START-NEW-PLAN-DIALOG.OR' | translate }}</p> <p class="m-0">{{ 'START-NEW-PLAN-DIALOG.OR' | translate }}</p>
</div> </div>
<div class="col-auto p-0"> <div class="start-wizard col-auto p-0">
<div class="pr-2">
<button type="button" class="normal-btn font-weight-bold d-flex flex-row align-items-center" (click)="startWizard()"> <button type="button" class="normal-btn font-weight-bold d-flex flex-row align-items-center" (click)="startWizard()">
<mat-icon>chevron_right</mat-icon> <mat-icon>chevron_right</mat-icon>
{{ 'START-NEW-PLAN-DIALOG.START-WIZARD' | translate }} {{ 'START-NEW-PLAN-DIALOG.START-WIZARD' | translate }}
@ -33,6 +36,7 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="d-flex justify-content-between pt-4"> <div class="d-flex justify-content-between pt-4">
<div class="pr-2"> <div class="pr-2">

View File

@ -11,8 +11,6 @@ import javax.management.InvalidApplicationException;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
@Component
@RequestScope
public class TenantScope { public class TenantScope {
public static final String TenantReplaceParameter = "::TenantCode::"; public static final String TenantReplaceParameter = "::TenantCode::";
private final MultitenancyProperties multitenancy; private final MultitenancyProperties multitenancy;
@ -66,7 +64,14 @@ public class TenantScope {
this.tenant.set(tenant); this.tenant.set(tenant);
this.tenantCode.set(tenantCode); this.tenantCode.set(tenantCode);
if (this.tenant.get() != null && !this.isDefaultTenant()) { entityManager
.unwrap(Session.class)
.disableFilter(TenantScopedBaseEntity.TENANT_FILTER);
entityManager
.unwrap(Session.class)
.disableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER);
if (this.tenant.get() != null || this.isDefaultTenant()) {
if(!this.isDefaultTenant()) { if(!this.isDefaultTenant()) {
entityManager entityManager
.unwrap(Session.class) .unwrap(Session.class)
@ -83,7 +88,16 @@ public class TenantScope {
public void removeTempTenant(EntityManager entityManager) { public void removeTempTenant(EntityManager entityManager) {
this.tenant.set(this.initialTenant.get()); this.tenant.set(this.initialTenant.get());
this.tenantCode.set(this.initialTenantCode.get()); this.tenantCode.set(this.initialTenantCode.get());
if (this.initialTenant.get() != null && !this.isDefaultTenant()) {
entityManager
.unwrap(Session.class)
.disableFilter(TenantScopedBaseEntity.TENANT_FILTER);
entityManager
.unwrap(Session.class)
.disableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER);
if (this.initialTenant.get() != null || this.isDefaultTenant()) {
if(!this.isDefaultTenant()) { if(!this.isDefaultTenant()) {
entityManager entityManager
.unwrap(Session.class) .unwrap(Session.class)