Make sure optional default attributes are removed when decorating the user-define user profile configuration
Closes #24420
This commit is contained in:
parent
e96d6b38a8
commit
be65ba8689
2 changed files with 54 additions and 1 deletions
|
@ -27,6 +27,7 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -448,6 +449,10 @@ public class DeclarativeUserProfileProvider extends AbstractUserProfileProvider<
|
||||||
return UserModel.USERNAME.equals(attributeName) || UserModel.EMAIL.equals(attributeName);
|
return UserModel.USERNAME.equals(attributeName) || UserModel.EMAIL.equals(attributeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isOptionalBuiltInAttribute(String attributeName) {
|
||||||
|
return UserModel.FIRST_NAME.equals(attributeName) || UserModel.LAST_NAME.equals(attributeName);
|
||||||
|
}
|
||||||
|
|
||||||
private Predicate<AttributeContext> createViewAllowedPredicate(Predicate<AttributeContext> canEdit,
|
private Predicate<AttributeContext> createViewAllowedPredicate(Predicate<AttributeContext> canEdit,
|
||||||
Set<String> viewRoles) {
|
Set<String> viewRoles) {
|
||||||
return ac -> UPConfigUtils.isRoleForContext(ac.getContext(), viewRoles) || canEdit.test(ac);
|
return ac -> UPConfigUtils.isRoleForContext(ac.getContext(), viewRoles) || canEdit.test(ac);
|
||||||
|
@ -521,7 +526,11 @@ public class DeclarativeUserProfileProvider extends AbstractUserProfileProvider<
|
||||||
throw new RuntimeException("UserProfile configuration for realm '" + session.getContext().getRealm().getName() + "' is invalid: " + errors.toString());
|
throw new RuntimeException("UserProfile configuration for realm '" + session.getContext().getRealm().getName() + "' is invalid: " + errors.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (AttributeMetadata metadata : decoratedMetadata.getAttributes()) {
|
Iterator<AttributeMetadata> attributes = decoratedMetadata.getAttributes().iterator();
|
||||||
|
|
||||||
|
while (attributes.hasNext()) {
|
||||||
|
AttributeMetadata metadata = attributes.next();
|
||||||
|
|
||||||
String attributeName = metadata.getName();
|
String attributeName = metadata.getName();
|
||||||
|
|
||||||
if (isBuiltInAttribute(attributeName)) {
|
if (isBuiltInAttribute(attributeName)) {
|
||||||
|
@ -534,6 +543,10 @@ public class DeclarativeUserProfileProvider extends AbstractUserProfileProvider<
|
||||||
// user-defined configuration will add its own validators
|
// user-defined configuration will add its own validators
|
||||||
validators.removeIf(m -> m.getValidatorId().equals(id));
|
validators.removeIf(m -> m.getValidatorId().equals(id));
|
||||||
}
|
}
|
||||||
|
} else if (isOptionalBuiltInAttribute(attributeName)) {
|
||||||
|
// removes optional default attributes in favor of user-defined configuration
|
||||||
|
// make sure any attribute other than username and email are removed from the metadata
|
||||||
|
attributes.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1665,4 +1665,44 @@ public class UserProfileTest extends AbstractUserProfileTest {
|
||||||
assertNull(user.getEmail());
|
assertNull(user.getEmail());
|
||||||
assertEquals(upAttributes.getFirstValue(UserModel.FIRST_NAME), attributes.get(UserModel.FIRST_NAME).get(0));
|
assertEquals(upAttributes.getFirstValue(UserModel.FIRST_NAME), attributes.get(UserModel.FIRST_NAME).get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemoveOptionalAttributesFromDefaultConfigIfNotSet() {
|
||||||
|
getTestingClient().server(TEST_REALM_NAME).run((RunOnServer) UserProfileTest::testRemoveOptionalAttributesFromDefaultConfigIfNotSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void testRemoveOptionalAttributesFromDefaultConfigIfNotSet(KeycloakSession session) throws IOException {
|
||||||
|
UPConfig config = new UPConfig();
|
||||||
|
UPAttribute attribute = new UPAttribute();
|
||||||
|
|
||||||
|
attribute.setName("foo");
|
||||||
|
|
||||||
|
config.addAttribute(attribute);
|
||||||
|
|
||||||
|
UserProfileProvider provider = getUserProfileProvider(session);
|
||||||
|
provider.setConfiguration(JsonSerialization.writeValueAsString(config));
|
||||||
|
|
||||||
|
Map<String, Object> attributes = new HashMap<>();
|
||||||
|
|
||||||
|
attributes.put(UserModel.USERNAME, org.keycloak.models.utils.KeycloakModelUtils.generateId() + "@keycloak.org");
|
||||||
|
attributes.put(UserModel.EMAIL, org.keycloak.models.utils.KeycloakModelUtils.generateId() + "@keycloak.org");
|
||||||
|
attributes.put("foo", "foo");
|
||||||
|
|
||||||
|
UserProfile profile = provider.create(UserProfileContext.UPDATE_PROFILE, attributes);
|
||||||
|
UserModel user = profile.create();
|
||||||
|
|
||||||
|
assertFalse(profile.getAttributes().contains(UserModel.FIRST_NAME));
|
||||||
|
assertFalse(profile.getAttributes().contains(UserModel.LAST_NAME));
|
||||||
|
|
||||||
|
UPAttribute firstName = new UPAttribute();
|
||||||
|
firstName.setName(UserModel.FIRST_NAME);
|
||||||
|
config.addAttribute(firstName);
|
||||||
|
UPAttribute lastName = new UPAttribute();
|
||||||
|
lastName.setName(UserModel.LAST_NAME);
|
||||||
|
config.addAttribute(lastName);
|
||||||
|
provider.setConfiguration(JsonSerialization.writeValueAsString(config));
|
||||||
|
profile = provider.create(UserProfileContext.UPDATE_PROFILE, attributes, user);
|
||||||
|
assertTrue(profile.getAttributes().contains(UserModel.FIRST_NAME));
|
||||||
|
assertTrue(profile.getAttributes().contains(UserModel.LAST_NAME));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue