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" : [ ]