Search in sources :

Example 1 with UPAttributeSelector

use of org.keycloak.userprofile.config.UPAttributeSelector in project keycloak by keycloak.

the class UserProfileTest method testConfigurationInvalidScope.

private static void testConfigurationInvalidScope(KeycloakSession session) throws IOException {
    RealmModel realm = session.getContext().getRealm();
    DeclarativeUserProfileProvider provider = getDynamicUserProfileProvider(session);
    ComponentModel component = provider.getComponentModel();
    assertNotNull(component);
    UPConfig config = new UPConfig();
    UPAttribute attribute = new UPAttribute();
    attribute.setName(ATT_ADDRESS);
    UPAttributeRequired requirements = new UPAttributeRequired();
    requirements.setScopes(Collections.singleton("invalid"));
    attribute.setRequired(requirements);
    attribute.setSelector(new UPAttributeSelector());
    attribute.getSelector().setScopes(Collections.singleton("invalid"));
    config.addAttribute(attribute);
    try {
        provider.setConfiguration(JsonSerialization.writeValueAsString(config));
        Assert.fail("Expected to fail due to invalid client scope");
    } catch (ComponentValidationException cve) {
    // ignore
    }
}
Also used : RealmModel(org.keycloak.models.RealmModel) ComponentValidationException(org.keycloak.component.ComponentValidationException) DeclarativeUserProfileProvider(org.keycloak.userprofile.DeclarativeUserProfileProvider) UPConfig(org.keycloak.userprofile.config.UPConfig) ComponentModel(org.keycloak.component.ComponentModel) UPAttributeRequired(org.keycloak.userprofile.config.UPAttributeRequired) UPAttribute(org.keycloak.userprofile.config.UPAttribute) UPAttributeSelector(org.keycloak.userprofile.config.UPAttributeSelector)

Example 2 with UPAttributeSelector

use of org.keycloak.userprofile.config.UPAttributeSelector 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;
}
Also used : ClientModel(org.keycloak.models.ClientModel) UPConfigUtils(org.keycloak.userprofile.config.UPConfigUtils) Profile(org.keycloak.common.Profile) ProviderConfigProperty(org.keycloak.provider.ProviderConfigProperty) HashMap(java.util.HashMap) Config(org.keycloak.Config) Messages(org.keycloak.services.messages.Messages) TokenManager.getRequestedClientScopes(org.keycloak.protocol.oidc.TokenManager.getRequestedClientScopes) ArrayList(java.util.ArrayList) AmphibianProviderFactory(org.keycloak.component.AmphibianProviderFactory) AbstractSimpleValidator(org.keycloak.validate.AbstractSimpleValidator) UserModel(org.keycloak.models.UserModel) ByteArrayInputStream(java.io.ByteArrayInputStream) Map(java.util.Map) DeclarativeUserProfileModel(org.keycloak.userprofile.config.DeclarativeUserProfileModel) UPConfigUtils.readConfig(org.keycloak.userprofile.config.UPConfigUtils.readConfig) ComponentModel(org.keycloak.component.ComponentModel) AttributeRequiredByMetadataValidator(org.keycloak.userprofile.validator.AttributeRequiredByMetadataValidator) UPGroup(org.keycloak.userprofile.config.UPGroup) AuthenticationSessionModel(org.keycloak.sessions.AuthenticationSessionModel) RealmModel(org.keycloak.models.RealmModel) UPAttributeSelector(org.keycloak.userprofile.config.UPAttributeSelector) ImmutableAttributeValidator(org.keycloak.userprofile.validator.ImmutableAttributeValidator) ValidatorConfig(org.keycloak.validate.ValidatorConfig) UPAttribute(org.keycloak.userprofile.config.UPAttribute) Predicate(java.util.function.Predicate) UPAttributeRequired(org.keycloak.userprofile.config.UPAttributeRequired) Set(java.util.Set) KeycloakSession(org.keycloak.models.KeycloakSession) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) UPConfig(org.keycloak.userprofile.config.UPConfig) List(java.util.List) ObjectUtil.isBlank(org.keycloak.common.util.ObjectUtil.isBlank) BlankAttributeValidator(org.keycloak.userprofile.validator.BlankAttributeValidator) OIDCLoginProtocol(org.keycloak.protocol.oidc.OIDCLoginProtocol) UPAttributePermissions(org.keycloak.userprofile.config.UPAttributePermissions) EmailValidator(org.keycloak.validate.validators.EmailValidator) MultivaluedHashMap(org.keycloak.common.util.MultivaluedHashMap) Collections(java.util.Collections) ComponentValidationException(org.keycloak.component.ComponentValidationException) ArrayList(java.util.ArrayList) UPAttributeRequired(org.keycloak.userprofile.config.UPAttributeRequired) UPAttribute(org.keycloak.userprofile.config.UPAttribute) UPAttributePermissions(org.keycloak.userprofile.config.UPAttributePermissions) UPConfig(org.keycloak.userprofile.config.UPConfig) UPGroup(org.keycloak.userprofile.config.UPGroup) HashMap(java.util.HashMap) Map(java.util.Map) MultivaluedHashMap(org.keycloak.common.util.MultivaluedHashMap) UPAttributeSelector(org.keycloak.userprofile.config.UPAttributeSelector)

Aggregations

ComponentModel (org.keycloak.component.ComponentModel)2 ComponentValidationException (org.keycloak.component.ComponentValidationException)2 RealmModel (org.keycloak.models.RealmModel)2 UPAttribute (org.keycloak.userprofile.config.UPAttribute)2 UPAttributeRequired (org.keycloak.userprofile.config.UPAttributeRequired)2 UPAttributeSelector (org.keycloak.userprofile.config.UPAttributeSelector)2 UPConfig (org.keycloak.userprofile.config.UPConfig)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 Collections (java.util.Collections)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 Set (java.util.Set)1 Predicate (java.util.function.Predicate)1 Collectors (java.util.stream.Collectors)1 Config (org.keycloak.Config)1 Profile (org.keycloak.common.Profile)1 MultivaluedHashMap (org.keycloak.common.util.MultivaluedHashMap)1