Skip to content

Commit 810ebf4

Browse files
committed
Migration steps for enabling user profile by default
Closes keycloak#25528 Signed-off-by: Pedro Igor <[email protected]>
1 parent 32a70cb commit 810ebf4

File tree

10 files changed

+129
-1
lines changed

10 files changed

+129
-1
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright 2023 Red Hat, Inc. and/or its affiliates
3+
* and other contributors as indicated by the @author tags.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
*
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*
18+
*/
19+
20+
package org.keycloak.migration.migrators;
21+
22+
import org.jboss.logging.Logger;
23+
import org.keycloak.migration.ModelVersion;
24+
import org.keycloak.models.KeycloakContext;
25+
import org.keycloak.models.KeycloakSession;
26+
import org.keycloak.models.RealmModel;
27+
import org.keycloak.representations.idm.RealmRepresentation;
28+
import org.keycloak.representations.userprofile.config.UPConfig;
29+
import org.keycloak.representations.userprofile.config.UPConfig.UnmanagedAttributePolicy;
30+
import org.keycloak.userprofile.UserProfileProvider;
31+
32+
public class MigrateTo24_0_0 implements Migration {
33+
34+
private static final Logger LOG = Logger.getLogger(MigrateTo24_0_0.class);
35+
public static final ModelVersion VERSION = new ModelVersion("24.0.0");
36+
private static final String REALM_USER_PROFILE_ENABLED = "userProfileEnabled";
37+
38+
@Override
39+
public void migrate(KeycloakSession session) {
40+
session.realms().getRealmsStream().forEach(realm -> migrateRealm(session, realm));
41+
}
42+
43+
@Override
44+
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
45+
migrateRealm(session, realm);
46+
}
47+
48+
@Override
49+
public ModelVersion getVersion() {
50+
return VERSION;
51+
}
52+
53+
private void migrateRealm(KeycloakSession session, RealmModel realm) {
54+
KeycloakContext context = session.getContext();
55+
try {
56+
context.setRealm(realm);
57+
updateUserProfileSettings(session);
58+
} finally {
59+
context.setRealm(null);
60+
}
61+
}
62+
63+
private void updateUserProfileSettings(KeycloakSession session) {
64+
RealmModel realm = session.getContext().getRealm();
65+
boolean isUserProfileEnabled = Boolean.parseBoolean(realm.getAttribute(REALM_USER_PROFILE_ENABLED));
66+
67+
if (isUserProfileEnabled) {
68+
// existing realms with user profile enabled does not need any addition migration step
69+
LOG.debugf("Skipping migration for realm %s. The declarative user profile is already enabled.", realm.getName());
70+
return;
71+
}
72+
73+
// user profile is enabled by default since this version
74+
realm.setAttribute(REALM_USER_PROFILE_ENABLED, Boolean.TRUE.toString());
75+
76+
// for backward compatibility in terms of behavior, we enable unmanaged attributes for existing realms
77+
// that don't have the declarative user profile enabled
78+
UserProfileProvider provider = session.getProvider(UserProfileProvider.class);
79+
UPConfig upConfig = provider.getConfiguration();
80+
upConfig.setUnmanagedAttributePolicy(UnmanagedAttributePolicy.ENABLED);
81+
provider.setConfiguration(upConfig);
82+
83+
LOG.debugf("Enabled the declarative user profile to realm %s with support for unmanaged attributes", realm.getName());
84+
}
85+
}

model/legacy-private/src/main/java/org/keycloak/storage/datastore/LegacyMigrationManager.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.keycloak.migration.migrators.MigrateTo21_0_0;
3838
import org.keycloak.migration.migrators.MigrateTo22_0_0;
3939
import org.keycloak.migration.migrators.MigrateTo23_0_0;
40+
import org.keycloak.migration.migrators.MigrateTo24_0_0;
4041
import org.keycloak.migration.migrators.MigrateTo2_0_0;
4142
import org.keycloak.migration.migrators.MigrateTo2_1_0;
4243
import org.keycloak.migration.migrators.MigrateTo2_2_0;
@@ -112,7 +113,8 @@ public class LegacyMigrationManager implements MigrationManager {
112113
new MigrateTo20_0_0(),
113114
new MigrateTo21_0_0(),
114115
new MigrateTo22_0_0(),
115-
new MigrateTo23_0_0()
116+
new MigrateTo23_0_0(),
117+
new MigrateTo24_0_0()
116118
};
117119

