Merge branch 'dmp-refactoring' of https://code-repo.d4science.org/MaDgiK-CITE/argos into dmp-refactoring
This commit is contained in:
commit
82e7075667
|
@ -22,9 +22,12 @@ public class TenantEntityManager {
|
|||
private final TenantScope tenantScope;
|
||||
private final ErrorThesaurusProperties errors;
|
||||
|
||||
boolean tenantFiltersDisabled;
|
||||
|
||||
public TenantEntityManager(TenantScope tenantScope, ErrorThesaurusProperties errors) {
|
||||
this.tenantScope = tenantScope;
|
||||
this.errors = errors;
|
||||
this.tenantFiltersDisabled = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,7 +36,7 @@ public class TenantEntityManager {
|
|||
}
|
||||
|
||||
public <T> T merge(T entity) throws InvalidApplicationException {
|
||||
if (this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (!this.tenantFiltersDisabled && this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (!this.tenantScope.isDefaultTenant()) {
|
||||
if (tenantScopedEntity.getTenantId() == null || !tenantScopedEntity.getTenantId().equals(this.tenantScope.getTenant())) throw new MyForbiddenException(this.errors.getTenantTampering().getCode(), this.errors.getTenantTampering().getMessage());
|
||||
} else if (tenantScopedEntity.getTenantId() != null) {
|
||||
|
@ -44,7 +47,7 @@ public class TenantEntityManager {
|
|||
}
|
||||
|
||||
public void remove(Object entity) throws InvalidApplicationException {
|
||||
if (this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (!this.tenantFiltersDisabled && this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (!this.tenantScope.isDefaultTenant()) {
|
||||
if (tenantScopedEntity.getTenantId() == null || !tenantScopedEntity.getTenantId().equals(this.tenantScope.getTenant())) throw new MyForbiddenException(this.errors.getTenantTampering().getCode(), this.errors.getTenantTampering().getMessage());
|
||||
} else if (tenantScopedEntity.getTenantId() != null) {
|
||||
|
@ -57,7 +60,7 @@ public class TenantEntityManager {
|
|||
public <T> T find(Class<T> entityClass, Object primaryKey) throws InvalidApplicationException {
|
||||
T entity = this.entityManager.find(entityClass, primaryKey);
|
||||
|
||||
if (this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (!this.tenantFiltersDisabled && this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (tenantScopedEntity.getTenantId() != null && !tenantScopedEntity.getTenantId().equals(this.tenantScope.getTenant())) return null;
|
||||
}
|
||||
return entity;
|
||||
|
@ -66,7 +69,7 @@ public class TenantEntityManager {
|
|||
public <T> T find(Class<T> entityClass, Object primaryKey, boolean disableTracking) throws InvalidApplicationException {
|
||||
T entity = this.entityManager.find(entityClass, primaryKey);
|
||||
|
||||
if (this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (!this.tenantFiltersDisabled && this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (tenantScopedEntity.getTenantId() != null && !tenantScopedEntity.getTenantId().equals(this.tenantScope.getTenant())) return null;
|
||||
}
|
||||
if (disableTracking) this.entityManager.detach(entity);
|
||||
|
@ -106,6 +109,7 @@ public class TenantEntityManager {
|
|||
.unwrap(Session.class)
|
||||
.enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER);
|
||||
}
|
||||
this.tenantFiltersDisabled = false;
|
||||
}
|
||||
|
||||
public void loadExplictTenantFilters() throws InvalidApplicationException {
|
||||
|
@ -123,6 +127,7 @@ public class TenantEntityManager {
|
|||
.unwrap(Session.class)
|
||||
.enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER);
|
||||
}
|
||||
this.tenantFiltersDisabled = false;
|
||||
}
|
||||
|
||||
public void disableTenantFilters() {
|
||||
|
@ -137,6 +142,11 @@ public class TenantEntityManager {
|
|||
this.entityManager
|
||||
.unwrap(Session.class)
|
||||
.disableFilter(TenantScopedBaseEntity.TENANT_FILTER_EXPLICT);
|
||||
this.tenantFiltersDisabled = true;
|
||||
}
|
||||
|
||||
public boolean isTenantFiltersDisabled() {
|
||||
return tenantFiltersDisabled;
|
||||
}
|
||||
|
||||
public EntityManager getEntityManager() {
|
||||
|
|
|
@ -2,6 +2,7 @@ package gr.cite.annotation.data.tenant;
|
|||
|
||||
import gr.cite.annotation.common.scope.tenant.TenantScope;
|
||||
import gr.cite.annotation.common.scope.tenant.TenantScoped;
|
||||
import gr.cite.annotation.data.TenantEntityManager;
|
||||
import gr.cite.annotation.errorcode.ErrorThesaurusProperties;
|
||||
import gr.cite.tools.exception.MyForbiddenException;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
|
@ -19,18 +20,21 @@ public class TenantListener {
|
|||
private final TenantScope tenantScope;
|
||||
|
||||
private final ErrorThesaurusProperties errors;
|
||||
private final TenantEntityManager tenantEntityManager;
|
||||
|
||||
|
||||
@Autowired
|
||||
public TenantListener(
|
||||
TenantScope tenantScope, ErrorThesaurusProperties errors
|
||||
TenantScope tenantScope, ErrorThesaurusProperties errors, TenantEntityManager tenantEntityManager
|
||||
) {
|
||||
this.tenantScope = tenantScope;
|
||||
this.errors = errors;
|
||||
this.tenantEntityManager = tenantEntityManager;
|
||||
}
|
||||
|
||||
@PrePersist
|
||||
public void setTenantOnCreate(TenantScoped entity) throws InvalidApplicationException {
|
||||
if (this.tenantEntityManager.isTenantFiltersDisabled()) return;
|
||||
if (tenantScope.isMultitenant()) {
|
||||
if (entity.getTenantId() != null && (this.tenantScope.isDefaultTenant() || entity.getTenantId().compareTo(tenantScope.getTenant()) != 0)) {
|
||||
logger.error("somebody tried to set not login tenant");
|
||||
|
@ -48,6 +52,7 @@ public class TenantListener {
|
|||
@PreUpdate
|
||||
@PreRemove
|
||||
public void setTenantOnUpdate(TenantScoped entity) throws InvalidApplicationException {
|
||||
if (this.tenantEntityManager.isTenantFiltersDisabled()) return;
|
||||
if (tenantScope.isMultitenant()) {
|
||||
if (!tenantScope.isDefaultTenant()) {
|
||||
if (entity.getTenantId() == null) {
|
||||
|
|
|
@ -74,24 +74,11 @@ public class AnnotationEntitiesRemovalIntegrationEventHandlerImpl implements Ann
|
|||
|
||||
EventProcessingStatus status = EventProcessingStatus.Success;
|
||||
try {
|
||||
if (this.tenantScope.isMultitenant() && properties.getTenantId() != null) {
|
||||
TenantEntity tenant = queryFactory.query(TenantQuery.class).disableTracking().ids(properties.getTenantId()).firstAs(new BaseFieldSet().ensure(Tenant._id).ensure(Tenant._code));
|
||||
if (tenant == null) {
|
||||
logger.error("missing tenant from event message");
|
||||
return EventProcessingStatus.Error;
|
||||
}
|
||||
this.tenantScope.setTempTenant(tenantEntityManager, properties.getTenantId(), tenant.getCode());
|
||||
} else if (this.tenantScope.isMultitenant()) {
|
||||
// logger.error("missing tenant from event message");
|
||||
// return EventProcessingStatus.Error;
|
||||
this.tenantScope.setTempTenant(tenantEntityManager, null, this.tenantScope.getDefaultTenantCode());
|
||||
}
|
||||
|
||||
tenantEntityManager.disableTenantFilters();
|
||||
|
||||
currentPrincipalResolver.push(InboxPrincipal.build(properties, claimExtractorProperties));
|
||||
|
||||
|
||||
tenantEntityManager.disableTenantFilters();
|
||||
EntityUserQuery entityUserQuery = this.queryFactory.query(EntityUserQuery.class);
|
||||
List<EntityUserEntity> items = entityUserQuery
|
||||
.entityIds(event.getEntityIds())
|
||||
|
@ -101,6 +88,7 @@ public class AnnotationEntitiesRemovalIntegrationEventHandlerImpl implements Ann
|
|||
|
||||
deleterFactory.deleter(gr.cite.EntityUser.model.deleter.EntityUserDeleter.class).delete(items);
|
||||
|
||||
tenantEntityManager.flush();
|
||||
|
||||
auditService.track(AuditableAction.User_Persist, Map.ofEntries(
|
||||
new AbstractMap.SimpleEntry<String, Object>("model", event)
|
||||
|
@ -112,11 +100,11 @@ public class AnnotationEntitiesRemovalIntegrationEventHandlerImpl implements Ann
|
|||
logger.error("Problem getting list of queue outbox. Skipping: {}", ex.getMessage(), ex);
|
||||
} finally {
|
||||
currentPrincipalResolver.pop();
|
||||
try {
|
||||
tenantScope.removeTempTenant(this.tenantEntityManager);
|
||||
this.tenantEntityManager.reloadTenantFilters();
|
||||
} catch (InvalidApplicationException e) {
|
||||
}
|
||||
try {
|
||||
tenantEntityManager.reloadTenantFilters();
|
||||
} catch (InvalidApplicationException ex) {
|
||||
logger.error(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -32,8 +32,6 @@ public class UserTouchedIntegrationEventHandlerImpl implements UserTouchedIntegr
|
|||
private final JsonHandlingService jsonHandlingService;
|
||||
|
||||
private final ValidatorFactory validatorFactory;
|
||||
private final QueryFactory queryFactory;
|
||||
private final TenantScope tenantScope;
|
||||
private final CurrentPrincipalResolver currentPrincipalResolver;
|
||||
private final ClaimExtractorProperties claimExtractorProperties;
|
||||
private final UserService userService;
|
||||
|
@ -42,11 +40,9 @@ public class UserTouchedIntegrationEventHandlerImpl implements UserTouchedIntegr
|
|||
|
||||
public UserTouchedIntegrationEventHandlerImpl(
|
||||
JsonHandlingService jsonHandlingService,
|
||||
ValidatorFactory validatorFactory, QueryFactory queryFactory, TenantScope tenantScope, CurrentPrincipalResolver currentPrincipalResolver, ClaimExtractorProperties claimExtractorProperties, UserService userService, AuditService auditService, TenantEntityManager tenantEntityManager) {
|
||||
ValidatorFactory validatorFactory, CurrentPrincipalResolver currentPrincipalResolver, ClaimExtractorProperties claimExtractorProperties, UserService userService, AuditService auditService, TenantEntityManager tenantEntityManager) {
|
||||
this.jsonHandlingService = jsonHandlingService;
|
||||
this.validatorFactory = validatorFactory;
|
||||
this.queryFactory = queryFactory;
|
||||
this.tenantScope = tenantScope;
|
||||
this.currentPrincipalResolver = currentPrincipalResolver;
|
||||
this.claimExtractorProperties = claimExtractorProperties;
|
||||
this.userService = userService;
|
||||
|
|
|
@ -22,9 +22,12 @@ public class TenantEntityManager {
|
|||
private final TenantScope tenantScope;
|
||||
private final ErrorThesaurusProperties errors;
|
||||
|
||||
boolean tenantFiltersDisabled;
|
||||
|
||||
public TenantEntityManager(TenantScope tenantScope, ErrorThesaurusProperties errors) {
|
||||
this.tenantScope = tenantScope;
|
||||
this.errors = errors;
|
||||
this.tenantFiltersDisabled = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,7 +36,7 @@ public class TenantEntityManager {
|
|||
}
|
||||
|
||||
public <T> T merge(T entity) throws InvalidApplicationException {
|
||||
if (this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (!this.tenantFiltersDisabled && this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (!this.tenantScope.isDefaultTenant()) {
|
||||
if (tenantScopedEntity.getTenantId() == null || !tenantScopedEntity.getTenantId().equals(this.tenantScope.getTenant())) throw new MyForbiddenException(this.errors.getTenantTampering().getCode(), this.errors.getTenantTampering().getMessage());
|
||||
} else if (tenantScopedEntity.getTenantId() != null) {
|
||||
|
@ -44,7 +47,7 @@ public class TenantEntityManager {
|
|||
}
|
||||
|
||||
public void remove(Object entity) throws InvalidApplicationException {
|
||||
if (this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (!this.tenantFiltersDisabled && this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (!this.tenantScope.isDefaultTenant()) {
|
||||
if (tenantScopedEntity.getTenantId() == null || !tenantScopedEntity.getTenantId().equals(this.tenantScope.getTenant())) throw new MyForbiddenException(this.errors.getTenantTampering().getCode(), this.errors.getTenantTampering().getMessage());
|
||||
} else if (tenantScopedEntity.getTenantId() != null) {
|
||||
|
@ -57,7 +60,7 @@ public class TenantEntityManager {
|
|||
public <T> T find(Class<T> entityClass, Object primaryKey) throws InvalidApplicationException {
|
||||
T entity = this.entityManager.find(entityClass, primaryKey);
|
||||
|
||||
if (this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (!this.tenantFiltersDisabled && this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (tenantScopedEntity.getTenantId() != null && !tenantScopedEntity.getTenantId().equals(this.tenantScope.getTenant())) return null;
|
||||
}
|
||||
return entity;
|
||||
|
@ -66,7 +69,7 @@ public class TenantEntityManager {
|
|||
public <T> T find(Class<T> entityClass, Object primaryKey, boolean disableTracking) throws InvalidApplicationException {
|
||||
T entity = this.entityManager.find(entityClass, primaryKey);
|
||||
|
||||
if (this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (!this.tenantFiltersDisabled && this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (tenantScopedEntity.getTenantId() != null && !tenantScopedEntity.getTenantId().equals(this.tenantScope.getTenant())) return null;
|
||||
}
|
||||
if (disableTracking) this.entityManager.detach(entity);
|
||||
|
@ -96,7 +99,7 @@ public class TenantEntityManager {
|
|||
|
||||
if (!this.tenantScope.isSet()) return;
|
||||
|
||||
if(!this.tenantScope.isDefaultTenant()) {
|
||||
if (!this.tenantScope.isDefaultTenant()) {
|
||||
this.entityManager
|
||||
.unwrap(Session.class)
|
||||
.enableFilter(TenantScopedBaseEntity.TENANT_FILTER)
|
||||
|
@ -106,6 +109,7 @@ public class TenantEntityManager {
|
|||
.unwrap(Session.class)
|
||||
.enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER);
|
||||
}
|
||||
this.tenantFiltersDisabled = false;
|
||||
}
|
||||
|
||||
public void loadExplictTenantFilters() throws InvalidApplicationException {
|
||||
|
@ -113,7 +117,7 @@ public class TenantEntityManager {
|
|||
|
||||
if (!this.tenantScope.isSet()) return;
|
||||
|
||||
if(!this.tenantScope.isDefaultTenant()) {
|
||||
if (!this.tenantScope.isDefaultTenant()) {
|
||||
this.entityManager
|
||||
.unwrap(Session.class)
|
||||
.enableFilter(TenantScopedBaseEntity.TENANT_FILTER_EXPLICT)
|
||||
|
@ -123,9 +127,10 @@ public class TenantEntityManager {
|
|||
.unwrap(Session.class)
|
||||
.enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER);
|
||||
}
|
||||
this.tenantFiltersDisabled = false;
|
||||
}
|
||||
|
||||
public void disableTenantFilters(){
|
||||
public void disableTenantFilters() {
|
||||
this.entityManager
|
||||
.unwrap(Session.class)
|
||||
.disableFilter(TenantScopedBaseEntity.TENANT_FILTER);
|
||||
|
@ -137,6 +142,11 @@ public class TenantEntityManager {
|
|||
this.entityManager
|
||||
.unwrap(Session.class)
|
||||
.disableFilter(TenantScopedBaseEntity.TENANT_FILTER_EXPLICT);
|
||||
this.tenantFiltersDisabled = true;
|
||||
}
|
||||
|
||||
public boolean isTenantFiltersDisabled() {
|
||||
return this.tenantFiltersDisabled;
|
||||
}
|
||||
|
||||
public EntityManager getEntityManager() {
|
||||
|
@ -146,5 +156,5 @@ public class TenantEntityManager {
|
|||
public void setEntityManager(EntityManager entityManager) {
|
||||
this.entityManager = entityManager;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package org.opencdmp.data;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import org.opencdmp.commons.enums.IsActive;
|
||||
import org.opencdmp.data.converters.enums.IsActiveConverter;
|
||||
import org.opencdmp.data.tenant.TenantScopedBaseEntity;
|
||||
import jakarta.persistence.*;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -37,7 +38,7 @@ public class TenantUserEntity extends TenantScopedBaseEntity {
|
|||
public final static String _updatedAt = "updatedAt";
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setId(UUID id) {
|
||||
|
@ -45,7 +46,7 @@ public class TenantUserEntity extends TenantScopedBaseEntity {
|
|||
}
|
||||
|
||||
public UUID getUserId() {
|
||||
return userId;
|
||||
return this.userId;
|
||||
}
|
||||
|
||||
public void setUserId(UUID userId) {
|
||||
|
@ -53,7 +54,7 @@ public class TenantUserEntity extends TenantScopedBaseEntity {
|
|||
}
|
||||
|
||||
public UUID getTenantId() {
|
||||
return tenantId;
|
||||
return this.tenantId;
|
||||
}
|
||||
|
||||
public void setTenantId(UUID tenantId) {
|
||||
|
@ -61,7 +62,7 @@ public class TenantUserEntity extends TenantScopedBaseEntity {
|
|||
}
|
||||
|
||||
public IsActive getIsActive() {
|
||||
return isActive;
|
||||
return this.isActive;
|
||||
}
|
||||
|
||||
public void setIsActive(IsActive isActive) {
|
||||
|
@ -69,7 +70,7 @@ public class TenantUserEntity extends TenantScopedBaseEntity {
|
|||
}
|
||||
|
||||
public Instant getCreatedAt() {
|
||||
return createdAt;
|
||||
return this.createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(Instant createdAt) {
|
||||
|
@ -77,7 +78,7 @@ public class TenantUserEntity extends TenantScopedBaseEntity {
|
|||
}
|
||||
|
||||
public Instant getUpdatedAt() {
|
||||
return updatedAt;
|
||||
return this.updatedAt;
|
||||
}
|
||||
|
||||
public void setUpdatedAt(Instant updatedAt) {
|
||||
|
|
|
@ -8,6 +8,7 @@ import jakarta.persistence.PreRemove;
|
|||
import jakarta.persistence.PreUpdate;
|
||||
import org.opencdmp.commons.scope.tenant.TenantScope;
|
||||
import org.opencdmp.commons.scope.tenant.TenantScoped;
|
||||
import org.opencdmp.data.TenantEntityManager;
|
||||
import org.opencdmp.errorcode.ErrorThesaurusProperties;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
@ -20,18 +21,21 @@ public class TenantListener {
|
|||
private final TenantScope tenantScope;
|
||||
|
||||
private final ErrorThesaurusProperties errors;
|
||||
private final TenantEntityManager tenantEntityManager;
|
||||
|
||||
|
||||
@Autowired
|
||||
public TenantListener(
|
||||
TenantScope tenantScope, ErrorThesaurusProperties errors
|
||||
TenantScope tenantScope, ErrorThesaurusProperties errors, TenantEntityManager tenantEntityManager
|
||||
) {
|
||||
this.tenantScope = tenantScope;
|
||||
this.errors = errors;
|
||||
this.tenantEntityManager = tenantEntityManager;
|
||||
}
|
||||
|
||||
@PrePersist
|
||||
public void setTenantOnCreate(TenantScoped entity) throws InvalidApplicationException {
|
||||
if (this.tenantEntityManager.isTenantFiltersDisabled()) return;
|
||||
if (this.tenantScope.isMultitenant()) {
|
||||
if (entity.getTenantId() != null && (this.tenantScope.isDefaultTenant() || entity.getTenantId().compareTo(this.tenantScope.getTenant()) != 0)) {
|
||||
logger.error("somebody tried to set not login tenant");
|
||||
|
@ -49,6 +53,7 @@ public class TenantListener {
|
|||
@PreUpdate
|
||||
@PreRemove
|
||||
public void setTenantOnUpdate(TenantScoped entity) throws InvalidApplicationException {
|
||||
if (this.tenantEntityManager.isTenantFiltersDisabled()) return;
|
||||
if (this.tenantScope.isMultitenant()) {
|
||||
if (!this.tenantScope.isDefaultTenant()) {
|
||||
if (entity.getTenantId() == null) {
|
||||
|
@ -77,3 +82,4 @@ public class TenantListener {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.springframework.stereotype.Component;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class TenantPersist {
|
||||
|
||||
|
@ -115,6 +116,10 @@ public class TenantPersist {
|
|||
.iff(() -> !this.isEmpty(item.getCode()))
|
||||
.must(() -> this.lessEqualLength(item.getCode(), TenantEntity._codeLength))
|
||||
.failOn(TenantPersist._code).failWith(messageSource.getMessage("Validation_MaxLength", new Object[]{TenantPersist._code}, LocaleContextHolder.getLocale())),
|
||||
this.spec()
|
||||
.iff(() -> !this.isEmpty(item.getCode()))
|
||||
.must(() -> this.validateCodePattern(item.getCode()))
|
||||
.failOn(TenantPersist._code).failWith(messageSource.getMessage("Validation_UnexpectedValue", new Object[]{TenantPersist._code}, LocaleContextHolder.getLocale())),
|
||||
this.spec()
|
||||
.must(() -> !this.isEmpty(item.getName()))
|
||||
.failOn(TenantPersist._name).failWith(messageSource.getMessage("Validation_Required", new Object[]{TenantPersist._name}, LocaleContextHolder.getLocale())),
|
||||
|
@ -128,6 +133,13 @@ public class TenantPersist {
|
|||
|
||||
);
|
||||
}
|
||||
|
||||
private boolean validateCodePattern(String code){
|
||||
if (this.isEmpty(code)) return false;
|
||||
|
||||
Pattern pattern = Pattern.compile("^[a-z0-9_]*$");
|
||||
return pattern.matcher(code).matches();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package org.opencdmp.model.persist;
|
||||
|
||||
import org.opencdmp.commons.validation.BaseValidator;
|
||||
import gr.cite.tools.validation.specification.Specification;
|
||||
import org.opencdmp.commons.validation.BaseValidator;
|
||||
import org.opencdmp.convention.ConventionService;
|
||||
import org.opencdmp.errorcode.ErrorThesaurusProperties;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
|
@ -27,7 +27,7 @@ public class UserRolePatchPersist {
|
|||
public static final String _hash = "hash";
|
||||
|
||||
public UUID getId() {
|
||||
return id;
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setId(UUID id) {
|
||||
|
@ -35,7 +35,7 @@ public class UserRolePatchPersist {
|
|||
}
|
||||
|
||||
public List<String> getRoles() {
|
||||
return roles;
|
||||
return this.roles;
|
||||
}
|
||||
|
||||
public void setRoles(List<String> roles) {
|
||||
|
@ -43,7 +43,7 @@ public class UserRolePatchPersist {
|
|||
}
|
||||
|
||||
public String getHash() {
|
||||
return hash;
|
||||
return this.hash;
|
||||
}
|
||||
|
||||
public void setHash(String hash) {
|
||||
|
@ -74,14 +74,14 @@ public class UserRolePatchPersist {
|
|||
this.spec()
|
||||
.iff(() -> this.isValidGuid(item.getId()))
|
||||
.must(() -> this.isValidHash(item.getHash()))
|
||||
.failOn(UserRolePatchPersist._hash).failWith(messageSource.getMessage("Validation_Required", new Object[]{UserRolePatchPersist._hash}, LocaleContextHolder.getLocale())),
|
||||
.failOn(UserRolePatchPersist._hash).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{UserRolePatchPersist._hash}, LocaleContextHolder.getLocale())),
|
||||
this.spec()
|
||||
.iff(() -> !this.isValidGuid(item.getId()))
|
||||
.must(() -> !this.isValidHash(item.getHash()))
|
||||
.failOn(UserRolePatchPersist._hash).failWith(messageSource.getMessage("Validation_OverPosting", new Object[]{}, LocaleContextHolder.getLocale())),
|
||||
.failOn(UserRolePatchPersist._hash).failWith(this.messageSource.getMessage("Validation_OverPosting", new Object[]{}, LocaleContextHolder.getLocale())),
|
||||
this.spec()
|
||||
.must(() -> !this.isListNullOrEmpty(item.getRoles()))
|
||||
.failOn(UserRolePatchPersist._roles).failWith(messageSource.getMessage("Validation_Required", new Object[]{UserRolePatchPersist._roles}, LocaleContextHolder.getLocale()))
|
||||
.failOn(UserRolePatchPersist._roles).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{UserRolePatchPersist._roles}, LocaleContextHolder.getLocale()))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,15 +23,13 @@ import org.opencdmp.authorization.Permission;
|
|||
import org.opencdmp.commons.enums.IsActive;
|
||||
import org.opencdmp.commons.scope.tenant.TenantScope;
|
||||
import org.opencdmp.convention.ConventionService;
|
||||
import org.opencdmp.data.TenantEntity;
|
||||
import org.opencdmp.data.TenantEntityManager;
|
||||
import org.opencdmp.data.UserCredentialEntity;
|
||||
import org.opencdmp.data.UserRoleEntity;
|
||||
import org.opencdmp.data.*;
|
||||
import org.opencdmp.errorcode.ErrorThesaurusProperties;
|
||||
import org.opencdmp.integrationevent.outbox.tenantremoval.TenantRemovalIntegrationEvent;
|
||||
import org.opencdmp.integrationevent.outbox.tenantremoval.TenantRemovalIntegrationEventHandler;
|
||||
import org.opencdmp.integrationevent.outbox.tenanttouched.TenantTouchedIntegrationEvent;
|
||||
import org.opencdmp.integrationevent.outbox.tenanttouched.TenantTouchedIntegrationEventHandler;
|
||||
import org.opencdmp.integrationevent.outbox.usertouched.UserTouchedIntegrationEventHandler;
|
||||
import org.opencdmp.model.Tenant;
|
||||
import org.opencdmp.model.builder.TenantBuilder;
|
||||
import org.opencdmp.model.deleter.TenantDeleter;
|
||||
|
@ -76,6 +74,7 @@ public class TenantServiceImpl implements TenantService {
|
|||
private final ErrorThesaurusProperties errors;
|
||||
private final TenantTouchedIntegrationEventHandler tenantTouchedIntegrationEventHandler;
|
||||
private final TenantRemovalIntegrationEventHandler tenantRemovalIntegrationEventHandler;
|
||||
private final UserTouchedIntegrationEventHandler userTouchedIntegrationEventHandler;
|
||||
private final KeycloakService keycloakService;
|
||||
private final AuthorizationProperties authorizationProperties;
|
||||
private final TenantScope tenantScope;
|
||||
|
@ -92,7 +91,7 @@ public class TenantServiceImpl implements TenantService {
|
|||
BuilderFactory builderFactory,
|
||||
ConventionService conventionService,
|
||||
MessageSource messageSource,
|
||||
ErrorThesaurusProperties errors, TenantTouchedIntegrationEventHandler tenantTouchedIntegrationEventHandler, TenantRemovalIntegrationEventHandler tenantRemovalIntegrationEventHandler, KeycloakService keycloakService, AuthorizationProperties authorizationProperties, TenantScope tenantScope, QueryFactory queryFactory, CurrentPrincipalResolver currentPrincipalResolver, ClaimExtractor claimExtractor) {
|
||||
ErrorThesaurusProperties errors, TenantTouchedIntegrationEventHandler tenantTouchedIntegrationEventHandler, TenantRemovalIntegrationEventHandler tenantRemovalIntegrationEventHandler, UserTouchedIntegrationEventHandler userTouchedIntegrationEventHandler, KeycloakService keycloakService, AuthorizationProperties authorizationProperties, TenantScope tenantScope, QueryFactory queryFactory, CurrentPrincipalResolver currentPrincipalResolver, ClaimExtractor claimExtractor) {
|
||||
this.entityManager = entityManager;
|
||||
this.authorizationService = authorizationService;
|
||||
this.deleterFactory = deleterFactory;
|
||||
|
@ -102,6 +101,7 @@ public class TenantServiceImpl implements TenantService {
|
|||
this.errors = errors;
|
||||
this.tenantTouchedIntegrationEventHandler = tenantTouchedIntegrationEventHandler;
|
||||
this.tenantRemovalIntegrationEventHandler = tenantRemovalIntegrationEventHandler;
|
||||
this.userTouchedIntegrationEventHandler = userTouchedIntegrationEventHandler;
|
||||
this.keycloakService = keycloakService;
|
||||
this.authorizationProperties = authorizationProperties;
|
||||
this.tenantScope = tenantScope;
|
||||
|
@ -145,16 +145,16 @@ public class TenantServiceImpl implements TenantService {
|
|||
Long tenantsWithThisCode = this.queryFactory.query(TenantQuery.class).codes(data.getCode()).count();
|
||||
if (tenantsWithThisCode > 1) throw new MyValidationException(this.errors.getTenantCodeExists().getCode(), this.errors.getTenantCodeExists().getMessage());
|
||||
|
||||
if (!isUpdate) {
|
||||
this.keycloakService.createTenantGroups(data.getCode());
|
||||
this.autoAssignGlobalAdminsToNewTenant(data);
|
||||
}
|
||||
|
||||
TenantTouchedIntegrationEvent tenantTouchedIntegrationEvent = new TenantTouchedIntegrationEvent();
|
||||
tenantTouchedIntegrationEvent.setId(data.getId());
|
||||
tenantTouchedIntegrationEvent.setCode(data.getCode());
|
||||
this.tenantTouchedIntegrationEventHandler.handle(tenantTouchedIntegrationEvent);
|
||||
|
||||
if (!isUpdate) {
|
||||
this.keycloakService.createTenantGroups(data.getCode());
|
||||
this.autoAssignGlobalAdminsToNewTenant(data);
|
||||
}
|
||||
|
||||
return this.builderFactory.builder(TenantBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermission).build(BaseFieldSet.build(fields, Tenant._id), data);
|
||||
}
|
||||
|
||||
|
@ -170,6 +170,15 @@ public class TenantServiceImpl implements TenantService {
|
|||
|
||||
List<String> keycloakIdsToAddToTenantGroup = new ArrayList<>();
|
||||
for (UUID userId : existingItems.stream().map(UserRoleEntity::getUserId).distinct().toList()) {
|
||||
TenantUserEntity tenantUserEntity = new TenantUserEntity();
|
||||
tenantUserEntity.setId(UUID.randomUUID());
|
||||
tenantUserEntity.setUserId(userId);
|
||||
tenantUserEntity.setIsActive(IsActive.Active);
|
||||
tenantUserEntity.setTenantId(tenant.getId());
|
||||
tenantUserEntity.setCreatedAt(Instant.now());
|
||||
tenantUserEntity.setUpdatedAt(Instant.now());
|
||||
this.entityManager.persist(tenantUserEntity);
|
||||
|
||||
UserCredentialEntity userCredential = userCredentialEntities.stream().filter(x-> !this.conventionService.isNullOrEmpty(x.getExternalId()) && x.getUserId().equals(userId)).findFirst().orElse(null);
|
||||
if (userCredential == null) continue;
|
||||
UserRoleEntity item = new UserRoleEntity();
|
||||
|
@ -180,13 +189,18 @@ public class TenantServiceImpl implements TenantService {
|
|||
item.setCreatedAt(Instant.now());
|
||||
this.entityManager.persist(item);
|
||||
keycloakIdsToAddToTenantGroup.add(userCredential.getExternalId());
|
||||
this.keycloakService.addUserToTenantRoleGroup(userCredential.getExternalId(), this.tenantScope.getTenantCode(), this.authorizationProperties.getTenantAdminRole());
|
||||
}
|
||||
|
||||
this.entityManager.flush();
|
||||
|
||||
for (UUID userId : existingItems.stream().map(UserRoleEntity::getUserId).distinct().toList()) {
|
||||
this.userTouchedIntegrationEventHandler.handle(userId);
|
||||
}
|
||||
|
||||
this.entityManager.flush();
|
||||
|
||||
for (String externalId : keycloakIdsToAddToTenantGroup) {
|
||||
this.keycloakService.addUserToTenantRoleGroup(externalId, this.tenantScope.getTenantCode(), this.authorizationProperties.getTenantAdminRole());
|
||||
this.keycloakService.addUserToTenantRoleGroup(externalId, tenant.getCode(), this.authorizationProperties.getTenantAdminRole());
|
||||
}
|
||||
} finally {
|
||||
this.entityManager.reloadTenantFilters();
|
||||
|
|
|
@ -380,6 +380,8 @@ public class UserServiceImpl implements UserService {
|
|||
if (this.tenantScope.isDefaultTenant()) userRoleQuery.tenantIsSet(false);
|
||||
else userRoleQuery.tenantIsSet(true).tenantIds(this.tenantScope.getTenant());
|
||||
|
||||
boolean hasTenantUser = this.queryFactory.query(TenantUserQuery.class).isActive(IsActive.Active).userIds(userId).count() > 0;
|
||||
|
||||
List<UserRoleEntity> existingItems = userRoleQuery.collect();
|
||||
List<UUID> foundIds = new ArrayList<>();
|
||||
for (String roleName : model.getRoles().stream().filter(x-> x != null && !x.isBlank() && this.authorizationProperties.getAllowedTenantRoles().contains(x)).distinct().toList()) {
|
||||
|
@ -396,6 +398,17 @@ public class UserServiceImpl implements UserService {
|
|||
foundIds.add(item.getId());
|
||||
}
|
||||
|
||||
if (!hasTenantUser && !model.getRoles().isEmpty() && !this.tenantScope.isDefaultTenant()){
|
||||
TenantUserEntity tenantUserEntity = new TenantUserEntity();
|
||||
tenantUserEntity.setId(UUID.randomUUID());
|
||||
tenantUserEntity.setUserId(userId);
|
||||
tenantUserEntity.setIsActive(IsActive.Active);
|
||||
tenantUserEntity.setTenantId(this.tenantScope.getTenant());
|
||||
tenantUserEntity.setCreatedAt(Instant.now());
|
||||
tenantUserEntity.setUpdatedAt(Instant.now());
|
||||
this.entityManager.persist(tenantUserEntity);
|
||||
}
|
||||
|
||||
this.entityManager.flush();
|
||||
|
||||
List<UserRoleEntity> toDelete = existingItems.stream().filter(x-> foundIds.stream().noneMatch(y-> y.equals(x.getId()))).collect(Collectors.toList());
|
||||
|
|
|
@ -22,9 +22,12 @@ public class TenantEntityManager {
|
|||
private final TenantScope tenantScope;
|
||||
private final ErrorThesaurusProperties errors;
|
||||
|
||||
boolean tenantFiltersDisabled;
|
||||
|
||||
public TenantEntityManager(TenantScope tenantScope, ErrorThesaurusProperties errors) {
|
||||
this.tenantScope = tenantScope;
|
||||
this.errors = errors;
|
||||
this.tenantFiltersDisabled = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -33,7 +36,7 @@ public class TenantEntityManager {
|
|||
}
|
||||
|
||||
public <T> T merge(T entity) throws InvalidApplicationException {
|
||||
if (this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (!this.tenantFiltersDisabled && this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (!this.tenantScope.isDefaultTenant()) {
|
||||
if (tenantScopedEntity.getTenantId() == null || !tenantScopedEntity.getTenantId().equals(this.tenantScope.getTenant())) throw new MyForbiddenException(this.errors.getTenantTampering().getCode(), this.errors.getTenantTampering().getMessage());
|
||||
} else if (tenantScopedEntity.getTenantId() != null) {
|
||||
|
@ -44,7 +47,7 @@ public class TenantEntityManager {
|
|||
}
|
||||
|
||||
public void remove(Object entity) throws InvalidApplicationException {
|
||||
if (this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (!this.tenantFiltersDisabled && this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (!this.tenantScope.isDefaultTenant()) {
|
||||
if (tenantScopedEntity.getTenantId() == null || !tenantScopedEntity.getTenantId().equals(this.tenantScope.getTenant())) throw new MyForbiddenException(this.errors.getTenantTampering().getCode(), this.errors.getTenantTampering().getMessage());
|
||||
} else if (tenantScopedEntity.getTenantId() != null) {
|
||||
|
@ -57,7 +60,7 @@ public class TenantEntityManager {
|
|||
public <T> T find(Class<T> entityClass, Object primaryKey) throws InvalidApplicationException {
|
||||
T entity = this.entityManager.find(entityClass, primaryKey);
|
||||
|
||||
if (this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (!this.tenantFiltersDisabled && this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (tenantScopedEntity.getTenantId() != null && !tenantScopedEntity.getTenantId().equals(this.tenantScope.getTenant())) return null;
|
||||
}
|
||||
return entity;
|
||||
|
@ -66,7 +69,7 @@ public class TenantEntityManager {
|
|||
public <T> T find(Class<T> entityClass, Object primaryKey, boolean disableTracking) throws InvalidApplicationException {
|
||||
T entity = this.entityManager.find(entityClass, primaryKey);
|
||||
|
||||
if (this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (!this.tenantFiltersDisabled && this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) {
|
||||
if (tenantScopedEntity.getTenantId() != null && !tenantScopedEntity.getTenantId().equals(this.tenantScope.getTenant())) return null;
|
||||
}
|
||||
if (disableTracking) this.entityManager.detach(entity);
|
||||
|
@ -96,7 +99,7 @@ public class TenantEntityManager {
|
|||
|
||||
if (!this.tenantScope.isSet()) return;
|
||||
|
||||
if(!this.tenantScope.isDefaultTenant()) {
|
||||
if (!this.tenantScope.isDefaultTenant()) {
|
||||
this.entityManager
|
||||
.unwrap(Session.class)
|
||||
.enableFilter(TenantScopedBaseEntity.TENANT_FILTER)
|
||||
|
@ -106,6 +109,7 @@ public class TenantEntityManager {
|
|||
.unwrap(Session.class)
|
||||
.enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER);
|
||||
}
|
||||
this.tenantFiltersDisabled = false;
|
||||
}
|
||||
|
||||
public void loadExplictTenantFilters() throws InvalidApplicationException {
|
||||
|
@ -113,7 +117,7 @@ public class TenantEntityManager {
|
|||
|
||||
if (!this.tenantScope.isSet()) return;
|
||||
|
||||
if(!this.tenantScope.isDefaultTenant()) {
|
||||
if (!this.tenantScope.isDefaultTenant()) {
|
||||
this.entityManager
|
||||
.unwrap(Session.class)
|
||||
.enableFilter(TenantScopedBaseEntity.TENANT_FILTER_EXPLICT)
|
||||
|
@ -123,9 +127,10 @@ public class TenantEntityManager {
|
|||
.unwrap(Session.class)
|
||||
.enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER);
|
||||
}
|
||||
this.tenantFiltersDisabled = false;
|
||||
}
|
||||
|
||||
public void disableTenantFilters(){
|
||||
public void disableTenantFilters() {
|
||||
this.entityManager
|
||||
.unwrap(Session.class)
|
||||
.disableFilter(TenantScopedBaseEntity.TENANT_FILTER);
|
||||
|
@ -137,6 +142,11 @@ public class TenantEntityManager {
|
|||
this.entityManager
|
||||
.unwrap(Session.class)
|
||||
.disableFilter(TenantScopedBaseEntity.TENANT_FILTER_EXPLICT);
|
||||
this.tenantFiltersDisabled = true;
|
||||
}
|
||||
|
||||
public boolean isTenantFiltersDisabled() {
|
||||
return tenantFiltersDisabled;
|
||||
}
|
||||
|
||||
public EntityManager getEntityManager() {
|
||||
|
@ -146,5 +156,4 @@ public class TenantEntityManager {
|
|||
public void setEntityManager(EntityManager entityManager) {
|
||||
this.entityManager = entityManager;
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ package gr.cite.notification.data.tenant;
|
|||
|
||||
import gr.cite.notification.common.scope.tenant.TenantScope;
|
||||
import gr.cite.notification.common.scope.tenant.TenantScoped;
|
||||
import gr.cite.notification.data.TenantEntityManager;
|
||||
import gr.cite.notification.errorcode.ErrorThesaurusProperties;
|
||||
import gr.cite.tools.exception.MyForbiddenException;
|
||||
import gr.cite.tools.logging.LoggerService;
|
||||
|
@ -20,25 +21,28 @@ public class TenantListener {
|
|||
private final TenantScope tenantScope;
|
||||
|
||||
private final ErrorThesaurusProperties errors;
|
||||
private final TenantEntityManager tenantEntityManager;
|
||||
|
||||
|
||||
@Autowired
|
||||
public TenantListener(
|
||||
TenantScope tenantScope, ErrorThesaurusProperties errors
|
||||
TenantScope tenantScope, ErrorThesaurusProperties errors, TenantEntityManager tenantEntityManager
|
||||
) {
|
||||
this.tenantScope = tenantScope;
|
||||
this.errors = errors;
|
||||
this.tenantEntityManager = tenantEntityManager;
|
||||
}
|
||||
|
||||
@PrePersist
|
||||
public void setTenantOnCreate(TenantScoped entity) throws InvalidApplicationException {
|
||||
if (this.tenantScope.isMultitenant()) {
|
||||
if (entity.getTenantId() != null && (this.tenantScope.isDefaultTenant() || entity.getTenantId().compareTo(this.tenantScope.getTenant()) != 0)) {
|
||||
if (this.tenantEntityManager.isTenantFiltersDisabled()) return;
|
||||
if (tenantScope.isMultitenant()) {
|
||||
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(this.errors.getTenantTampering().getCode(), this.errors.getTenantTampering().getMessage());
|
||||
}
|
||||
if (!this.tenantScope.isDefaultTenant()) {
|
||||
final UUID tenantId = this.tenantScope.getTenant();
|
||||
if (!tenantScope.isDefaultTenant()) {
|
||||
final UUID tenantId = tenantScope.getTenant();
|
||||
entity.setTenantId(tenantId);
|
||||
}
|
||||
} else {
|
||||
|
@ -49,18 +53,19 @@ public class TenantListener {
|
|||
@PreUpdate
|
||||
@PreRemove
|
||||
public void setTenantOnUpdate(TenantScoped entity) throws InvalidApplicationException {
|
||||
if (this.tenantScope.isMultitenant()) {
|
||||
if (!this.tenantScope.isDefaultTenant()) {
|
||||
if (this.tenantEntityManager.isTenantFiltersDisabled()) return;
|
||||
if (tenantScope.isMultitenant()) {
|
||||
if (!tenantScope.isDefaultTenant()) {
|
||||
if (entity.getTenantId() == null) {
|
||||
logger.error("somebody tried to set null tenant");
|
||||
throw new MyForbiddenException(this.errors.getTenantTampering().getCode(), this.errors.getTenantTampering().getMessage());
|
||||
}
|
||||
if (entity.getTenantId().compareTo(this.tenantScope.getTenant()) != 0) {
|
||||
if (entity.getTenantId().compareTo(tenantScope.getTenant()) != 0) {
|
||||
logger.error("somebody tried to change an entries tenant");
|
||||
throw new MyForbiddenException(this.errors.getTenantTampering().getCode(), this.errors.getTenantTampering().getMessage());
|
||||
}
|
||||
|
||||
final UUID tenantId = this.tenantScope.getTenant();
|
||||
final UUID tenantId = tenantScope.getTenant();
|
||||
entity.setTenantId(tenantId);
|
||||
} else {
|
||||
if (entity.getTenantId() != null) {
|
||||
|
@ -69,7 +74,7 @@ public class TenantListener {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (entity.getTenantId() != null && (!this.tenantScope.isDefaultTenant() ||entity.getTenantId().compareTo(this.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(this.errors.getTenantTampering().getCode(), this.errors.getTenantTampering().getMessage());
|
||||
}
|
||||
|
@ -77,3 +82,4 @@ public class TenantListener {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue