[KEYCLOAK-16341] Make the new stream-based methods in server-spi user interfaces default instead of the collection-based versions.
- this ensures that providing implementation for the collection-based methods is enough, which preserves backwards compatibility with older custom implementations. - alternative interfaces now allow new implementations to focus on the stream variants of the query methods.
This commit is contained in:
parent
43baf1bea7
commit
84df008bc2
37 changed files with 932 additions and 264 deletions
|
@ -92,7 +92,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
|
|||
CredentialAuthentication,
|
||||
UserLookupProvider,
|
||||
UserRegistrationProvider,
|
||||
UserQueryProvider,
|
||||
UserQueryProvider.Streams,
|
||||
ImportedUserValidation {
|
||||
private static final Logger logger = Logger.getLogger(LDAPStorageProvider.class);
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ import org.keycloak.storage.ReadOnlyException;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class ReadonlyLDAPUserModelDelegate extends UserModelDelegate implements UserModel {
|
||||
public class ReadonlyLDAPUserModelDelegate extends UserModelDelegate {
|
||||
|
||||
public ReadonlyLDAPUserModelDelegate(UserModel delegate) {
|
||||
super(delegate);
|
||||
|
|
|
@ -36,7 +36,7 @@ import java.util.stream.Stream;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class GroupAdapter implements GroupModel {
|
||||
public class GroupAdapter implements GroupModel.Streams {
|
||||
|
||||
protected final CachedGroup cached;
|
||||
protected final RealmCacheSession cacheSession;
|
||||
|
|
|
@ -42,7 +42,7 @@ import java.util.stream.Stream;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class UserAdapter implements CachedUserModel {
|
||||
public class UserAdapter implements CachedUserModel.Streams {
|
||||
|
||||
private final Supplier<UserModel> modelSupplier;
|
||||
protected final CachedUser cached;
|
||||
|
|
|
@ -71,7 +71,7 @@ import java.util.stream.Stream;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class UserCacheSession implements UserCache {
|
||||
public class UserCacheSession implements UserCache.Streams {
|
||||
protected static final Logger logger = Logger.getLogger(UserCacheSession.class);
|
||||
protected UserCacheManager cache;
|
||||
protected KeycloakSession session;
|
||||
|
|
|
@ -31,12 +31,10 @@ import org.keycloak.models.utils.RoleUtils;
|
|||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.TypedQuery;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
import javax.persistence.LockModeType;
|
||||
|
||||
|
@ -46,7 +44,7 @@ import static org.keycloak.utils.StreamsUtil.closing;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class GroupAdapter implements GroupModel , JpaModel<GroupEntity> {
|
||||
public class GroupAdapter implements GroupModel.Streams , JpaModel<GroupEntity> {
|
||||
|
||||
protected GroupEntity group;
|
||||
protected EntityManager em;
|
||||
|
|
|
@ -82,7 +82,7 @@ import static org.keycloak.utils.StreamsUtil.closing;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
@SuppressWarnings("JpaQueryApiInspection")
|
||||
public class JpaUserProvider implements UserProvider, UserCredentialStore {
|
||||
public class JpaUserProvider implements UserProvider.Streams, UserCredentialStore {
|
||||
|
||||
private static final String EMAIL = "email";
|
||||
private static final String EMAIL_VERIFIED = "emailVerified";
|
||||
|
|
|
@ -53,7 +53,7 @@ import static org.keycloak.utils.StreamsUtil.closing;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class UserAdapter implements UserModel, JpaModel<UserEntity> {
|
||||
public class UserAdapter implements UserModel.Streams, JpaModel<UserEntity> {
|
||||
|
||||
protected UserEntity user;
|
||||
protected EntityManager em;
|
||||
|
|
|
@ -70,7 +70,7 @@ import static org.keycloak.utils.StreamsUtil.closing;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class JpaUserFederatedStorageProvider implements
|
||||
UserFederatedStorageProvider,
|
||||
UserFederatedStorageProvider.Streams,
|
||||
UserCredentialStore {
|
||||
|
||||
protected static final Logger logger = Logger.getLogger(JpaUserFederatedStorageProvider.class);
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.keycloak.models.map.common.AbstractEntity;
|
|||
|
||||
import java.util.Objects;
|
||||
|
||||
public abstract class AbstractGroupModel<E extends AbstractEntity> implements GroupModel {
|
||||
public abstract class AbstractGroupModel<E extends AbstractEntity> implements GroupModel.Streams {
|
||||
|
||||
protected final KeycloakSession session;
|
||||
protected final RealmModel realm;
|
||||
|
|
|
@ -31,7 +31,6 @@ import org.keycloak.models.utils.RoleUtils;
|
|||
import org.keycloak.storage.ReadOnlyException;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -41,7 +40,7 @@ import java.util.stream.Stream;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class InMemoryUserAdapter extends UserModelDefaultMethods {
|
||||
public class InMemoryUserAdapter extends UserModelDefaultMethods.Streams {
|
||||
private Long createdTimestamp = Time.currentTimeMillis();
|
||||
private boolean emailVerified;
|
||||
private boolean enabled;
|
||||
|
|
|
@ -68,11 +68,12 @@ public interface GroupModel extends RoleMapperModel {
|
|||
* @return list of all attribute values or empty list if there are not any values. Never return null
|
||||
*/
|
||||
@Deprecated
|
||||
default List<String> getAttribute(String name) {
|
||||
return getAttributeStream(name).collect(Collectors.toList());
|
||||
}
|
||||
List<String> getAttribute(String name);
|
||||
|
||||
Stream<String> getAttributeStream(String name);
|
||||
default Stream<String> getAttributeStream(String name) {
|
||||
List<String> value = this.getAttribute(name);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
Map<String, List<String>> getAttributes();
|
||||
|
||||
|
@ -80,11 +81,12 @@ public interface GroupModel extends RoleMapperModel {
|
|||
String getParentId();
|
||||
|
||||
@Deprecated
|
||||
default Set<GroupModel> getSubGroups() {
|
||||
return getSubGroupsStream().collect(Collectors.toSet());
|
||||
}
|
||||
Set<GroupModel> getSubGroups();
|
||||
|
||||
Stream<GroupModel> getSubGroupsStream();
|
||||
default Stream<GroupModel> getSubGroupsStream() {
|
||||
Set<GroupModel> value = this.getSubGroups();
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* You must also call addChild on the parent group, addChild on RealmModel if there is no parent group
|
||||
|
@ -106,4 +108,29 @@ public interface GroupModel extends RoleMapperModel {
|
|||
* @param subGroup
|
||||
*/
|
||||
void removeChild(GroupModel subGroup);
|
||||
|
||||
/**
|
||||
* The {@link GroupModel.Streams} interface makes all collection-based methods in {@link GroupModel} default by providing
|
||||
* implementations that delegate to the {@link Stream}-based variants instead of the other way around.
|
||||
* <p/>
|
||||
* It allows for implementations to focus on the {@link Stream}-based approach for processing sets of data and benefit
|
||||
* from the potential memory and performance optimizations of that approach.
|
||||
*/
|
||||
interface Streams extends GroupModel, RoleMapperModel.Streams {
|
||||
@Override
|
||||
default List<String> getAttribute(String name) {
|
||||
return this.getAttributeStream(name).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<String> getAttributeStream(String name);
|
||||
|
||||
@Override
|
||||
default Set<GroupModel> getSubGroups() {
|
||||
return this.getSubGroupsStream().collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<GroupModel> getSubGroupsStream();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,15 +32,16 @@ public interface RoleMapperModel {
|
|||
* @deprecated Use {@link #getRealmRoleMappingsStream()} getRealmRoleMappingsStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default Set<RoleModel> getRealmRoleMappings() {
|
||||
return getRealmRoleMappingsStream().collect(Collectors.toSet());
|
||||
}
|
||||
Set<RoleModel> getRealmRoleMappings();
|
||||
|
||||
/**
|
||||
* Returns stream of realm roles that are directly set to this object.
|
||||
* @return stream of {@link RoleModel}
|
||||
*/
|
||||
Stream<RoleModel> getRealmRoleMappingsStream();
|
||||
default Stream<RoleModel> getRealmRoleMappingsStream() {
|
||||
Set<RoleModel> value = this.getRealmRoleMappings();
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set of client roles that are directly set to this object for the given client.
|
||||
|
@ -49,16 +50,17 @@ public interface RoleMapperModel {
|
|||
* @deprecated Use {@link #getClientRoleMappingsStream(ClientModel)} getClientRoleMappingsStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default Set<RoleModel> getClientRoleMappings(ClientModel app) {
|
||||
return getClientRoleMappingsStream(app).collect(Collectors.toSet());
|
||||
}
|
||||
Set<RoleModel> getClientRoleMappings(ClientModel app);
|
||||
|
||||
/**
|
||||
* Returns stream of client roles that are directly set to this object for the given client.
|
||||
* @param app Client to get the roles for
|
||||
* @return stream of {@link RoleModel}
|
||||
*/
|
||||
Stream<RoleModel> getClientRoleMappingsStream(ClientModel app);
|
||||
default Stream<RoleModel> getClientRoleMappingsStream(ClientModel app) {
|
||||
Set<RoleModel> value = this.getClientRoleMappings(app);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this object is directly or indirectly assigned the given role, {@code false} otherwise.
|
||||
|
@ -86,19 +88,53 @@ public interface RoleMapperModel {
|
|||
* @deprecated Use {@link #getRoleMappingsStream()} getRoleMappingsStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default Set<RoleModel> getRoleMappings() {
|
||||
return getRoleMappingsStream().collect(Collectors.toSet());
|
||||
}
|
||||
Set<RoleModel> getRoleMappings();
|
||||
|
||||
/**
|
||||
* Returns stream of all role (both realm all client) that are directly set to this object.
|
||||
* @return stream of {@link RoleModel}
|
||||
*/
|
||||
Stream<RoleModel> getRoleMappingsStream();
|
||||
default Stream<RoleModel> getRoleMappingsStream() {
|
||||
Set<RoleModel> value = this.getRoleMappings();
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given role mapping from this object.
|
||||
* @param role Role to remove
|
||||
*/
|
||||
void deleteRoleMapping(RoleModel role);
|
||||
|
||||
/**
|
||||
* The {@link Streams} interface makes all collection-based methods in {@link RoleMapperModel} default by providing
|
||||
* implementations that delegate to the {@link Stream}-based variants instead of the other way around.
|
||||
* <p/>
|
||||
* It allows for implementations to focus on the {@link Stream}-based approach for processing sets of data and benefit
|
||||
* from the potential memory and performance optimizations of that approach.
|
||||
*/
|
||||
interface Streams extends RoleMapperModel {
|
||||
@Override
|
||||
default Set<RoleModel> getRealmRoleMappings() {
|
||||
return this.getRealmRoleMappingsStream().collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<RoleModel> getRealmRoleMappingsStream();
|
||||
|
||||
@Override
|
||||
default Set<RoleModel> getClientRoleMappings(ClientModel app) {
|
||||
return this.getClientRoleMappingsStream(app).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<RoleModel> getClientRoleMappingsStream(ClientModel app);
|
||||
|
||||
@Override
|
||||
default Set<RoleModel> getRoleMappings() {
|
||||
return this.getRoleMappingsStream().collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<RoleModel> getRoleMappingsStream();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,17 +94,18 @@ public interface UserModel extends RoleMapperModel {
|
|||
* @deprecated Use {@link #getAttributeStream(String) getAttributeStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<String> getAttribute(String name) {
|
||||
return this.getAttributeStream(name).collect(Collectors.toList());
|
||||
}
|
||||
List<String> getAttribute(String name);
|
||||
|
||||
/**
|
||||
* Obtains all values associated with the specified attribute name.
|
||||
*
|
||||
* @param name the name of the attribute.
|
||||
* @return a non-null {@code Stream} of attribute values.
|
||||
* @return a non-null {@link Stream} of attribute values.
|
||||
*/
|
||||
Stream<String> getAttributeStream(final String name);
|
||||
default Stream<String> getAttributeStream(final String name) {
|
||||
List<String> value = this.getAttribute(name);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
Map<String, List<String>> getAttributes();
|
||||
|
||||
|
@ -112,16 +113,17 @@ public interface UserModel extends RoleMapperModel {
|
|||
* @deprecated Use {@link #getRequiredActionsStream() getRequiredActionsStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default Set<String> getRequiredActions() {
|
||||
return this.getRequiredActionsStream().collect(Collectors.toSet());
|
||||
}
|
||||
Set<String> getRequiredActions();
|
||||
|
||||
/**
|
||||
* Obtains the names of required actions associated with the user.
|
||||
*
|
||||
* @return a non-null {@code Stream} of required action names.
|
||||
* @return a non-null {@link Stream} of required action names.
|
||||
*/
|
||||
Stream<String> getRequiredActionsStream();
|
||||
default Stream<String> getRequiredActionsStream() {
|
||||
Set<String> value = this.getRequiredActions();
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
void addRequiredAction(String action);
|
||||
|
||||
|
@ -151,16 +153,17 @@ public interface UserModel extends RoleMapperModel {
|
|||
* @deprecated Use {@link #getGroupsStream() getGroupsStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default Set<GroupModel> getGroups() {
|
||||
return getGroupsStream().collect(Collectors.toSet());
|
||||
}
|
||||
Set<GroupModel> getGroups();
|
||||
|
||||
/**
|
||||
* Obtains the groups associated with the user.
|
||||
*
|
||||
* @return a non-null {@code Stream} of groups.
|
||||
* @return a non-null {@link Stream} of groups.
|
||||
*/
|
||||
Stream<GroupModel> getGroupsStream();
|
||||
default Stream<GroupModel> getGroupsStream() {
|
||||
Set<GroupModel> value = this.getGroups();
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getGroupsStream(String, Integer, Integer) getGroupsStream} instead.
|
||||
|
@ -230,4 +233,37 @@ public interface UserModel extends RoleMapperModel {
|
|||
enum RequiredAction {
|
||||
VERIFY_EMAIL, UPDATE_PROFILE, CONFIGURE_TOTP, UPDATE_PASSWORD, TERMS_AND_CONDITIONS
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link UserModel.Streams} interface makes all collection-based methods in {@link UserModel} default by providing
|
||||
* implementations that delegate to the {@link Stream}-based variants instead of the other way around.
|
||||
* <p/>
|
||||
* It allows for implementations to focus on the {@link Stream}-based approach for processing sets of data and benefit
|
||||
* from the potential memory and performance optimizations of that approach.
|
||||
*/
|
||||
interface Streams extends UserModel, RoleMapperModel.Streams {
|
||||
@Override
|
||||
default List<String> getAttribute(String name) {
|
||||
return this.getAttributeStream(name).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<String> getAttributeStream(final String name);
|
||||
|
||||
@Override
|
||||
default Set<String> getRequiredActions() {
|
||||
return this.getRequiredActionsStream().collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<String> getRequiredActionsStream();
|
||||
|
||||
@Override
|
||||
default Set<GroupModel> getGroups() {
|
||||
return this.getGroupsStream().collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<GroupModel> getGroupsStream();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
package org.keycloak.models;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:external.Martin.Idel@bosch.io">Martin Idel</a>
|
||||
* @version $Revision: 1 $
|
||||
|
@ -53,4 +55,13 @@ public abstract class UserModelDefaultMethods implements UserModel {
|
|||
email = email == null ? null : email.toLowerCase();
|
||||
setSingleAttribute(EMAIL, email);
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link UserModelDefaultMethods.Streams} class extends the {@link UserModelDefaultMethods} abstract class and
|
||||
* implements the {@link UserModel.Streams} interface, allowing subclasses to focus on the implementation of the
|
||||
* {@link Stream}-based query methods and providing default implementations for the collections-based variants that
|
||||
* delegate to their {@link Stream} counterparts.
|
||||
*/
|
||||
public abstract static class Streams extends UserModelDefaultMethods implements UserModel.Streams {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,18 +49,19 @@ public interface UserProvider extends Provider,
|
|||
* @deprecated Use {@link #getFederatedIdentitiesStream(UserModel, RealmModel) getFederatedIdentitiesStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default Set<FederatedIdentityModel> getFederatedIdentities(UserModel user, RealmModel realm) {
|
||||
return this.getFederatedIdentitiesStream(user, realm).collect(Collectors.toSet());
|
||||
}
|
||||
Set<FederatedIdentityModel> getFederatedIdentities(UserModel user, RealmModel realm);
|
||||
|
||||
/**
|
||||
* Obtains the federated identities of the specified user.
|
||||
*
|
||||
* @param user a reference to the user.
|
||||
* @param realm a reference to the realm.
|
||||
* @return a non-null {@code Stream} of federated identities associated with the user.
|
||||
* @return a non-null {@link Stream} of federated identities associated with the user.
|
||||
*/
|
||||
Stream<FederatedIdentityModel> getFederatedIdentitiesStream(UserModel user, RealmModel realm);
|
||||
default Stream<FederatedIdentityModel> getFederatedIdentitiesStream(UserModel user, RealmModel realm) {
|
||||
Set<FederatedIdentityModel> value = this.getFederatedIdentities(user, realm);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm);
|
||||
UserModel getUserByFederatedIdentity(FederatedIdentityModel socialLink, RealmModel realm);
|
||||
|
@ -72,18 +73,19 @@ public interface UserProvider extends Provider,
|
|||
* @deprecated Use {@link #getConsentsStream(RealmModel, String) getConsentsStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<UserConsentModel> getConsents(RealmModel realm, String userId) {
|
||||
return getConsentsStream(realm, userId).collect(Collectors.toList());
|
||||
}
|
||||
List<UserConsentModel> getConsents(RealmModel realm, String userId);
|
||||
|
||||
/**
|
||||
* Obtains the consents associated with the user identified by the specified {@code userId}.
|
||||
*
|
||||
* @param realm a reference to the realm.
|
||||
* @param userId the user identifier.
|
||||
* @return a non-null {@code Stream} of consents associated with the user.
|
||||
* @return a non-null {@link Stream} of consents associated with the user.
|
||||
*/
|
||||
Stream<UserConsentModel> getConsentsStream(RealmModel realm, String userId);
|
||||
default Stream<UserConsentModel> getConsentsStream(RealmModel realm, String userId) {
|
||||
List<UserConsentModel> value = this.getConsents(realm, userId);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
void updateConsent(RealmModel realm, String userId, UserConsentModel consent);
|
||||
boolean revokeConsentForClient(RealmModel realm, String userId, String clientInternalId);
|
||||
|
@ -97,26 +99,25 @@ public interface UserProvider extends Provider,
|
|||
* @deprecated Use {@link #getUsersStream(RealmModel, boolean) getUsersStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<UserModel> getUsers(RealmModel realm, boolean includeServiceAccounts) {
|
||||
return this.getUsersStream(realm, includeServiceAccounts).collect(Collectors.toList());
|
||||
}
|
||||
List<UserModel> getUsers(RealmModel realm, boolean includeServiceAccounts);
|
||||
|
||||
/**
|
||||
* Obtains the users associated with the specified realm.
|
||||
*
|
||||
* @param realm a reference to the realm being used for the search.
|
||||
* @param includeServiceAccounts {@code true} if service accounts should be included in the result; {@code false} otherwise.
|
||||
* @return a non-null {@code Stream} of users associated withe the realm.
|
||||
* @return a non-null {@link Stream} of users associated withe the realm.
|
||||
*/
|
||||
Stream<UserModel> getUsersStream(RealmModel realm, boolean includeServiceAccounts);
|
||||
default Stream<UserModel> getUsersStream(RealmModel realm, boolean includeServiceAccounts) {
|
||||
List<UserModel> value = this.getUsers(realm, includeServiceAccounts);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getUsersStream(RealmModel, int, int, boolean) getUsersStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults, boolean includeServiceAccounts) {
|
||||
return this.getUsersStream(realm, firstResult, maxResults, includeServiceAccounts).collect(Collectors.toList());
|
||||
}
|
||||
List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults, boolean includeServiceAccounts);
|
||||
|
||||
/**
|
||||
* Obtains the users associated with the specified realm.
|
||||
|
@ -125,9 +126,12 @@ public interface UserProvider extends Provider,
|
|||
* @param firstResult first result to return. Ignored if negative.
|
||||
* @param maxResults maximum number of results to return. Ignored if negative.
|
||||
* @param includeServiceAccounts {@code true} if service accounts should be included in the result; {@code false} otherwise.
|
||||
* @return a non-null {@code Stream} of users associated withe the realm.
|
||||
* @return a non-null {@link Stream} of users associated withe the realm.
|
||||
*/
|
||||
Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults, boolean includeServiceAccounts);
|
||||
default Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults, boolean includeServiceAccounts) {
|
||||
List<UserModel> value = this.getUsers(realm, firstResult, maxResults, includeServiceAccounts);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* only used for local storage
|
||||
|
@ -168,4 +172,38 @@ public interface UserProvider extends Provider,
|
|||
void close();
|
||||
|
||||
void preRemove(RealmModel realm, ComponentModel component);
|
||||
|
||||
interface Streams extends UserProvider, UserQueryProvider.Streams {
|
||||
@Override
|
||||
default Set<FederatedIdentityModel> getFederatedIdentities(UserModel user, RealmModel realm) {
|
||||
return this.getFederatedIdentitiesStream(user, realm).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<FederatedIdentityModel> getFederatedIdentitiesStream(UserModel user, RealmModel realm);
|
||||
|
||||
@Override
|
||||
default List<UserConsentModel> getConsents(RealmModel realm, String userId) {
|
||||
return this.getConsentsStream(realm, userId).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<UserConsentModel> getConsentsStream(RealmModel realm, String userId);
|
||||
|
||||
@Override
|
||||
default List<UserModel> getUsers(RealmModel realm, boolean includeServiceAccounts) {
|
||||
return this.getUsersStream(realm, includeServiceAccounts).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<UserModel> getUsersStream(RealmModel realm, boolean includeServiceAccounts);
|
||||
|
||||
@Override
|
||||
default List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults, boolean includeServiceAccounts) {
|
||||
return this.getUsersStream(realm, firstResult, maxResults, includeServiceAccounts).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults, boolean includeServiceAccounts);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package org.keycloak.models.cache;
|
||||
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserProvider;
|
||||
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
|
@ -56,4 +57,12 @@ public interface CachedUserModel extends UserModel {
|
|||
* @return
|
||||
*/
|
||||
ConcurrentMap getCachedWith();
|
||||
|
||||
/**
|
||||
* The {@link CachedUserModel.Streams} interface differs from {@link CachedUserModel} in that it extends the
|
||||
* {@link UserModel.Streams} interface, allowing implementations of {@link CachedUserModel} to focus on the
|
||||
* {@link java.util.stream.Stream}-based methods in the {@link UserModel} interface.
|
||||
*/
|
||||
interface Streams extends CachedUserModel, UserModel.Streams {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,4 +47,12 @@ public interface UserCache extends UserProvider {
|
|||
*
|
||||
*/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* The {@link UserCache.Streams} interface differs from {@link UserCache} in that it extends the {@link UserProvider.Streams}
|
||||
* interface, allowing implementations of {@link UserCache} to focus on the {@link java.util.stream.Stream}-based methods
|
||||
* in the {@link UserProvider} interface.
|
||||
*/
|
||||
interface Streams extends UserCache, UserProvider.Streams {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ import java.util.stream.Stream;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class UserModelDelegate implements UserModel {
|
||||
public class UserModelDelegate implements UserModel.Streams {
|
||||
protected UserModel delegate;
|
||||
|
||||
public UserModelDelegate(UserModel delegate) {
|
||||
|
|
|
@ -30,8 +30,12 @@ import org.keycloak.models.utils.RoleUtils;
|
|||
import org.keycloak.storage.ReadOnlyException;
|
||||
import org.keycloak.storage.StorageId;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
|
@ -59,8 +63,8 @@ public abstract class AbstractUserAdapter extends UserModelDefaultMethods {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getRequiredActionsStream() {
|
||||
return Stream.empty();
|
||||
public Set<String> getRequiredActions() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -91,8 +95,8 @@ public abstract class AbstractUserAdapter extends UserModelDefaultMethods {
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
protected Stream<GroupModel> getGroupsInternal() {
|
||||
return Stream.empty();
|
||||
protected Set<GroupModel> getGroupsInternal() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,10 +111,11 @@ public abstract class AbstractUserAdapter extends UserModelDefaultMethods {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Stream<GroupModel> getGroupsStream() {
|
||||
Stream<GroupModel> groups = getGroupsInternal();
|
||||
if (appendDefaultGroups()) groups = Stream.concat(groups, realm.getDefaultGroupsStream());
|
||||
return groups;
|
||||
public Set<GroupModel> getGroups() {
|
||||
Set<GroupModel> set = new HashSet<>();
|
||||
if (appendDefaultGroups()) set.addAll(realm.getDefaultGroupsStream().collect(Collectors.toSet()));
|
||||
set.addAll(getGroupsInternal());
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -127,23 +132,23 @@ public abstract class AbstractUserAdapter extends UserModelDefaultMethods {
|
|||
|
||||
@Override
|
||||
public boolean isMemberOf(GroupModel group) {
|
||||
return RoleUtils.isMember(getGroupsStream(), group);
|
||||
return RoleUtils.isMember(getGroups().stream(), group);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<RoleModel> getRealmRoleMappingsStream() {
|
||||
return getRoleMappingsStream().filter(RoleUtils::isRealmRole);
|
||||
public Set<RoleModel> getRealmRoleMappings() {
|
||||
return getRoleMappings().stream().filter(RoleUtils::isRealmRole).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<RoleModel> getClientRoleMappingsStream(ClientModel app) {
|
||||
return getRoleMappingsStream().filter(r -> RoleUtils.isClientRole(r, app));
|
||||
public Set<RoleModel> getClientRoleMappings(ClientModel app) {
|
||||
return getRoleMappings().stream().filter(r -> RoleUtils.isClientRole(r, app)).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRole(RoleModel role) {
|
||||
return RoleUtils.hasRole(getRoleMappingsStream(), role)
|
||||
|| RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true);
|
||||
return RoleUtils.hasRole(getRoleMappings().stream(), role)
|
||||
|| RoleUtils.hasRoleFromGroup(getGroups().stream(), role, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -163,15 +168,16 @@ public abstract class AbstractUserAdapter extends UserModelDefaultMethods {
|
|||
return true;
|
||||
}
|
||||
|
||||
protected Stream<RoleModel> getRoleMappingsInternal() {
|
||||
return Stream.empty();
|
||||
protected Set<RoleModel> getRoleMappingsInternal() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<RoleModel> getRoleMappingsStream() {
|
||||
Stream<RoleModel> roleMappings = getRoleMappingsInternal();
|
||||
if (appendDefaultRolesToRoleMappings()) return Stream.concat(roleMappings, DefaultRoles.getDefaultRoles(realm));
|
||||
return roleMappings;
|
||||
public Set<RoleModel> getRoleMappings() {
|
||||
Set<RoleModel> set = new HashSet<>();
|
||||
if (appendDefaultRolesToRoleMappings()) set.addAll(DefaultRoles.getDefaultRoles(realm).collect(Collectors.toSet()));
|
||||
set.addAll(getRoleMappingsInternal());
|
||||
return set;
|
||||
}
|
||||
|
||||
|
||||
|
@ -300,11 +306,11 @@ public abstract class AbstractUserAdapter extends UserModelDefaultMethods {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getAttributeStream(String name) {
|
||||
public List<String> getAttribute(String name) {
|
||||
if (name.equals(UserModel.USERNAME)) {
|
||||
return Stream.of(getUsername());
|
||||
return Collections.singletonList(getUsername());
|
||||
}
|
||||
return Stream.empty();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -365,4 +371,100 @@ public abstract class AbstractUserAdapter extends UserModelDefaultMethods {
|
|||
return getId().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link AbstractUserAdapter.Streams} class extends the {@link AbstractUserAdapter} abstract class and implements
|
||||
* the {@link UserModel.Streams} interface, allowing subclasses to focus on the implementation of the {@link Stream}-based
|
||||
* query methods and providing default implementations for the collections-based variants that delegate to their
|
||||
* {@link Stream} counterparts.
|
||||
*/
|
||||
public abstract static class Streams extends AbstractUserAdapter implements UserModel.Streams {
|
||||
|
||||
public Streams(final KeycloakSession session, final RealmModel realm, final ComponentModel storageProviderModel) {
|
||||
super(session, realm, storageProviderModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRequiredActions() {
|
||||
return this.getRequiredActionsStream().collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getRequiredActionsStream() {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAttribute(String name) {
|
||||
return this.getAttributeStream(name).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getAttributeStream(String name) {
|
||||
if (name.equals(UserModel.USERNAME)) {
|
||||
return Stream.of(getUsername());
|
||||
}
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
// group-related methods.
|
||||
|
||||
|
||||
@Override
|
||||
public Set<GroupModel> getGroups() {
|
||||
return this.getGroupsStream().collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<GroupModel> getGroupsStream() {
|
||||
Stream<GroupModel> groups = getGroupsInternal().stream();
|
||||
if (appendDefaultGroups()) groups = Stream.concat(groups, realm.getDefaultGroupsStream());
|
||||
return groups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMemberOf(GroupModel group) {
|
||||
return RoleUtils.isMember(this.getGroupsStream(), group);
|
||||
}
|
||||
|
||||
// role-related methods.
|
||||
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> getRealmRoleMappings() {
|
||||
return this.getRealmRoleMappingsStream().collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<RoleModel> getRealmRoleMappingsStream() {
|
||||
return getRoleMappingsStream().filter(RoleUtils::isRealmRole);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> getClientRoleMappings(ClientModel app) {
|
||||
return this.getClientRoleMappingsStream(app).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<RoleModel> getClientRoleMappingsStream(ClientModel app) {
|
||||
return getRoleMappingsStream().filter(r -> RoleUtils.isClientRole(r, app));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> getRoleMappings() {
|
||||
return this.getRoleMappingsStream().collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<RoleModel> getRoleMappingsStream() {
|
||||
Stream<RoleModel> roleMappings = getRoleMappingsInternal().stream();
|
||||
if (appendDefaultRolesToRoleMappings()) return Stream.concat(roleMappings, DefaultRoles.getDefaultRoles(realm));
|
||||
return roleMappings;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRole(RoleModel role) {
|
||||
return RoleUtils.hasRole(this.getRoleMappingsStream(), role)
|
||||
|| RoleUtils.hasRoleFromGroup(this.getGroupsStream(), role, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,8 +30,12 @@ import org.keycloak.models.utils.RoleUtils;
|
|||
import org.keycloak.storage.StorageId;
|
||||
import org.keycloak.storage.federated.UserFederatedStorageProvider;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
|
@ -68,8 +72,8 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau
|
|||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getRequiredActionsStream() {
|
||||
return getFederatedStorage().getRequiredActionsStream(realm, this.getId());
|
||||
public Set<String> getRequiredActions() {
|
||||
return getFederatedStorage().getRequiredActions(realm, this.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -100,8 +104,8 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau
|
|||
*
|
||||
* @return
|
||||
*/
|
||||
protected Stream<GroupModel> getGroupsInternal() {
|
||||
return Stream.empty();
|
||||
protected Set<GroupModel> getGroupsInternal() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -124,10 +128,11 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau
|
|||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Stream<GroupModel> getGroupsStream() {
|
||||
Stream<GroupModel> groups = getFederatedStorage().getGroupsStream(realm, this.getId());
|
||||
if (appendDefaultGroups()) groups = Stream.concat(groups, realm.getDefaultGroupsStream());
|
||||
return Stream.concat(groups, getGroupsInternal());
|
||||
public Set<GroupModel> getGroups() {
|
||||
Set<GroupModel> set = new HashSet<>(getFederatedStorage().getGroups(realm, this.getId()));
|
||||
if (appendDefaultGroups()) set.addAll(realm.getDefaultGroupsStream().collect(Collectors.toSet()));
|
||||
set.addAll(getGroupsInternal());
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -144,7 +149,7 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau
|
|||
|
||||
@Override
|
||||
public boolean isMemberOf(GroupModel group) {
|
||||
return RoleUtils.isMember(getGroupsStream(), group);
|
||||
return RoleUtils.isMember(getGroups().stream(), group);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -156,8 +161,8 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau
|
|||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Stream<RoleModel> getRealmRoleMappingsStream() {
|
||||
return getRoleMappingsStream().filter(RoleUtils::isRealmRole);
|
||||
public Set<RoleModel> getRealmRoleMappings() {
|
||||
return this.getRoleMappings().stream().filter(RoleUtils::isRealmRole).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -169,14 +174,15 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau
|
|||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Stream<RoleModel> getClientRoleMappingsStream(ClientModel app) {
|
||||
return getRoleMappingsStream().filter(r -> RoleUtils.isClientRole(r, app));
|
||||
public Set<RoleModel> getClientRoleMappings(ClientModel app) {
|
||||
return getRoleMappings().stream().filter(r -> RoleUtils.isClientRole(r, app)).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean hasRole(RoleModel role) {
|
||||
return RoleUtils.hasRole(getRoleMappingsStream(), role)
|
||||
|| RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true);
|
||||
return RoleUtils.hasRole(getRoleMappings().stream(), role)
|
||||
|| RoleUtils.hasRoleFromGroup(getGroups().stream(), role, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -196,8 +202,8 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau
|
|||
return true;
|
||||
}
|
||||
|
||||
protected Stream<RoleModel> getRoleMappingsInternal() {
|
||||
return Stream.empty();
|
||||
protected Set<RoleModel> getRoleMappingsInternal() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -208,14 +214,15 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau
|
|||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Stream<RoleModel> getRoleMappingsStream() {
|
||||
Stream<RoleModel> roleMappings = getFederatedRoleMappings();
|
||||
if (appendDefaultRolesToRoleMappings()) roleMappings = Stream.concat(roleMappings, DefaultRoles.getDefaultRoles(realm));
|
||||
return Stream.concat(roleMappings, getRoleMappingsInternal());
|
||||
public Set<RoleModel> getRoleMappings() {
|
||||
Set<RoleModel> set = new HashSet<>(getFederatedRoleMappings());
|
||||
if (appendDefaultRolesToRoleMappings()) set.addAll(DefaultRoles.getDefaultRoles(realm).collect(Collectors.toSet()));
|
||||
set.addAll(getRoleMappingsInternal());
|
||||
return set;
|
||||
}
|
||||
|
||||
protected Stream<RoleModel> getFederatedRoleMappings() {
|
||||
return getFederatedStorage().getRoleMappingsStream(realm, this.getId());
|
||||
protected Set<RoleModel> getFederatedRoleMappings() {
|
||||
return getFederatedStorage().getRoleMappings(realm, this.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -357,15 +364,15 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau
|
|||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getAttributeStream(String name) {
|
||||
public List<String> getAttribute(String name) {
|
||||
if (UserModel.USERNAME.equals(name)) {
|
||||
return Stream.of(getUsername());
|
||||
return Collections.singletonList(getUsername());
|
||||
}
|
||||
List<String> result = getFederatedStorage().getAttributes(realm, this.getId()).get(mapAttribute(name));
|
||||
return (result == null) ? Stream.empty() : result.stream();
|
||||
return (result == null) ? Collections.emptyList() : result;
|
||||
}
|
||||
|
||||
private String mapAttribute(String attributeName) {
|
||||
protected String mapAttribute(String attributeName) {
|
||||
if (UserModel.FIRST_NAME.equals(attributeName)) {
|
||||
return FIRST_NAME_ATTRIBUTE;
|
||||
} else if (UserModel.LAST_NAME.equals(attributeName)) {
|
||||
|
@ -409,4 +416,101 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau
|
|||
return getId().hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link AbstractUserAdapterFederatedStorage.Streams} class extends the {@link AbstractUserAdapterFederatedStorage}
|
||||
* abstract class and implements the {@link UserModel.Streams} interface, allowing subclasses to focus on the implementation
|
||||
* of the {@link Stream}-based query methods and providing default implementations for the collections-based variants
|
||||
* that delegate to their {@link Stream} counterparts.
|
||||
*/
|
||||
public abstract static class Streams extends AbstractUserAdapterFederatedStorage implements UserModel.Streams {
|
||||
|
||||
public Streams(final KeycloakSession session, final RealmModel realm, final ComponentModel storageProviderModel) {
|
||||
super(session, realm, storageProviderModel);
|
||||
}
|
||||
|
||||
// user-related methods.
|
||||
|
||||
@Override
|
||||
public Set<String> getRequiredActions() {
|
||||
return this.getRequiredActionsStream().collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getRequiredActionsStream() {
|
||||
return super.getFederatedStorage().getRequiredActionsStream(super.realm, super.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getAttribute(String name) {
|
||||
return this.getAttributeStream(name).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getAttributeStream(String name) {
|
||||
if (UserModel.USERNAME.equals(name)) {
|
||||
return Stream.of(getUsername());
|
||||
}
|
||||
List<String> result = super.getFederatedStorage().getAttributes(realm, this.getId()).get(super.mapAttribute(name));
|
||||
return (result == null) ? Stream.empty() : result.stream();
|
||||
}
|
||||
|
||||
// group-related methods.
|
||||
|
||||
@Override
|
||||
public Set<GroupModel> getGroups() {
|
||||
return this.getGroupsStream().collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<GroupModel> getGroupsStream() {
|
||||
Stream<GroupModel> groups = getFederatedStorage().getGroupsStream(realm, this.getId());
|
||||
if (appendDefaultGroups()) groups = Stream.concat(groups, realm.getDefaultGroupsStream());
|
||||
return Stream.concat(groups, getGroupsInternal().stream());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMemberOf(GroupModel group) {
|
||||
return RoleUtils.isMember(this.getGroupsStream(), group);
|
||||
}
|
||||
|
||||
// role-related methods.
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> getRealmRoleMappings() {
|
||||
return this.getRealmRoleMappingsStream().collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<RoleModel> getRealmRoleMappingsStream() {
|
||||
return getRoleMappingsStream().filter(RoleUtils::isRealmRole);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> getClientRoleMappings(ClientModel app) {
|
||||
return this.getClientRoleMappingsStream(app).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<RoleModel> getClientRoleMappingsStream(ClientModel app) {
|
||||
return getRoleMappingsStream().filter(r -> RoleUtils.isClientRole(r, app));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<RoleModel> getRoleMappings() {
|
||||
return this.getRoleMappingsStream().collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<RoleModel> getRoleMappingsStream() {
|
||||
Stream<RoleModel> roleMappings = getFederatedRoleMappings().stream();
|
||||
if (appendDefaultRolesToRoleMappings()) roleMappings = Stream.concat(roleMappings, DefaultRoles.getDefaultRoles(realm));
|
||||
return Stream.concat(roleMappings, getRoleMappingsInternal().stream());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRole(RoleModel role) {
|
||||
return RoleUtils.hasRole(this.getRoleMappingsStream(), role)
|
||||
|| RoleUtils.hasRoleFromGroup(this.getGroupsStream(), role, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,9 +37,7 @@ public interface UserAttributeFederatedStorage {
|
|||
* @deprecated Use {@link #getUsersByUserAttributeStream(RealmModel, String, String) getUsersByUserAttributeStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<String> getUsersByUserAttribute(RealmModel realm, String name, String value) {
|
||||
return this.getUsersByUserAttributeStream(realm, name, value).collect(Collectors.toList());
|
||||
}
|
||||
List<String> getUsersByUserAttribute(RealmModel realm, String name, String value);
|
||||
|
||||
/**
|
||||
* Searches for federated users that have an attribute with the specified {@code name} and {@code value}.
|
||||
|
@ -47,7 +45,29 @@ public interface UserAttributeFederatedStorage {
|
|||
* @param realm a reference to the realm.
|
||||
* @param name the attribute name.
|
||||
* @param value the attribute value.
|
||||
* @return a non-null {@code Stream} of users that match the search criteria.
|
||||
* @return a non-null {@link Stream} of users that match the search criteria.
|
||||
*/
|
||||
Stream<String> getUsersByUserAttributeStream(RealmModel realm, String name, String value);
|
||||
default Stream<String> getUsersByUserAttributeStream(RealmModel realm, String name, String value) {
|
||||
List<String> users = this.getUsersByUserAttribute(realm, name, value);
|
||||
return users != null ? users.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link Streams} interface makes all collection-based methods in {@link UserAttributeFederatedStorage}
|
||||
* default by providing implementations that delegate to the {@link Stream}-based variants instead of the other way
|
||||
* around.
|
||||
* <p/>
|
||||
* It allows for implementations to focus on the {@link Stream}-based approach for processing sets of data and benefit
|
||||
* from the potential memory and performance optimizations of that approach.
|
||||
*/
|
||||
interface Streams extends UserAttributeFederatedStorage {
|
||||
|
||||
@Override
|
||||
default List<String> getUsersByUserAttribute(RealmModel realm, String name, String value) {
|
||||
return this.getUsersByUserAttributeStream(realm, name, value).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<String> getUsersByUserAttributeStream(RealmModel realm, String name, String value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,18 +39,37 @@ public interface UserBrokerLinkFederatedStorage {
|
|||
* @deprecated Use {@link #getFederatedIdentitiesStream(String, RealmModel) getFederatedIdentitiesStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default Set<FederatedIdentityModel> getFederatedIdentities(String userId, RealmModel realm) {
|
||||
return this.getFederatedIdentitiesStream(userId, realm).collect(Collectors.toSet());
|
||||
}
|
||||
Set<FederatedIdentityModel> getFederatedIdentities(String userId, RealmModel realm);
|
||||
|
||||
/**
|
||||
* Obtains the identities of the federated user identified by {@code userId}.
|
||||
*
|
||||
* @param userId the user identifier.
|
||||
* @param realm a reference to the realm.
|
||||
* @return a non-null {@code Stream} of federated identities associated with the user.
|
||||
* @return a non-null {@link Stream} of federated identities associated with the user.
|
||||
*/
|
||||
Stream<FederatedIdentityModel> getFederatedIdentitiesStream(String userId, RealmModel realm);
|
||||
default Stream<FederatedIdentityModel> getFederatedIdentitiesStream(String userId, RealmModel realm) {
|
||||
Set<FederatedIdentityModel> value = this.getFederatedIdentities(userId, realm);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
FederatedIdentityModel getFederatedIdentity(String userId, String socialProvider, RealmModel realm);
|
||||
|
||||
/**
|
||||
* The {@link Streams} interface makes all collection-based methods in {@link UserBrokerLinkFederatedStorage}
|
||||
* default by providing implementations that delegate to the {@link Stream}-based variants instead of the other way
|
||||
* around.
|
||||
* <p/>
|
||||
* It allows for implementations to focus on the {@link Stream}-based approach for processing sets of data and benefit
|
||||
* from the potential memory and performance optimizations of that approach.
|
||||
*/
|
||||
interface Streams extends UserBrokerLinkFederatedStorage {
|
||||
@Override
|
||||
default Set<FederatedIdentityModel> getFederatedIdentities(String userId, RealmModel realm) {
|
||||
return this.getFederatedIdentitiesStream(userId, realm).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<FederatedIdentityModel> getFederatedIdentitiesStream(String userId, RealmModel realm);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,19 +35,38 @@ public interface UserConsentFederatedStorage {
|
|||
* @deprecated Use {@link #getConsentsStream(RealmModel, String) getConsentsStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<UserConsentModel> getConsents(RealmModel realm, String userId) {
|
||||
return this.getConsentsStream(realm, userId).collect(Collectors.toList());
|
||||
}
|
||||
List<UserConsentModel> getConsents(RealmModel realm, String userId);
|
||||
|
||||
/**
|
||||
* Obtains the consents associated with the federated user identified by {@code userId}.
|
||||
*
|
||||
* @param realm a reference to the realm.
|
||||
* @param userId the user identifier.
|
||||
* @return a non-null {@code Stream} of consents associated with the user.
|
||||
* @return a non-null {@link Stream} of consents associated with the user.
|
||||
*/
|
||||
Stream<UserConsentModel> getConsentsStream(RealmModel realm, String userId);
|
||||
default Stream<UserConsentModel> getConsentsStream(RealmModel realm, String userId) {
|
||||
List<UserConsentModel> value = this.getConsents(realm, userId);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
void updateConsent(RealmModel realm, String userId, UserConsentModel consent);
|
||||
boolean revokeConsentForClient(RealmModel realm, String userId, String clientInternalId);
|
||||
|
||||
/**
|
||||
* The {@link Streams} interface makes all collection-based methods in {@link UserConsentFederatedStorage}
|
||||
* default by providing implementations that delegate to the {@link Stream}-based variants instead of the other way
|
||||
* around.
|
||||
* <p/>
|
||||
* It allows for implementations to focus on the {@link Stream}-based approach for processing sets of data and benefit
|
||||
* from the potential memory and performance optimizations of that approach.
|
||||
*/
|
||||
interface Streams extends UserConsentFederatedStorage {
|
||||
@Override
|
||||
default List<UserConsentModel> getConsents(RealmModel realm, String userId) {
|
||||
return this.getConsentsStream(realm, userId).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<UserConsentModel> getConsentsStream(RealmModel realm, String userId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,9 +49,7 @@ public interface UserFederatedStorageProvider extends Provider,
|
|||
* @deprecated Use {@link #getStoredUsersStream(RealmModel, int, int) getStoredUsersStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<String> getStoredUsers(RealmModel realm, int first, int max) {
|
||||
return getStoredUsersStream(realm, first, max).collect(Collectors.toList());
|
||||
}
|
||||
List<String> getStoredUsers(RealmModel realm, int first, int max);
|
||||
|
||||
/**
|
||||
* Obtains the ids of all federated users in the realm.
|
||||
|
@ -59,9 +57,12 @@ public interface UserFederatedStorageProvider extends Provider,
|
|||
* @param realm a reference to the realm.
|
||||
* @param first first result to return. Ignored if negative.
|
||||
* @param max maximum number of results to return. Ignored if negative.
|
||||
* @return a non-null {@code Stream} of federated user ids.
|
||||
* @return a non-null {@link Stream} of federated user ids.
|
||||
*/
|
||||
Stream<String> getStoredUsersStream(RealmModel realm, int first, int max);
|
||||
default Stream<String> getStoredUsersStream(RealmModel realm, int first, int max) {
|
||||
List<String> value = this.getStoredUsers(realm, first, max);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
int getStoredUsersCount(RealmModel realm);
|
||||
|
||||
|
@ -80,4 +81,30 @@ public interface UserFederatedStorageProvider extends Provider,
|
|||
void preRemove(RealmModel realm, UserModel user);
|
||||
|
||||
void preRemove(RealmModel realm, ComponentModel model);
|
||||
|
||||
/**
|
||||
* The {@link UserFederatedStorageProvider.Streams} interface makes all collection-based methods in {@link UserFederatedStorageProvider}
|
||||
* default by providing implementations that delegate to the {@link Stream}-based variants instead of the other way
|
||||
* around.
|
||||
* <p/>
|
||||
* It allows for implementations to focus on the {@link Stream}-based approach for processing sets of data and benefit
|
||||
* from the potential memory and performance optimizations of that approach.
|
||||
*/
|
||||
interface Streams extends UserFederatedStorageProvider,
|
||||
UserAttributeFederatedStorage.Streams,
|
||||
UserBrokerLinkFederatedStorage.Streams,
|
||||
UserConsentFederatedStorage.Streams,
|
||||
UserFederatedUserCredentialStore.Streams,
|
||||
UserGroupMembershipFederatedStorage.Streams,
|
||||
UserRequiredActionsFederatedStorage.Streams,
|
||||
UserRoleMappingsFederatedStorage.Streams {
|
||||
|
||||
@Override
|
||||
default List<String> getStoredUsers(RealmModel realm, int first, int max) {
|
||||
return this.getStoredUsersStream(realm, first, max).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<String> getStoredUsersStream(RealmModel realm, int first, int max);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,26 +38,25 @@ public interface UserFederatedUserCredentialStore extends Provider {
|
|||
* @deprecated Use {@link #getStoredCredentialsStream(RealmModel, String) getStoredCredentialsStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<CredentialModel> getStoredCredentials(RealmModel realm, String userId) {
|
||||
return this.getStoredCredentialsStream(realm, userId).collect(Collectors.toList());
|
||||
}
|
||||
List<CredentialModel> getStoredCredentials(RealmModel realm, String userId);
|
||||
|
||||
/**
|
||||
* Obtains the credentials associated with the federated user identified by {@code userId}.
|
||||
*
|
||||
* @param realm a reference to the realm.
|
||||
* @param userId the user identifier.
|
||||
* @return a non-null {@code Stream} of credentials.
|
||||
* @return a non-null {@link Stream} of credentials.
|
||||
*/
|
||||
Stream<CredentialModel> getStoredCredentialsStream(RealmModel realm, String userId);
|
||||
default Stream<CredentialModel> getStoredCredentialsStream(RealmModel realm, String userId) {
|
||||
List<CredentialModel> value = this.getStoredCredentials(realm, userId);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getStoredCredentialsByTypeStream(RealmModel, String, String) getStoredCredentialsByTypeStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<CredentialModel> getStoredCredentialsByType(RealmModel realm, String userId, String type) {
|
||||
return this.getStoredCredentialsByTypeStream(realm, userId, type).collect(Collectors.toList());
|
||||
}
|
||||
List<CredentialModel> getStoredCredentialsByType(RealmModel realm, String userId, String type);
|
||||
|
||||
/**
|
||||
* Obtains the credentials of type {@code type} that are associated with the federated user identified by {@code userId}.
|
||||
|
@ -65,9 +64,38 @@ public interface UserFederatedUserCredentialStore extends Provider {
|
|||
* @param realm a reference to the realm.
|
||||
* @param userId the user identifier.
|
||||
* @param type the credential type.
|
||||
* @return a non-null {@code Stream} of credentials.
|
||||
* @return a non-null {@link Stream} of credentials.
|
||||
*/
|
||||
Stream<CredentialModel> getStoredCredentialsByTypeStream(RealmModel realm, String userId, String type);
|
||||
default Stream<CredentialModel> getStoredCredentialsByTypeStream(RealmModel realm, String userId, String type) {
|
||||
List<CredentialModel> value = this.getStoredCredentialsByType(realm, userId, type);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
CredentialModel getStoredCredentialByNameAndType(RealmModel realm, String userId, String name, String type);
|
||||
|
||||
/**
|
||||
* The {@link Streams} interface makes all collection-based methods in {@link UserFederatedUserCredentialStore}
|
||||
* default by providing implementations that delegate to the {@link Stream}-based variants instead of the other way
|
||||
* around.
|
||||
* <p/>
|
||||
* It allows for implementations to focus on the {@link Stream}-based approach for processing sets of data and benefit
|
||||
* from the potential memory and performance optimizations of that approach.
|
||||
*/
|
||||
interface Streams extends UserFederatedUserCredentialStore {
|
||||
@Override
|
||||
default List<CredentialModel> getStoredCredentials(RealmModel realm, String userId) {
|
||||
return this.getStoredCredentialsStream(realm, userId).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<CredentialModel> getStoredCredentialsStream(RealmModel realm, String userId);
|
||||
|
||||
@Override
|
||||
default List<CredentialModel> getStoredCredentialsByType(RealmModel realm, String userId, String type) {
|
||||
return this.getStoredCredentialsByTypeStream(realm, userId, type).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<CredentialModel> getStoredCredentialsByTypeStream(RealmModel realm, String userId, String type);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,12 +29,24 @@ import java.util.stream.Stream;
|
|||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface UserGroupMembershipFederatedStorage {
|
||||
@Deprecated
|
||||
default Set<GroupModel> getGroups(RealmModel realm, String userId) {
|
||||
return getGroupsStream(realm, userId).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
Stream<GroupModel> getGroupsStream(RealmModel realm, String userId);
|
||||
/**
|
||||
* @deprecated Use {@link #getGroupsStream(RealmModel, String) getGroupsStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
Set<GroupModel> getGroups(RealmModel realm, String userId);
|
||||
|
||||
/**
|
||||
* Obtains the groups associated with the federated user.
|
||||
*
|
||||
* @param realm a reference to the realm.
|
||||
* @param userId the user identifier.
|
||||
* @return a non-null {@code Stream} of groups.
|
||||
*/
|
||||
default Stream<GroupModel> getGroupsStream(RealmModel realm, String userId) {
|
||||
Set<GroupModel> value = this.getGroups(realm, userId);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
void joinGroup(RealmModel realm, String userId, GroupModel group);
|
||||
void leaveGroup(RealmModel realm, String userId, GroupModel group);
|
||||
|
@ -43,9 +55,7 @@ public interface UserGroupMembershipFederatedStorage {
|
|||
* @deprecated Use {@link #getMembershipStream(RealmModel, GroupModel, int, int) getMembershipStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<String> getMembership(RealmModel realm, GroupModel group, int firstResult, int max) {
|
||||
return this.getMembershipStream(realm, group, firstResult, max).collect(Collectors.toList());
|
||||
}
|
||||
List<String> getMembership(RealmModel realm, GroupModel group, int firstResult, int max);
|
||||
|
||||
/**
|
||||
* Obtains the federated users that are members of the given {@code group} in the specified {@code realm}.
|
||||
|
@ -56,6 +66,34 @@ public interface UserGroupMembershipFederatedStorage {
|
|||
* @param max maximum number of results to return. Ignored if negative.
|
||||
* @return a non-null {@code Stream} of federated user ids that are members of the group in the realm.
|
||||
*/
|
||||
Stream<String> getMembershipStream(RealmModel realm, GroupModel group, int firstResult, int max);
|
||||
default Stream<String> getMembershipStream(RealmModel realm, GroupModel group, int firstResult, int max) {
|
||||
List<String> value = this.getMembership(realm, group, firstResult, max);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link Streams} interface makes all collection-based methods in {@link UserGroupMembershipFederatedStorage}
|
||||
* default by providing implementations that delegate to the {@link Stream}-based variants instead of the other way
|
||||
* around.
|
||||
* <p/>
|
||||
* It allows for implementations to focus on the {@link Stream}-based approach for processing sets of data and benefit
|
||||
* from the potential memory and performance optimizations of that approach.
|
||||
*/
|
||||
interface Streams extends UserGroupMembershipFederatedStorage {
|
||||
@Override
|
||||
default Set<GroupModel> getGroups(RealmModel realm, String userId) {
|
||||
return getGroupsStream(realm, userId).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<GroupModel> getGroupsStream(RealmModel realm, String userId);
|
||||
|
||||
@Override
|
||||
default List<String> getMembership(RealmModel realm, GroupModel group, int firstResult, int max) {
|
||||
return this.getMembershipStream(realm, group, firstResult, max).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<String> getMembershipStream(RealmModel realm, GroupModel group, int firstResult, int max);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,18 +32,38 @@ public interface UserRequiredActionsFederatedStorage {
|
|||
* @deprecated Use {@link #getRequiredActionsStream(RealmModel, String) getRequiredActionsStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default Set<String> getRequiredActions(RealmModel realm, String userId) {
|
||||
return this.getRequiredActionsStream(realm, userId).collect(Collectors.toSet());
|
||||
}
|
||||
Set<String> getRequiredActions(RealmModel realm, String userId);
|
||||
|
||||
/**
|
||||
* Obtains the names of required actions associated with the federated user identified by {@code userId}.
|
||||
*
|
||||
* @param realm a reference to the realm.
|
||||
* @param userId the user identifier.
|
||||
* @return a non-null {@code Stream} of required action names.
|
||||
* @return a non-null {@link Stream} of required action names.
|
||||
*/
|
||||
Stream<String> getRequiredActionsStream(RealmModel realm, String userId);
|
||||
default Stream<String> getRequiredActionsStream(RealmModel realm, String userId) {
|
||||
Set<String> value = this.getRequiredActions(realm, userId);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
void addRequiredAction(RealmModel realm, String userId, String action);
|
||||
void removeRequiredAction(RealmModel realm, String userId, String action);
|
||||
|
||||
/**
|
||||
* The {@link Streams} interface makes all collection-based methods in {@link UserRequiredActionsFederatedStorage}
|
||||
* default by providing implementations that delegate to the {@link Stream}-based variants instead of the other way
|
||||
* around.
|
||||
* <p/>
|
||||
* It allows for implementations to focus on the {@link Stream}-based approach for processing sets of data and benefit
|
||||
* from the potential memory and performance optimizations of that approach.
|
||||
*/
|
||||
interface Streams extends UserRequiredActionsFederatedStorage {
|
||||
@Override
|
||||
default Set<String> getRequiredActions(RealmModel realm, String userId) {
|
||||
return this.getRequiredActionsStream(realm, userId).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<String> getRequiredActionsStream(RealmModel realm, String userId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,15 +29,13 @@ import java.util.stream.Stream;
|
|||
*/
|
||||
public interface UserRoleMappingsFederatedStorage {
|
||||
|
||||
void grantRole(RealmModel realm, String userId, RoleModel role);
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getRoleMappingsStream(RealmModel, String) getRoleMappingsStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default Set<RoleModel> getRoleMappings(RealmModel realm,String userId) {
|
||||
return getRoleMappingsStream(realm, userId).collect(Collectors.toSet());
|
||||
}
|
||||
Set<RoleModel> getRoleMappings(RealmModel realm,String userId);
|
||||
|
||||
void grantRole(RealmModel realm, String userId, RoleModel role);
|
||||
|
||||
/**
|
||||
* Obtains the roles associated with the federated user identified by {@code userId}.
|
||||
|
@ -46,7 +44,28 @@ public interface UserRoleMappingsFederatedStorage {
|
|||
* @param userId the user identifier.
|
||||
* @return a non-null {@code Stream} of roles.
|
||||
*/
|
||||
Stream<RoleModel> getRoleMappingsStream(RealmModel realm, String userId);
|
||||
default Stream<RoleModel> getRoleMappingsStream(RealmModel realm, String userId) {
|
||||
Set<RoleModel> value = this.getRoleMappings(realm, userId);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
void deleteRoleMapping(RealmModel realm, String userId, RoleModel role);
|
||||
|
||||
/**
|
||||
* The {@link Streams} interface makes all collection-based methods in {@link UserRoleMappingsFederatedStorage}
|
||||
* default by providing implementations that delegate to the {@link Stream}-based variants instead of the other way
|
||||
* around.
|
||||
* <p/>
|
||||
* It allows for implementations to focus on the {@link Stream}-based approach for processing sets of data and benefit
|
||||
* from the potential memory and performance optimizations of that approach.
|
||||
*/
|
||||
interface Streams extends UserRoleMappingsFederatedStorage {
|
||||
@Override
|
||||
default Set<RoleModel> getRoleMappings(RealmModel realm, String userId) {
|
||||
return getRoleMappingsStream(realm, userId).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<RoleModel> getRoleMappingsStream(RealmModel realm, String userId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -141,25 +141,23 @@ public interface UserQueryProvider {
|
|||
* @deprecated Use {@link #getUsersStream(RealmModel) getUsersStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<UserModel> getUsers(RealmModel realm) {
|
||||
return this.getUsersStream(realm).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
List<UserModel> getUsers(RealmModel realm);
|
||||
/**
|
||||
* Searches all users in the realm.
|
||||
*
|
||||
* @param realm a reference to the realm.
|
||||
* @return a non-null {@code Stream} of users.
|
||||
* @return a non-null {@link Stream} of users.
|
||||
*/
|
||||
Stream<UserModel> getUsersStream(RealmModel realm);
|
||||
default Stream<UserModel> getUsersStream(RealmModel realm) {
|
||||
List<UserModel> value = this.getUsers(realm);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getUsersStream(RealmModel, int, int) getUsersStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults) {
|
||||
return this.getUsersStream(realm, firstResult, maxResults).collect(Collectors.toList());
|
||||
}
|
||||
List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults);
|
||||
|
||||
/**
|
||||
* Searches all users in the realm, starting from the {@code firstResult} and containing at most {@code maxResults}.
|
||||
|
@ -167,9 +165,12 @@ public interface UserQueryProvider {
|
|||
* @param realm a reference to the realm.
|
||||
* @param firstResult first result to return. Ignored if negative.
|
||||
* @param maxResults maximum number of results to return. Ignored if negative.
|
||||
* @return a non-null {@code Stream} of users.
|
||||
* @return a non-null {@link Stream} of users.
|
||||
*/
|
||||
Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults);
|
||||
default Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults) {
|
||||
List<UserModel> value = this.getUsers(realm, firstResult, maxResults);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for users with username, email or first + last name that is like search string.
|
||||
|
@ -184,9 +185,7 @@ public interface UserQueryProvider {
|
|||
* @deprecated Use {@link #searchForUserStream(String, RealmModel) searchForUserStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<UserModel> searchForUser(String search, RealmModel realm) {
|
||||
return this.searchForUserStream(search, realm).collect(Collectors.toList());
|
||||
}
|
||||
List<UserModel> searchForUser(String search, RealmModel realm);
|
||||
|
||||
/**
|
||||
* Searches for users with username, email or first + last name that is like search string. If possible, implementations
|
||||
|
@ -196,9 +195,12 @@ public interface UserQueryProvider {
|
|||
*
|
||||
* @param search case sensitive search string.
|
||||
* @param realm a reference to the realm.
|
||||
* @return a non-null {@code Stream} of users that match the search string.
|
||||
* @return a non-null {@link Stream} of users that match the search string.
|
||||
*/
|
||||
Stream<UserModel> searchForUserStream(String search, RealmModel realm);
|
||||
default Stream<UserModel> searchForUserStream(String search, RealmModel realm) {
|
||||
List<UserModel> value = this.searchForUser(search, realm);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for users with username, email or first + last name that is like search string.
|
||||
|
@ -215,9 +217,7 @@ public interface UserQueryProvider {
|
|||
* @deprecated Use {@link #searchForUserStream(String, RealmModel, int, int) searchForUserStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults) {
|
||||
return this.searchForUserStream(search, realm, firstResult, maxResults).collect(Collectors.toList());
|
||||
}
|
||||
List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults);
|
||||
|
||||
/**
|
||||
* Searches for users with username, email or first + last name that is like search string. If possible, implementations
|
||||
|
@ -229,9 +229,12 @@ public interface UserQueryProvider {
|
|||
* @param realm a reference to the realm.
|
||||
* @param firstResult first result to return. Ignored if negative.
|
||||
* @param maxResults maximum number of results to return. Ignored if negative.
|
||||
* @return a non-null {@code Stream} of users that match the search criteria.
|
||||
* @return a non-null {@link Stream} of users that match the search criteria.
|
||||
*/
|
||||
Stream<UserModel> searchForUserStream(String search, RealmModel realm, int firstResult, int maxResults);
|
||||
default Stream<UserModel> searchForUserStream(String search, RealmModel realm, int firstResult, int maxResults) {
|
||||
List<UserModel> value = this.searchForUser(search, realm, firstResult, maxResults);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for user by parameter. Valid parameters are:
|
||||
|
@ -251,9 +254,7 @@ public interface UserQueryProvider {
|
|||
* @deprecated Use {@link #searchForUserStream(Map, RealmModel) searchForUserStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<UserModel> searchForUser(Map<String, String> params, RealmModel realm) {
|
||||
return this.searchForUserStream(params, realm).collect(Collectors.toList());
|
||||
}
|
||||
List<UserModel> searchForUser(Map<String, String> params, RealmModel realm);
|
||||
|
||||
/**
|
||||
* Searches for user by parameter. If possible, implementations should treat the parameter values as partial match patterns
|
||||
|
@ -269,9 +270,12 @@ public interface UserQueryProvider {
|
|||
*
|
||||
* @param params a map containing the search parameters.
|
||||
* @param realm a reference to the realm.
|
||||
* @return a non-null {@code Stream} of users that match the search parameters.
|
||||
* @return a non-null {@link Stream} of users that match the search parameters.
|
||||
*/
|
||||
Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm);
|
||||
default Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm) {
|
||||
List<UserModel> value = this.searchForUser(params, realm);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for user by parameter. Valid parameters are:
|
||||
|
@ -293,9 +297,7 @@ public interface UserQueryProvider {
|
|||
* @deprecated Use {@link #searchForUserStream(Map, RealmModel, int, int) searchForUserStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<UserModel> searchForUser(Map<String, String> params, RealmModel realm, int firstResult, int maxResults) {
|
||||
return this.searchForUserStream(params, realm, firstResult, maxResults).collect(Collectors.toList());
|
||||
}
|
||||
List<UserModel> searchForUser(Map<String, String> params, RealmModel realm, int firstResult, int maxResults);
|
||||
|
||||
/**
|
||||
* Searches for user by parameter. If possible, implementations should treat the parameter values as partial match patterns
|
||||
|
@ -313,9 +315,12 @@ public interface UserQueryProvider {
|
|||
* @param realm a reference to the realm.
|
||||
* @param firstResult first result to return. Ignored if negative.
|
||||
* @param maxResults maximum number of results to return. Ignored if negative.
|
||||
* @return a non-null {@code Stream} of users that match the search criteria.
|
||||
* @return a non-null {@link Stream} of users that match the search criteria.
|
||||
*/
|
||||
Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm, int firstResult, int maxResults);
|
||||
default Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm, int firstResult, int maxResults) {
|
||||
List<UserModel> value = this.searchForUser(params, realm, firstResult, maxResults);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get users that belong to a specific group. Implementations do not have to search in UserFederatedStorageProvider
|
||||
|
@ -329,9 +334,7 @@ public interface UserQueryProvider {
|
|||
* @deprecated Use {@link #getGroupMembersStream(RealmModel, GroupModel) getGroupMembersStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<UserModel> getGroupMembers(RealmModel realm, GroupModel group) {
|
||||
return this.getGroupMembersStream(realm, group).collect(Collectors.toList());
|
||||
}
|
||||
List<UserModel> getGroupMembers(RealmModel realm, GroupModel group);
|
||||
|
||||
/**
|
||||
* Obtains users that belong to a specific group. Implementations do not have to search in {@code UserFederatedStorageProvider}
|
||||
|
@ -341,9 +344,12 @@ public interface UserQueryProvider {
|
|||
*
|
||||
* @param realm a reference to the realm.
|
||||
* @param group a reference to the group.
|
||||
* @return a non-null {@code Stream} of users that belong to the group.
|
||||
* @return a non-null {@link Stream} of users that belong to the group.
|
||||
*/
|
||||
Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group);
|
||||
default Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group) {
|
||||
List<UserModel> value = this.getGroupMembers(realm, group);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get users that belong to a specific group. Implementations do not have to search in UserFederatedStorageProvider
|
||||
|
@ -359,9 +365,7 @@ public interface UserQueryProvider {
|
|||
* @deprecated Use {@link #getGroupMembersStream(RealmModel, GroupModel, int, int) getGroupMembersStream} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<UserModel> getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults) {
|
||||
return this.getGroupMembersStream(realm, group, firstResult, maxResults).collect(Collectors.toList());
|
||||
}
|
||||
List<UserModel> getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults);
|
||||
|
||||
/**
|
||||
* Obtains users that belong to a specific group. Implementations do not have to search in {@code UserFederatedStorageProvider}
|
||||
|
@ -373,9 +377,12 @@ public interface UserQueryProvider {
|
|||
* @param group a reference to the group.
|
||||
* @param firstResult first result to return. Ignored if negative.
|
||||
* @param maxResults maximum number of results to return. Ignored if negative.
|
||||
* @return a non-null {@code Stream} of users that belong to the group.
|
||||
* @return a non-null {@link Stream} of users that belong to the group.
|
||||
*/
|
||||
Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group, int firstResult, int maxResults);
|
||||
default Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group, int firstResult, int maxResults) {
|
||||
List<UserModel> value = this.getGroupMembers(realm, group, firstResult, maxResults);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get users that belong to a specific role.
|
||||
|
@ -395,7 +402,7 @@ public interface UserQueryProvider {
|
|||
*
|
||||
* @param realm a reference to the realm.
|
||||
* @param role a reference to the role.
|
||||
* @return a non-null {@code Stream} of users that have the specified role.
|
||||
* @return a non-null {@link Stream} of users that have the specified role.
|
||||
*/
|
||||
default Stream<UserModel> getRoleMembersStream(RealmModel realm, RoleModel role) {
|
||||
return Stream.empty();
|
||||
|
@ -422,7 +429,7 @@ public interface UserQueryProvider {
|
|||
* @param role a reference to the role.
|
||||
* @param firstResult first result to return. Ignored if negative.
|
||||
* @param maxResults maximum number of results to return. Ignored if negative.
|
||||
* @return a non-null {@code Stream} of users that have the specified role.
|
||||
* @return a non-null {@link Stream} of users that have the specified role.
|
||||
*/
|
||||
default Stream<UserModel> getRoleMembersStream(RealmModel realm, RoleModel role, int firstResult, int maxResults) {
|
||||
return Stream.empty();
|
||||
|
@ -443,9 +450,7 @@ public interface UserQueryProvider {
|
|||
* instead.
|
||||
*/
|
||||
@Deprecated
|
||||
default List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
|
||||
return this.searchForUserByUserAttributeStream(attrName, attrValue, realm).collect(Collectors.toList());
|
||||
}
|
||||
List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm);
|
||||
|
||||
/**
|
||||
* Searches for users that have a specific attribute with a specific value. Implementations do not have to search in
|
||||
|
@ -456,7 +461,91 @@ public interface UserQueryProvider {
|
|||
* @param attrName the attribute name.
|
||||
* @param attrValue the attribute value.
|
||||
* @param realm a reference to the realm.
|
||||
* @return a non-null {@code Stream} of users that match the search criteria.
|
||||
* @return a non-null {@link Stream} of users that match the search criteria.
|
||||
*/
|
||||
Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm);
|
||||
default Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm) {
|
||||
List<UserModel> value = this.searchForUserByUserAttribute(attrName, attrValue, realm);
|
||||
return value != null ? value.stream() : Stream.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link Streams} interface makes all collection-based methods in {@link UserQueryProvider} default by
|
||||
* providing implementations that delegate to the {@link Stream}-based variants instead of the other way around.
|
||||
* <p/>
|
||||
* It allows for implementations to focus on the {@link Stream}-based approach for processing sets of data and benefit
|
||||
* from the potential memory and performance optimizations of that approach.
|
||||
*/
|
||||
interface Streams extends UserQueryProvider {
|
||||
@Override
|
||||
default List<UserModel> getUsers(RealmModel realm) {
|
||||
return this.getUsersStream(realm).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<UserModel> getUsersStream(RealmModel realm);
|
||||
|
||||
@Override
|
||||
default List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults) {
|
||||
return this.getUsersStream(realm, firstResult, maxResults).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults);
|
||||
|
||||
@Override
|
||||
default List<UserModel> searchForUser(String search, RealmModel realm) {
|
||||
return this.searchForUserStream(search, realm).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<UserModel> searchForUserStream(String search, RealmModel realm);
|
||||
|
||||
@Override
|
||||
default List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults) {
|
||||
return this.searchForUserStream(search, realm, firstResult, maxResults).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<UserModel> searchForUserStream(String search, RealmModel realm, int firstResult, int maxResults);
|
||||
|
||||
@Override
|
||||
default List<UserModel> searchForUser(Map<String, String> params, RealmModel realm) {
|
||||
return this.searchForUserStream(params, realm).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm);
|
||||
|
||||
@Override
|
||||
default List<UserModel> searchForUser(Map<String, String> params, RealmModel realm, int firstResult, int maxResults) {
|
||||
return this.searchForUserStream(params, realm, firstResult, maxResults).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm, int firstResult, int maxResults);
|
||||
|
||||
@Override
|
||||
default List<UserModel> getGroupMembers(RealmModel realm, GroupModel group) {
|
||||
return this.getGroupMembersStream(realm, group).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group);
|
||||
|
||||
@Override
|
||||
default List<UserModel> getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults) {
|
||||
return this.getGroupMembersStream(realm, group, firstResult, maxResults).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group, int firstResult, int maxResults);
|
||||
|
||||
@Override
|
||||
default List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
|
||||
return this.searchForUserByUserAttributeStream(attrName, attrValue, realm).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
package org.keycloak.storage;
|
||||
|
||||
import com.google.common.collect.Streams;
|
||||
import org.jboss.logging.Logger;
|
||||
import org.keycloak.component.ComponentFactory;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
|
@ -27,7 +26,6 @@ import org.keycloak.models.FederatedIdentityModel;
|
|||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.IdentityProviderModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionTask;
|
||||
import org.keycloak.models.ModelException;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
|
@ -65,7 +63,8 @@ import static org.keycloak.models.utils.KeycloakModelUtils.runJobInTransaction;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class UserStorageManager extends AbstractStorageManager<UserStorageProvider, UserStorageProviderModel> implements UserProvider, OnUserCache, OnCreateComponent, OnUpdateComponent {
|
||||
public class UserStorageManager extends AbstractStorageManager<UserStorageProvider, UserStorageProviderModel>
|
||||
implements UserProvider.Streams, OnUserCache, OnCreateComponent, OnUpdateComponent {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(UserStorageManager.class);
|
||||
|
||||
|
@ -605,7 +604,7 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
|||
Stream<FederatedIdentityModel> stream = StorageId.isLocalStorage(user) ?
|
||||
localStorage().getFederatedIdentitiesStream(user, realm) : Stream.empty();
|
||||
if (getFederatedStorage() != null)
|
||||
stream = Streams.concat(stream, getFederatedStorage().getFederatedIdentitiesStream(user.getId(), realm));
|
||||
stream = Stream.concat(stream, getFederatedStorage().getFederatedIdentitiesStream(user.getId(), realm));
|
||||
return stream.distinct();
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ import org.keycloak.storage.user.UserRegistrationProvider;
|
|||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||
*/
|
||||
public class BackwardsCompatibilityUserStorage implements UserLookupProvider, UserStorageProvider, UserRegistrationProvider,
|
||||
CredentialInputUpdater, CredentialInputValidator, UserQueryProvider {
|
||||
CredentialInputUpdater, CredentialInputValidator, UserQueryProvider.Streams {
|
||||
|
||||
private static final Logger log = Logger.getLogger(BackwardsCompatibilityUserStorage.class);
|
||||
|
||||
|
@ -82,7 +82,7 @@ public class BackwardsCompatibilityUserStorage implements UserLookupProvider, Us
|
|||
}
|
||||
|
||||
private UserModel createUser(RealmModel realm, String username) {
|
||||
return new AbstractUserAdapterFederatedStorage(session, realm, model) {
|
||||
return new AbstractUserAdapterFederatedStorage.Streams(session, realm, model) {
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return username;
|
||||
|
|
|
@ -43,7 +43,8 @@ import java.util.stream.Stream;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class FailableHardcodedStorageProvider implements UserStorageProvider, UserLookupProvider, UserQueryProvider, ImportedUserValidation, CredentialInputUpdater, CredentialInputValidator {
|
||||
public class FailableHardcodedStorageProvider implements UserStorageProvider, UserLookupProvider, UserQueryProvider.Streams,
|
||||
ImportedUserValidation, CredentialInputUpdater, CredentialInputValidator {
|
||||
|
||||
public static String username = "billb";
|
||||
public static String password = "password";
|
||||
|
|
|
@ -68,7 +68,7 @@ public class HardcodedGroupStorageProvider implements GroupStorageProvider {
|
|||
}
|
||||
|
||||
|
||||
public class HardcodedGroupAdapter implements GroupModel {
|
||||
public class HardcodedGroupAdapter implements GroupModel.Streams {
|
||||
|
||||
private final RealmModel realm;
|
||||
private StorageId storageId;
|
||||
|
|
|
@ -154,7 +154,7 @@ public class PassThroughFederatedUserStorageProvider implements
|
|||
}
|
||||
|
||||
private UserModel getUserModel(final RealmModel realm) {
|
||||
return new AbstractUserAdapterFederatedStorage(session, realm, component) {
|
||||
return new AbstractUserAdapterFederatedStorage.Streams(session, realm, component) {
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return PASSTHROUGH_USERNAME;
|
||||
|
|
|
@ -54,8 +54,8 @@ import static org.keycloak.storage.UserStorageProviderModel.IMPORT_ENABLED;
|
|||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class UserMapStorage implements UserLookupProvider, UserStorageProvider, UserRegistrationProvider, CredentialInputUpdater, CredentialInputValidator,
|
||||
UserGroupMembershipFederatedStorage, UserQueryProvider, ImportedUserValidation {
|
||||
public class UserMapStorage implements UserLookupProvider, UserStorageProvider, UserRegistrationProvider, CredentialInputUpdater,
|
||||
CredentialInputValidator, UserGroupMembershipFederatedStorage.Streams, UserQueryProvider.Streams, ImportedUserValidation {
|
||||
|
||||
private static final Logger log = Logger.getLogger(UserMapStorage.class);
|
||||
|
||||
|
@ -113,7 +113,7 @@ public class UserMapStorage implements UserLookupProvider, UserStorageProvider,
|
|||
user.setEnabled(true);
|
||||
user.setFederationLink(model.getId());
|
||||
} else {
|
||||
user = new AbstractUserAdapterFederatedStorage(session, realm, model) {
|
||||
user = new AbstractUserAdapterFederatedStorage.Streams(session, realm, model) {
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return username;
|
||||
|
|
|
@ -33,11 +33,13 @@ import org.keycloak.storage.adapter.AbstractUserAdapterFederatedStorage;
|
|||
import org.keycloak.storage.user.UserLookupProvider;
|
||||
import org.keycloak.storage.user.UserQueryProvider;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
|
@ -69,7 +71,7 @@ public class UserPropertyFileStorage implements UserLookupProvider, UserStorageP
|
|||
|
||||
private UserModel createUser(RealmModel realm, String username) {
|
||||
if (federatedStorageEnabled) {
|
||||
return new AbstractUserAdapterFederatedStorage(session, realm, model) {
|
||||
return new AbstractUserAdapterFederatedStorage.Streams(session, realm, model) {
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return username;
|
||||
|
@ -81,7 +83,7 @@ public class UserPropertyFileStorage implements UserLookupProvider, UserStorageP
|
|||
}
|
||||
};
|
||||
} else {
|
||||
return new AbstractUserAdapter(session, realm, model) {
|
||||
return new AbstractUserAdapter.Streams(session, realm, model) {
|
||||
@Override
|
||||
public String getUsername() {
|
||||
return username;
|
||||
|
@ -90,7 +92,6 @@ public class UserPropertyFileStorage implements UserLookupProvider, UserStorageP
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserModel getUserByUsername(String username, RealmModel realm) {
|
||||
if (!userPasswords.containsKey(username)) return null;
|
||||
|
||||
|
@ -144,59 +145,67 @@ public class UserPropertyFileStorage implements UserLookupProvider, UserStorageP
|
|||
}
|
||||
|
||||
@Override
|
||||
public Stream<UserModel> getUsersStream(RealmModel realm) {
|
||||
return userPasswords.keySet().stream().map(obj -> createUser(realm, (String) obj));
|
||||
public List<UserModel> getUsers(RealmModel realm) {
|
||||
List<UserModel> users = new LinkedList<>();
|
||||
for (Object username : userPasswords.keySet()) {
|
||||
users.add(createUser(realm, (String)username));
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<UserModel> searchForUserStream(Map<String, String> attributes, RealmModel realm) {
|
||||
return searchForUserStream(attributes, realm, 0, Integer.MAX_VALUE - 1);
|
||||
public List<UserModel> searchForUser(Map<String, String> attributes, RealmModel realm) {
|
||||
return searchForUser(attributes, realm, 0, Integer.MAX_VALUE - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults) {
|
||||
Stream<Object> stream = userPasswords.keySet().stream();
|
||||
if (firstResult > 0)
|
||||
stream = stream.skip(firstResult);
|
||||
if (maxResults >= 0)
|
||||
stream = stream.limit(maxResults);
|
||||
return stream.map(obj -> createUser(realm, (String) obj));
|
||||
public List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults) {
|
||||
if (maxResults == 0) return Collections.EMPTY_LIST;
|
||||
List<UserModel> users = new LinkedList<>();
|
||||
int count = 0;
|
||||
for (Object un : userPasswords.keySet()) {
|
||||
if (count++ < firstResult) continue;
|
||||
String username = (String)un;
|
||||
users.add(createUser(realm, username));
|
||||
if (users.size() + 1 > maxResults) break;
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<UserModel> searchForUserStream(String search, RealmModel realm, int firstResult, int maxResults) {
|
||||
return searchForUserStream(search, realm, firstResult, maxResults, username -> username.contains(search));
|
||||
public List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults) {
|
||||
return searchForUser(search, realm, firstResult, maxResults, username -> username.contains(search));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<UserModel> searchForUserStream(Map<String, String> attributes, RealmModel realm, int firstResult, int maxResults) {
|
||||
public List<UserModel> searchForUser(Map<String, String> attributes, RealmModel realm, int firstResult, int maxResults) {
|
||||
String search = Optional.ofNullable(attributes.get(UserModel.USERNAME))
|
||||
.orElseGet(()-> attributes.get(UserModel.SEARCH));
|
||||
if (search == null) return Stream.empty();
|
||||
if (search == null) return Collections.EMPTY_LIST;
|
||||
Predicate<String> p = Boolean.valueOf(attributes.getOrDefault(UserModel.EXACT, Boolean.FALSE.toString()))
|
||||
? username -> username.equals(search)
|
||||
: username -> username.contains(search);
|
||||
return searchForUserStream(search, realm, firstResult, maxResults, p);
|
||||
? username -> username.equals(search)
|
||||
: username -> username.contains(search);
|
||||
return searchForUser(search, realm, firstResult, maxResults, p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group, int firstResult, int maxResults) {
|
||||
return Stream.empty();
|
||||
public List<UserModel> getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group) {
|
||||
return Stream.empty();
|
||||
public List<UserModel> getGroupMembers(RealmModel realm, GroupModel group) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<UserModel> searchForUserStream(String search, RealmModel realm) {
|
||||
return searchForUserStream(search, realm, 0, Integer.MAX_VALUE - 1);
|
||||
public List<UserModel> searchForUser(String search, RealmModel realm) {
|
||||
return searchForUser(search, realm, 0, Integer.MAX_VALUE - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm) {
|
||||
return Stream.empty();
|
||||
public List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -204,8 +213,20 @@ public class UserPropertyFileStorage implements UserLookupProvider, UserStorageP
|
|||
|
||||
}
|
||||
|
||||
private Stream<UserModel> searchForUserStream(String search, RealmModel realm, int firstResult, int maxResults, Predicate<String> matcher) {
|
||||
return userPasswords.keySet().stream().filter(obj -> matcher.test((String) obj)).skip(firstResult < 0 ? 0 : firstResult)
|
||||
.limit(maxResults < 0 ? 0 : maxResults).map(obj -> createUser(realm, (String) obj));
|
||||
private List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults, Predicate<String> matcher) {
|
||||
if (maxResults == 0) return Collections.EMPTY_LIST;
|
||||
List<UserModel> users = new LinkedList<>();
|
||||
int count = 0;
|
||||
for (Object un : userPasswords.keySet()) {
|
||||
String username = (String)un;
|
||||
if (matcher.test(username)) {
|
||||
if (count++ < firstResult) {
|
||||
continue;
|
||||
}
|
||||
users.add(createUser(realm, username));
|
||||
if (users.size() + 1 > maxResults) break;
|
||||
}
|
||||
}
|
||||
return users;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue