Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e7606f2f7 | ||
|
|
5adb79aa3e |
@ -53,7 +53,7 @@ public class SMTPConfigurationController implements SMTPConfigurationResource, P
|
||||
throw new BadRequestException("Current license does not allow updating the SMTP configuration!");
|
||||
}
|
||||
|
||||
smtpService.updateSMTPConfiguration(smtpConfigurationModel, TenantContext.getTenantId());
|
||||
smtpService.updateSMTPConfiguration(smtpConfigurationModel);
|
||||
}
|
||||
|
||||
|
||||
@ -84,7 +84,7 @@ public class SMTPConfigurationController implements SMTPConfigurationResource, P
|
||||
@PreAuthorize("hasAuthority('" + WRITE_SMTP_CONFIGURATION + "')")
|
||||
public void clearSMTPConfiguration() {
|
||||
|
||||
smtpService.clearSMTPConfiguration();
|
||||
smtpService.createDefaultSMTPConfiguration();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
package com.knecon.fforesight.tenantusermanagement.entity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Table(name = "global_smtp_configuration")
|
||||
public class GlobalSMTPConfigurationEntity {
|
||||
|
||||
@Id
|
||||
@Column(nullable = false, updatable = false)
|
||||
private String id = "singleton";
|
||||
|
||||
@Column
|
||||
private Boolean auth;
|
||||
|
||||
@Column
|
||||
private String envelopeFrom;
|
||||
|
||||
@Column
|
||||
private String fromEmail;
|
||||
|
||||
@Column
|
||||
private String fromDisplayName;
|
||||
|
||||
@Column
|
||||
private String host;
|
||||
|
||||
@Column
|
||||
private String password;
|
||||
|
||||
@Column
|
||||
private Integer port;
|
||||
|
||||
@Column
|
||||
private String replyTo;
|
||||
|
||||
@Column
|
||||
private String replyToDisplayName;
|
||||
|
||||
@Column
|
||||
private Boolean ssl;
|
||||
|
||||
@Column
|
||||
private Boolean starttls;
|
||||
|
||||
@Column
|
||||
private String userName;
|
||||
}
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
package com.knecon.fforesight.tenantusermanagement.repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import com.knecon.fforesight.tenantusermanagement.entity.GlobalSMTPConfigurationEntity;
|
||||
|
||||
public interface GlobalSMTPConfigurationRepository extends JpaRepository<GlobalSMTPConfigurationEntity, String> {
|
||||
|
||||
default Optional<GlobalSMTPConfigurationEntity> findSingleton() {
|
||||
|
||||
return findById("singleton");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package com.knecon.fforesight.tenantusermanagement.service;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.knecon.fforesight.tenantusermanagement.model.SMTPConfiguration;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class EnvironmentSMTPConfigurationProvider {
|
||||
|
||||
private final Environment environment;
|
||||
|
||||
public static final Integer KEYCLOAK_DEFAULT_PORT = 25;
|
||||
public static final String SMTP_DEFAULT_HOST = "SMTP_DEFAULT_HOST";
|
||||
public static final String SMTP_DEFAULT_PORT = "SMTP_DEFAULT_PORT";
|
||||
public static final String SMTP_DEFAULT_SENDER_EMAIL = "SMTP_DEFAULT_SENDER_EMAIL";
|
||||
public static final String SMTP_DEFAULT_SENDER_NAME = "SMTP_DEFAULT_SENDER_NAME";
|
||||
public static final String SMTP_DEFAULT_REPLY_EMAIL = "SMTP_DEFAULT_REPLY_EMAIL";
|
||||
public static final String SMTP_DEFAULT_REPLY_NAME = "SMTP_DEFAULT_REPLY_NAME";
|
||||
public static final String SMTP_DEFAULT_SENDER_ENVELOPE = "SMTP_DEFAULT_SENDER_ENVELOPE";
|
||||
public static final String SMTP_DEFAULT_SSL = "SMTP_DEFAULT_SSL";
|
||||
public static final String SMTP_DEFAULT_STARTTLS = "SMTP_DEFAULT_STARTTLS";
|
||||
public static final String SMTP_DEFAULT_AUTH = "SMTP_DEFAULT_AUTH";
|
||||
public static final String SMTP_DEFAULT_AUTH_USER = "SMTP_DEFAULT_AUTH_USER";
|
||||
public static final String SMTP_DEFAULT_AUTH_PASSWORD = "SMTP_DEFAULT_AUTH_PASSWORD";
|
||||
|
||||
|
||||
public SMTPConfiguration get() {
|
||||
|
||||
String port = environment.getProperty(SMTP_DEFAULT_PORT, "");
|
||||
return SMTPConfiguration.builder()
|
||||
.id("singleton")
|
||||
.host(environment.getProperty(SMTP_DEFAULT_HOST, ""))
|
||||
.port(StringUtils.isEmpty(port) || !StringUtils.isNumeric(port) ? KEYCLOAK_DEFAULT_PORT : Integer.parseInt(port))
|
||||
.from(environment.getProperty(SMTP_DEFAULT_SENDER_EMAIL, ""))
|
||||
.fromDisplayName(environment.getProperty(SMTP_DEFAULT_SENDER_NAME, ""))
|
||||
.replyTo(environment.getProperty(SMTP_DEFAULT_REPLY_EMAIL, ""))
|
||||
.replyToDisplayName(environment.getProperty(SMTP_DEFAULT_REPLY_NAME, ""))
|
||||
.envelopeFrom(environment.getProperty(SMTP_DEFAULT_SENDER_ENVELOPE, ""))
|
||||
.ssl(Boolean.parseBoolean(environment.getProperty(SMTP_DEFAULT_SSL, "false")))
|
||||
.starttls(Boolean.parseBoolean(environment.getProperty(SMTP_DEFAULT_STARTTLS, "false")))
|
||||
.auth(Boolean.parseBoolean(environment.getProperty(SMTP_DEFAULT_AUTH, "false")))
|
||||
.user(environment.getProperty(SMTP_DEFAULT_AUTH_USER, ""))
|
||||
.password(environment.getProperty(SMTP_DEFAULT_AUTH_PASSWORD, ""))
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
package com.knecon.fforesight.tenantusermanagement.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.knecon.fforesight.tenantcommons.EncryptionDecryptionService;
|
||||
import com.knecon.fforesight.tenantusermanagement.entity.GlobalSMTPConfigurationEntity;
|
||||
import com.knecon.fforesight.tenantusermanagement.repository.GlobalSMTPConfigurationRepository;
|
||||
import com.knecon.fforesight.tenantusermanagement.utils.SMTPConfigurationMapper;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE, makeFinal = true)
|
||||
public class GlobalSMTPConfigurationPersistenceService {
|
||||
|
||||
GlobalSMTPConfigurationRepository smtpConfigurationRepository;
|
||||
EnvironmentSMTPConfigurationProvider environmentSMTPConfigurationProvider;
|
||||
EncryptionDecryptionService encryptionDecryptionService;
|
||||
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
|
||||
smtpConfigurationRepository.findSingleton()
|
||||
.orElseGet(() -> {
|
||||
GlobalSMTPConfigurationEntity defaultConfig = SMTPConfigurationMapper.toEntity(environmentSMTPConfigurationProvider.get());
|
||||
defaultConfig.setPassword(encryptionDecryptionService.encrypt(defaultConfig.getPassword()));
|
||||
return smtpConfigurationRepository.save(defaultConfig);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public GlobalSMTPConfigurationEntity getConfiguration() {
|
||||
|
||||
return smtpConfigurationRepository.findSingleton()
|
||||
.orElseThrow(() -> new IllegalStateException("Global SMTP Configuration not found."));
|
||||
}
|
||||
|
||||
|
||||
@Transactional
|
||||
public GlobalSMTPConfigurationEntity updateConfiguration(GlobalSMTPConfigurationEntity smtpConfiguration) {
|
||||
|
||||
smtpConfiguration.setId("singleton");
|
||||
return smtpConfigurationRepository.save(smtpConfiguration);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,11 +1,10 @@
|
||||
package com.knecon.fforesight.tenantusermanagement.service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
@ -16,8 +15,13 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.license.Red
|
||||
import com.knecon.fforesight.tenantcommons.EncryptionDecryptionService;
|
||||
import com.knecon.fforesight.tenantcommons.TenantContext;
|
||||
import com.knecon.fforesight.tenantusermanagement.client.LicenseClient;
|
||||
import com.knecon.fforesight.tenantusermanagement.entity.GlobalSMTPConfigurationEntity;
|
||||
import com.knecon.fforesight.tenantusermanagement.entity.TenantEntity;
|
||||
import com.knecon.fforesight.tenantusermanagement.model.SMTPConfiguration;
|
||||
import com.knecon.fforesight.tenantusermanagement.repository.TenantRepository;
|
||||
import com.knecon.fforesight.tenantusermanagement.utils.SMTPConfigurationMapper;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@ -26,9 +30,11 @@ import lombok.extern.slf4j.Slf4j;
|
||||
@Slf4j
|
||||
public class SMTPService {
|
||||
|
||||
private final Environment environment;
|
||||
private final GlobalSMTPConfigurationPersistenceService smtpConfigurationPersistenceService;
|
||||
private final EnvironmentSMTPConfigurationProvider environmentSMTPConfigurationProvider;
|
||||
private final LicenseClient licenseClient;
|
||||
private final RealmService realmService;
|
||||
private final TenantRepository tenantRepository;
|
||||
|
||||
private final EncryptionDecryptionService encryptionDecryptionService;
|
||||
|
||||
@ -36,22 +42,72 @@ public class SMTPService {
|
||||
|
||||
private final static String SMTP_PASSWORD_KEY = "FFORESIGHT_SMTP_PASSWORD";
|
||||
private final static String DEFAULT_PASSWORD = "**********";
|
||||
|
||||
public static final String SMTP_DEFAULT_HOST = "SMTP_DEFAULT_HOST";
|
||||
public static final String SMTP_DEFAULT_PORT = "SMTP_DEFAULT_PORT";
|
||||
public static final String SMTP_DEFAULT_SENDER_EMAIL = "SMTP_DEFAULT_SENDER_EMAIL";
|
||||
public static final String SMTP_DEFAULT_SENDER_NAME = "SMTP_DEFAULT_SENDER_NAME";
|
||||
public static final String SMTP_DEFAULT_REPLY_EMAIL = "SMTP_DEFAULT_REPLY_EMAIL";
|
||||
public static final String SMTP_DEFAULT_REPLY_NAME = "SMTP_DEFAULT_REPLY_NAME";
|
||||
public static final String SMTP_DEFAULT_SENDER_ENVELOPE = "SMTP_DEFAULT_SENDER_ENVELOPE";
|
||||
public static final String SMTP_DEFAULT_SSL = "SMTP_DEFAULT_SSL";
|
||||
public static final String SMTP_DEFAULT_STARTTLS = "SMTP_DEFAULT_STARTTLS";
|
||||
public static final String SMTP_DEFAULT_AUTH = "SMTP_DEFAULT_AUTH";
|
||||
public static final String SMTP_DEFAULT_AUTH_USER = "SMTP_DEFAULT_AUTH_USER";
|
||||
public static final String SMTP_DEFAULT_AUTH_PASSWORD = "SMTP_DEFAULT_AUTH_PASSWORD";
|
||||
public static final String CONFIGURABLE_SMTP_SERVER_FEATURE = "configurableSMTPServer";
|
||||
|
||||
|
||||
@PostConstruct
|
||||
public void synchronizeSMTPConfigurations() {
|
||||
|
||||
log.info("Starting SMTP configuration synchronization...");
|
||||
|
||||
try {
|
||||
// Step 1: Retrieve all tenants
|
||||
List<TenantEntity> tenants = tenantRepository.findAll();
|
||||
log.info("Retrieved {} tenants for SMTP synchronization.", tenants.size());
|
||||
|
||||
// Step 2: Retrieve the global SMTP configuration
|
||||
GlobalSMTPConfigurationEntity latestGlobalConfigEntity = smtpConfigurationPersistenceService.getConfiguration();
|
||||
SMTPConfiguration latestGlobalConfig = SMTPConfigurationMapper.toModel(latestGlobalConfigEntity);
|
||||
latestGlobalConfig.setPassword(encryptionDecryptionService.decrypt(latestGlobalConfig.getPassword()));
|
||||
log.info("Loaded existing global SMTP configuration.");
|
||||
|
||||
// Step 3: Generate the latest SMTP config from environment variables and compare it to the saved global config
|
||||
SMTPConfiguration currentGlobalConfig = environmentSMTPConfigurationProvider.get();
|
||||
if (!currentGlobalConfig.equals(latestGlobalConfig)) {
|
||||
log.info("Environment SMTP configuration has changed. Updating global SMTP configuration.");
|
||||
|
||||
// Step 4: Iterate through each tenant to synchronize SMTP configurations
|
||||
tenants
|
||||
.forEach(tenant -> {
|
||||
String tenantId = tenant.getTenantId();
|
||||
log.info("Processing SMTP configuration for tenant: {}", tenantId);
|
||||
|
||||
try {
|
||||
TenantContext.setTenantId(tenantId);
|
||||
SMTPConfiguration tenantSMTPConfig = getSMTPConfiguration();
|
||||
tenantSMTPConfig.setId("singleton");
|
||||
updatePassword(tenantSMTPConfig);
|
||||
if(!tenantSMTPConfig.getPassword().isBlank()) {
|
||||
tenantSMTPConfig.setPassword(encryptionDecryptionService.decrypt(tenantSMTPConfig.getPassword()));
|
||||
}
|
||||
if (tenantSMTPConfig.equals(latestGlobalConfig)) {
|
||||
log.info("Tenant '{}' SMTP configuration matches global. Updating to latest environment configuration.", tenantId);
|
||||
updateSMTPConfiguration(currentGlobalConfig);
|
||||
log.info("Tenant '{}' SMTP configuration updated successfully.", tenantId);
|
||||
} else {
|
||||
log.info("Tenant '{}' SMTP configuration differs from global. No action taken.", tenantId);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Error processing SMTP configuration for tenant '{}': {}", tenant.getTenantId(), e.getMessage());
|
||||
} finally {
|
||||
TenantContext.clear();
|
||||
}
|
||||
});
|
||||
|
||||
currentGlobalConfig.setPassword(encryptionDecryptionService.encrypt(currentGlobalConfig.getPassword()));
|
||||
GlobalSMTPConfigurationEntity updatedGlobalConfig = SMTPConfigurationMapper.toEntity(currentGlobalConfig);
|
||||
smtpConfigurationPersistenceService.updateConfiguration(updatedGlobalConfig);
|
||||
} else {
|
||||
log.info("No changes detected in environment SMTP configuration.");
|
||||
}
|
||||
|
||||
log.info("SMTP configuration synchronization completed successfully.");
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to synchronize SMTP configurations: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public SMTPConfiguration getSMTPConfiguration() {
|
||||
@ -93,34 +149,16 @@ public class SMTPService {
|
||||
}
|
||||
|
||||
|
||||
public void createDefaultSMTPConfiguration(String tenantId) {
|
||||
public void createDefaultSMTPConfiguration() {
|
||||
|
||||
SMTPConfiguration defaultConfig = generateDefaultSMTPConfiguration();
|
||||
updateSMTPConfiguration(defaultConfig, tenantId);
|
||||
}
|
||||
|
||||
private SMTPConfiguration generateDefaultSMTPConfiguration() {
|
||||
|
||||
String port = environment.getProperty(SMTP_DEFAULT_PORT, "1234");
|
||||
return SMTPConfiguration.builder()
|
||||
.host(environment.getProperty(SMTP_DEFAULT_HOST, ""))
|
||||
.port(StringUtils.isEmpty(port) ? null : Integer.parseInt(port))
|
||||
.from(environment.getProperty(SMTP_DEFAULT_SENDER_EMAIL, ""))
|
||||
.fromDisplayName(environment.getProperty(SMTP_DEFAULT_SENDER_NAME, ""))
|
||||
.replyTo(environment.getProperty(SMTP_DEFAULT_REPLY_EMAIL, ""))
|
||||
.replyToDisplayName(environment.getProperty(SMTP_DEFAULT_REPLY_NAME, ""))
|
||||
.envelopeFrom(environment.getProperty(SMTP_DEFAULT_SENDER_ENVELOPE, ""))
|
||||
.ssl(Boolean.parseBoolean(environment.getProperty(SMTP_DEFAULT_SSL, "false")))
|
||||
.starttls(Boolean.parseBoolean(environment.getProperty(SMTP_DEFAULT_STARTTLS, "false")))
|
||||
.auth(Boolean.parseBoolean(environment.getProperty(SMTP_DEFAULT_AUTH, "false")))
|
||||
.user(environment.getProperty(SMTP_DEFAULT_AUTH_USER, ""))
|
||||
.password(environment.getProperty(SMTP_DEFAULT_AUTH_PASSWORD, ""))
|
||||
.build();
|
||||
SMTPConfiguration defaultConfig = environmentSMTPConfigurationProvider.get();
|
||||
updateSMTPConfiguration(defaultConfig);
|
||||
}
|
||||
|
||||
|
||||
public void updateSMTPConfiguration(SMTPConfiguration smtpConfigurationModel, String tenantId) {
|
||||
public void updateSMTPConfiguration(SMTPConfiguration smtpConfigurationModel) {
|
||||
|
||||
String tenantId = TenantContext.getTenantId();
|
||||
var realmRepresentation = realmService.realm(tenantId).toRepresentation();
|
||||
var propertiesMap = convertSMTPConfigurationModelToMap(smtpConfigurationModel);
|
||||
realmRepresentation.setSmtpServer(propertiesMap);
|
||||
@ -163,7 +201,7 @@ public class SMTPService {
|
||||
if (DEFAULT_PASSWORD.equals(smtpConfiguration.getPassword())) {
|
||||
try {
|
||||
var password = realmService.realm(TenantContext.getTenantId()).toRepresentation().getAttributesOrEmpty()
|
||||
.get(SMTP_PASSWORD_KEY);
|
||||
.getOrDefault(SMTP_PASSWORD_KEY, "");
|
||||
smtpConfiguration.setPassword(password);
|
||||
} catch (Exception e) {
|
||||
log.info("No current SMTP Config exists", e);
|
||||
|
||||
@ -214,7 +214,8 @@ public class TenantManagementService implements TenantProvider {
|
||||
|
||||
log.info("Updated roles for tenant: {}", tenantRequest.getTenantId());
|
||||
|
||||
smtpService.createDefaultSMTPConfiguration(tenantRequest.getTenantId());
|
||||
TenantContext.setTenantId(tenantEntity.getTenantId());
|
||||
smtpService.createDefaultSMTPConfiguration();
|
||||
|
||||
log.info("Created default SMTP configuration.");
|
||||
|
||||
@ -223,7 +224,6 @@ public class TenantManagementService implements TenantProvider {
|
||||
|
||||
log.info("Persisted tenant: {}", tenantRequest.getTenantId());
|
||||
|
||||
TenantContext.setTenantId(tenantEntity.getTenantId());
|
||||
rabbitTemplate.convertAndSend(tenantExchangeName, "tenant.created", new TenantCreatedEvent(tenantEntity.getTenantId()));
|
||||
TenantContext.clear();
|
||||
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
package com.knecon.fforesight.tenantusermanagement.utils;
|
||||
|
||||
import com.knecon.fforesight.tenantusermanagement.entity.GlobalSMTPConfigurationEntity;
|
||||
import com.knecon.fforesight.tenantusermanagement.model.SMTPConfiguration;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
@UtilityClass
|
||||
public final class SMTPConfigurationMapper {
|
||||
|
||||
public static GlobalSMTPConfigurationEntity toEntity(SMTPConfiguration smtpConfig) {
|
||||
|
||||
if (smtpConfig == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return GlobalSMTPConfigurationEntity.builder()
|
||||
.id("singleton")
|
||||
.auth(smtpConfig.isAuth())
|
||||
.envelopeFrom(smtpConfig.getEnvelopeFrom())
|
||||
.fromEmail(smtpConfig.getFrom())
|
||||
.fromDisplayName(smtpConfig.getFromDisplayName())
|
||||
.host(smtpConfig.getHost())
|
||||
.password(smtpConfig.getPassword())
|
||||
.port(smtpConfig.getPort())
|
||||
.replyTo(smtpConfig.getReplyTo())
|
||||
.replyToDisplayName(smtpConfig.getReplyToDisplayName())
|
||||
.ssl(smtpConfig.isSsl())
|
||||
.starttls(smtpConfig.isStarttls())
|
||||
.userName(smtpConfig.getUser())
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
public static SMTPConfiguration toModel(GlobalSMTPConfigurationEntity entity) {
|
||||
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SMTPConfiguration smtpConfig = new SMTPConfiguration();
|
||||
smtpConfig.setId(entity.getId());
|
||||
smtpConfig.setAuth(entity.getAuth() != null && entity.getAuth());
|
||||
smtpConfig.setEnvelopeFrom(entity.getEnvelopeFrom());
|
||||
smtpConfig.setFrom(entity.getFromEmail());
|
||||
smtpConfig.setFromDisplayName(entity.getFromDisplayName());
|
||||
smtpConfig.setHost(entity.getHost());
|
||||
smtpConfig.setPassword(entity.getPassword());
|
||||
smtpConfig.setPort(entity.getPort());
|
||||
smtpConfig.setReplyTo(entity.getReplyTo());
|
||||
smtpConfig.setReplyToDisplayName(entity.getReplyToDisplayName());
|
||||
smtpConfig.setSsl(entity.getSsl() != null && entity.getSsl());
|
||||
smtpConfig.setStarttls(entity.getStarttls() != null && entity.getStarttls());
|
||||
smtpConfig.setUser(entity.getUserName());
|
||||
|
||||
return smtpConfig;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -17,3 +17,5 @@ databaseChangeLog:
|
||||
file: db/changelog/master/9-add-mongodb-connection-columns.yaml
|
||||
- include:
|
||||
file: db/changelog/master/10-add-application-type-to-tenant.yaml
|
||||
- include:
|
||||
file: db/changelog/master/11-add-global-smtp-config.yaml
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
databaseChangeLog:
|
||||
- changeSet:
|
||||
id: add-global-smtp-config-table
|
||||
author: dom
|
||||
changes:
|
||||
- createTable:
|
||||
tableName: global_smtp_configuration
|
||||
columns:
|
||||
- column:
|
||||
name: id
|
||||
type: VARCHAR(255)
|
||||
constraints:
|
||||
nullable: false
|
||||
primaryKey: true
|
||||
primaryKeyName: global_smtp_configuration_pkey
|
||||
- column:
|
||||
name: auth
|
||||
type: BOOLEAN
|
||||
- column:
|
||||
name: envelope_from
|
||||
type: VARCHAR(255)
|
||||
- column:
|
||||
name: from_email
|
||||
type: VARCHAR(255)
|
||||
- column:
|
||||
name: from_display_name
|
||||
type: VARCHAR(255)
|
||||
- column:
|
||||
name: host
|
||||
type: VARCHAR(255)
|
||||
- column:
|
||||
name: password
|
||||
type: VARCHAR(255)
|
||||
- column:
|
||||
name: port
|
||||
type: INTEGER
|
||||
- column:
|
||||
name: reply_to
|
||||
type: VARCHAR(255)
|
||||
- column:
|
||||
name: reply_to_display_name
|
||||
type: VARCHAR(255)
|
||||
- column:
|
||||
name: ssl
|
||||
type: BOOLEAN
|
||||
- column:
|
||||
name: starttls
|
||||
type: BOOLEAN
|
||||
- column:
|
||||
name: user_name
|
||||
type: VARCHAR(255)
|
||||
@ -1,15 +1,6 @@
|
||||
package com.knecon.fforesight.tenantusermanagement.tests;
|
||||
|
||||
import static com.knecon.fforesight.tenantusermanagement.service.SMTPService.SMTP_DEFAULT_AUTH;
|
||||
import static com.knecon.fforesight.tenantusermanagement.service.SMTPService.SMTP_DEFAULT_HOST;
|
||||
import static com.knecon.fforesight.tenantusermanagement.service.SMTPService.SMTP_DEFAULT_PORT;
|
||||
import static com.knecon.fforesight.tenantusermanagement.service.SMTPService.SMTP_DEFAULT_REPLY_EMAIL;
|
||||
import static com.knecon.fforesight.tenantusermanagement.service.SMTPService.SMTP_DEFAULT_REPLY_NAME;
|
||||
import static com.knecon.fforesight.tenantusermanagement.service.SMTPService.SMTP_DEFAULT_SENDER_EMAIL;
|
||||
import static com.knecon.fforesight.tenantusermanagement.service.SMTPService.SMTP_DEFAULT_SENDER_ENVELOPE;
|
||||
import static com.knecon.fforesight.tenantusermanagement.service.SMTPService.SMTP_DEFAULT_SENDER_NAME;
|
||||
import static com.knecon.fforesight.tenantusermanagement.service.SMTPService.SMTP_DEFAULT_SSL;
|
||||
import static com.knecon.fforesight.tenantusermanagement.service.SMTPService.SMTP_DEFAULT_STARTTLS;
|
||||
import static com.knecon.fforesight.tenantusermanagement.service.EnvironmentSMTPConfigurationProvider.*;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@ -0,0 +1,242 @@
|
||||
package com.knecon.fforesight.tenantusermanagement.tests;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.knecon.fforesight.tenantcommons.EncryptionDecryptionService;
|
||||
import com.knecon.fforesight.tenantusermanagement.entity.GlobalSMTPConfigurationEntity;
|
||||
import com.knecon.fforesight.tenantusermanagement.entity.TenantEntity;
|
||||
import com.knecon.fforesight.tenantusermanagement.model.SMTPConfiguration;
|
||||
import com.knecon.fforesight.tenantusermanagement.repository.TenantRepository;
|
||||
import com.knecon.fforesight.tenantusermanagement.service.EnvironmentSMTPConfigurationProvider;
|
||||
import com.knecon.fforesight.tenantusermanagement.service.GlobalSMTPConfigurationPersistenceService;
|
||||
import com.knecon.fforesight.tenantusermanagement.service.RealmService;
|
||||
import com.knecon.fforesight.tenantusermanagement.service.SMTPService;
|
||||
|
||||
@ExtendWith(org.mockito.junit.jupiter.MockitoExtension.class)
|
||||
public class SMTPServiceTest {
|
||||
|
||||
public static final String NEW_SMTP_HOST = "new.smtp.host";
|
||||
public static final int NEW_SMTP_PORT = 465;
|
||||
public static final String NEW_SMTP_USER = "newUser";
|
||||
public static final String NEW_SMTP_PASSWORD = "newPassword";
|
||||
public static final String OLD_SMTP_HOST = "old.smtp.host";
|
||||
public static final int OLD_SMTP_PORT = 587;
|
||||
public static final String OLD_SMTP_USER = "globalUser";
|
||||
public static final String OLD_SMTP_PASSWORD = "oldPassword";
|
||||
@Mock
|
||||
private GlobalSMTPConfigurationPersistenceService smtpConfigurationPersistenceService;
|
||||
|
||||
@Mock
|
||||
private EnvironmentSMTPConfigurationProvider environmentSMTPConfigurationProvider;
|
||||
|
||||
@Mock
|
||||
private RealmService realmService;
|
||||
|
||||
@Mock
|
||||
private TenantRepository tenantRepository;
|
||||
|
||||
@Mock
|
||||
private EncryptionDecryptionService encryptionDecryptionService;
|
||||
|
||||
@InjectMocks
|
||||
private SMTPService smtpService;
|
||||
|
||||
private SMTPConfiguration oldGlobalConfig;
|
||||
private SMTPConfiguration overriddenConfig;
|
||||
private List<TenantEntity> tenantEntities;
|
||||
private final static String DEFAULT_PASSWORD = "**********";
|
||||
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
|
||||
smtpService = new SMTPService(smtpConfigurationPersistenceService,
|
||||
environmentSMTPConfigurationProvider,
|
||||
null,
|
||||
realmService,
|
||||
tenantRepository,
|
||||
encryptionDecryptionService,
|
||||
new ObjectMapper());
|
||||
|
||||
oldGlobalConfig = new SMTPConfiguration();
|
||||
oldGlobalConfig.setId("singleton");
|
||||
oldGlobalConfig.setHost(OLD_SMTP_HOST);
|
||||
oldGlobalConfig.setPort(OLD_SMTP_PORT);
|
||||
oldGlobalConfig.setUser(OLD_SMTP_USER);
|
||||
oldGlobalConfig.setPassword(OLD_SMTP_PASSWORD);
|
||||
|
||||
overriddenConfig = new SMTPConfiguration();
|
||||
overriddenConfig.setHost("custom.smtp.host");
|
||||
overriddenConfig.setPort(2525);
|
||||
overriddenConfig.setUser("customUser");
|
||||
overriddenConfig.setPassword("encrypted_customPassword");
|
||||
|
||||
TenantEntity tenant1 = new TenantEntity();
|
||||
tenant1.setTenantId("tenant1");
|
||||
|
||||
TenantEntity tenant2 = new TenantEntity();
|
||||
tenant2.setTenantId("tenant2");
|
||||
|
||||
TenantEntity tenant3 = new TenantEntity();
|
||||
tenant3.setTenantId("tenant3");
|
||||
|
||||
tenantEntities = Arrays.asList(tenant1, tenant2, tenant3);
|
||||
when(tenantRepository.findAll()).thenReturn(tenantEntities);
|
||||
|
||||
GlobalSMTPConfigurationEntity globalEntity = new GlobalSMTPConfigurationEntity();
|
||||
globalEntity.setHost(oldGlobalConfig.getHost());
|
||||
globalEntity.setPort(oldGlobalConfig.getPort());
|
||||
globalEntity.setUserName(oldGlobalConfig.getUser());
|
||||
globalEntity.setPassword(oldGlobalConfig.getPassword());
|
||||
when(smtpConfigurationPersistenceService.getConfiguration()).thenReturn(globalEntity);
|
||||
|
||||
for (TenantEntity tenant : tenantEntities) {
|
||||
RealmResource tenantRealmResource = mock(RealmResource.class);
|
||||
when(realmService.realm(tenant.getTenantId())).thenReturn(tenantRealmResource);
|
||||
}
|
||||
|
||||
when(encryptionDecryptionService.decrypt(anyString())).thenAnswer(invocation -> {
|
||||
String encrypted = invocation.getArgument(0);
|
||||
if (encrypted.startsWith("encrypted_")) {
|
||||
return encrypted.substring("encrypted_".length());
|
||||
}
|
||||
return encrypted;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSynchronizeSMTPConfigurations() {
|
||||
|
||||
for (TenantEntity tenant : tenantEntities) {
|
||||
RealmResource tenantRealmResource = mock(RealmResource.class);
|
||||
when(realmService.realm(tenant.getTenantId())).thenReturn(tenantRealmResource);
|
||||
// for this test also mock toRepresentation
|
||||
RealmRepresentation realm = getRealmRepresentation(tenant, overriddenConfig, oldGlobalConfig);
|
||||
when(tenantRealmResource.toRepresentation()).thenReturn(realm);
|
||||
}
|
||||
|
||||
when(encryptionDecryptionService.encrypt(anyString())).thenAnswer(invocation -> "encrypted_" + invocation.getArgument(0));
|
||||
|
||||
SMTPConfiguration newEnvConfig = new SMTPConfiguration();
|
||||
newEnvConfig.setId("singleton");
|
||||
newEnvConfig.setHost(NEW_SMTP_HOST);
|
||||
newEnvConfig.setPort(NEW_SMTP_PORT);
|
||||
newEnvConfig.setUser(NEW_SMTP_USER);
|
||||
newEnvConfig.setPassword(NEW_SMTP_PASSWORD);
|
||||
when(environmentSMTPConfigurationProvider.get()).thenReturn(newEnvConfig);
|
||||
|
||||
smtpService.synchronizeSMTPConfigurations();
|
||||
|
||||
ArgumentCaptor<GlobalSMTPConfigurationEntity> globalConfigCaptor = ArgumentCaptor.forClass(GlobalSMTPConfigurationEntity.class);
|
||||
verify(smtpConfigurationPersistenceService).updateConfiguration(globalConfigCaptor.capture());
|
||||
|
||||
GlobalSMTPConfigurationEntity updatedGlobalConfig = globalConfigCaptor.getValue();
|
||||
assertEquals(NEW_SMTP_HOST, updatedGlobalConfig.getHost());
|
||||
assertEquals(NEW_SMTP_PORT, updatedGlobalConfig.getPort());
|
||||
assertEquals(NEW_SMTP_USER, updatedGlobalConfig.getUserName());
|
||||
assertEquals("encrypted_" + NEW_SMTP_PASSWORD, updatedGlobalConfig.getPassword());
|
||||
|
||||
// Verify that tenant1 and tenant3 were not updated, and tenant2 was
|
||||
for (TenantEntity tenant : tenantEntities) {
|
||||
RealmResource tenantRealmResource = realmService.realm(tenant.getTenantId());
|
||||
|
||||
if ("tenant1".equals(tenant.getTenantId()) || "tenant3".equals(tenant.getTenantId())) {
|
||||
// Verify that update() was called once for tenant1 and tenant3
|
||||
verify(tenantRealmResource, times(1)).update(any(RealmRepresentation.class));
|
||||
|
||||
ArgumentCaptor<RealmRepresentation> realmCaptor = ArgumentCaptor.forClass(RealmRepresentation.class);
|
||||
verify(tenantRealmResource).update(realmCaptor.capture());
|
||||
|
||||
RealmRepresentation updatedRealm = realmCaptor.getValue();
|
||||
Map<String, String> smtpServer = updatedRealm.getSmtpServer();
|
||||
smtpServer.putAll(updatedRealm.getAttributes());
|
||||
assertEquals(NEW_SMTP_HOST, smtpServer.get("host"));
|
||||
assertEquals(String.valueOf(NEW_SMTP_PORT), smtpServer.get("port"));
|
||||
assertEquals(NEW_SMTP_USER, smtpServer.get("user"));
|
||||
assertEquals("encrypted_" + NEW_SMTP_PASSWORD, smtpServer.get("FFORESIGHT_SMTP_PASSWORD"));
|
||||
} else if ("tenant2".equals(tenant.getTenantId())) {
|
||||
// Verify that update() was never called for tenant2
|
||||
verify(tenantRealmResource, never()).update(any(RealmRepresentation.class));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSynchronizeSMTPConfigurationsWithoutGlobalChanges() {
|
||||
|
||||
SMTPConfiguration newEnvConfig = new SMTPConfiguration();
|
||||
newEnvConfig.setId("singleton");
|
||||
newEnvConfig.setHost(OLD_SMTP_HOST);
|
||||
newEnvConfig.setPort(OLD_SMTP_PORT);
|
||||
newEnvConfig.setUser(OLD_SMTP_USER);
|
||||
newEnvConfig.setPassword(OLD_SMTP_PASSWORD);
|
||||
when(environmentSMTPConfigurationProvider.get()).thenReturn(newEnvConfig);
|
||||
|
||||
smtpService.synchronizeSMTPConfigurations();
|
||||
|
||||
verify(smtpConfigurationPersistenceService, never()).updateConfiguration(any(GlobalSMTPConfigurationEntity.class));
|
||||
|
||||
// Verify that all tenants are unchanged
|
||||
for (TenantEntity tenant : tenantEntities) {
|
||||
RealmResource tenantRealmResource = realmService.realm(tenant.getTenantId());
|
||||
|
||||
verify(tenantRealmResource, never()).update(any(RealmRepresentation.class));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@NotNull
|
||||
private static RealmRepresentation getRealmRepresentation(TenantEntity tenant, SMTPConfiguration overriddenConfig, SMTPConfiguration oldGlobalConfig) {
|
||||
|
||||
RealmRepresentation realm = new RealmRepresentation();
|
||||
Map<String, String> smtpMap = new HashMap<>();
|
||||
smtpMap.put("password", DEFAULT_PASSWORD);
|
||||
Map<String, String> attributes = new HashMap<>();
|
||||
|
||||
if ("tenant2".equals(tenant.getTenantId())) {
|
||||
// tenant2 has overridden SMTP config
|
||||
smtpMap.put("host", overriddenConfig.getHost());
|
||||
smtpMap.put("port", String.valueOf(overriddenConfig.getPort()));
|
||||
smtpMap.put("user", overriddenConfig.getUser());
|
||||
attributes.put("FFORESIGHT_SMTP_PASSWORD", overriddenConfig.getPassword());
|
||||
|
||||
} else {
|
||||
// tenant1 and tenant3 have SMTP config matching global
|
||||
smtpMap.put("host", oldGlobalConfig.getHost());
|
||||
smtpMap.put("port", String.valueOf(oldGlobalConfig.getPort()));
|
||||
smtpMap.put("user", oldGlobalConfig.getUser());
|
||||
attributes.put("FFORESIGHT_SMTP_PASSWORD", oldGlobalConfig.getPassword());
|
||||
|
||||
}
|
||||
realm.setSmtpServer(smtpMap);
|
||||
|
||||
realm.setAttributes(attributes);
|
||||
return realm;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user