Skip to content

Commit

Permalink
Import migration step for kc22
Browse files Browse the repository at this point in the history
Closes keycloak#24031

Co-authored-by: Alexander Schwartz <[email protected]>
  • Loading branch information
vramik and ahus1 authored Oct 19, 2023
1 parent d10ccc7 commit f6d582c
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ protected void generateStatementsImpl() throws CustomChangeException {
.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))
Expand Down
Original file line number Diff line number Diff line change
@@ -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;

/**
* <p>Migration class to update themes for those who had upgraded to 22.0.0 already.</p>
*/
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";
}

}
14 changes: 13 additions & 1 deletion model/jpa/src/main/resources/META-INF/jpa-changelog-22.0.0.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,20 @@
-->
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">

<changeSet author="keycloak" id="22.0.0-17484">
<changeSet author="keycloak" id="22.0.0-17484-updated">
<preConditions onSqlOutput="TEST" onFail="MARK_RAN">
<not>
<changeSetExecuted id="22.0.0-17484" author="keycloak" changeLogFile="META-INF/jpa-changelog-22.0.0.xml"/>
</not>
</preConditions>
<customChange class="org.keycloak.connections.jpa.updater.liquibase.custom.JpaUpdate22_0_0_RemoveRhssoThemes"/>
</changeSet>

<changeSet author="keycloak" id="22.0.5-24031">
<preConditions onSqlOutput="TEST" onFail="MARK_RAN">
<changeSetExecuted id="22.0.0-17484" author="keycloak" changeLogFile="META-INF/jpa-changelog-22.0.0.xml"/>
</preConditions>
<customChange class="org.keycloak.connections.jpa.updater.liquibase.custom.JpaUpdate22_0_5_UpdateAccountTheme"/>
</changeSet>

</databaseChangeLog>
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -69,11 +70,34 @@ private void removeHttpChallengeFlow(RealmModel realm) {

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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,12 @@
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;
Expand Down Expand Up @@ -161,7 +163,8 @@ protected void testRhssoThemes(RealmResource realm) {
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<ClientRepresentation> client = realm.clients().findByClientId("migration-saml-client");
Assert.assertNotNull("migration-saml-client client is missing", client);
Expand Down
Original file line number Diff line number Diff line change
@@ -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<RealmRepresentation> testRealms) {
Map<String, RealmRepresentation> 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();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5811,7 +5811,7 @@
"clientOfflineSessionIdleTimeout" : "0",
"cibaInterval" : "5"
},
"keycloakVersion" : "17.0.0",
"keycloakVersion" : "19.0.3",
"userManagedAccessAllowed" : false,
"clientProfiles" : {
"profiles" : [ ]
Expand Down

0 comments on commit f6d582c

Please sign in to comment.