use of org.keycloak.userprofile.config.UPGroup in project keycloak by keycloak.
the class UPConfigParserTest method validateConfiguration_attributeGroupConfigurationErrors.
private static void validateConfiguration_attributeGroupConfigurationErrors(KeycloakSession session) throws IOException {
UPConfig config = loadValidConfig();
// add a group without name
UPGroup groupWithoutName = new UPGroup();
config.addGroup(groupWithoutName);
List<String> errors = validate(session, config);
Assert.assertEquals(1, errors.size());
Assert.assertEquals("Name is mandatory for groups, found 1 group(s) without name.", errors.get(0));
}
use of org.keycloak.userprofile.config.UPGroup in project keycloak by keycloak.
the class UPConfigParserTest method parseConfigurationFile_OK.
@Test
public void parseConfigurationFile_OK() throws IOException {
UPConfig config = loadValidConfig();
Assert.assertNotNull(config);
// assert *** attributes ***
Assert.assertEquals(5, config.getAttributes().size());
UPAttribute att = config.getAttributes().get(1);
Assert.assertNotNull(att);
Assert.assertEquals("email", att.getName());
// validation
Assert.assertEquals(3, att.getValidations().size());
Assert.assertEquals(1, att.getValidations().get("length").size());
Assert.assertEquals(255, att.getValidations().get("length").get("max"));
// annotations
Assert.assertEquals("userEmailFormFieldHint", att.getAnnotations().get("formHintKey"));
att = config.getAttributes().get(4);
// required
Assert.assertNotNull(att.getRequired());
Assert.assertFalse(att.getRequired().isAlways());
Assert.assertNotNull(att.getRequired().getScopes());
Assert.assertNotNull(att.getRequired().getRoles());
Assert.assertEquals(2, att.getRequired().getRoles().size());
att = config.getAttributes().get(3);
Assert.assertTrue(att.getRequired().isAlways());
// permissions
Assert.assertNotNull(att.getPermissions());
Assert.assertNotNull(att.getPermissions().getEdit());
Assert.assertEquals(1, att.getPermissions().getEdit().size());
Assert.assertTrue(att.getPermissions().getEdit().contains("admin"));
Assert.assertNotNull(att.getPermissions().getView());
Assert.assertEquals(2, att.getPermissions().getView().size());
Assert.assertTrue(att.getPermissions().getView().contains("admin"));
Assert.assertTrue(att.getPermissions().getView().contains("user"));
// selector
att = config.getAttributes().get(4);
Assert.assertNotNull(att.getSelector().getScopes());
Assert.assertEquals(3, att.getSelector().getScopes().size());
Assert.assertTrue(att.getSelector().getScopes().contains("phone-3-sel"));
// displayName
att = config.getAttributes().get(4);
Assert.assertEquals("${profile.phone}", att.getDisplayName());
// group
Assert.assertEquals("contact", att.getGroup());
// assert *** groups ***
Assert.assertEquals(1, config.getGroups().size());
UPGroup group = config.getGroups().get(0);
Assert.assertEquals("contact", group.getName());
Assert.assertEquals("Contact information", group.getDisplayHeader());
Assert.assertEquals("Required to contact you in case of emergency", group.getDisplayDescription());
Assert.assertEquals(1, group.getAnnotations().size());
Assert.assertEquals("value1", group.getAnnotations().get("contactanno1"));
}
use of org.keycloak.userprofile.config.UPGroup in project keycloak by keycloak.
the class DeclarativeUserProfileProvider method decorateUserProfileForCache.
/**
* Decorate basic metadata provided from {@link AbstractUserProfileProvider} based on 'per realm' configuration.
* This method is called for each {@link UserProfileContext} in each realm, and metadata are cached then and this
* method is called again only if configuration changes.
*
* @param decoratedMetadata base to be decorated based on configuration loaded from component model
* @param model component model to get "per realm" configuration from
* @return decorated metadata
*/
protected UserProfileMetadata decorateUserProfileForCache(UserProfileMetadata decoratedMetadata, ComponentModel model) {
UserProfileContext context = decoratedMetadata.getContext();
UPConfig parsedConfig = getParsedConfig(model);
// do not change config for REGISTRATION_USER_CREATION context, everything important is covered thanks to REGISTRATION_PROFILE
if (parsedConfig == null || context == UserProfileContext.REGISTRATION_USER_CREATION) {
return decoratedMetadata;
}
Map<String, UPGroup> groupsByName = asHashMap(parsedConfig.getGroups());
int guiOrder = 0;
for (UPAttribute attrConfig : parsedConfig.getAttributes()) {
String attributeName = attrConfig.getName();
List<AttributeValidatorMetadata> validators = new ArrayList<>();
Map<String, Map<String, Object>> validationsConfig = attrConfig.getValidations();
if (validationsConfig != null) {
for (Map.Entry<String, Map<String, Object>> vc : validationsConfig.entrySet()) {
validators.add(createConfiguredValidator(vc.getKey(), vc.getValue()));
}
}
UPAttributeRequired rc = attrConfig.getRequired();
Predicate<AttributeContext> required = AttributeMetadata.ALWAYS_FALSE;
if (rc != null && !isUsernameOrEmailAttribute(attributeName)) {
// driven by business logic from parent!
if (rc.isAlways() || UPConfigUtils.isRoleForContext(context, rc.getRoles())) {
required = AttributeMetadata.ALWAYS_TRUE;
} else if (UPConfigUtils.canBeAuthFlowContext(context) && rc.getScopes() != null && !rc.getScopes().isEmpty()) {
// for contexts executed from auth flow and with configured scopes requirement
// we have to create required validation with scopes based selector
required = (c) -> requestedScopePredicate(c, rc.getScopes());
}
validators.add(new AttributeValidatorMetadata(AttributeRequiredByMetadataValidator.ID));
}
Predicate<AttributeContext> writeAllowed = AttributeMetadata.ALWAYS_FALSE;
Predicate<AttributeContext> readAllowed = AttributeMetadata.ALWAYS_FALSE;
UPAttributePermissions permissions = attrConfig.getPermissions();
if (permissions != null) {
Set<String> editRoles = permissions.getEdit();
if (!editRoles.isEmpty()) {
writeAllowed = ac -> UPConfigUtils.isRoleForContext(ac.getContext(), editRoles);
}
Set<String> viewRoles = permissions.getView();
if (viewRoles.isEmpty()) {
readAllowed = writeAllowed;
} else {
readAllowed = createViewAllowedPredicate(writeAllowed, viewRoles);
}
}
Predicate<AttributeContext> selector = AttributeMetadata.ALWAYS_TRUE;
UPAttributeSelector sc = attrConfig.getSelector();
if (sc != null && !isUsernameOrEmailAttribute(attributeName) && UPConfigUtils.canBeAuthFlowContext(context) && sc.getScopes() != null && !sc.getScopes().isEmpty()) {
// for contexts executed from auth flow and with configured scopes selector
// we have to create correct predicate
selector = (c) -> requestedScopePredicate(c, sc.getScopes());
}
Map<String, Object> annotations = attrConfig.getAnnotations();
String attributeGroup = attrConfig.getGroup();
AttributeGroupMetadata groupMetadata = toAttributeGroupMeta(groupsByName.get(attributeGroup));
if (isUsernameOrEmailAttribute(attributeName)) {
if (permissions == null) {
writeAllowed = AttributeMetadata.ALWAYS_TRUE;
}
List<AttributeMetadata> atts = decoratedMetadata.getAttribute(attributeName);
if (atts.isEmpty()) {
// attribute metadata doesn't exist so we have to add it. We keep it optional as Abstract base
// doesn't require it.
decoratedMetadata.addAttribute(attributeName, guiOrder++, writeAllowed, validators).addAnnotations(annotations).setAttributeDisplayName(attrConfig.getDisplayName()).setAttributeGroupMetadata(groupMetadata);
} else {
final int localGuiOrder = guiOrder++;
// only add configured validators and annotations if attribute metadata exist
atts.stream().forEach(c -> c.addValidator(validators).addAnnotations(annotations).setAttributeDisplayName(attrConfig.getDisplayName()).setGuiOrder(localGuiOrder).setAttributeGroupMetadata(groupMetadata));
}
} else {
// always add validation for immutable/read-only attributes
validators.add(new AttributeValidatorMetadata(ImmutableAttributeValidator.ID));
decoratedMetadata.addAttribute(attributeName, guiOrder++, validators, selector, writeAllowed, required, readAllowed).addAnnotations(annotations).setAttributeDisplayName(attrConfig.getDisplayName()).setAttributeGroupMetadata(groupMetadata);
}
}
return decoratedMetadata;
}
Aggregations