diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/scope/tenant/MultitenancyProperties.java b/dmp-backend/core/src/main/java/eu/eudat/commons/scope/tenant/MultitenancyProperties.java index 79b9ed745..e7c89bb3c 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/scope/tenant/MultitenancyProperties.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/scope/tenant/MultitenancyProperties.java @@ -5,6 +5,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "tenant.multitenancy") public class MultitenancyProperties { private boolean isMultitenant; + private String defaultTenantCode; public boolean isMultitenant() { return isMultitenant; @@ -13,4 +14,12 @@ public class MultitenancyProperties { public void setIsMultitenant(boolean multitenant) { isMultitenant = multitenant; } + + public String getDefaultTenantCode() { + return defaultTenantCode; + } + + public void setDefaultTenantCode(String defaultTenantCode) { + this.defaultTenantCode = defaultTenantCode; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/scope/tenant/TenantScope.java b/dmp-backend/core/src/main/java/eu/eudat/commons/scope/tenant/TenantScope.java index a0cbf2d9a..3c88a8115 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/scope/tenant/TenantScope.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/scope/tenant/TenantScope.java @@ -1,10 +1,8 @@ package eu.eudat.commons.scope.tenant; import eu.eudat.data.tenant.TenantScopedBaseEntity; -import gr.cite.tools.logging.LoggerService; import jakarta.persistence.EntityManager; import org.hibernate.Session; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.context.annotation.RequestScope; @@ -22,7 +20,6 @@ public class TenantScope { public static final String TenantClaimName = "x-tenant"; private final MultitenancyProperties multitenancy; - private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(TenantScope.class)); private final AtomicReference tenant = new AtomicReference<>(); private final AtomicReference tenantCode = new AtomicReference<>(); private final AtomicReference initialTenant = new AtomicReference<>(); @@ -37,45 +34,70 @@ public class TenantScope { return multitenancy.isMultitenant(); } + public String getDefaultTenantCode() { + return multitenancy.getDefaultTenantCode(); + } + public Boolean isSet() { if (!this.isMultitenant()) return Boolean.TRUE; - return this.tenant.get() != null; + return this.tenant.get() != null || this.isDefaultTenant(); + } + + public Boolean isDefaultTenant() { + if (!this.isMultitenant()) + return Boolean.TRUE; + return this.multitenancy.getDefaultTenantCode().equalsIgnoreCase(this.tenantCode.get()); } public UUID getTenant() throws InvalidApplicationException { if (!this.isMultitenant()) return null; - if (this.tenant.get() == null) + if (this.tenant.get() == null && !this.isDefaultTenant()) throw new InvalidApplicationException("tenant not set"); - return this.tenant.get(); + return this.isDefaultTenant() ? null : this.tenant.get(); } public String getTenantCode() throws InvalidApplicationException { if (!this.isMultitenant()) return null; - if (this.tenant.get() == null) + if (this.tenantCode.get() == null) throw new InvalidApplicationException("tenant not set"); return this.tenantCode.get(); } - public void setTempTenant(EntityManager entityManager, UUID tenant) { + public void setTempTenant(EntityManager entityManager, UUID tenant, String tenantCode) { this.tenant.set(tenant); + this.tenantCode.set(tenantCode); - if (this.tenant.get() != null) { - entityManager - .unwrap(Session.class) - .enableFilter(TenantScopedBaseEntity.tenantFilter).setParameter(TenantScopedBaseEntity.tenantFilterTenantParam, this.tenant.get().toString()); + if (this.tenant.get() != null && !this.isDefaultTenant()) { + if(!this.isDefaultTenant()) { + entityManager + .unwrap(Session.class) + .enableFilter(TenantScopedBaseEntity.TENANT_FILTER) + .setParameter(TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, this.tenant.get().toString()); + } else { + entityManager + .unwrap(Session.class) + .enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER); + } } } public void removeTempTenant(EntityManager entityManager) { this.tenant.set(this.initialTenant.get()); this.tenantCode.set(this.initialTenantCode.get()); - if (this.initialTenant.get() != null) { - entityManager - .unwrap(Session.class) - .enableFilter(TenantScopedBaseEntity.tenantFilter).setParameter(TenantScopedBaseEntity.tenantFilterTenantParam, this.initialTenant.get().toString()); + if (this.initialTenant.get() != null && !this.isDefaultTenant()) { + if(!this.isDefaultTenant()) { + entityManager + .unwrap(Session.class) + .enableFilter(TenantScopedBaseEntity.TENANT_FILTER) + .setParameter(TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, this.tenant.get().toString()); + } else { + entityManager + .unwrap(Session.class) + .enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER); + } } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/TenantEntityManager.java b/dmp-backend/core/src/main/java/eu/eudat/data/TenantEntityManager.java index 9869eb536..9d715901d 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/data/TenantEntityManager.java +++ b/dmp-backend/core/src/main/java/eu/eudat/data/TenantEntityManager.java @@ -41,7 +41,7 @@ public class TenantEntityManager { // this.claimExtractor.subjectUUID(this.currentPrincipalResolver.currentPrincipal()); // boolean isAllowedNoTenant = authorizationService.authorize(Permission.AllowNoTenant); - boolean isAllowedNoTenant = ((TenantScoped) entity).allowNullTenant(); + boolean isAllowedNoTenant = ((TenantScoped) entity).allowNullTenant() || this.tenantScope.isDefaultTenant(); final UUID tenantId = !isAllowedNoTenant ? tenantScope.getTenant() : null; if (!isAllowedNoTenant && !tenantId.equals(((TenantScoped) entity).getTenantId())) throw new MyForbiddenException("tenant tampering"); } @@ -50,7 +50,7 @@ public class TenantEntityManager { public void remove(Object entity) throws InvalidApplicationException { if (tenantScope.isMultitenant() && (entity instanceof TenantScoped)) { - boolean isAllowedNoTenant = ((TenantScoped) entity).allowNullTenant(); + boolean isAllowedNoTenant = ((TenantScoped) entity).allowNullTenant() || this.tenantScope.isDefaultTenant(); final UUID tenantId = !isAllowedNoTenant ? tenantScope.getTenant() : null; if (!isAllowedNoTenant && !tenantId.equals(((TenantScoped) entity).getTenantId())) throw new MyForbiddenException("tenant tampering"); } @@ -65,7 +65,7 @@ public class TenantEntityManager { // this.claimExtractor.subjectUUID(this.currentPrincipalResolver.currentPrincipal()); // boolean isAllowedNoTenant = authorizationService.authorize(Permission.AllowNoTenant); - boolean isAllowedNoTenant = ((TenantScoped) entity).allowNullTenant(); + boolean isAllowedNoTenant = ((TenantScoped) entity).allowNullTenant() || this.tenantScope.isDefaultTenant(); final UUID tenantId = !isAllowedNoTenant ? tenantScope.getTenant() : null; if (!isAllowedNoTenant && !tenantId.equals(((TenantScoped) entity).getTenantId())) return null; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/tenant/TenantFilterAspect.java b/dmp-backend/core/src/main/java/eu/eudat/data/tenant/TenantFilterAspect.java index ecc1b11a0..8b7edc9a7 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/data/tenant/TenantFilterAspect.java +++ b/dmp-backend/core/src/main/java/eu/eudat/data/tenant/TenantFilterAspect.java @@ -29,11 +29,16 @@ public class TenantFilterAspect { pointcut = "bean(entityManagerFactory) && execution(* createEntityManager(..))", returning = "retVal") public void getSessionAfter(JoinPoint joinPoint, Object retVal) throws InvalidApplicationException { - if (retVal != null && retVal instanceof EntityManager && tenantScope.isSet()) { + if (retVal instanceof EntityManager && tenantScope.isSet()) { Session session = ((EntityManager) retVal).unwrap(Session.class); - session - .enableFilter(TenantScopedBaseEntity.tenantFilter) - .setParameter(TenantScopedBaseEntity.tenantFilterTenantParam, tenantScope.getTenant().toString()); + if(!tenantScope.isDefaultTenant()) { + session + .enableFilter(TenantScopedBaseEntity.TENANT_FILTER) + .setParameter(TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, tenantScope.getTenant().toString()); + } else { + session + .enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER); + } } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/tenant/TenantListener.java b/dmp-backend/core/src/main/java/eu/eudat/data/tenant/TenantListener.java index 2e810510a..965658728 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/data/tenant/TenantListener.java +++ b/dmp-backend/core/src/main/java/eu/eudat/data/tenant/TenantListener.java @@ -29,11 +29,11 @@ public class TenantListener { @PrePersist public void setTenantOnCreate(TenantScoped entity) throws InvalidApplicationException { if (tenantScope.isMultitenant()) { - if (entity.getTenantId() != null && entity.getTenantId().compareTo(tenantScope.getTenant()) != 0) { - logger.error("somebody tried to set not login tenat"); + if (entity.getTenantId() != null && (this.tenantScope.isDefaultTenant() || entity.getTenantId().compareTo(tenantScope.getTenant()) != 0)) { + logger.error("somebody tried to set not login tenant"); throw new MyForbiddenException("tenant tampering"); } - if (!entity.allowNullTenant()) { + if (!entity.allowNullTenant() && !tenantScope.isDefaultTenant()) { final UUID tenantId = tenantScope.getTenant(); entity.setTenantId(tenantId); } @@ -47,19 +47,26 @@ public class TenantListener { public void setTenantOnUpdate(TenantScoped entity) throws InvalidApplicationException { if (tenantScope.isMultitenant()) { if (!entity.allowNullTenant()){ - if (entity.getTenantId() == null) { - logger.error("somebody tried to set null tenant"); - throw new MyForbiddenException("tenant tampering"); - } - if (entity.getTenantId().compareTo(tenantScope.getTenant()) != 0) { - logger.error("somebody tried to change an entries tenant"); - throw new MyForbiddenException("tenant tampering"); - } + if (!tenantScope.isDefaultTenant()) { + if (entity.getTenantId() == null) { + logger.error("somebody tried to set null tenant"); + throw new MyForbiddenException("tenant tampering"); + } + if (entity.getTenantId().compareTo(tenantScope.getTenant()) != 0) { + logger.error("somebody tried to change an entries tenant"); + throw new MyForbiddenException("tenant tampering"); + } - final UUID tenantId = tenantScope.getTenant(); - entity.setTenantId(tenantId); + final UUID tenantId = tenantScope.getTenant(); + entity.setTenantId(tenantId); + } else { + if (entity.getTenantId() != null) { + logger.error("somebody tried to set null tenant"); + throw new MyForbiddenException("tenant tampering"); + } + } } else { - if (entity.getTenantId() != null && entity.getTenantId().compareTo(tenantScope.getTenant()) != 0) { + if (entity.getTenantId() != null && (!this.tenantScope.isDefaultTenant() ||entity.getTenantId().compareTo(tenantScope.getTenant()) != 0)) { logger.error("somebody tried to change an entries tenant"); throw new MyForbiddenException("tenant tampering"); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/data/tenant/TenantScopedBaseEntity.java b/dmp-backend/core/src/main/java/eu/eudat/data/tenant/TenantScopedBaseEntity.java index 108a1d38d..91d82d259 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/data/tenant/TenantScopedBaseEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/data/tenant/TenantScopedBaseEntity.java @@ -14,13 +14,16 @@ import java.util.UUID; //@Getter //@Setter //@NoArgsConstructor -@FilterDef(name = TenantScopedBaseEntity.tenantFilter, parameters = {@ParamDef(name = TenantScopedBaseEntity.tenantFilterTenantParam, type = String.class)}) -@Filter(name = "tenantFilter", condition = "(tenant = (cast(:tenantId as uuid)) or tenant is null)") +@FilterDef(name = TenantScopedBaseEntity.TENANT_FILTER, parameters = {@ParamDef(name = TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, type = String.class)}) +@FilterDef(name = TenantScopedBaseEntity.DEFAULT_TENANT_FILTER) +@Filter(name = TenantScopedBaseEntity.DEFAULT_TENANT_FILTER, condition = "(tenant = tenant is null)") +@Filter(name = TenantScopedBaseEntity.TENANT_FILTER, condition = "(tenant = (cast(:tenantId as uuid)) or tenant is null)") @EntityListeners(TenantListener.class) public abstract class TenantScopedBaseEntity implements TenantScoped, Serializable { private static final long serialVersionUID = 1L; - public static final String tenantFilter = "tenantFilter"; - public static final String tenantFilterTenantParam = "tenantId"; + public static final String TENANT_FILTER = "tenantFilter"; + public static final String DEFAULT_TENANT_FILTER = "defaultTenantFilter"; + public static final String TENANT_FILTER_TENANT_PARAM = "tenantId"; @Column(name = "tenant", columnDefinition = "uuid", nullable = true) private UUID tenantId; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java index be90667b9..3b51ebef0 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/DescriptionTemplateTypePersist.java @@ -38,15 +38,6 @@ public class DescriptionTemplateTypePersist { private DescriptionTemplateTypeStatus status; private Map test; - public final static String _test = "test"; - - public Map getTest() { - return test; - } - - public void setTest(Map test) { - this.test = test; - } public UUID getId() { return id; @@ -86,12 +77,10 @@ public class DescriptionTemplateTypePersist { public static final String ValidatorName = "DescriptionTemplateTypePersistValidator"; private final MessageSource messageSource; - private final ValidatorFactory validatorFactory; - public DescriptionTemplateTypePersistValidator(MessageSource messageSource, ConventionService conventionService, ErrorThesaurusProperties errors, ValidatorFactory validatorFactory) { + public DescriptionTemplateTypePersistValidator(MessageSource messageSource, ConventionService conventionService, ErrorThesaurusProperties errors) { super(conventionService, errors); this.messageSource = messageSource; - this.validatorFactory = validatorFactory; } @Override diff --git a/dmp-backend/web/src/main/java/eu/eudat/interceptors/tenant/TenantInterceptor.java b/dmp-backend/web/src/main/java/eu/eudat/interceptors/tenant/TenantInterceptor.java index 660e71852..904bc2b67 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/interceptors/tenant/TenantInterceptor.java +++ b/dmp-backend/web/src/main/java/eu/eudat/interceptors/tenant/TenantInterceptor.java @@ -3,10 +3,9 @@ package eu.eudat.interceptors.tenant; import eu.eudat.authorization.Permission; import eu.eudat.commons.enums.IsActive; +import eu.eudat.commons.lock.LockByKeyManager; import eu.eudat.commons.scope.tenant.TenantScope; import eu.eudat.commons.scope.user.UserScope; -import eu.eudat.data.DmpReferenceEntity; -import eu.eudat.data.ReferenceEntity; import eu.eudat.data.TenantUserEntity; import eu.eudat.data.UserEntity; import eu.eudat.data.tenant.TenantScopedBaseEntity; @@ -24,7 +23,6 @@ import jakarta.persistence.Tuple; import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Root; -import jakarta.persistence.criteria.Subquery; import org.hibernate.Session; import org.jetbrains.annotations.NotNull; import org.slf4j.LoggerFactory; @@ -46,6 +44,7 @@ import java.time.Instant; import java.util.List; import java.util.Locale; import java.util.UUID; +import java.util.concurrent.TimeUnit; @Component public class TenantInterceptor implements WebRequestInterceptor { @@ -61,6 +60,7 @@ public class TenantInterceptor implements WebRequestInterceptor { private final PlatformTransactionManager transactionManager; private final ErrorThesaurusProperties errors; private final QueryUtilsService queryUtilsService; + private final LockByKeyManager lockByKeyManager; @PersistenceContext public EntityManager entityManager; @@ -74,7 +74,7 @@ public class TenantInterceptor implements WebRequestInterceptor { TenantScopeProperties tenantScopeProperties, UserAllowedTenantCacheService userAllowedTenantCacheService, PlatformTransactionManager transactionManager, - ErrorThesaurusProperties errors, QueryUtilsService queryUtilsService) { + ErrorThesaurusProperties errors, QueryUtilsService queryUtilsService, LockByKeyManager lockByKeyManager) { this.tenantScope = tenantScope; this.userScope = userScope; this.currentPrincipalResolver = currentPrincipalResolver; @@ -85,10 +85,11 @@ public class TenantInterceptor implements WebRequestInterceptor { this.transactionManager = transactionManager; this.errors = errors; this.queryUtilsService = queryUtilsService; + this.lockByKeyManager = lockByKeyManager; } @Override - public void preHandle(@NotNull WebRequest request) throws InvalidApplicationException { + public void preHandle(@NotNull WebRequest request) throws InvalidApplicationException, InterruptedException { if (!this.currentPrincipalResolver.currentPrincipal().isAuthenticated()) return; if (!this.tenantScope.isMultitenant()) return; @@ -101,18 +102,29 @@ public class TenantInterceptor implements WebRequestInterceptor { } boolean isUserAllowedTenant = false; - UserAllowedTenantCacheService.UserAllowedTenantCacheValue cacheValue = this.userAllowedTenantCacheService.lookup(this.userAllowedTenantCacheService.buildKey(this.userScope.getUserId(), this.tenantScope.getTenant())); - if (cacheValue != null) { - isUserAllowedTenant = cacheValue.isAllowed(); + if (this.tenantScope.isDefaultTenant()){ + isUserAllowedTenant = true; } else { - isUserAllowedTenant = this.isUserAllowedTenant(); - this.userAllowedTenantCacheService.put(new UserAllowedTenantCacheService.UserAllowedTenantCacheValue(this.userScope.getUserId(), this.tenantScope.getTenant(), isUserAllowedTenant)); + UserAllowedTenantCacheService.UserAllowedTenantCacheValue cacheValue = this.userAllowedTenantCacheService.lookup(this.userAllowedTenantCacheService.buildKey(this.userScope.getUserId(), this.tenantScope.getTenant())); + if (cacheValue != null) { + isUserAllowedTenant = cacheValue.isAllowed(); + } else { + isUserAllowedTenant = this.isUserAllowedTenant(); + this.userAllowedTenantCacheService.put(new UserAllowedTenantCacheService.UserAllowedTenantCacheValue(this.userScope.getUserId(), this.tenantScope.getTenant(), isUserAllowedTenant)); + } } if (isUserAllowedTenant) { - this.entityManager - .unwrap(Session.class) - .enableFilter(TenantScopedBaseEntity.tenantFilter).setParameter(TenantScopedBaseEntity.tenantFilterTenantParam, tenantScope.getTenant().toString()); + if(!tenantScope.isDefaultTenant()) { + this.entityManager + .unwrap(Session.class) + .enableFilter(TenantScopedBaseEntity.TENANT_FILTER) + .setParameter(TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, tenantScope.getTenant().toString()); + } else { + this.entityManager + .unwrap(Session.class) + .enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER); + } } else { if (isAllowedNoTenant || this.isWhiteListedEndpoint(request)) { tenantScope.setTenant(null, null); @@ -143,40 +155,47 @@ public class TenantInterceptor implements WebRequestInterceptor { return false; } - private boolean isUserAllowedTenant() throws InvalidApplicationException { + private boolean isUserAllowedTenant() throws InvalidApplicationException, InterruptedException { if (userScope.isSet()) { - - CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder(); - CriteriaQuery query = criteriaBuilder.createQuery(Tuple.class); - Root root = query.from(UserEntity.class); - query.where(criteriaBuilder.and( - criteriaBuilder.equal(root.get(UserEntity._isActive), IsActive.Active), - criteriaBuilder.in(root.get(UserEntity._id)).value(queryUtilsService.buildSubQuery(new BuildSubQueryInput<>(new BuildSubQueryInput.Builder<>(TenantUserEntity.class, UUID.class) - .query(query) - .criteriaBuilder(criteriaBuilder) - .keyPathFunc((subQueryRoot) -> subQueryRoot.get(TenantUserEntity._userId)) - .filterFunc((subQueryRoot, cb) -> - { - try { - return cb.and( - criteriaBuilder.equal(subQueryRoot.get(TenantUserEntity._tenantId), this.tenantScope.getTenant()), - criteriaBuilder.equal(subQueryRoot.get(TenantUserEntity._userId), this.userScope.getUserId()), - criteriaBuilder.equal(subQueryRoot.get(TenantUserEntity._isActive), IsActive.Active) - ); - } catch (InvalidApplicationException e) { - throw new RuntimeException(e); + boolean usedResource = false; + String lockId = userScope.getUserId().toString().toLowerCase(Locale.ROOT); + try { + if (this.tenantScopeProperties.getAutoCreateTenantUser()) usedResource = this.lockByKeyManager.tryLock(lockId, 5000, TimeUnit.MILLISECONDS); + + CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder(); + CriteriaQuery query = criteriaBuilder.createQuery(Tuple.class); + Root root = query.from(UserEntity.class); + query.where(criteriaBuilder.and( + criteriaBuilder.equal(root.get(UserEntity._isActive), IsActive.Active), + criteriaBuilder.in(root.get(UserEntity._id)).value(queryUtilsService.buildSubQuery(new BuildSubQueryInput<>(new BuildSubQueryInput.Builder<>(TenantUserEntity.class, UUID.class) + .query(query) + .criteriaBuilder(criteriaBuilder) + .keyPathFunc((subQueryRoot) -> subQueryRoot.get(TenantUserEntity._userId)) + .filterFunc((subQueryRoot, cb) -> + { + try { + return cb.and( + criteriaBuilder.equal(subQueryRoot.get(TenantUserEntity._tenantId), this.tenantScope.getTenant()), + criteriaBuilder.equal(subQueryRoot.get(TenantUserEntity._userId), this.userScope.getUserId()), + criteriaBuilder.equal(subQueryRoot.get(TenantUserEntity._isActive), IsActive.Active) + ); + } catch (InvalidApplicationException e) { + throw new RuntimeException(e); + } } - } - ) - )) - ) - )); - query.multiselect(root.get(UserEntity._id).alias(UserEntity._id)); - List results = this.entityManager.createQuery(query).getResultList(); - if (results.isEmpty() && this.tenantScopeProperties.getAutoCreateTenantUser()) { - return this.createTenantUser(); - } else { - return !results.isEmpty(); + ) + )) + ) + )); + query.multiselect(root.get(UserEntity._id).alias(UserEntity._id)); + List results = this.entityManager.createQuery(query).getResultList(); + if (results.isEmpty() && this.tenantScopeProperties.getAutoCreateTenantUser()) { + return this.createTenantUser(); + } else { + return !results.isEmpty(); + } + } finally { + if (usedResource) this.lockByKeyManager.unlock(lockId); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/interceptors/tenant/TenantScopeClaimInterceptor.java b/dmp-backend/web/src/main/java/eu/eudat/interceptors/tenant/TenantScopeClaimInterceptor.java index c103ce2f9..38236eba7 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/interceptors/tenant/TenantScopeClaimInterceptor.java +++ b/dmp-backend/web/src/main/java/eu/eudat/interceptors/tenant/TenantScopeClaimInterceptor.java @@ -78,21 +78,26 @@ public class TenantScopeClaimInterceptor implements WebRequestInterceptor { MyPrincipal principal = this.currentPrincipalResolver.currentPrincipal(); if (principal != null && principal.isAuthenticated() /* principal.Claims.Any() */) { - Boolean scoped = this.scopeByPrincipal(this.tenantScope, principal); - if (!scoped) scoped = this.scopeByClient(this.tenantScope, principal); + boolean scoped = this.scopeByPrincipal(principal); + if (!scoped) scoped = this.scopeByClient(principal); if (!scoped && this.tenantScope.isSet() && this.tenantScopeProperties.getEnforceTrustedTenant()) throw new MyForbiddenException(this.errorThesaurusProperties.getMissingTenant().getCode(), this.errorThesaurusProperties.getMissingTenant().getMessage()); } } - private Boolean scopeByPrincipal(TenantScope scope, MyPrincipal principal) { + private boolean scopeByPrincipal(MyPrincipal principal) { String tenantCode = this.claimExtractor.tenantString(principal); - if (tenantCode == null || tenantCode.isBlank()) - tenantCode = this.claimExtractor.asString(principal, this.clientTenantClaimName); + if (this.conventionService.isNullOrEmpty(tenantCode)) tenantCode = this.claimExtractor.asString(principal, this.clientTenantClaimName); + if (tenantCode == null || this.conventionService.isNullOrEmpty(tenantCode)) return false; + if (tenantCode.equalsIgnoreCase(this.tenantScope.getDefaultTenantCode())){ + logger.debug("parsed tenant header and set tenant to default tenant"); + this.tenantScope.setTenant(null, tenantCode); + this.claimExtractorContext.putReplaceParameter(TenantScope.TenantReplaceParameter, tenantCode); + return true; + } + UUID tenantId = this.conventionService.parseUUIDSafe(tenantCode); - if (tenantId == null && tenantCode == null) - return Boolean.FALSE; if (tenantId == null) { TenantByCodeCacheService.TenantByCodeCacheValue cacheValue = this.tenantByCodeCacheService.lookup(this.tenantByCodeCacheService.buildKey(tenantCode)); if (cacheValue != null) { @@ -115,21 +120,22 @@ public class TenantScopeClaimInterceptor implements WebRequestInterceptor { } } - if (tenantId != null && tenantCode != null && !tenantCode.isBlank()) { + if (tenantId != null) { logger.debug("parsed tenant header and set tenant id to {}", tenantId); this.tenantScope.setTenant(tenantId, tenantCode); this.claimExtractorContext.putReplaceParameter(TenantScope.TenantReplaceParameter, tenantCode); + return true; } - return tenantId != null; + return false; } - private Boolean scopeByClient(TenantScope scope, MyPrincipal principal) throws InvalidApplicationException { + private boolean scopeByClient(MyPrincipal principal) throws InvalidApplicationException { String client = this.claimExtractor.client(principal); Boolean isWhiteListed = this.tenantScopeProperties.getWhiteListedClients() != null && !this.conventionService.isNullOrEmpty(client) && this.tenantScopeProperties.getWhiteListedClients().contains(client); - logger.debug("client is whitelisted : {}, scope is set: {}, with value {}", isWhiteListed, scope.isSet(), (scope.isSet() ? scope.getTenant() : null)); + logger.debug("client is whitelisted : {}, scope is set: {}, with value {}", isWhiteListed, this.tenantScope.isSet(), (this.tenantScope.isSet() ? this.tenantScope.getTenant() : null)); - return isWhiteListed && scope.isSet(); + return isWhiteListed && this.tenantScope.isSet(); } private UUID getTenantIdFromDatabase(String tenantCode) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/interceptors/tenant/TenantScopeHeaderInterceptor.java b/dmp-backend/web/src/main/java/eu/eudat/interceptors/tenant/TenantScopeHeaderInterceptor.java index 26c201526..b301abea7 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/interceptors/tenant/TenantScopeHeaderInterceptor.java +++ b/dmp-backend/web/src/main/java/eu/eudat/interceptors/tenant/TenantScopeHeaderInterceptor.java @@ -62,10 +62,16 @@ public class TenantScopeHeaderInterceptor implements WebRequestInterceptor { String tenantCode = request.getHeader(TenantScope.TenantClaimName); logger.debug("retrieved request tenant header is: {}", tenantCode); - if (this.conventionService.isNullOrEmpty(tenantCode)) return; + if (tenantCode == null || this.conventionService.isNullOrEmpty(tenantCode)) return; + + if (tenantCode.equalsIgnoreCase(this.tenantScope.getDefaultTenantCode())){ + logger.debug("parsed tenant header and set tenant to default tenant"); + this.tenantScope.setTenant(null, tenantCode); + this.claimExtractorContext.putReplaceParameter(TenantScope.TenantReplaceParameter, tenantCode); + return; + } UUID tenantId = this.conventionService.parseUUIDSafe(tenantCode); - if (tenantId == null && tenantCode == null) return; if (tenantId == null) { TenantByCodeCacheService.TenantByCodeCacheValue cacheValue = this.tenantByCodeCacheService.lookup(this.tenantByCodeCacheService.buildKey(tenantCode)); if (cacheValue != null) { @@ -86,7 +92,7 @@ public class TenantScopeHeaderInterceptor implements WebRequestInterceptor { } } - if (tenantId != null && tenantCode != null && !tenantCode.isBlank()) { + if (tenantId != null) { logger.debug("parsed tenant header and set tenant id to {}", tenantId); this.tenantScope.setTenant(tenantId, tenantCode); this.claimExtractorContext.putReplaceParameter(TenantScope.TenantReplaceParameter, tenantCode); diff --git a/dmp-backend/web/src/main/resources/config/tenant-devel.yml b/dmp-backend/web/src/main/resources/config/tenant-devel.yml new file mode 100644 index 000000000..9f42782a8 --- /dev/null +++ b/dmp-backend/web/src/main/resources/config/tenant-devel.yml @@ -0,0 +1,10 @@ +tenant: + configEncryptionAesKey: rmpTvZnRWzyisUtFADBcZCn0q7Z75Xdz + configEncryptionAesIv: ec05d521a23f80ad + multitenancy: + is-multitenant: true + default-tenant-code: default + interceptor: + client-claims-prefix: client_ + enforce-trusted-tenant: false + auto-create-tenant-user: true \ No newline at end of file diff --git a/dmp-backend/web/src/main/resources/config/tenant.yml b/dmp-backend/web/src/main/resources/config/tenant.yml index df2f0017c..55df880cd 100644 --- a/dmp-backend/web/src/main/resources/config/tenant.yml +++ b/dmp-backend/web/src/main/resources/config/tenant.yml @@ -1,11 +1,8 @@ tenant: - configEncryptionAesKey: rmpTvZnRWzyisUtFADBcZCn0q7Z75Xdz - configEncryptionAesIv: ec05d521a23f80ad multitenancy: - is-multitenant: true + is-multitenant: false interceptor: - client-claims-prefix: client_ white-listed-clients: [ ] enforce-trusted-tenant: false - auto-create-tenant-user: true + auto-create-tenant-user: false white-listed-endpoints: [ '/api/principal/my-tenants', '/api/principal/me' ] \ No newline at end of file