118120
private final KeycloakSession session;

testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/AbstractMigrationTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@
6363
import org.keycloak.representations.idm.authorization.DecisionStrategy;
6464
import org.keycloak.representations.idm.authorization.ResourceRepresentation;
6565
import org.keycloak.representations.idm.authorization.ResourceServerRepresentation;
66+
import org.keycloak.representations.userprofile.config.UPConfig;
67+
import org.keycloak.representations.userprofile.config.UPConfig.UnmanagedAttributePolicy;
6668
import org.keycloak.storage.UserStorageProvider;
6769
import org.keycloak.testsuite.AbstractKeycloakTest;
6870
import org.keycloak.testsuite.Assert;
@@ -110,6 +112,7 @@
110112
import static org.keycloak.models.Constants.ACCOUNT_MANAGEMENT_CLIENT_ID;
111113
import static org.keycloak.testsuite.Assert.assertNames;
112114
import static org.keycloak.testsuite.auth.page.AuthRealm.MASTER;
115+
import static org.keycloak.userprofile.DeclarativeUserProfileProvider.REALM_USER_PROFILE_ENABLED;
113116
import static org.keycloak.userprofile.DeclarativeUserProfileProvider.UP_COMPONENT_CONFIG_KEY;
114117

115118
/**
@@ -395,6 +398,15 @@ protected void testMigrationTo23_0_0(boolean testUserProfileMigration) {
395398
testRegistrationProfileFormActionRemoved(migrationRealm2);
396399
}
397400

401+
protected void testMigrationTo24_0_0(boolean testUserProfileMigration) {
402+
if (testUserProfileMigration) {
403+
testUserProfileEnabledByDefault(migrationRealm);
404+
testUnmanagedAttributePolicySet(migrationRealm, UnmanagedAttributePolicy.ENABLED);
405+
testUserProfileEnabledByDefault(migrationRealm2);
406+
testUnmanagedAttributePolicySet(migrationRealm2, null);
407+
}
408+
}
409+
398410
protected void testDeleteAccount(RealmResource realm) {
399411
ClientRepresentation accountClient = realm.clients().findByClientId(ACCOUNT_MANAGEMENT_CLIENT_ID).get(0);
400412
ClientResource accountResource = realm.clients().get(accountClient.getId());
@@ -1079,6 +1091,10 @@ protected void testMigrationTo23_x(boolean testUserProfileMigration) {
10791091
testMigrationTo23_0_0(testUserProfileMigration);
10801092
}
10811093

1094+
protected void testMigrationTo24_x(boolean testUserProfileMigration) {
1095+
testMigrationTo24_0_0(testUserProfileMigration);
1096+
}
1097+
10821098
protected void testMigrationTo7_x(boolean supportedAuthzServices) {
10831099
if (supportedAuthzServices) {
10841100
testDecisionStrategySetOnResourceServer();
@@ -1183,4 +1199,16 @@ protected void testRealmAttributesMigration() {
11831199
Map<String, String> realmAttributes = migrationRealm.toRepresentation().getAttributes();
11841200
assertEquals("custom_value", realmAttributes.get("custom_attribute"));
11851201
}
1202+
1203+
private void testUserProfileEnabledByDefault(RealmResource realm) {
1204+
RealmRepresentation rep = realm.toRepresentation();
1205+
Map<String, String> attributes = rep.getAttributes();
1206+
String userProfileEnabled = attributes.get(REALM_USER_PROFILE_ENABLED);
1207+
assertTrue(Boolean.parseBoolean(userProfileEnabled));
1208+
}
1209+
1210+
private void testUnmanagedAttributePolicySet(RealmResource realm, UnmanagedAttributePolicy policy) {
1211+
UPConfig upConfig = realm.users().userProfile().getConfiguration();
1212+
assertEquals(policy, upConfig.getUnmanagedAttributePolicy());
1213+
}
11861214
}

testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/JsonFileImport1903MigrationTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
package org.keycloak.testsuite.migration;
1818

1919
import org.junit.Test;
20+
import org.keycloak.common.Profile.Feature;
2021
import org.keycloak.exportimport.util.ImportUtils;
2122
import org.keycloak.representations.idm.RealmRepresentation;
23+
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
2224
import org.keycloak.testsuite.utils.io.IOUtil;
2325
import org.keycloak.util.JsonSerialization;
2426

@@ -29,6 +31,7 @@
2931
/**
3032
* Tests that we can import json file from previous version. MigrationTest only tests DB.
3133
*/
34+
@EnableFeature(Feature.DECLARATIVE_USER_PROFILE)
3235
public class JsonFileImport1903MigrationTest extends AbstractJsonFileImportMigrationTest {
3336

3437
@Override
@@ -52,6 +55,7 @@ public void migration19_0_3Test() throws Exception {
5255
testMigrationTo21_x();
5356
testMigrationTo22_x();
5457
testMigrationTo23_x(true);
58+
testMigrationTo24_x(true);
5559
}
5660

5761
}

testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/JsonFileImport198MigrationTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public void migration1_9_8Test() {
7878
testMigrationTo21_x();
7979
testMigrationTo22_x();
8080
testMigrationTo23_x(false);
81+
testMigrationTo24_x(false);
8182
}
8283

8384
@Override

testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/JsonFileImport255MigrationTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public void migration2_5_5Test() throws Exception {
7272
testMigrationTo21_x();
7373
testMigrationTo22_x();
7474
testMigrationTo23_x(false);
75+
testMigrationTo24_x(false);
7576
}
7677

7778
}

testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/JsonFileImport343MigrationTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public void migration3_4_3Test() throws Exception {
6767
testMigrationTo21_x();
6868
testMigrationTo22_x();
6969
testMigrationTo23_x(false);
70+
testMigrationTo24_x(false);
7071
}
7172

7273
}

testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/JsonFileImport483MigrationTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public void migration4_8_3Test() throws Exception {
6161
testMigrationTo21_x();
6262
testMigrationTo22_x();
6363
testMigrationTo23_x(false);
64+
testMigrationTo24_x(false);
6465
}
6566

6667
}

testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/JsonFileImport903MigrationTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public void migration9_0_3Test() throws Exception {
5454
testMigrationTo21_x();
5555
testMigrationTo22_x();
5656
testMigrationTo23_x(false);
57+
testMigrationTo24_x(false);
5758
}
5859

5960
}

testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/migration/MigrationTest.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
import org.junit.Before;
2020
import org.junit.Test;
2121
import org.keycloak.admin.client.resource.RealmResource;
22+
import org.keycloak.common.Profile.Feature;
2223
import org.keycloak.representations.idm.RealmRepresentation;
24+
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
2325
import org.keycloak.testsuite.arquillian.migration.Migration;
2426

2527
import jakarta.ws.rs.NotFoundException;
@@ -32,6 +34,7 @@
3234
*
3335
* @author <a href="mailto:[email protected]">Vlastislav Ramik</a>
3436
*/
37+
@EnableFeature(Feature.DECLARATIVE_USER_PROFILE)
3538
public class MigrationTest extends AbstractMigrationTest {
3639

3740
@Override
@@ -69,5 +72,6 @@ public void migration19_xTest() throws Exception{
6972
testMigrationTo21_x();
7073
testMigrationTo22_x();
7174
testMigrationTo23_x(true);
75+
testMigrationTo24_x(true);
7276
}
7377
}

0 commit comments

Comments
 (0)