org.keycloak.userprofile.Attributes Maven / Gradle / Ivy
/*
*
* * Copyright 2021 Red Hat, Inc. and/or its affiliates
* * and other contributors as indicated by the @author tags.
* *
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
*
*/
package org.keycloak.userprofile;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import org.keycloak.models.UserModel;
import org.keycloak.validate.ValidationError;
/**
* This interface wraps the attributes associated with a user profile. Different operations are provided to access and
* manage these attributes.
*
* @author Pedro Igor
*/
public interface Attributes {
/**
* Default value for attributes with no value set.
*/
List EMPTY_VALUE = Collections.emptyList();
/**
* Returns the first value associated with the attribute with the given {@name}.
*
* @param name the name of the attribute
*
* @return the first value
*/
default String getFirstValue(String name) {
List values = getValues(name);
if (values.isEmpty()) {
return null;
}
return values.get(0);
}
/**
* Returns all values for an attribute with the given {@code name}.
*
* @param name the name of the attribute
*
* @return the attribute values
*/
List getValues(String name);
/**
* Checks whether an attribute is read-only.
*
* @param key
*
* @return
*/
boolean isReadOnly(String key);
/**
* Validates the attribute with the given {@code name}.
*
* @param name the name of the attribute
* @param listeners the listeners for listening for errors. ValidationError.inputHint
contains name of the attribute in error.
*
* @return {@code true} if validation is successful. Otherwise, {@code false}. In case there is no attribute with the given {@code name},
* {@code false} is also returned but without triggering listeners
*/
boolean validate(String name, Consumer... listeners);
/**
* Checks whether an attribute with the given {@code name} is defined.
*
* @param name the name of the attribute
*
* @return {@code true} if the attribute is defined. Otherwise, {@code false}
*/
boolean contains(String name);
/**
* Returns the names of all defined attributes.
*
* @return the set of attribute names
*/
Set nameSet();
/**
* Returns all attributes that can be written.
*
* @return the attributes
*/
Map> getWritable();
/**
* Returns the metadata associated with the attribute with the given {@code name}.
*
*
The {@link AttributeMetadata} is a copy of the original metadata. The original metadata
* keeps immutable.
*
* @param name the attribute name
* @return the metadata
*/
AttributeMetadata getMetadata(String name);
/**
* Returns whether the attribute with the given {@code name} is required.
*
* @param name the attribute name
* @return {@code true} if the attribute is required. Otherwise, {@code false}.
*/
boolean isRequired(String name);
/**
* Similar to {{@link #getReadable(boolean)}} but with the possibility to add or remove
* the root attributes.
*
* @param includeBuiltin if the root attributes should be included.
* @return the attributes with read/write permission.
*/
default Map> getReadable(boolean includeBuiltin) {
return getReadable().entrySet().stream().filter(entry -> {
if (includeBuiltin) {
return true;
}
if (isRootAttribute(entry.getKey())) {
if (UserModel.LOCALE.equals(entry.getKey()) && !entry.getValue().isEmpty()) {
// locale is different form of built-in attribute in the sense it is related to a
// specific feature (i18n) and does not have a top-level attribute in the user representation
// the locale should be available from the attribute map if not empty
return true;
}
return false;
}
return true;
}).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
/**
* Returns only the attributes that have read/write permissions.
*
* @return the attributes with read/write permission.
*/
Map> getReadable();
/**
* Returns whether the attribute with the given {@code name} is a root attribute.
*
* @param name the attribute name
* @return
*/
default boolean isRootAttribute(String name) {
return UserModel.USERNAME.equals(name)
|| UserModel.EMAIL.equals(name)
|| UserModel.FIRST_NAME.equals(name)
|| UserModel.LAST_NAME.equals(name)
|| UserModel.LOCALE.equals(name);
}
Map> toMap();
}