Migrating Realm JSON with declarative user profile fails when scope selectors present on any attributes
closes #26266 Signed-off-by: mposolda <mposolda@gmail.com>
This commit is contained in:
parent
64b5f42c4a
commit
cdc5d8fff8
3 changed files with 73 additions and 14 deletions
|
@ -44,26 +44,24 @@ public class MigrateTo23_0_0 implements Migration {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void migrate(KeycloakSession session) {
|
public void migrate(KeycloakSession session) {
|
||||||
session.realms().getRealmsStream().forEach(realm -> {
|
session.realms().getRealmsStream().forEach(realm -> migrateRealm(session, realm));
|
||||||
KeycloakContext context = session.getContext();
|
|
||||||
|
|
||||||
try {
|
|
||||||
context.setRealm(realm);
|
|
||||||
migrateRealm(realm);
|
|
||||||
} finally {
|
|
||||||
context.setRealm(null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
public void migrateImport(KeycloakSession session, RealmModel realm, RealmRepresentation rep, boolean skipUserDependent) {
|
||||||
migrateRealm(realm);
|
migrateRealm(session, realm);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void migrateRealm(RealmModel realm) {
|
private void migrateRealm(KeycloakSession session, RealmModel realm) {
|
||||||
|
KeycloakContext context = session.getContext();
|
||||||
|
|
||||||
|
try {
|
||||||
|
context.setRealm(realm);
|
||||||
updateUserProfileConfig(realm);
|
updateUserProfileConfig(realm);
|
||||||
removeRegistrationProfileFormExecution(realm);
|
removeRegistrationProfileFormExecution(realm);
|
||||||
|
} finally {
|
||||||
|
context.setRealm(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateUserProfileConfig(RealmModel realm) {
|
private void updateUserProfileConfig(RealmModel realm) {
|
||||||
|
|
|
@ -17,14 +17,26 @@
|
||||||
package org.keycloak.testsuite.migration;
|
package org.keycloak.testsuite.migration;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.keycloak.OAuth2Constants;
|
||||||
import org.keycloak.exportimport.util.ImportUtils;
|
import org.keycloak.exportimport.util.ImportUtils;
|
||||||
|
import org.keycloak.representations.idm.ComponentRepresentation;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
import org.keycloak.representations.userprofile.config.UPAttribute;
|
||||||
|
import org.keycloak.representations.userprofile.config.UPConfig;
|
||||||
import org.keycloak.testsuite.utils.io.IOUtil;
|
import org.keycloak.testsuite.utils.io.IOUtil;
|
||||||
|
import org.keycloak.userprofile.config.UPConfigUtils;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
|
import static org.hamcrest.Matchers.hasSize;
|
||||||
|
import static org.hamcrest.Matchers.notNullValue;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.keycloak.userprofile.DeclarativeUserProfileProvider.UP_COMPONENT_CONFIG_KEY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that we can import json file from previous version. MigrationTest only tests DB.
|
* Tests that we can import json file from previous version. MigrationTest only tests DB.
|
||||||
|
@ -37,6 +49,9 @@ public class JsonFileImport1903MigrationTest extends AbstractJsonFileImportMigra
|
||||||
try {
|
try {
|
||||||
reps = ImportUtils.getRealmsFromStream(JsonSerialization.mapper, IOUtil.class.getResourceAsStream("/migration-test/migration-realm-19.0.3.json"));
|
reps = ImportUtils.getRealmsFromStream(JsonSerialization.mapper, IOUtil.class.getResourceAsStream("/migration-test/migration-realm-19.0.3.json"));
|
||||||
masterRep = reps.remove("master");
|
masterRep = reps.remove("master");
|
||||||
|
|
||||||
|
RealmRepresentation upRealm = JsonSerialization.readValue(IOUtil.class.getResourceAsStream("/migration-test/migration-realm-19.0.3-user-profile.json"), RealmRepresentation.class);
|
||||||
|
reps.put(upRealm.getRealm(), upRealm);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@ -55,4 +70,24 @@ public class JsonFileImport1903MigrationTest extends AbstractJsonFileImportMigra
|
||||||
testMigrationTo24_x(true);
|
testMigrationTo24_x(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUserProfileMigration() throws Exception {
|
||||||
|
List<ComponentRepresentation> userProfileComponents = adminClient.realm("migration-user-profile")
|
||||||
|
.components()
|
||||||
|
.query(null, "org.keycloak.userprofile.UserProfileProvider");
|
||||||
|
assertThat(userProfileComponents, hasSize(1));
|
||||||
|
ComponentRepresentation component = userProfileComponents.get(0);
|
||||||
|
|
||||||
|
// Test "street" attribute being presented with the expected scope selectors
|
||||||
|
UPConfig upConfig = UPConfigUtils.parseConfig(component.getConfig().getFirst(UP_COMPONENT_CONFIG_KEY));
|
||||||
|
UPAttribute streetAttr = upConfig.getAttribute("street");
|
||||||
|
assertThat(streetAttr, notNullValue());
|
||||||
|
|
||||||
|
assertThat(streetAttr.getSelector(), notNullValue());
|
||||||
|
assertEquals(Set.of(OAuth2Constants.SCOPE_ADDRESS), streetAttr.getSelector().getScopes());
|
||||||
|
|
||||||
|
assertThat(streetAttr.getSelector(), notNullValue());
|
||||||
|
assertEquals(Set.of(OAuth2Constants.SCOPE_PHONE), streetAttr.getRequired().getScopes());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"id": "migration-user-profile",
|
||||||
|
"realm": "migration-user-profile",
|
||||||
|
"enabled": true,
|
||||||
|
"attributes" : {
|
||||||
|
"userProfileEnabled" : "true"
|
||||||
|
},
|
||||||
|
"components" : {
|
||||||
|
"org.keycloak.userprofile.UserProfileProvider": [
|
||||||
|
{
|
||||||
|
"id": "98cef18c-bcd8-40d2-9e7d-d257298317f2",
|
||||||
|
"providerId": "declarative-user-profile",
|
||||||
|
"subComponents": {},
|
||||||
|
"config": {
|
||||||
|
"config-piece-0": [
|
||||||
|
"{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"validations\":{\"length\":{\"min\":3,\"max\":255},\"username-prohibited-characters\":{},\"up-username-not-idn-homograph\":{}}},{\"name\":\"email\",\"displayName\":\"${email}\",\"permissions\":{\"edit\":[\"admin\",\"user\"],\"view\":[\"admin\",\"user\"]},\"validations\":{\"email\":{},\"length\":{\"max\":255},\"pattern\":{\"pattern\":\"[a-zA-Z0-9!#$%&'*+/=?^_`{|}~.-]+@example.nl\",\"error-message\":\"Invalid domain selected\"}},\"annotations\":{\"\":\"\"},\"required\":{\"roles\":[\"user\"]},\"group\":null},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}}},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"required\":{\"roles\":[\"user\"]},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}}},{\"name\":\"street\",\"displayName\":\"Street\",\"required\":{\"scopes\":[\"phone\"],\"roles\":[\"admin\",\"user\"]},\"validations\":{},\"selector\":{\"scopes\":[\"address\"]},\"permissions\":{\"view\":[\"user\"],\"edit\":[\"user\",\"admin\"]},\"annotations\":{\"foo\":\"bar\"}}]}"
|
||||||
|
],
|
||||||
|
"config-pieces-count": [
|
||||||
|
"1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"keycloakVersion" : "19.0.3"
|
||||||
|
}
|
Loading…
Reference in a new issue