diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e0cacd7f..eb63e78d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,13 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] + +## Fixed +- otpPolicyAlgorithm ignored during import [#847](https://github.com/adorsys/keycloak-config-cli/issues/847) + ### Added -- Added Navigation in the readme [#1010](https://github.com/adorsys/keycloak-config-cli/issues/1010) +- Added Navigation in the readme [#1099](https://github.com/adorsys/keycloak-config-cli/issues/1099) ### Added - improved logging for realm retrieval errors [#1010](https://github.com/adorsys/keycloak-config-cli/issues/1010) ### Fixed - Fix required action import handling for no-delete option [#834](https://github.com/adorsys/keycloak-config-cli/issues/834) + ### Fixed - Allow environment variables from existing secrets [#822](https://github.com/adorsys/keycloak-config-cli/issues/822) ### Fixed diff --git a/src/main/java/de/adorsys/keycloak/config/repository/OtpPolicyRepository.java b/src/main/java/de/adorsys/keycloak/config/repository/OtpPolicyRepository.java new file mode 100644 index 000000000..def03b1ec --- /dev/null +++ b/src/main/java/de/adorsys/keycloak/config/repository/OtpPolicyRepository.java @@ -0,0 +1,44 @@ +/*- + * ---license-start + * keycloak-config-cli + * --- + * Copyright (C) 2017 - 2021 adorsys GmbH & Co. KG @ https://adorsys.com + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ + +package de.adorsys.keycloak.config.repository; + +import org.keycloak.representations.idm.RealmRepresentation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class OtpPolicyRepository { + private final RealmRepository realmRepository; + + @Autowired + public OtpPolicyRepository(RealmRepository realmRepository) { + this.realmRepository = realmRepository; + } + + public void updateOtpPolicy(String realmName, RealmRepresentation newRealmRepresentation) { + RealmRepresentation existingRealm = realmRepository.get(realmName); + + existingRealm.setOtpPolicyAlgorithm(newRealmRepresentation.getOtpPolicyAlgorithm()); + + + realmRepository.update(existingRealm); + } +} diff --git a/src/main/java/de/adorsys/keycloak/config/service/OtpPolicyImportService.java b/src/main/java/de/adorsys/keycloak/config/service/OtpPolicyImportService.java new file mode 100644 index 000000000..20ba43f56 --- /dev/null +++ b/src/main/java/de/adorsys/keycloak/config/service/OtpPolicyImportService.java @@ -0,0 +1,42 @@ +/*- + * ---license-start + * keycloak-config-cli + * --- + * Copyright (C) 2017 - 2021 adorsys GmbH & Co. KG @ https://adorsys.com + * --- + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ---license-end + */ + +package de.adorsys.keycloak.config.service; + +import de.adorsys.keycloak.config.repository.OtpPolicyRepository; +import org.keycloak.representations.idm.RealmRepresentation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class OtpPolicyImportService { + private final OtpPolicyRepository otpPolicyRepository; + + @Autowired + public OtpPolicyImportService(OtpPolicyRepository otpPolicyRepository) { + this.otpPolicyRepository = otpPolicyRepository; + } + + public void updateOtpPolicy(String realmName, RealmRepresentation realmRepresentation) { + if (realmRepresentation.getOtpPolicyAlgorithm() != null) { + otpPolicyRepository.updateOtpPolicy(realmName, realmRepresentation); + } + } +} diff --git a/src/main/java/de/adorsys/keycloak/config/service/RealmImportService.java b/src/main/java/de/adorsys/keycloak/config/service/RealmImportService.java index 14b257063..c1af0878e 100644 --- a/src/main/java/de/adorsys/keycloak/config/service/RealmImportService.java +++ b/src/main/java/de/adorsys/keycloak/config/service/RealmImportService.java @@ -64,6 +64,7 @@ public class RealmImportService { private static final Logger logger = LoggerFactory.getLogger(RealmImportService.class); private final KeycloakProvider keycloakProvider; private final RealmRepository realmRepository; + private final OtpPolicyImportService otpPolicyImportService; private final UserImportService userImportService; private final UserProfileImportService userProfileImportService; @@ -112,6 +113,7 @@ public RealmImportService( ClientScopeMappingImportService clientScopeMappingImportService, IdentityProviderImportService identityProviderImportService, MessageBundleImportService messageBundleImportService, + OtpPolicyImportService otpPolicyImportService, ChecksumService checksumService, StateService stateService) { this.importProperties = importProperties; @@ -134,6 +136,7 @@ public RealmImportService( this.clientScopeMappingImportService = clientScopeMappingImportService; this.identityProviderImportService = identityProviderImportService; this.messageBundleImportService = messageBundleImportService; + this.otpPolicyImportService = otpPolicyImportService; this.checksumService = checksumService; this.stateService = stateService; } @@ -192,6 +195,8 @@ private void updateRealm(RealmImport realmImport) { if (existingRealm.getEventsExpiration() != null) { realm.setEventsExpiration(existingRealm.getEventsExpiration()); } + + otpPolicyImportService.updateOtpPolicy(realmImport.getRealm(), realm); stateService.loadState(realm); realmRepository.update(realm); @@ -199,7 +204,18 @@ private void updateRealm(RealmImport realmImport) { configureRealm(realmImport, realm); } + private void importOtpPolicy(RealmImport realmImport) { + RealmRepresentation realmConfig = realmRepository.get(realmImport.getRealm()); + if (realmConfig.getOtpPolicyAlgorithm() != null) { + otpPolicyImportService.updateOtpPolicy( + realmImport.getRealm(), + realmConfig + ); + } + } + private void configureRealm(RealmImport realmImport, RealmRepresentation existingRealm) { + importOtpPolicy(realmImport); clientScopeImportService.doImport(realmImport); clientScopeImportService.updateDefaultClientScopes(realmImport, existingRealm); clientPoliciesImportService.doImport(realmImport); @@ -214,6 +230,7 @@ private void configureRealm(RealmImport realmImport, RealmRepresentation existin authenticationFlowsImportService.doImport(realmImport); authenticatorConfigImportService.doImport(realmImport); clientImportService.doImportDependencies(realmImport); + clientScopeImportService.updateDefaultClientScopes(realmImport, existingRealm); identityProviderImportService.doImport(realmImport); clientAuthorizationImportService.doImport(realmImport); scopeMappingImportService.doImport(realmImport); diff --git a/src/test/java/de/adorsys/keycloak/config/service/ImportSimpleRealmIT.java b/src/test/java/de/adorsys/keycloak/config/service/ImportSimpleRealmIT.java index e04166b88..a495fd476 100644 --- a/src/test/java/de/adorsys/keycloak/config/service/ImportSimpleRealmIT.java +++ b/src/test/java/de/adorsys/keycloak/config/service/ImportSimpleRealmIT.java @@ -315,4 +315,15 @@ void shouldPreserveEventsExpirationWhenUpdatingRealm() throws Exception { realm = keycloakProvider.getInstance().realm(REALM_NAME).toRepresentation(); assertThat(realm.getEventsExpiration(), is(3600L)); } + @Test + @Order(84) + void shouldUpdateOtpPolicyAlgorithmWhenUpdatingRealm() throws Exception { + doImport("08.5_update_simple-realm_with_otp-policy-algorithm.json"); + RealmRepresentation realm = keycloakProvider.getInstance().realm("realmWithOtpPolicy").toRepresentation(); + assertThat(realm.getOtpPolicyAlgorithm(), is("HmacSHA1")); + + doImport("08.6_update_simple-realm_with_new_otp-policy-algorithm.json"); + realm = keycloakProvider.getInstance().realm("realmWithOtpPolicy").toRepresentation(); + assertThat(realm.getOtpPolicyAlgorithm(), is("HmacSHA512")); + } } diff --git a/src/test/resources/import-files/simple-realm/08.5_update_simple-realm_with_otp-policy-algorithm.json b/src/test/resources/import-files/simple-realm/08.5_update_simple-realm_with_otp-policy-algorithm.json new file mode 100644 index 000000000..4482c6c4b --- /dev/null +++ b/src/test/resources/import-files/simple-realm/08.5_update_simple-realm_with_otp-policy-algorithm.json @@ -0,0 +1,4 @@ +{ + "realm": "realmWithOtpPolicy", + "otpPolicyAlgorithm": "HmacSHA1" +} diff --git a/src/test/resources/import-files/simple-realm/08.6_update_simple-realm_with_new_otp-policy-algorithm.json b/src/test/resources/import-files/simple-realm/08.6_update_simple-realm_with_new_otp-policy-algorithm.json new file mode 100644 index 000000000..584aee9fc --- /dev/null +++ b/src/test/resources/import-files/simple-realm/08.6_update_simple-realm_with_new_otp-policy-algorithm.json @@ -0,0 +1,4 @@ +{ + "realm": "realmWithOtpPolicy", + "otpPolicyAlgorithm": "HmacSHA512" +}