From 115200d3ccd3ea79892a159ae80f9b475bc9492a Mon Sep 17 00:00:00 2001 From: Vlasta Ramik Date: Thu, 19 Oct 2023 09:00:49 +0200 Subject: [PATCH] Import migration step for kc22 Closes #24031 Co-authored-by: Alexander Schwartz (cherry picked from commit f6d582c761ccdf5931c915380ee57da821496ccc) --- .../JpaUpdate22_0_0_RemoveRhssoThemes.java | 7 ++- .../JpaUpdate22_0_5_UpdateAccountTheme.java | 41 ++++++++++++++ .../META-INF/jpa-changelog-22.0.0.xml | 14 ++++- .../migration/migrators/MigrateTo22_0_0.java | 34 +++++++++-- .../migration/AbstractMigrationTest.java | 5 +- .../JsonFileImport1903MigrationTest.java | 56 +++++++++++++++++++ .../migration-realm-19.0.3.json | 2 +- 7 files changed, 148 insertions(+), 11 deletions(-) create mode 100644 model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate22_0_5_UpdateAccountTheme.java create mode 100644 testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/JsonFileImport1903MigrationTest.java diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate22_0_0_RemoveRhssoThemes.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate22_0_0_RemoveRhssoThemes.java index 7acc290ec64..29c7a667b05 100644 --- a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate22_0_0_RemoveRhssoThemes.java +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate22_0_0_RemoveRhssoThemes.java @@ -43,10 +43,11 @@ public class JpaUpdate22_0_0_RemoveRhssoThemes extends CustomKeycloakTask { .addWhereParameter("rh-sso")); // remove account theme for realms statements.add(new UpdateStatement(null, null, database.correctObjectName("REALM", Table.class)) - .addNewColumnValue("ACCOUNT_THEME", null) - .setWhereClause("ACCOUNT_THEME=? OR ACCOUNT_THEME=?") + .addNewColumnValue("ACCOUNT_THEME", "keycloak.v2") + .setWhereClause("ACCOUNT_THEME=? OR ACCOUNT_THEME=? OR ACCOUNT_THEME=?") .addWhereParameter("rh-sso") - .addWhereParameter("rh-sso.v2")); + .addWhereParameter("rh-sso.v2") + .addWhereParameter("keycloak")); // remove login_theme for clients if ("oracle".equals(database.getShortName())) { statements.add(new DeleteStatement(null, null, database.correctObjectName("CLIENT_ATTRIBUTES", Table.class)) diff --git a/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate22_0_5_UpdateAccountTheme.java b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate22_0_5_UpdateAccountTheme.java new file mode 100644 index 00000000000..e12649cae96 --- /dev/null +++ b/model/jpa/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate22_0_5_UpdateAccountTheme.java @@ -0,0 +1,41 @@ +/* + * Copyright 2023 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * 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. + */ +package org.keycloak.connections.jpa.updater.liquibase.custom; + +import liquibase.exception.CustomChangeException; +import liquibase.statement.core.UpdateStatement; +import liquibase.structure.core.Table; + +/** + *

Migration class to update themes for those who had upgraded to 22.0.0 already.

