diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d2333b8d..f177260f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] ### Added -- Workaround for creating client authorization resources, if a username is defined an owner through `owner.name`. Keycloak [excepts](https://github.com/keycloak/keycloak/blob/bfce612641a70e106b20b136431f0e4046b5c37f/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java#L2647-L2649) `owner.id` here instead `owner.name`. - See [#589](https://github.com/adorsys/keycloak-config-cli/pull/589) +- Support for multiple realm definitions inside one YAML file. +- Workaround for creating client authorization resources, if a username is defined an owner through `owner.name`. Keycloak [excepts](https://github.com/keycloak/keycloak/blob/bfce612641a70e106b20b136431f0e4046b5c37f/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java#L2647-L2649) `owner.id` here instead `owner.name`. See [#589](https://github.com/adorsys/keycloak-config-cli/pull/589) ## [4.4.0] - 2021-12-04 diff --git a/src/main/java/de/adorsys/keycloak/config/KeycloakConfigRunner.java b/src/main/java/de/adorsys/keycloak/config/KeycloakConfigRunner.java index 0405da4bb..84791ac50 100644 --- a/src/main/java/de/adorsys/keycloak/config/KeycloakConfigRunner.java +++ b/src/main/java/de/adorsys/keycloak/config/KeycloakConfigRunner.java @@ -33,6 +33,7 @@ import java.text.SimpleDateFormat; import java.util.Date; +import java.util.List; import java.util.Map; @Component @@ -64,11 +65,13 @@ public void run(String... args) { try { KeycloakImport keycloakImport = keycloakImportProvider.get(); - Map realmImports = keycloakImport.getRealmImports(); + Map> realmImports = keycloakImport.getRealmImports(); - for (Map.Entry realmImport : realmImports.entrySet()) { + for (Map.Entry> realmImport : realmImports.entrySet()) { logger.info("Importing file '{}'", realmImport.getKey()); - realmImportService.doImport(realmImport.getValue()); + for (RealmImport realmImportParts : realmImport.getValue()) { + realmImportService.doImport(realmImportParts); + } } } catch (NullPointerException e) { throw e; diff --git a/src/main/java/de/adorsys/keycloak/config/model/KeycloakImport.java b/src/main/java/de/adorsys/keycloak/config/model/KeycloakImport.java index cad8121a8..35f859fc7 100644 --- a/src/main/java/de/adorsys/keycloak/config/model/KeycloakImport.java +++ b/src/main/java/de/adorsys/keycloak/config/model/KeycloakImport.java @@ -22,17 +22,18 @@ import org.springframework.stereotype.Component; +import java.util.List; import java.util.Map; @Component public class KeycloakImport { - private final Map realmImports; + private final Map> realmImports; - public KeycloakImport(Map realmImports) { + public KeycloakImport(Map> realmImports) { this.realmImports = realmImports; } - public Map getRealmImports() { + public Map> getRealmImports() { return realmImports; } } diff --git a/src/main/java/de/adorsys/keycloak/config/provider/KeycloakImportProvider.java b/src/main/java/de/adorsys/keycloak/config/provider/KeycloakImportProvider.java index 1179895cc..be33124a6 100644 --- a/src/main/java/de/adorsys/keycloak/config/provider/KeycloakImportProvider.java +++ b/src/main/java/de/adorsys/keycloak/config/provider/KeycloakImportProvider.java @@ -20,6 +20,9 @@ package de.adorsys.keycloak.config.provider; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; @@ -51,9 +54,10 @@ public class KeycloakImportProvider { private StringSubstitutor interpolator = null; - private static final ObjectMapper OBJECT_MAPPER_JSON = new ObjectMapper() - .enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); - private static final ObjectMapper OBJECT_MAPPER_YAML = new ObjectMapper(new YAMLFactory()) + private static final JsonFactory JSON_FACTORY = new JsonFactory(); + private static final YAMLFactory YAML_FACTORY = new YAMLFactory(); + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() .enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); @Autowired @@ -116,7 +120,7 @@ public KeycloakImport readFromPath(String path) { } private KeycloakImport readRealmImportsFromResource(Collection importResources) { - Map realmImports = importResources.stream() + Map> realmImports = importResources.stream() // https://stackoverflow.com/a/52130074/8087167 .collect(Collectors.toMap( File::getAbsolutePath, @@ -130,35 +134,49 @@ private KeycloakImport readRealmImportsFromResource(Collection importResou } public KeycloakImport readRealmImportFromFile(File importFile) { - Map realmImports = new HashMap<>(); + Map> realmImports = new HashMap<>(); - RealmImport realmImport = readRealmImport(importFile); + List realmImport = readRealmImport(importFile); realmImports.put(importFile.getAbsolutePath(), realmImport); return new KeycloakImport(realmImports); } - private RealmImport readRealmImport(File importFile) { + private List readRealmImport(File importFile) { + String importConfig; + + try { + importConfig = FileUtils.readFileToString(importFile, StandardCharsets.UTF_8); + } catch (IOException e) { + throw new InvalidImportException(e); + } + + if (importConfigProperties.isVarSubstitution()) { + importConfig = interpolator.replace(importConfig); + } + + String checksum = ChecksumUtil.checksum(importConfig.getBytes(StandardCharsets.UTF_8)); + ImportConfigProperties.ImportFileType fileType = importConfigProperties.getFileType(); - ObjectMapper objectMapper; + JsonFactory factory; switch (fileType) { case YAML: - objectMapper = OBJECT_MAPPER_YAML; + factory = YAML_FACTORY; break; case JSON: - objectMapper = OBJECT_MAPPER_JSON; + factory = JSON_FACTORY; break; case AUTO: String fileExt = FilenameUtils.getExtension(importFile.getName()); switch (fileExt) { case "yaml": case "yml": - objectMapper = OBJECT_MAPPER_YAML; + factory = YAML_FACTORY; break; case "json": - objectMapper = OBJECT_MAPPER_JSON; + factory = JSON_FACTORY; break; default: throw new InvalidImportException("Unknown file extension: " + fileExt); @@ -167,25 +185,16 @@ private RealmImport readRealmImport(File importFile) { default: throw new InvalidImportException("Unknown import file type: " + fileType); } - String importConfig; try { - importConfig = FileUtils.readFileToString(importFile, StandardCharsets.UTF_8); - } catch (IOException e) { - throw new InvalidImportException(e); - } + factory.setCodec(OBJECT_MAPPER); + JsonParser parser = factory.createParser(importConfig); + List realmImports = OBJECT_MAPPER.readValues(parser, new TypeReference() { + }).readAll(); - if (importConfigProperties.isVarSubstitution()) { - importConfig = interpolator.replace(importConfig); - } - - String checksum = ChecksumUtil.checksum(importConfig.getBytes(StandardCharsets.UTF_8)); - - try { - RealmImport realmImport = objectMapper.readValue(importConfig, RealmImport.class); - realmImport.setChecksum(checksum); + realmImports.forEach(realmImport -> realmImport.setChecksum(checksum)); - return realmImport; + return realmImports; } catch (IOException e) { throw new InvalidImportException(e); } diff --git a/src/test/java/de/adorsys/keycloak/config/AbstractImportTest.java b/src/test/java/de/adorsys/keycloak/config/AbstractImportTest.java index 06f239b27..3d318151a 100644 --- a/src/test/java/de/adorsys/keycloak/config/AbstractImportTest.java +++ b/src/test/java/de/adorsys/keycloak/config/AbstractImportTest.java @@ -48,6 +48,7 @@ import java.io.File; import java.io.IOException; import java.time.Duration; +import java.util.List; import static java.util.concurrent.TimeUnit.SECONDS; @@ -128,12 +129,18 @@ public void doImport(String fileName) throws IOException { } public void doImport(String fileName, RealmImportService _realmImportService) throws IOException { - RealmImport realmImport = getImport(fileName); + List realmImports = getImport(fileName); - _realmImportService.doImport(realmImport); + for (RealmImport realmImport : realmImports) { + _realmImportService.doImport(realmImport); + } + } + + public RealmImport getFirstImport(String fileName) throws IOException { + return getImport(fileName).get(0); } - public RealmImport getImport(String fileName) throws IOException { + public List getImport(String fileName) throws IOException { File realmImportFile = new ClassPathResource(this.resourcePath + '/' + fileName).getFile(); return keycloakImportProvider diff --git a/src/test/java/de/adorsys/keycloak/config/mock/CookieMockIT.java b/src/test/java/de/adorsys/keycloak/config/mock/CookieMockIT.java index 3d3aee30f..b8dc203ff 100644 --- a/src/test/java/de/adorsys/keycloak/config/mock/CookieMockIT.java +++ b/src/test/java/de/adorsys/keycloak/config/mock/CookieMockIT.java @@ -43,6 +43,7 @@ import java.io.File; import java.io.IOException; +import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; @@ -90,12 +91,14 @@ void run() throws Exception { return KeycloakMock.serverInfo(request); }); - RealmImport realmImport = getRealmImport("import-files/simple-realm/00_create_simple-realm.json"); - realmImportService.doImport(realmImport); + List realmImports = getRealmImport("import-files/simple-realm/00_create_simple-realm.json"); + for (RealmImport realmImport : realmImports) { + realmImportService.doImport(realmImport); + } } @SuppressWarnings("SameParameterValue") - private RealmImport getRealmImport(String file) throws IOException { + private List getRealmImport(String file) throws IOException { File realmImportFile = new ClassPathResource(file).getFile(); return keycloakImportProvider diff --git a/src/test/java/de/adorsys/keycloak/config/service/ImportAuthenticationFlowsIT.java b/src/test/java/de/adorsys/keycloak/config/service/ImportAuthenticationFlowsIT.java index 3b34ded1a..c1a2fb9c4 100644 --- a/src/test/java/de/adorsys/keycloak/config/service/ImportAuthenticationFlowsIT.java +++ b/src/test/java/de/adorsys/keycloak/config/service/ImportAuthenticationFlowsIT.java @@ -225,7 +225,7 @@ void shouldAddFlowWithExecutionFlow() throws IOException { @Test @Order(5) void shouldFailWhenTryAddFlowWithDefectiveExecutionFlow() throws IOException { - RealmImport foundImport = getImport("05_try_to_update_realm__add_flow_with_defective_execution_flow.json"); + RealmImport foundImport = getFirstImport("05_try_to_update_realm__add_flow_with_defective_execution_flow.json"); InvalidImportException thrown = assertThrows(InvalidImportException.class, () -> realmImportService.doImport(foundImport)); @@ -281,7 +281,7 @@ void shouldChangeFlowRequirementWithExecutionFlow() throws IOException { @Test @Order(7) void shouldFailWhenTryToUpdateDefectiveFlowRequirementWithExecutionFlow() throws IOException { - RealmImport foundImport = getImport("06_try_to_update_realm__change_requirement_in_defective_flow_with_execution_flow.json"); + RealmImport foundImport = getFirstImport("06_try_to_update_realm__change_requirement_in_defective_flow_with_execution_flow.json"); InvalidImportException thrown = assertThrows(InvalidImportException.class, () -> realmImportService.doImport(foundImport)); @@ -291,7 +291,7 @@ void shouldFailWhenTryToUpdateDefectiveFlowRequirementWithExecutionFlow() throws @Test @Order(8) void shouldFailWhenTryToUpdateFlowRequirementWithExecutionFlowWithNotExistingExecution() throws IOException { - RealmImport foundImport = getImport("07_try_to_update_realm__change_requirement_flow_with_execution_flow_with_not_existing_execution.json"); + RealmImport foundImport = getFirstImport("07_try_to_update_realm__change_requirement_flow_with_execution_flow_with_not_existing_execution.json"); ImportProcessingException thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport)); @@ -301,7 +301,7 @@ void shouldFailWhenTryToUpdateFlowRequirementWithExecutionFlowWithNotExistingExe @Test @Order(9) void shouldFailWhenTryToUpdateFlowRequirementWithExecutionFlowWithDefectiveExecution() throws IOException { - RealmImport foundImport = getImport("08_try_to_update_realm__change_requirement_flow_with_execution_flow_with_defective_execution.json"); + RealmImport foundImport = getFirstImport("08_try_to_update_realm__change_requirement_flow_with_execution_flow_with_defective_execution.json"); ImportProcessingException thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport)); @@ -311,7 +311,7 @@ void shouldFailWhenTryToUpdateFlowRequirementWithExecutionFlowWithDefectiveExecu @Test @Order(10) void shouldFailWhenTryToUpdateFlowRequirementWithDefectiveExecutionFlow() throws IOException { - RealmImport foundImport = getImport("09_try_to_update_realm__change_requirement_flow_with_defective_execution_flow.json"); + RealmImport foundImport = getFirstImport("09_try_to_update_realm__change_requirement_flow_with_defective_execution_flow.json"); ImportProcessingException thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport)); @@ -638,7 +638,7 @@ void shouldUpdateSubFlowWithPseudoId() throws IOException { @Order(27) @DisabledIfSystemProperty(named = "keycloak.dockerImage", matches = ".*/keycloak-x") void shouldNotUpdateSubFlowWithPseudoId() throws IOException { - RealmImport foundImport = getImport("27_update_realm__try-to-update-non-top-level-flow-with-pseudo-id.json"); + RealmImport foundImport = getFirstImport("27_update_realm__try-to-update-non-top-level-flow-with-pseudo-id.json"); ImportProcessingException thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport)); @@ -669,7 +669,7 @@ void shouldUpdateSubFlowWithPseudoIdAndReUseTempFlow() throws IOException { @Order(29) @DisabledIfSystemProperty(named = "keycloak.dockerImage", matches = ".*/keycloak-x") void shouldNotUpdateInvalidTopLevelFlow() throws IOException { - RealmImport foundImport = getImport("29_update_realm__try-to-update-invalid-top-level-flow.json"); + RealmImport foundImport = getFirstImport("29_update_realm__try-to-update-invalid-top-level-flow.json"); ImportProcessingException thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport)); @@ -792,7 +792,7 @@ void shouldUpdateMultipleExecutionsWithSameAuthenticatorWithConfig() throws IOEx @Test @Order(40) void shouldFailWhenTryingToUpdateBuiltInFlow() throws IOException { - RealmImport foundImport = getImport("40_update_realm__try-to-update-built-in-flow.json"); + RealmImport foundImport = getFirstImport("40_update_realm__try-to-update-built-in-flow.json"); InvalidImportException thrown = assertThrows(InvalidImportException.class, () -> realmImportService.doImport(foundImport)); @@ -802,7 +802,7 @@ void shouldFailWhenTryingToUpdateBuiltInFlow() throws IOException { @Test @Order(41) void shouldFailWhenTryingToUpdateWithNonExistingFlow() throws IOException { - RealmImport foundImport = getImport("41_update_realm__try-to-update-with-non-existing-flow.json"); + RealmImport foundImport = getFirstImport("41_update_realm__try-to-update-with-non-existing-flow.json"); ImportProcessingException thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport)); @@ -857,7 +857,7 @@ void shouldUpdateSubBuiltinFLow() throws IOException { @Test @Order(44) void shouldNotUpdateFlowWithBuiltInFalse() throws IOException { - RealmImport foundImport = getImport("44_update_realm__try-to-update-flow-set-builtin-false.json"); + RealmImport foundImport = getFirstImport("44_update_realm__try-to-update-flow-set-builtin-false.json"); InvalidImportException thrown = assertThrows(InvalidImportException.class, () -> realmImportService.doImport(foundImport)); @@ -867,7 +867,7 @@ void shouldNotUpdateFlowWithBuiltInFalse() throws IOException { @Test @Order(45) void shouldNotUpdateFlowWithBuiltInTrue() throws IOException { - RealmImport foundImport = getImport("45_update_realm__try-to-update-flow-set-builtin-true.json"); + RealmImport foundImport = getFirstImport("45_update_realm__try-to-update-flow-set-builtin-true.json"); InvalidImportException thrown = assertThrows(InvalidImportException.class, () -> realmImportService.doImport(foundImport)); @@ -877,7 +877,7 @@ void shouldNotUpdateFlowWithBuiltInTrue() throws IOException { @Test @Order(46) void shouldNotCreateBuiltInFlow() throws IOException { - RealmImport foundImport = getImport("46_update_realm__try-to-create-builtin-flow.json"); + RealmImport foundImport = getFirstImport("46_update_realm__try-to-create-builtin-flow.json"); if (VersionUtil.ge(KEYCLOAK_VERSION, "11")) { ImportProcessingException thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport)); @@ -1128,7 +1128,7 @@ void shouldChangeFirstBrokerLoginFlowForIdentityProvider() throws IOException { @Test @Order(64) void shouldNotUpdateFlowWithAuthenticatorOnBasicFlow() throws IOException { - RealmImport foundImport = getImport("63_update-realm__try-to-set-authenticator-basic-flow.json"); + RealmImport foundImport = getFirstImport("63_update-realm__try-to-set-authenticator-basic-flow.json"); InvalidImportException thrown = assertThrows(InvalidImportException.class, () -> realmImportService.doImport(foundImport)); diff --git a/src/test/java/de/adorsys/keycloak/config/service/ImportAuthenticatorConfigIT.java b/src/test/java/de/adorsys/keycloak/config/service/ImportAuthenticatorConfigIT.java index 7707f3dfc..d5e99a65f 100644 --- a/src/test/java/de/adorsys/keycloak/config/service/ImportAuthenticatorConfigIT.java +++ b/src/test/java/de/adorsys/keycloak/config/service/ImportAuthenticatorConfigIT.java @@ -197,7 +197,7 @@ void shouldUpdateRealmDeleteFlowAuthConfigInsideBuiltinSubFlow() throws IOExcept @Test @Order(9) void shouldThrowInvalidAuthConfig() throws IOException { - RealmImport foundImport = getImport("9_update_realm__invalid_auth_config.json"); + RealmImport foundImport = getFirstImport("9_update_realm__invalid_auth_config.json"); ImportProcessingException thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport)); diff --git a/src/test/java/de/adorsys/keycloak/config/service/ImportClientScopesIT.java b/src/test/java/de/adorsys/keycloak/config/service/ImportClientScopesIT.java index a9823ce68..2de4de7e3 100644 --- a/src/test/java/de/adorsys/keycloak/config/service/ImportClientScopesIT.java +++ b/src/test/java/de/adorsys/keycloak/config/service/ImportClientScopesIT.java @@ -215,7 +215,7 @@ void shouldChangeClientScopeWithReplaceProtocolMapper() throws IOException { @Test @Order(6) void shouldNotUpdateRealmUpdateScopeMappingsWithError() throws IOException { - RealmImport foundImport = getImport("06_update_realm__try-to-change_clientScope_invalid_protocolMapper.json"); + RealmImport foundImport = getFirstImport("06_update_realm__try-to-change_clientScope_invalid_protocolMapper.json"); ImportProcessingException thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport)); diff --git a/src/test/java/de/adorsys/keycloak/config/service/ImportClientsIT.java b/src/test/java/de/adorsys/keycloak/config/service/ImportClientsIT.java index dcc23c741..404f5256c 100644 --- a/src/test/java/de/adorsys/keycloak/config/service/ImportClientsIT.java +++ b/src/test/java/de/adorsys/keycloak/config/service/ImportClientsIT.java @@ -414,7 +414,7 @@ void shouldUpdateRealmIgnoreProtocolMapper() throws IOException { @Test @Order(7) void shouldNotUpdateRealmUpdateScopeMappingsWithError() throws IOException { - RealmImport foundImport = getImport("07_update_realm__try-to-update_protocol-mapper.json"); + RealmImport foundImport = getFirstImport("07_update_realm__try-to-update_protocol-mapper.json"); if (VersionUtil.lt(KEYCLOAK_VERSION, "11")) { ImportProcessingException thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport)); @@ -511,28 +511,28 @@ void shouldUpdateRealmDeleteAllProtocolMapper() throws IOException { void shouldUpdateRealmRaiseErrorAddAuthorizationInvalidClient() throws IOException { ImportProcessingException thrown; - RealmImport foundImport0 = getImport("10.0_update_realm__raise_error_add_authorization_client_bearer_only.json"); + RealmImport foundImport0 = getFirstImport("10.0_update_realm__raise_error_add_authorization_client_bearer_only.json"); thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport0)); assertThat(thrown.getMessage(), is("Unsupported authorization settings for client 'auth-moped-client' in realm 'realmWithClients': client must be confidential.")); - RealmImport foundImport1 = getImport("10.1_update_realm__raise_error_add_authorization_client_public.json"); + RealmImport foundImport1 = getFirstImport("10.1_update_realm__raise_error_add_authorization_client_public.json"); thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport1)); assertThat(thrown.getMessage(), is("Unsupported authorization settings for client 'auth-moped-client' in realm 'realmWithClients': client must be confidential.")); - RealmImport foundImport2 = getImport("10.2_update_realm__raise_error_add_authorization_without_service_account_enabled.json"); + RealmImport foundImport2 = getFirstImport("10.2_update_realm__raise_error_add_authorization_without_service_account_enabled.json"); thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport2)); assertThat(thrown.getMessage(), is("Unsupported authorization settings for client 'auth-moped-client' in realm 'realmWithClients': serviceAccountsEnabled must be 'true'.")); - RealmImport foundImport3 = getImport("10.3_update_realm__raise_error_update_authorization_client_bearer_only.json"); + RealmImport foundImport3 = getFirstImport("10.3_update_realm__raise_error_update_authorization_client_bearer_only.json"); thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport3)); assertThat(thrown.getMessage(), is("Unsupported authorization settings for client 'realm-management' in realm 'realmWithClients': client must be confidential.")); doImport("10.4.1_update_realm__raise_error_update_authorization_client_public.json"); - RealmImport foundImport4 = getImport("10.4.2_update_realm__raise_error_update_authorization_client_public.json"); + RealmImport foundImport4 = getFirstImport("10.4.2_update_realm__raise_error_update_authorization_client_public.json"); thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport4)); assertThat(thrown.getMessage(), is("Unsupported authorization settings for client 'realm-management' in realm 'realmWithClients': client must be confidential.")); - RealmImport foundImport5 = getImport("10.5_update_realm__raise_error_update_authorization_without_service_account_enabled.json"); + RealmImport foundImport5 = getFirstImport("10.5_update_realm__raise_error_update_authorization_without_service_account_enabled.json"); thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport5)); assertThat(thrown.getMessage(), is("Unsupported authorization settings for client 'realm-management' in realm 'realmWithClients': serviceAccountsEnabled must be 'true'.")); } @@ -1119,7 +1119,7 @@ void shouldUpdateAuthenticationFlowBindingOverridesIdWhenFlowChanged() throws IO @Test @Order(18) void shouldntUpdateWithAnInvalidAuthenticationFlowBindingOverrides() throws IOException { - RealmImport foundImport = getImport("18_cannot_update_realm__with_invalid_auth-flow-overrides.json"); + RealmImport foundImport = getFirstImport("18_cannot_update_realm__with_invalid_auth-flow-overrides.json"); KeycloakRepositoryException thrown = assertThrows(KeycloakRepositoryException.class, () -> realmImportService.doImport(foundImport)); assertThat(thrown.getMessage(), is("Cannot find top-level-flow 'bad value' in realm 'realmWithClients'.")); @@ -1548,7 +1548,7 @@ void shouldSetAuthenticationFlowBindingOverridesByIds() throws IOException { @Test @Order(90) void shouldNotUpdateRealmCreateClientWithError_And_ReamStateSurvivesAttributesUpdate() throws IOException { - RealmImport foundImport = getImport("90_update_realm__try-to-create-client.json"); + RealmImport foundImport = getFirstImport("90_update_realm__try-to-create-client.json"); // Given the state of the realm already exists assertThat(getRealmState(foundImport.getRealm()), not(anEmptyMap())); @@ -1568,7 +1568,7 @@ void shouldNotUpdateRealmCreateClientWithError_And_ReamStateSurvivesAttributesUp @Order(91) void shouldNotUpdateRealmUpdateClientWithError() throws IOException { doImport("91.0_update_realm__try-to-update-client.json"); - RealmImport foundImport = getImport("91.1_update_realm__try-to-update-client.json"); + RealmImport foundImport = getFirstImport("91.1_update_realm__try-to-update-client.json"); ImportProcessingException thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport)); @@ -1578,7 +1578,7 @@ void shouldNotUpdateRealmUpdateClientWithError() throws IOException { @Test @Order(92) void shouldNotUpdateRealmInvalidClient() throws IOException { - RealmImport foundImport = getImport("92_update_realm__invalid-client.json"); + RealmImport foundImport = getFirstImport("92_update_realm__invalid-client.json"); ImportProcessingException thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport)); diff --git a/src/test/java/de/adorsys/keycloak/config/service/ImportComponentsIT.java b/src/test/java/de/adorsys/keycloak/config/service/ImportComponentsIT.java index bae025dcd..f525fb38f 100644 --- a/src/test/java/de/adorsys/keycloak/config/service/ImportComponentsIT.java +++ b/src/test/java/de/adorsys/keycloak/config/service/ImportComponentsIT.java @@ -698,7 +698,7 @@ void shouldUpdateComponentRemoveAllSubComponent() throws IOException { @Test @Order(12) void shouldNotCreateComponents() throws IOException { - RealmImport foundImport = getImport("12_update_realm__try-to-create-component.json"); + RealmImport foundImport = getFirstImport("12_update_realm__try-to-create-component.json"); ImportProcessingException thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport)); diff --git a/src/test/java/de/adorsys/keycloak/config/service/ImportDefaultGroupsIT.java b/src/test/java/de/adorsys/keycloak/config/service/ImportDefaultGroupsIT.java index 083c39e0d..b35d78dbb 100644 --- a/src/test/java/de/adorsys/keycloak/config/service/ImportDefaultGroupsIT.java +++ b/src/test/java/de/adorsys/keycloak/config/service/ImportDefaultGroupsIT.java @@ -82,7 +82,7 @@ void shouldUpdateRealmAddDefaultSubGroup() throws IOException { @Test @Order(96) void shouldUpdateRealmAddNonExistSubGroup() throws IOException { - RealmImport foundImport = getImport("96_update_realm_add_non_exists_default_subgroup.json"); + RealmImport foundImport = getFirstImport("96_update_realm_add_non_exists_default_subgroup.json"); InvalidImportException thrown = assertThrows(InvalidImportException.class, () -> realmImportService.doImport(foundImport)); diff --git a/src/test/java/de/adorsys/keycloak/config/service/ImportRealmFileTypeIT.java b/src/test/java/de/adorsys/keycloak/config/service/ImportRealmFileTypeIT.java index 5c1cd8788..821495c45 100644 --- a/src/test/java/de/adorsys/keycloak/config/service/ImportRealmFileTypeIT.java +++ b/src/test/java/de/adorsys/keycloak/config/service/ImportRealmFileTypeIT.java @@ -46,11 +46,26 @@ void shouldCreateRealm() throws IOException { doImport("0_create_realm.yaml"); doImport("1_update_realm.json"); - RealmRepresentation createdRealm = keycloakProvider.getInstance().realm(REALM_NAME).toRepresentation(); + RealmRepresentation realm = keycloakProvider.getInstance().realm(REALM_NAME).toRepresentation(); - assertThat(createdRealm.getRealm(), is(REALM_NAME)); - assertThat(createdRealm.isEnabled(), is(true)); - assertThat(createdRealm.getLoginTheme(), is("moped")); + assertThat(realm.getRealm(), is(REALM_NAME)); + assertThat(realm.isEnabled(), is(true)); + assertThat(realm.getLoginTheme(), is("moped")); + } + + @Test + @Order(1) + void shouldCreateMultipleRealm() throws IOException { + doImport("2_multi_document.yaml"); + + for (int i = 0; i < 5; i++) { + String realmName = REALM_NAME + "-" + i; + + RealmRepresentation realm = keycloakProvider.getInstance().realm(realmName).toRepresentation(); + + assertThat(realm.getRealm(), is(realmName)); + assertThat(realm.isEnabled(), is(true)); + } } } @@ -97,12 +112,12 @@ void shouldCreateRealm() throws IOException { doImport("1_update_realm.yml"); doImport("2_update_realm.json"); - RealmRepresentation createdRealm = keycloakProvider.getInstance().realm(REALM_NAME).toRepresentation(); + RealmRepresentation realm = keycloakProvider.getInstance().realm(REALM_NAME).toRepresentation(); - assertThat(createdRealm.getRealm(), is(REALM_NAME)); - assertThat(createdRealm.isEnabled(), is(true)); - assertThat(createdRealm.getLoginTheme(), is("moped")); - assertThat(createdRealm.getDisplayName(), is("Realm YAML")); + assertThat(realm.getRealm(), is(REALM_NAME)); + assertThat(realm.isEnabled(), is(true)); + assertThat(realm.getLoginTheme(), is("moped")); + assertThat(realm.getDisplayName(), is("Realm YAML")); } } @@ -122,10 +137,10 @@ void shouldCreateRealm() throws IOException { doImport("0_create_realm.json"); doImport("1_update_realm.yml"); - RealmRepresentation createdRealm = keycloakProvider.getInstance().realm(REALM_NAME).toRepresentation(); + RealmRepresentation realm = keycloakProvider.getInstance().realm(REALM_NAME).toRepresentation(); - assertThat(createdRealm.getRealm(), is(REALM_NAME)); - assertThat(createdRealm.isEnabled(), is(true)); - assertThat(createdRealm.getLoginTheme(), is("moped")); + assertThat(realm.getRealm(), is(REALM_NAME)); + assertThat(realm.isEnabled(), is(true)); + assertThat(realm.getLoginTheme(), is("moped")); } } diff --git a/src/test/java/de/adorsys/keycloak/config/service/ImportRequiredActionsIT.java b/src/test/java/de/adorsys/keycloak/config/service/ImportRequiredActionsIT.java index b4a80a773..3de1813ed 100644 --- a/src/test/java/de/adorsys/keycloak/config/service/ImportRequiredActionsIT.java +++ b/src/test/java/de/adorsys/keycloak/config/service/ImportRequiredActionsIT.java @@ -64,7 +64,7 @@ void shouldCreateRealmWithRequiredActions() throws IOException { @Test @Order(1) void shouldFailIfAddingInvalidRequiredActionName() throws IOException { - RealmImport foundImport = getImport("01_update_realm__try_adding_invalid_required-action.json"); + RealmImport foundImport = getFirstImport("01_update_realm__try_adding_invalid_required-action.json"); realmImportService.doImport(foundImport); diff --git a/src/test/java/de/adorsys/keycloak/config/service/ImportRolesIT.java b/src/test/java/de/adorsys/keycloak/config/service/ImportRolesIT.java index f76162b9d..c914ec83d 100644 --- a/src/test/java/de/adorsys/keycloak/config/service/ImportRolesIT.java +++ b/src/test/java/de/adorsys/keycloak/config/service/ImportRolesIT.java @@ -465,7 +465,7 @@ void shouldAddCompositeClientToRealmRole() throws IOException { assertThat(composites.getClient(), hasEntry(is("moped-client"), containsInAnyOrder("my_client_role", "my_other_client_role"))); assertThat(composites.getClient(), hasEntry(is("second-moped-client"), containsInAnyOrder("my_other_second_client_role", "my_second_client_role"))); - RealmImport foundImport = getImport("15.2_update_realm__add_non_existing_composite_client_to_realm_role.json"); + RealmImport foundImport = getFirstImport("15.2_update_realm__add_non_existing_composite_client_to_realm_role.json"); KeycloakRepositoryException thrown = assertThrows(KeycloakRepositoryException.class, () -> realmImportService.doImport(foundImport)); assertThat(thrown.getMessage(), is("Error adding composite roles to realm role 'my_composite_client_role': Cannot find client role 'non_exists' within realm 'realmWithRoles'")); } @@ -582,7 +582,7 @@ void shouldAddClientRoleCompositeToClientRole() throws IOException { assertThat(composites.getClient(), hasEntry(is("moped-client"), containsInAnyOrder("my_client_role", "my_other_client_role"))); - RealmImport foundImport = getImport("19.2_update_realm__add_non_existing_client_role_composite_to_client_role.json"); + RealmImport foundImport = getFirstImport("19.2_update_realm__add_non_existing_client_role_composite_to_client_role.json"); KeycloakRepositoryException thrown = assertThrows(KeycloakRepositoryException.class, () -> realmImportService.doImport(foundImport)); assertThat(thrown.getMessage(), is("Error adding composite roles to client role 'my_other_composite_moped_client_role': Cannot find client role 'non_exists' within realm 'realmWithRoles'")); } @@ -843,7 +843,7 @@ void shouldCreateRolesWithAttributes() throws IOException { @Test @Order(28) void shouldThrowUpdateRealmAddReferNonExistClientRole() throws IOException { - RealmImport foundImport = getImport("28_try-to_update_realm__refer-non-exist-role.json"); + RealmImport foundImport = getFirstImport("28_try-to_update_realm__refer-non-exist-role.json"); KeycloakRepositoryException thrown = assertThrows(KeycloakRepositoryException.class, () -> realmImportService.doImport(foundImport)); @@ -853,7 +853,7 @@ void shouldThrowUpdateRealmAddReferNonExistClientRole() throws IOException { @Test @Order(29) void shouldThrowUpdateRealmAddClientRoleWithoutClient() throws IOException { - RealmImport foundImport = getImport("29_try-to_update_realm__add-client-role-without-client.json"); + RealmImport foundImport = getFirstImport("29_try-to_update_realm__add-client-role-without-client.json"); ImportProcessingException thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport)); @@ -864,7 +864,7 @@ void shouldThrowUpdateRealmAddClientRoleWithoutClient() throws IOException { @Order(30) @SuppressWarnings("deprecation") void shouldNotThrowImportingClientRoleThatAlreadyExists() throws IOException { - RealmImport foundImport = getImport("30_import_realm_with_duplicated_client_role.json"); + RealmImport foundImport = getFirstImport("30_import_realm_with_duplicated_client_role.json"); assertThat( foundImport diff --git a/src/test/java/de/adorsys/keycloak/config/service/ImportScopeMappingsIT.java b/src/test/java/de/adorsys/keycloak/config/service/ImportScopeMappingsIT.java index e13c0db9b..490ec2e30 100644 --- a/src/test/java/de/adorsys/keycloak/config/service/ImportScopeMappingsIT.java +++ b/src/test/java/de/adorsys/keycloak/config/service/ImportScopeMappingsIT.java @@ -320,7 +320,7 @@ void shouldUpdateRealmByAddingRolesForClient() throws IOException { @Test @Order(10) void shouldThrowOnUpdateRealmNonExistClientScope() throws IOException { - RealmImport foundImport = getImport("10_1_update-realm__throw-invalid-client-scope.json"); + RealmImport foundImport = getFirstImport("10_1_update-realm__throw-invalid-client-scope.json"); KeycloakRepositoryException thrown = assertThrows(KeycloakRepositoryException.class, () -> realmImportService.doImport(foundImport)); @@ -330,7 +330,7 @@ void shouldThrowOnUpdateRealmNonExistClientScope() throws IOException { @Test @Order(11) void shouldThrowOnUpdateRealmClientScopeWithNonExistRoles() throws IOException { - RealmImport foundImport = getImport("10_2_update-realm__throw-invalid-client-scope-role.json"); + RealmImport foundImport = getFirstImport("10_2_update-realm__throw-invalid-client-scope-role.json"); KeycloakRepositoryException thrown = assertThrows(KeycloakRepositoryException.class, () -> realmImportService.doImport(foundImport)); @@ -340,7 +340,7 @@ void shouldThrowOnUpdateRealmClientScopeWithNonExistRoles() throws IOException { @Test @Order(12) void shouldThrowOnUpdateRealmNonExistClient() throws IOException { - RealmImport foundImport = getImport("10_3_update-realm__throw-invalid-client.json"); + RealmImport foundImport = getFirstImport("10_3_update-realm__throw-invalid-client.json"); KeycloakRepositoryException thrown = assertThrows(KeycloakRepositoryException.class, () -> realmImportService.doImport(foundImport)); @@ -350,7 +350,7 @@ void shouldThrowOnUpdateRealmNonExistClient() throws IOException { @Test @Order(13) void shouldThrowOnUpdateRealmClientWithNonExistRoles() throws IOException { - RealmImport foundImport = getImport("10_4_update-realm__throw-invalid-client-role.json"); + RealmImport foundImport = getFirstImport("10_4_update-realm__throw-invalid-client-role.json"); KeycloakRepositoryException thrown = assertThrows(KeycloakRepositoryException.class, () -> realmImportService.doImport(foundImport)); diff --git a/src/test/java/de/adorsys/keycloak/config/service/ImportUsersIT.java b/src/test/java/de/adorsys/keycloak/config/service/ImportUsersIT.java index 7b1be3024..36b7f0717 100644 --- a/src/test/java/de/adorsys/keycloak/config/service/ImportUsersIT.java +++ b/src/test/java/de/adorsys/keycloak/config/service/ImportUsersIT.java @@ -27,14 +27,15 @@ import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.keycloak.admin.client.resource.RealmResource; -import org.keycloak.admin.client.resource.UserResource; import org.keycloak.representations.AccessTokenResponse; -import org.keycloak.representations.idm.*; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.GroupRepresentation; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.representations.idm.UserRepresentation; import java.io.IOException; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; @@ -332,7 +333,7 @@ void shouldUpdateRealmAndNotRemoveUsers() throws IOException { @Test @Order(7) void shouldNotUpdateRealmUserWithNonExistsRole() throws IOException { - RealmImport foundImport = getImport("07_update_realm_try_to_create_user_invalid_role.json"); + RealmImport foundImport = getFirstImport("07_update_realm_try_to_create_user_invalid_role.json"); ImportProcessingException thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport)); @@ -342,7 +343,7 @@ void shouldNotUpdateRealmUserWithNonExistsRole() throws IOException { @Test @Order(8) void shouldNotUpdateRealmUserWithNonExistsGroup() throws IOException { - RealmImport foundImport = getImport("08_update_realm_try_to_create_user_invalid_group.json"); + RealmImport foundImport = getFirstImport("08_update_realm_try_to_create_user_invalid_group.json"); ImportProcessingException thrown = assertThrows(ImportProcessingException.class, () -> realmImportService.doImport(foundImport)); diff --git a/src/test/resources/import-files/realm-file-type/auto/2_multi_document.yaml b/src/test/resources/import-files/realm-file-type/auto/2_multi_document.yaml new file mode 100644 index 000000000..15253ea9d --- /dev/null +++ b/src/test/resources/import-files/realm-file-type/auto/2_multi_document.yaml @@ -0,0 +1,17 @@ +enabled: true +realm: realm-file-type-auto-0 +--- +enabled: true +realm: realm-file-type-auto-1 +--- +enabled: true +realm: realm-file-type-auto-2 +--- +enabled: true +realm: realm-file-type-auto-3 +--- +enabled: true +realm: realm-file-type-auto-4 +--- +enabled: true +realm: realm-file-type-auto-5