Merge branch 'RED-7006' into 'main'

Red 7006 - Fix error message + passwords for db/schema shown in response + don't allow to set both azure and s3 for tenant

See merge request fforesight/tenant-user-management-service!6
This commit is contained in:
Ali Oezyetimoglu 2023-07-25 12:44:40 +02:00
commit a41dc2a4dd
6 changed files with 143 additions and 44 deletions

View File

@ -26,7 +26,7 @@ public class ControllerAdvice {
@ExceptionHandler(ResponseStatusException.class)
public ResponseEntity<ErrorMessage> handleResponseStatusException(ResponseStatusException e) {
return new ResponseEntity<>(new ErrorMessage(e.getMessage()), e.getStatusCode());
return new ResponseEntity<>(new ErrorMessage(e.getReason()), e.getStatusCode());
}
}

View File

@ -366,6 +366,10 @@ public class TenantManagementService implements TenantProvider {
public TenantResponse updateTenant(String tenantId, TenantRequest tenantRequest) {
if (tenantRequest.getS3StorageConnection() != null && tenantRequest.getAzureStorageConnection() != null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Not possible to set both azure and s3 connection, please only specify one");
}
var tenant = tenantRepository.findById(tenantId);
if (tenant.isPresent()) {
var tenantEntity = tenant.get();
@ -401,15 +405,23 @@ public class TenantManagementService implements TenantProvider {
var azureStorageConnection = tenantRequest.getAzureStorageConnection();
if (azureStorageConnection != null) {
if (tenantEntity.getS3StorageConnection() != null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Not possible to set both azure and s3 connection, please only specify one");
}
testAzureConnection(azureStorageConnection.getConnectionString(), azureStorageConnection.getContainerName());
tenantEntity.setAzureStorageConnection(AzureStorageConnectionEntity.builder()
.connectionString(encryptionService.encrypt(azureStorageConnection.getConnectionString()))
.containerName(azureStorageConnection.getContainerName())
.build());
} else {
tenantEntity.setAzureStorageConnection(null);
}
var s3StorageConnection = tenantRequest.getS3StorageConnection();
if (s3StorageConnection != null) {
if (tenantEntity.getAzureStorageConnection() != null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Not possible to set both azure and s3 connection, please only specify one");
}
testS3Connection(s3StorageConnection);
tenantEntity.setS3StorageConnection(S3StorageConnectionEntity.builder()
.key(s3StorageConnection.getKey())
@ -419,6 +431,8 @@ public class TenantManagementService implements TenantProvider {
.region(s3StorageConnection.getRegion())
.endpoint(s3StorageConnection.getEndpoint())
.build());
} else {
tenantEntity.setS3StorageConnection(null);
}
return convert(tenantRepository.save(tenantEntity));
@ -454,7 +468,6 @@ public class TenantManagementService implements TenantProvider {
.database(entity.getDatabaseConnection().getDatabase())
.schema(entity.getDatabaseConnection().getSchema())
.username(entity.getDatabaseConnection().getUsername())
.password(entity.getDatabaseConnection().getPassword())
.params(entity.getDatabaseConnection().getParams())
.build())
.searchConnection(SearchConnection.builder()
@ -462,7 +475,6 @@ public class TenantManagementService implements TenantProvider {
.port(entity.getSearchConnection().getPort())
.scheme(entity.getSearchConnection().getScheme())
.username(entity.getSearchConnection().getUsername())
.password(entity.getSearchConnection().getPassword())
.numberOfShards(entity.getSearchConnection().getNumberOfShards())
.numberOfReplicas(entity.getSearchConnection().getNumberOfReplicas())
.build())

View File

@ -1,5 +1,7 @@
package com.knecon.fforesight;
import java.io.IOException;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
@ -24,10 +26,12 @@ import com.knecon.fforesight.feigntestclients.external.TenantsClient;
import com.knecon.fforesight.feigntestclients.internal.InternalTenantsClient;
import com.knecon.fforesight.tenantusermanagement.TenantUserManagementServiceApplication;
import com.knecon.fforesight.testcontainers.KeyCloakTestContainer;
import com.knecon.fforesight.testcontainers.MinioTestContainer;
import com.knecon.fforesight.testcontainers.RedisTestContainer;
import com.knecon.fforesight.testcontainers.SpringPostgreSQLTestContainer;
import com.knecon.fforesight.utils.TestTenantService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@ExtendWith(SpringExtension.class)
@ -49,16 +53,6 @@ public class AbstractTenantUserManagementIntegrationTest {
public static int minioPort;
@BeforeAll
static void setupMinioContainer() {
minioServer = new GenericContainer("minio/minio")
.withEnv("MINIO_ACCESS_KEY", "minioadmin")
.withEnv("MINIO_SECRET_KEY", "minioadmin")
.withCommand("server /entity")
.withExposedPorts(9000);
minioServer.start();
minioPort = minioServer.getFirstMappedPort();
}
@BeforeEach
public void createTestTenant(){
@ -68,6 +62,7 @@ public class AbstractTenantUserManagementIntegrationTest {
@Slf4j
static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@SneakyThrows
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
var postgreSQLContainerMaster = SpringPostgreSQLTestContainer.getInstance().withDatabaseName("integration-tests-db-master").withUsername("sa").withPassword("sa");
@ -90,6 +85,11 @@ public class AbstractTenantUserManagementIntegrationTest {
"fforesight.jobs.enabled=false",
"fforesight.keycloak.enabled=true").applyTo(configurableApplicationContext.getEnvironment());
var minioInstance = MinioTestContainer.getInstance();
minioInstance.start();
minioInstance.execInContainer("mc mb --with-locks redaction2");
minioPort = minioInstance.getFirstMappedPort();
}
}

View File

@ -0,0 +1,27 @@
package com.knecon.fforesight.testcontainers;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.DockerImageName;
public final class MinioTestContainer extends GenericContainer<MinioTestContainer> {
private static final String IMAGE_VERSION = "minio/minio";
private static MinioTestContainer container;
private MinioTestContainer() {
super(DockerImageName.parse(IMAGE_VERSION));
}
public static MinioTestContainer getInstance() {
if (container == null) {
container = new MinioTestContainer().withEnv("MINIO_ACCESS_KEY", "minioadmin")
.withEnv("MINIO_SECRET_KEY", "minioadmin")
.withCommand("server /entity")
.withExposedPorts(9000);
}
return container;
}
}

View File

@ -80,16 +80,35 @@ public class TenantsTest extends AbstractTenantUserManagementIntegrationTest {
.password("updated_pwd")
.username("updated_username")
.build())
.s3StorageConnection(S3StorageConnection.builder()
.key("minioadmin")
.secret("minioadmin")
.bucketName("redaction2")
.endpoint("http://localhost:" + minioPort).build())
.build();
var tenantEntity = tenantsClient.updateTenant("new_tenant", tenantRequest);
var updatedTenant = tenantsClient.updateTenant("new_tenant", tenantRequest);
tenantRequest.getSearchConnection().setPassword(encryptionService.encrypt("updated_pwd"));
tenantRequest.getDatabaseConnection().setPassword(encryptionService.encrypt("updated_pwd"));
tenantRequest.getSearchConnection().setPassword(null);
tenantRequest.getDatabaseConnection().setPassword(null);
assertThat(updatedTenant.getDisplayName()).isEqualTo(tenantRequest.getDisplayName());
assertThat(updatedTenant.getSearchConnection()).isEqualTo(tenantRequest.getSearchConnection());
assertThat(updatedTenant.getDatabaseConnection()).isEqualTo(tenantRequest.getDatabaseConnection());
assertThat(updatedTenant.getS3StorageConnection().getBucketName()).isEqualTo("redaction2");
var tenantEntity = tenantsClient.getTenant("new_tenant");
assertThat(tenantEntity.getDisplayName()).isEqualTo(tenantRequest.getDisplayName());
assertThat(tenantEntity.getSearchConnection()).isEqualTo(tenantRequest.getSearchConnection());
assertThat(tenantEntity.getDatabaseConnection()).isEqualTo(tenantRequest.getDatabaseConnection());
assertThat(tenantEntity.getS3StorageConnection().getBucketName()).isEqualTo("redaction2");
tenantRequest.setS3StorageConnection(null);
updatedTenant = tenantsClient.updateTenant("new_tenant", tenantRequest);
assertThat(updatedTenant.getS3StorageConnection()).isNull();
TenantContext.clear();
}
@ -119,6 +138,25 @@ public class TenantsTest extends AbstractTenantUserManagementIntegrationTest {
@Test
public void testUpdateTenantWithIncorrectAzureStorage() {
testTenantService.createTestTenantWithoutStorageIfNotExist("new_tenant_without_storage");
TenantContext.setTenantId("new_tenant_without_storage");
var tenantRequest = TenantRequest.builder()
.tenantId("new_tenant_without_storage")
.azureStorageConnection(AzureStorageConnection.builder()
.connectionString("updated_connection")
.containerName("updated_container")
.build())
.build();
var exception = assertThrows(FeignException.BadRequest.class, () -> tenantsClient.updateTenant("new_tenant_without_storage", tenantRequest));
assertThat(exception.getMessage()).contains("Could not connect to Azure storage");
TenantContext.clear();
}
@Test
public void testUpdateTenantWithBothAzureAndS3Storage() {
testTenantService.createTestTenantIfNotExists("new_tenant", minioPort);
TenantContext.setTenantId("new_tenant");
@ -131,7 +169,7 @@ public class TenantsTest extends AbstractTenantUserManagementIntegrationTest {
.build();
var exception = assertThrows(FeignException.BadRequest.class, () -> tenantsClient.updateTenant("new_tenant", tenantRequest));
assertThat(exception.getMessage()).contains("Could not connect to Azure storage");
assertThat(exception.getMessage()).contains("Not possible to set both azure and s3 connection, please only specify one");
TenantContext.clear();
}

View File

@ -37,35 +37,57 @@ public class TestTenantService {
} catch (Exception e) {
// not found
var tenantRequest = TenantRequest.builder()
.tenantId(testTenantId)
.displayName(testTenantId)
.guid(UUID.randomUUID().toString())
.defaultUsers(List.of(TenantUser.builder().roles(Set.of("SUPER_USER")).username("test@fforesight.com").password("secret").email("test@fforesight.com").build()))
.databaseConnection(DatabaseConnection.builder()
.driver("postgresql")
.host(SpringPostgreSQLTestContainer.getInstance().getHost())
.port(String.valueOf(SpringPostgreSQLTestContainer.getInstance().getFirstMappedPort()))
.database(SpringPostgreSQLTestContainer.getInstance().getDatabaseName())
.schema(testTenantId)
.username(SpringPostgreSQLTestContainer.getInstance().getUsername())
.password(SpringPostgreSQLTestContainer.getInstance().getPassword())
.build())
.searchConnection(SearchConnection.builder().hosts(Set.of("localhost")).port(9200).scheme("http").numberOfShards("1").numberOfReplicas("5").build())
.s3StorageConnection(S3StorageConnection.builder().key("minioadmin").secret("minioadmin").bucketName("redaction").endpoint("http://localhost:" + actualPort).build())
.build();
var response = internalTenantsResource.createTenant(tenantRequest);
assertThat(response.getGuid()).isNotBlank();
TenantContext.setTenantId(testTenantId);
tokenService.setUser("test@fforesight.com", "secret");
var tenant = tenantsClient.getTenant(testTenantId);
assertThat(tenant.getGuid()).isNotBlank();
createUser(testTenantId, actualPort, true);
}
}
public void createTestTenantWithoutStorageIfNotExist(String testTenantId) {
try {
var tenantExists = internalTenantsResource.getTenant(testTenantId);
assertThat(tenantExists.getGuid()).isNotBlank();
} catch (Exception e) {
// not found
createUser(testTenantId, 0, false);
}
}
private void createUser(String testTenantId, int actualPort, boolean withStorage) {
// not found
TenantRequest tenantRequest;
var tenantRequestBuilder = TenantRequest.builder()
.tenantId(testTenantId)
.displayName(testTenantId)
.guid(UUID.randomUUID().toString())
.defaultUsers(List.of(TenantUser.builder().roles(Set.of("SUPER_USER")).username("test@fforesight.com").password("secret").email("test@fforesight.com").build()))
.databaseConnection(DatabaseConnection.builder()
.driver("postgresql")
.host(SpringPostgreSQLTestContainer.getInstance().getHost())
.port(String.valueOf(SpringPostgreSQLTestContainer.getInstance().getFirstMappedPort()))
.database(SpringPostgreSQLTestContainer.getInstance().getDatabaseName())
.schema(testTenantId)
.username(SpringPostgreSQLTestContainer.getInstance().getUsername())
.password(SpringPostgreSQLTestContainer.getInstance().getPassword())
.build())
.searchConnection(SearchConnection.builder().hosts(Set.of("localhost")).port(9200).scheme("http").numberOfShards("1").numberOfReplicas("5").build());
if (withStorage) {
tenantRequest = tenantRequestBuilder
.s3StorageConnection(S3StorageConnection.builder().key("minioadmin").secret("minioadmin").bucketName("redaction").endpoint("http://localhost:" + actualPort).build())
.build();
} else {
tenantRequest = tenantRequestBuilder.build();
}
var response = internalTenantsResource.createTenant(tenantRequest);
assertThat(response.getGuid()).isNotBlank();
TenantContext.setTenantId(testTenantId);
tokenService.setUser("test@fforesight.com", "secret");
var tenant = tenantsClient.getTenant(testTenantId);
assertThat(tenant.getGuid()).isNotBlank();
}
}