RED-4515 - kc createRealm

This commit is contained in:
Timo Bejan 2023-03-23 17:15:22 +02:00
parent e69a988e39
commit 91efd63311
5 changed files with 109 additions and 16 deletions

View File

@ -89,6 +89,7 @@ public class KeyCloakRoleManagerService {
realm.roles().create(role);
}
var applicationRoleResource = realm.roles().get(applicationRole);
Set<RoleRepresentation> composites = realm.rolesById()
.getClientRoleComposites(applicationRoleResource.toRepresentation().getId(), redactionClient.toRepresentation().getId());

View File

@ -32,6 +32,7 @@ import org.springframework.stereotype.Service;
import com.iqser.red.keycloak.commons.KeyCloakAdminClientService;
import com.iqser.red.keycloak.commons.KeyCloakSettings;
import com.iqser.red.service.persistence.management.v1.processor.exception.ConflictException;
import com.iqser.red.service.persistence.management.v1.processor.exception.InternalServerErrorException;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.migration.AsyncMigrationStarterService;
import com.iqser.red.service.persistence.management.v1.processor.multitenancy.entity.AzureStorageConnectionEntity;
@ -58,6 +59,8 @@ import lombok.extern.slf4j.Slf4j;
@EnableConfigurationProperties(LiquibaseProperties.class)
public class TenantManagementService {
private static final Long MAX_WAIT_TIME = 60_000L; // 60 seconds
private static final Set<String> SUPPORTED_DATABASES = Set.of("postgresql");
private static final Set<String> SQL_CONNECTION_ERROR_CODES = Set.of(
// connection_exception
@ -88,7 +91,8 @@ public class TenantManagementService {
AsyncMigrationStarterService asyncMigrationStarterService,
GeneralConfigurationService generalConfigurationService,
KeyCloakRoleManagerService keyCloakRoleManagerService,
KeyCloakAdminClientService keycloak, KeyCloakSettings keyCloakSettings) {
KeyCloakAdminClientService keycloak,
KeyCloakSettings keyCloakSettings) {
this.encryptionService = encryptionService;
this.liquibaseProperties = liquibaseProperties;
@ -165,7 +169,23 @@ public class TenantManagementService {
tenantRepository.save(tenantEntity);
createRealm(tenantRequest.getTenantId());
Thread.sleep(30_000);
var waitTime = 0;
boolean realmReady;
do {
realmReady = tryToAccessRealm(tenantRequest.getTenantId());
if (realmReady) {
break;
} else {
Thread.sleep(1_000L);
waitTime += 1_000L;
}
} while (waitTime < MAX_WAIT_TIME);
if (!realmReady) {
throw new InternalServerErrorException("Failed to create KC realm");
}
generalConfigurationService.initGeneralConfiguration(tenantRequest.getTenantId());
keyCloakRoleManagerService.updateRoles(tenantRequest.getTenantId());
@ -177,6 +197,16 @@ public class TenantManagementService {
}
private boolean tryToAccessRealm(String tenantId) {
try {
return keycloak.getAdminClient().realms().findAll().stream().anyMatch(r -> r.getRealm().equals(tenantId));
} catch (Exception e) {
return false;
}
}
private void createRealm(String tenantId) {
var redaction = new RealmRepresentation();
@ -192,7 +222,6 @@ public class TenantManagementService {
redactionClient.setImplicitFlowEnabled(true);
redactionClient.setDirectAccessGrantsEnabled(true);
var swaggerClient = new ClientRepresentation();
swaggerClient.setEnabled(true);
swaggerClient.setName("swagger-ui-client");
@ -204,7 +233,6 @@ public class TenantManagementService {
swaggerClient.setAuthorizationServicesEnabled(true);
swaggerClient.setSecret("OsloImWinter!23");
var redactionSystemClient = new ClientRepresentation();
redactionSystemClient.setEnabled(true);
redactionSystemClient.setName(keyCloakSettings.getClientId());

View File

@ -1,13 +1,23 @@
package com.iqser.red.service.peristence.v1.server;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
@ -17,7 +27,11 @@ import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.StatementCallback;
import org.springframework.jdbc.datasource.SingleConnectionDataSource;
import com.iqser.red.service.persistence.management.v1.processor.service.DossierTemplateImportService;
import com.iqser.red.service.persistence.management.v1.processor.service.TenantManagementService;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DossierTemplateRepository;
import com.iqser.red.service.persistence.management.v1.processor.utils.multitenancy.TenantContext;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.importexport.ImportDossierTemplateRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.DatabaseConnection;
import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.S3StorageConnection;
import com.iqser.red.service.persistence.service.v1.api.shared.model.multitenancy.SearchConnection;
@ -70,30 +84,81 @@ public class DevConfiguration {
.password("redaction")
.build())
.searchConnection(SearchConnection.builder()
.hosts(Set.of("elasticsearchHost"))
.hosts(Set.of("localhost"))
.port(9200)
.scheme("https")
.scheme("http")
.username("elastic")
.password("changeMe")
.numberOfShards("1")
.numberOfReplicas("5")
.build())
.s3StorageConnection(S3StorageConnection.builder()
.key("key")
.secret("secret")
.signerType("signerType")
.bucketName("bucketName")
.region("eu")
.endpoint("endpoint")
.key("minioadmin")
.secret("minioadmin")
.bucketName("redaction")
.endpoint("http://localhost:9000")
.build())
.build();
tenantManagementService.createTenant(tenantRequest);
}
TenantContext.setTenantId("redaction");
if(dossierTemplateRepository.count() == 0) {
testDossierTemplateImport();
}
}
@Autowired
private DossierTemplateImportService dossierTemplateImportService;
@Autowired
private DossierTemplateRepository dossierTemplateRepository;
public byte[] pack(String sourceDirPath) throws IOException {
var bos = new ByteArrayOutputStream();
var p = Paths.get(sourceDirPath);
try (ZipOutputStream zs = new ZipOutputStream(bos)) {
Stream<Path> paths = Files.walk(p);
{
paths.filter(path -> !Files.isDirectory(path)).forEach(path -> {
ZipEntry zipEntry = new ZipEntry(p.relativize(path).toString());
try {
zs.putNextEntry(zipEntry);
Files.copy(path, zs);
zs.closeEntry();
} catch (IOException e) {
System.err.println(e);
}
});
}
}
return bos.toByteArray();
}
@SneakyThrows
public void testDossierTemplateImport() {
var importDir = new File("/Users/timobejan/work/dossier-templates-v2/dev");
TenantContext.setTenantId("redaction");
for (var file : importDir.listFiles()) {
if(file.isDirectory()){
var archive = pack(file.getAbsolutePath());
log.info("Importing file: " + file.getName() + " " + " with size: " + archive.length);
var request = new ImportDossierTemplateRequest();
request.setArchive(archive);
request.setUpdateExistingDossierTemplate(false);
request.setUserId("system");
dossierTemplateImportService.importDossierTemplate(request);
}
}
}
@SneakyThrows
public void createSchema(String jdbcUrl, String username, String password) {

View File

@ -32,10 +32,9 @@ public class DossierTemplateImportTest extends AbstractPersistenceServerServiceT
@SneakyThrows
@Test
@Disabled
public void testDossierTemplateImport() {
var importDir = new File("/path/to/git/repo/dossier-templates-v2/dev");
var importDir = new File("/Users/timobejan/work/dossier-templates-v2/dev");
TenantContext.setTenantId("redaction");
for (var file : importDir.listFiles()) {

View File

@ -125,7 +125,7 @@ keycloak:
commons:
keycloak:
application-client-id: redaction-system
application-client-id: redaction
realm: master
client-id: redaction-system
client-secret: redaction-system