Make sure empty configuration resolves to the system default configuration

Closes #27611

Signed-off-by: Pedro Igor <pigor.craveiro@gmail.com>
This commit is contained in:
Pedro Igor 2024-03-08 16:47:12 -03:00
parent ccc4cd2ab4
commit 1e48cce3ae
3 changed files with 47 additions and 20 deletions

View file

@ -71,8 +71,11 @@ public class MigrateTo23_0_0 implements Migration {
if (component.isPresent()) {
ComponentModel userProfileComponent = component.get();
int count = userProfileComponent.get(UP_PIECES_COUNT_COMPONENT_CONFIG_KEY, 0);
if (count < 1) {
realm.removeComponent(userProfileComponent);
return;
}
userProfileComponent.getConfig().remove(UP_PIECES_COUNT_COMPONENT_CONFIG_KEY);
if (count < 1) return; // default config
String configuration;
if (count == 1) {
configuration = userProfileComponent.get(UP_PIECE_COMPONENT_CONFIG_KEY_BASE + "0");

View file

@ -459,16 +459,18 @@ public class DeclarativeUserProfileProvider implements UserProfileProvider {
/**
* Get parsed config file configured in model. Default one used if not configured.
*/
protected UPConfig getParsedConfig(String rawConfig) {
if (!isBlank(rawConfig)) {
try {
return UPConfigUtils.parseConfig(rawConfig);
} catch (IOException e) {
throw new RuntimeException("UserProfile configuration for realm '" + session.getContext().getRealm().getName() + "' is invalid:" + e.getMessage(), e);
}
protected UPConfig parseConfigOrDefault(ComponentModel component) {
String rawConfig = component.get(UP_COMPONENT_CONFIG_KEY);
if (isBlank(rawConfig)) {
return parsedDefaultRawConfig;
}
return null;
try {
return UPConfigUtils.parseConfig(rawConfig);
} catch (IOException e) {
throw new RuntimeException("UserProfile configuration for realm '" + session.getContext().getRealm().getName() + "' is invalid:" + e.getMessage(), e);
}
}
/**
@ -492,22 +494,27 @@ public class DeclarativeUserProfileProvider implements UserProfileProvider {
}
private UPConfig getConfigFromComponentModel(ComponentModel model) {
if (model == null)
return null;
UPConfig cached = getParsedConfigFromCache(model);
UPConfig cfg = model.getNote(PARSED_UP_CONFIG_COMPONENT_KEY);
if (cfg != null) {
return cfg;
if (cached == null) {
cached = parseAndCacheConfig(model);
}
String rawConfig = model.get(UP_COMPONENT_CONFIG_KEY);
if (rawConfig == null) {
return cached;
}
private UPConfig parseAndCacheConfig(ComponentModel model) {
UPConfig cfg = parseConfigOrDefault(model);
model.setNote(PARSED_UP_CONFIG_COMPONENT_KEY, cfg);
return cfg;
}
private UPConfig getParsedConfigFromCache(ComponentModel component) {
if (component == null) {
return null;
} else {
cfg = getParsedConfig(rawConfig);
model.setNote(PARSED_UP_CONFIG_COMPONENT_KEY, cfg);
return cfg;
}
return component.getNote(PARSED_UP_CONFIG_COMPONENT_KEY);
}
private void removeConfigJsonFromComponentModel(ComponentModel model) {

View file

@ -29,6 +29,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.keycloak.userprofile.config.UPConfigUtils.ROLE_ADMIN;
import static org.keycloak.userprofile.config.UPConfigUtils.ROLE_USER;
import static org.keycloak.userprofile.config.UPConfigUtils.parseSystemDefaultConfig;
import jakarta.ws.rs.core.Response;
import java.util.ArrayList;
@ -47,6 +48,7 @@ import org.junit.Assert;
import org.junit.Test;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.common.Profile.Feature;
import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.component.ComponentModel;
import org.keycloak.component.ComponentValidationException;
import org.keycloak.models.Constants;
@ -2244,4 +2246,19 @@ public class UserProfileTest extends AbstractUserProfileTest {
profile = provider.create(UserProfileContext.USER_API, attributes, user);
profile.update();
}
@Test
public void testDefaultConfigWhenComponentConfigIsNotSet() {
getTestingClient().server(TEST_REALM_NAME).run((RunOnServer) UserProfileTest::testDefaultConfigWhenComponentConfigIsNotSet);
}
private static void testDefaultConfigWhenComponentConfigIsNotSet(KeycloakSession session) {
UserProfileProvider provider = getUserProfileProvider(session);
provider.setConfiguration(parseSystemDefaultConfig());
RealmModel realm = session.getContext().getRealm();
ComponentModel component = realm.getComponentsStream(realm.getId(), UserProfileProvider.class.getName()).findAny().get();
component.setConfig(new MultivaluedHashMap<>());
realm.updateComponent(component);
provider.create(UserProfileContext.USER_API, Map.of());
}
}