+ */ +public class JpaUpdate22_0_5_UpdateAccountTheme extends CustomKeycloakTask { + + @Override + protected void generateStatementsImpl() throws CustomChangeException { + statements.add(new UpdateStatement(null, null, database.correctObjectName("REALM", Table.class)) + .addNewColumnValue("ACCOUNT_THEME", "keycloak.v2") + .setWhereClause("ACCOUNT_THEME=?") + .addWhereParameter("keycloak")); + } + + @Override + protected String getTaskId() { + return "Update account theme for keycloak 22.0.5"; + } + +} diff --git a/model/jpa/src/main/resources/META-INF/jpa-changelog-22.0.0.xml b/model/jpa/src/main/resources/META-INF/jpa-changelog-22.0.0.xml index 03bea59f914..2d89805278f 100644 --- a/model/jpa/src/main/resources/META-INF/jpa-changelog-22.0.0.xml +++ b/model/jpa/src/main/resources/META-INF/jpa-changelog-22.0.0.xml @@ -17,8 +17,20 @@ --> - + + + + + + + + + + + + + diff --git a/model/legacy-private/src/main/java/org/keycloak/migration/migrators/MigrateTo22_0_0.java b/model/legacy-private/src/main/java/org/keycloak/migration/migrators/MigrateTo22_0_0.java index 9935fdca1ac..1a96a87a725 100644 --- a/model/legacy-private/src/main/java/org/keycloak/migration/migrators/MigrateTo22_0_0.java +++ b/model/legacy-private/src/main/java/org/keycloak/migration/migrators/MigrateTo22_0_0.java @@ -41,16 +41,17 @@ public class MigrateTo22_0_0 implements Migration { @Override public void migrate(KeycloakSession session) { - session.realms().getRealmsStream().forEach((realm) -> { - removeHttpChallengeFlow(realm); - updateAccountTheme(realm); - }); + session.realms().getRealmsStream().forEach(this::removeHttpChallengeFlow); + //login, account, email themes are handled by JpaUpdate22_0_0_RemoveRhssoThemes } @Override public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) { removeHttpChallengeFlow(realm); + updateLoginTheme(realm); updateAccountTheme(realm); + updateEmailTheme(realm); + updateClientAttributes(realm); } private void removeHttpChallengeFlow(RealmModel realm) { @@ -69,11 +70,34 @@ public class MigrateTo22_0_0 implements Migration { private void updateAccountTheme(RealmModel realm) { String accountTheme = realm.getAccountTheme(); - if ("keycloak".equals(accountTheme) || "rh-sso".equals(accountTheme)) { + if ("keycloak".equals(accountTheme) || "rh-sso".equals(accountTheme) || "rh-sso.v2".equals(accountTheme)) { realm.setAccountTheme("keycloak.v2"); } } + private void updateEmailTheme(RealmModel realm) { + String emailTheme = realm.getEmailTheme(); + if ("rh-sso".equals(emailTheme)) { + realm.setEmailTheme(null); + } + } + + private void updateLoginTheme(RealmModel realm) { + String loginTheme = realm.getLoginTheme(); + if ("rh-sso".equals(loginTheme)) { + realm.setLoginTheme(null); + } + } + + private void updateClientAttributes(RealmModel realm) { + realm.getClientsStream() + .filter(client -> { + String clientLoginTheme = client.getAttribute("login_theme"); + return clientLoginTheme != null && clientLoginTheme.equals("rh-sso"); + }) + .forEach(client -> client.setAttribute("login_theme", null)); + } + @Override public ModelVersion getVersion() { return VERSION; diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/AbstractMigrationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/AbstractMigrationTest.java index c267672c7d1..7a7c4d9ad9f 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/AbstractMigrationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/AbstractMigrationTest.java @@ -90,10 +90,12 @@ import static net.bytebuddy.matcher.ElementMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.anyOf; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasEntry; import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -161,7 +163,8 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest { RealmRepresentation rep = realm.toRepresentation(); Assert.assertNull("Login theme was not modified", rep.getLoginTheme()); Assert.assertNull("Email theme was not modified", rep.getEmailTheme()); - Assert.assertNull("Account theme was not modified", rep.getAccountTheme()); + // there should be either new default or left null if not set + assertThat("Account theme was not modified", rep.getAccountTheme(), anyOf(equalTo("keycloak.v2"), nullValue())); // check the client theme is also removed List client = realm.clients().findByClientId("migration-saml-client"); Assert.assertNotNull("migration-saml-client client is missing", client); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/JsonFileImport1903MigrationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/JsonFileImport1903MigrationTest.java new file mode 100644 index 00000000000..9eec5da4dd8 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/JsonFileImport1903MigrationTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2023 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * 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. + */ +package org.keycloak.testsuite.migration; + +import org.junit.Test; +import org.keycloak.exportimport.util.ImportUtils; +import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testsuite.utils.io.IOUtil; +import org.keycloak.util.JsonSerialization; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * Tests that we can import json file from previous version. MigrationTest only tests DB. + */ +public class JsonFileImport1903MigrationTest extends AbstractJsonFileImportMigrationTest { + + @Override + public void addTestRealms(List testRealms) { + Map reps = null; + try { + reps = ImportUtils.getRealmsFromStream(JsonSerialization.mapper, IOUtil.class.getResourceAsStream("/migration-test/migration-realm-19.0.3.json")); + masterRep = reps.remove("master"); + } catch (IOException e) { + throw new RuntimeException(e); + } + for (RealmRepresentation rep : reps.values()) { + testRealms.add(rep); + } + } + + @Test + public void migration19_0_3Test() throws Exception { + checkRealmsImported(); + testMigrationTo20_x(); + testMigrationTo21_x(); + testMigrationTo22_x(); + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/migration-test/migration-realm-19.0.3.json b/testsuite/integration-arquillian/tests/base/src/test/resources/migration-test/migration-realm-19.0.3.json index edcb2f92c54..8542f3c15a5 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/migration-test/migration-realm-19.0.3.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/migration-test/migration-realm-19.0.3.json @@ -5811,7 +5811,7 @@ "clientOfflineSessionIdleTimeout" : "0", "cibaInterval" : "5" }, - "keycloakVersion" : "17.0.0", + "keycloakVersion" : "19.0.3", "userManagedAccessAllowed" : false, "clientProfiles" : { "profiles" : [ ]