KEYCLOAK-12988 Deprecate getUsers* methods in favor of searchUsers* variants
Closes #14018
This commit is contained in:
parent
f789b7997e
commit
f69497eb28
17 changed files with 98 additions and 160 deletions
|
@ -544,15 +544,11 @@ public class UserCacheSession implements UserCache.Streams, OnCreateComponent, O
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm, boolean includeServiceAccounts) {
|
|
||||||
return getDelegate().getUsersStream(realm, includeServiceAccounts);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CredentialValidationOutput getUserByCredential(RealmModel realm, CredentialInput input) {
|
public CredentialValidationOutput getUserByCredential(RealmModel realm, CredentialInput input) {
|
||||||
return getDelegate().getUserByCredential(realm, input);
|
return getDelegate().getUserByCredential(realm, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUsersCount(RealmModel realm, boolean includeServiceAccount) {
|
public int getUsersCount(RealmModel realm, boolean includeServiceAccount) {
|
||||||
return getDelegate().getUsersCount(realm, includeServiceAccount);
|
return getDelegate().getUsersCount(realm, includeServiceAccount);
|
||||||
|
@ -583,21 +579,6 @@ public class UserCacheSession implements UserCache.Streams, OnCreateComponent, O
|
||||||
return getDelegate().getUsersCount(realm, params, groupIds);
|
return getDelegate().getUsersCount(realm, params, groupIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults, boolean includeServiceAccounts) {
|
|
||||||
return getDelegate().getUsersStream(realm, firstResult, maxResults, includeServiceAccounts);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm) {
|
|
||||||
return getUsersStream(realm, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
|
||||||
return getUsersStream(realm, firstResult, maxResults, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(RealmModel realm, String search) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, String search) {
|
||||||
return getDelegate().searchForUserStream(realm, search);
|
return getDelegate().searchForUserStream(realm, search);
|
||||||
|
|
|
@ -68,6 +68,7 @@ import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@ -748,21 +749,6 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
return result.intValue();
|
return result.intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
|
||||||
return getUsersStream(realm, firstResult, maxResults, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults, boolean includeServiceAccounts) {
|
|
||||||
String queryName = includeServiceAccounts ? "getAllUsersByRealm" : "getAllUsersByRealmExcludeServiceAccount" ;
|
|
||||||
|
|
||||||
TypedQuery<UserEntity> query = em.createNamedQuery(queryName, UserEntity.class);
|
|
||||||
query.setParameter("realmId", realm.getId());
|
|
||||||
|
|
||||||
return closing(paginateQuery(query, firstResult, maxResults).getResultStream().map(entity -> new UserAdapter(session, realm, em, entity)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group, Integer firstResult, Integer maxResults) {
|
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group, Integer firstResult, Integer maxResults) {
|
||||||
TypedQuery<UserEntity> query = em.createNamedQuery("groupMembership", UserEntity.class);
|
TypedQuery<UserEntity> query = em.createNamedQuery("groupMembership", UserEntity.class);
|
||||||
|
@ -781,9 +767,10 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
|
||||||
Map<String, String> attributes = new HashMap<>();
|
Map<String, String> attributes = new HashMap<>(2);
|
||||||
attributes.put(UserModel.SEARCH, search);
|
attributes.put(UserModel.SEARCH, search);
|
||||||
session.setAttribute(UserModel.INCLUDE_SERVICE_ACCOUNT, false);
|
attributes.put(UserModel.INCLUDE_SERVICE_ACCOUNT, Boolean.FALSE.toString());
|
||||||
|
|
||||||
return searchForUserStream(realm, attributes, firstResult, maxResults);
|
return searchForUserStream(realm, attributes, firstResult, maxResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,10 +785,6 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
|
|
||||||
predicates.add(builder.equal(root.get("realmId"), realm.getId()));
|
predicates.add(builder.equal(root.get("realmId"), realm.getId()));
|
||||||
|
|
||||||
if (!session.getAttributeOrDefault(UserModel.INCLUDE_SERVICE_ACCOUNT, true)) {
|
|
||||||
predicates.add(root.get("serviceAccountClientLink").isNull());
|
|
||||||
}
|
|
||||||
|
|
||||||
Join<Object, Object> federatedIdentitiesJoin = null;
|
Join<Object, Object> federatedIdentitiesJoin = null;
|
||||||
|
|
||||||
for (Map.Entry<String, String> entry : attributes.entrySet()) {
|
for (Map.Entry<String, String> entry : attributes.entrySet()) {
|
||||||
|
@ -863,6 +846,13 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
builder.equal(builder.lower(attributesJoin.get("value")), value.toLowerCase())));
|
builder.equal(builder.lower(attributesJoin.get("value")), value.toLowerCase())));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
case UserModel.INCLUDE_SERVICE_ACCOUNT: {
|
||||||
|
if (!attributes.containsKey(UserModel.INCLUDE_SERVICE_ACCOUNT)
|
||||||
|
|| !Boolean.parseBoolean(attributes.get(UserModel.INCLUDE_SERVICE_ACCOUNT))) {
|
||||||
|
predicates.add(root.get("serviceAccountClientLink").isNull());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -908,7 +898,8 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||||
|
|
||||||
UserProvider users = session.users();
|
UserProvider users = session.users();
|
||||||
return closing(paginateQuery(query, firstResult, maxResults).getResultStream())
|
return closing(paginateQuery(query, firstResult, maxResults).getResultStream())
|
||||||
.map(userEntity -> users.getUserById(realm, userEntity.getId()));
|
.map(userEntity -> users.getUserById(realm, userEntity.getId()))
|
||||||
|
.filter(Objects::nonNull);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -42,8 +42,6 @@ import java.util.LinkedList;
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
@NamedQueries({
|
@NamedQueries({
|
||||||
@NamedQuery(name="getAllUsersByRealm", query="select u from UserEntity u where u.realmId = :realmId order by u.username"),
|
|
||||||
@NamedQuery(name="getAllUsersByRealmExcludeServiceAccount", query="select u from UserEntity u where u.realmId = :realmId and (u.serviceAccountClientLink is null) order by u.username"),
|
|
||||||
@NamedQuery(name="getRealmUserByUsername", query="select u from UserEntity u where u.username = :username and u.realmId = :realmId"),
|
@NamedQuery(name="getRealmUserByUsername", query="select u from UserEntity u where u.username = :username and u.realmId = :realmId"),
|
||||||
@NamedQuery(name="getRealmUserByEmail", query="select u from UserEntity u where u.email = :email and u.realmId = :realmId"),
|
@NamedQuery(name="getRealmUserByEmail", query="select u from UserEntity u where u.email = :email and u.realmId = :realmId"),
|
||||||
@NamedQuery(name="getRealmUserByLastName", query="select u from UserEntity u where u.lastName = :lastName and u.realmId = :realmId"),
|
@NamedQuery(name="getRealmUserByLastName", query="select u from UserEntity u where u.lastName = :lastName and u.realmId = :realmId"),
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.LDAPConstants;
|
import org.keycloak.models.LDAPConstants;
|
||||||
import org.keycloak.models.LegacyRealmModel;
|
import org.keycloak.models.LegacyRealmModel;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.models.cache.UserCache;
|
import org.keycloak.models.cache.UserCache;
|
||||||
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||||
import org.keycloak.models.utils.DefaultRequiredActions;
|
import org.keycloak.models.utils.DefaultRequiredActions;
|
||||||
|
@ -33,7 +34,9 @@ import org.keycloak.storage.UserStoragePrivateUtil;
|
||||||
import org.keycloak.storage.UserStorageUtil;
|
import org.keycloak.storage.UserStorageUtil;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,7 +84,10 @@ public class MigrateTo1_4_0 implements Migration {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void migrateUsers(KeycloakSession session, RealmModel realm) {
|
private void migrateUsers(KeycloakSession session, RealmModel realm) {
|
||||||
UserStoragePrivateUtil.userLocalStorage(session).getUsersStream(realm, false)
|
Map<String, String> searchAttributes = new HashMap<>(1);
|
||||||
|
searchAttributes.put(UserModel.INCLUDE_SERVICE_ACCOUNT, Boolean.FALSE.toString());
|
||||||
|
|
||||||
|
UserStoragePrivateUtil.userLocalStorage(session).searchForUserStream(realm, searchAttributes)
|
||||||
.forEach(user -> {
|
.forEach(user -> {
|
||||||
String email = KeycloakModelUtils.toLowerCaseSafe(user.getEmail());
|
String email = KeycloakModelUtils.toLowerCaseSafe(user.getEmail());
|
||||||
if (email != null && !email.equals(user.getEmail())) {
|
if (email != null && !email.equals(user.getEmail())) {
|
||||||
|
|
|
@ -379,31 +379,6 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
||||||
return importValidation(realm, results);
|
return importValidation(realm, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm) {
|
|
||||||
return getUsersStream(realm, null, null, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
|
||||||
return getUsersStream(realm, firstResult, maxResults, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getUsersStream(final RealmModel realm, Integer firstResult, Integer maxResults, final boolean includeServiceAccounts) {
|
|
||||||
Stream<UserModel> results = query((provider, firstResultInQuery, maxResultsInQuery) -> {
|
|
||||||
if (provider instanceof UserProvider) { // it is local storage
|
|
||||||
return ((UserProvider) provider).getUsersStream(realm, firstResultInQuery, maxResultsInQuery, includeServiceAccounts);
|
|
||||||
} else if (provider instanceof UserQueryProvider) {
|
|
||||||
return ((UserQueryProvider)provider).getUsersStream(realm);
|
|
||||||
}
|
|
||||||
return Stream.empty();
|
|
||||||
}
|
|
||||||
, realm, firstResult, maxResults);
|
|
||||||
return importValidation(realm, results);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getUsersCount(RealmModel realm, boolean includeServiceAccount) {
|
public int getUsersCount(RealmModel realm, boolean includeServiceAccount) {
|
||||||
int localStorageUsersCount = localStorage().getUsersCount(realm, includeServiceAccount);
|
int localStorageUsersCount = localStorage().getUsersCount(realm, includeServiceAccount);
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.storage.UserStorageUtil;
|
import org.keycloak.storage.UserStorageUtil;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@ -114,7 +115,7 @@ public abstract class MultipleStepsExportProvider implements ExportProvider {
|
||||||
protected void runExportImportTask(KeycloakSession session) throws IOException {
|
protected void runExportImportTask(KeycloakSession session) throws IOException {
|
||||||
RealmModel realm = session.realms().getRealmByName(realmName);
|
RealmModel realm = session.realms().getRealmByName(realmName);
|
||||||
usersHolder.users = session.users()
|
usersHolder.users = session.users()
|
||||||
.getUsersStream(realm, usersHolder.currentPageStart, usersHolder.currentPageEnd - usersHolder.currentPageStart, true)
|
.searchForUserStream(realm, Collections.emptyMap(), usersHolder.currentPageStart, usersHolder.currentPageEnd - usersHolder.currentPageStart)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
writeUsers(realmName + "-users-" + (usersHolder.currentPageStart / countPerPage) + ".json", session, realm, usersHolder.users);
|
writeUsers(realmName + "-users-" + (usersHolder.currentPageStart / countPerPage) + ".json", session, realm, usersHolder.users);
|
||||||
|
|
|
@ -540,32 +540,12 @@ public class MapUserProvider implements UserProvider.Streams {
|
||||||
return (int) tx.getCount(withCriteria(mcb));
|
return (int) tx.getCount(withCriteria(mcb));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults, boolean includeServiceAccounts) {
|
|
||||||
LOG.tracef("getUsersStream(%s, %d, %d, %s)%s", realm, firstResult, maxResults, includeServiceAccounts, getShortStackTrace());
|
|
||||||
DefaultModelCriteria<UserModel> mcb = criteria();
|
|
||||||
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
|
|
||||||
|
|
||||||
if (! includeServiceAccounts) {
|
|
||||||
mcb = mcb.compare(SearchableFields.SERVICE_ACCOUNT_CLIENT, Operator.NOT_EXISTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tx.read(withCriteria(mcb).pagination(firstResult, maxResults, SearchableFields.USERNAME))
|
|
||||||
.map(entityToAdapterFunc(realm));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
|
||||||
LOG.tracef("getUsersStream(%s, %d, %d)%s", realm, firstResult, maxResults, getShortStackTrace());
|
|
||||||
return getUsersStream(realm, firstResult, maxResults, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
|
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
|
||||||
LOG.tracef("searchForUserStream(%s, %s, %d, %d)%s", realm, search, firstResult, maxResults, getShortStackTrace());
|
LOG.tracef("searchForUserStream(%s, %s, %d, %d)%s", realm, search, firstResult, maxResults, getShortStackTrace());
|
||||||
Map<String, String> attributes = new HashMap<>();
|
Map<String, String> attributes = new HashMap<>();
|
||||||
attributes.put(UserModel.SEARCH, search);
|
attributes.put(UserModel.SEARCH, search);
|
||||||
session.setAttribute(UserModel.INCLUDE_SERVICE_ACCOUNT, false);
|
attributes.put(UserModel.INCLUDE_SERVICE_ACCOUNT, Boolean.FALSE.toString());
|
||||||
return searchForUserStream(realm, attributes, firstResult, maxResults);
|
return searchForUserStream(realm, attributes, firstResult, maxResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,10 +556,6 @@ public class MapUserProvider implements UserProvider.Streams {
|
||||||
final DefaultModelCriteria<UserModel> mcb = criteria();
|
final DefaultModelCriteria<UserModel> mcb = criteria();
|
||||||
DefaultModelCriteria<UserModel> criteria = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
|
DefaultModelCriteria<UserModel> criteria = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId());
|
||||||
|
|
||||||
if (! session.getAttributeOrDefault(UserModel.INCLUDE_SERVICE_ACCOUNT, true)) {
|
|
||||||
criteria = criteria.compare(SearchableFields.SERVICE_ACCOUNT_CLIENT, Operator.NOT_EXISTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
final boolean exactSearch = Boolean.parseBoolean(attributes.getOrDefault(UserModel.EXACT, Boolean.FALSE.toString()));
|
final boolean exactSearch = Boolean.parseBoolean(attributes.getOrDefault(UserModel.EXACT, Boolean.FALSE.toString()));
|
||||||
|
|
||||||
for (Map.Entry<String, String> entry : attributes.entrySet()) {
|
for (Map.Entry<String, String> entry : attributes.entrySet()) {
|
||||||
|
@ -638,6 +614,13 @@ public class MapUserProvider implements UserProvider.Streams {
|
||||||
value);
|
value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case UserModel.INCLUDE_SERVICE_ACCOUNT: {
|
||||||
|
if (!attributes.containsKey(UserModel.INCLUDE_SERVICE_ACCOUNT)
|
||||||
|
|| !Boolean.parseBoolean(attributes.get(UserModel.INCLUDE_SERVICE_ACCOUNT))) {
|
||||||
|
criteria = criteria.compare(SearchableFields.SERVICE_ACCOUNT_CLIENT, Operator.NOT_EXISTS);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case UserModel.EXACT:
|
case UserModel.EXACT:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -24,7 +24,9 @@ import org.keycloak.storage.user.UserLookupProvider;
|
||||||
import org.keycloak.storage.user.UserQueryProvider;
|
import org.keycloak.storage.user.UserQueryProvider;
|
||||||
import org.keycloak.storage.user.UserRegistrationProvider;
|
import org.keycloak.storage.user.UserRegistrationProvider;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
@ -71,10 +73,13 @@ public interface UserProvider extends Provider,
|
||||||
UserModel getServiceAccount(ClientModel client);
|
UserModel getServiceAccount(ClientModel client);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use {@link #getUsersStream(RealmModel, boolean) getUsersStream} instead.
|
* @deprecated Use {@link UserQueryProvider#searchForUserStream(RealmModel, Map)} with
|
||||||
|
* {@link UserModel#INCLUDE_SERVICE_ACCOUNT} within params instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
List<UserModel> getUsers(RealmModel realm, boolean includeServiceAccounts);
|
default List<UserModel> getUsers(RealmModel realm, boolean includeServiceAccounts) {
|
||||||
|
return this.getUsersStream(realm, includeServiceAccounts).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the users associated with the specified realm.
|
* Obtains the users associated with the specified realm.
|
||||||
|
@ -82,17 +87,25 @@ public interface UserProvider extends Provider,
|
||||||
* @param realm a reference to the realm being used for the search.
|
* @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.
|
* @param includeServiceAccounts {@code true} if service accounts should be included in the result; {@code false} otherwise.
|
||||||
* @return a non-null {@link Stream} of users associated withe the realm.
|
* @return a non-null {@link Stream} of users associated withe the realm.
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link UserQueryProvider#searchForUserStream(RealmModel, Map)} with
|
||||||
|
* {@link UserModel#INCLUDE_SERVICE_ACCOUNT} within params instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
default Stream<UserModel> getUsersStream(RealmModel realm, boolean includeServiceAccounts) {
|
default Stream<UserModel> getUsersStream(RealmModel realm, boolean includeServiceAccounts) {
|
||||||
List<UserModel> value = this.getUsers(realm, includeServiceAccounts);
|
Map<String, String> searchAttributes = new HashMap<>(1);
|
||||||
return value != null ? value.stream() : Stream.empty();
|
searchAttributes.put(UserModel.INCLUDE_SERVICE_ACCOUNT, Boolean.toString(includeServiceAccounts));
|
||||||
|
return this.searchForUserStream(realm, searchAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use {@link #getUsersStream(RealmModel, Integer, Integer, boolean) getUsersStream} instead.
|
* @deprecated Use {@link UserQueryProvider#searchForUserStream(RealmModel, Map, Integer, Integer)} with
|
||||||
|
* {@link UserModel#INCLUDE_SERVICE_ACCOUNT} within params instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults, boolean includeServiceAccounts);
|
default List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults, boolean includeServiceAccounts) {
|
||||||
|
return this.getUsersStream(realm, firstResult, maxResults, includeServiceAccounts).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the users associated with the specified realm.
|
* Obtains the users associated with the specified realm.
|
||||||
|
@ -102,10 +115,15 @@ public interface UserProvider extends Provider,
|
||||||
* @param maxResults maximum number of results to return. Ignored if negative or {@code null}.
|
* @param maxResults maximum number of results to return. Ignored if negative or {@code null}.
|
||||||
* @param includeServiceAccounts {@code true} if service accounts should be included in the result; {@code false} otherwise.
|
* @param includeServiceAccounts {@code true} if service accounts should be included in the result; {@code false} otherwise.
|
||||||
* @return a non-null {@link Stream} of users associated withe the realm.
|
* @return a non-null {@link Stream} of users associated withe the realm.
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link UserQueryProvider#searchForUserStream(RealmModel, Map, Integer, Integer)}
|
||||||
|
* with {@link UserModel#INCLUDE_SERVICE_ACCOUNT} within params
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
default Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults, boolean includeServiceAccounts) {
|
default Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults, boolean includeServiceAccounts) {
|
||||||
List<UserModel> value = this.getUsers(realm, firstResult == null ? -1 : firstResult, maxResults == null ? -1 : maxResults, includeServiceAccounts);
|
Map<String, String> searchAttributes = new HashMap<>(1);
|
||||||
return value != null ? value.stream() : Stream.empty();
|
searchAttributes.put(UserModel.INCLUDE_SERVICE_ACCOUNT, Boolean.toString(includeServiceAccounts));
|
||||||
|
return this.searchForUserStream(realm, searchAttributes, firstResult, maxResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -412,23 +430,5 @@ public interface UserProvider extends Provider,
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Stream<UserConsentModel> getConsentsStream(RealmModel realm, String userId);
|
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
|
|
||||||
default Stream<UserModel> getUsersStream(RealmModel realm, boolean includeServiceAccounts) {
|
|
||||||
return getUsersStream(realm, null, null, 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, Integer firstResult, Integer maxResults, boolean includeServiceAccounts);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ public interface UserQueryProvider {
|
||||||
if (groupIds == null || groupIds.isEmpty()) {
|
if (groupIds == null || groupIds.isEmpty()) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return countUsersInGroups(getUsersStream(realm), groupIds);
|
return countUsersInGroups(searchForUserStream(realm, Collections.emptyMap()), groupIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -176,26 +176,31 @@ public interface UserQueryProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use {@link #getUsersStream(RealmModel) getUsersStream} instead.
|
* @deprecated Use {@link #searchForUserStream(RealmModel, Map)} with an empty params map instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
List<UserModel> getUsers(RealmModel realm);
|
default List<UserModel> getUsers(RealmModel realm) {
|
||||||
|
return searchForUserStream(realm, Collections.emptyMap()).collect(Collectors.toList());
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Searches all users in the realm.
|
* Searches all users in the realm.
|
||||||
*
|
*
|
||||||
* @param realm a reference to the realm.
|
* @param realm a reference to the realm.
|
||||||
* @return a non-null {@link Stream} of users.
|
* @return a non-null {@link Stream} of users.
|
||||||
|
* @deprecated Use {@link #searchForUserStream(RealmModel, Map)} with an empty params map instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
default Stream<UserModel> getUsersStream(RealmModel realm) {
|
default Stream<UserModel> getUsersStream(RealmModel realm) {
|
||||||
List<UserModel> value = this.getUsers(realm);
|
return searchForUserStream(realm, Collections.emptyMap());
|
||||||
return value != null ? value.stream() : Stream.empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Use {@link #getUsersStream(RealmModel, Integer, Integer) getUsersStream} instead.
|
* @deprecated Use {@link #searchForUserStream(RealmModel, Map, Integer, Integer)} with an empty params map instead.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults);
|
default List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults) {
|
||||||
|
return searchForUserStream(realm, Collections.emptyMap(), firstResult, maxResults).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches all users in the realm, starting from the {@code firstResult} and containing at most {@code maxResults}.
|
* Searches all users in the realm, starting from the {@code firstResult} and containing at most {@code maxResults}.
|
||||||
|
@ -204,11 +209,11 @@ public interface UserQueryProvider {
|
||||||
* @param firstResult first result to return. Ignored if negative or {@code null}.
|
* @param firstResult first result to return. Ignored if negative or {@code null}.
|
||||||
* @param maxResults maximum number of results to return. Ignored if negative or {@code null}.
|
* @param maxResults maximum number of results to return. Ignored if negative or {@code null}.
|
||||||
* @return a non-null {@link Stream} of users.
|
* @return a non-null {@link Stream} of users.
|
||||||
|
* @deprecated Use {@link #searchForUserStream(RealmModel, Map, Integer, Integer)} with an empty params map instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
default Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
default Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
|
||||||
List<UserModel> value = this.getUsers(realm, firstResult == null ? -1 : firstResult,
|
return searchForUserStream(realm, Collections.emptyMap(), firstResult, maxResults);
|
||||||
maxResults == null ? -1 : maxResults);
|
|
||||||
return value != null ? value.stream() : Stream.empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -295,6 +300,14 @@ public interface UserQueryProvider {
|
||||||
* from idp with the given alias configured (case sensitive string)</li>
|
* from idp with the given alias configured (case sensitive string)</li>
|
||||||
* <li>{@link UserModel#IDP_USER_ID} - search for users with federated identity with
|
* <li>{@link UserModel#IDP_USER_ID} - search for users with federated identity with
|
||||||
* the given userId (case sensitive string)</li>
|
* the given userId (case sensitive string)</li>
|
||||||
|
* <li>{@link UserModel#SEARCH} - Searches for users whose username, email, first name or last name contain any
|
||||||
|
* of the strings in {@code search} separated by whitespace. If possible, implementations should treat the
|
||||||
|
* parameter values as partial match patterns (i.e. in RDMBS terms use LIKE).</li>
|
||||||
|
* <li>{@link UserModel#EXACT} - Used alongside with {@link UserModel#FIRST_NAME}, {@link UserModel#LAST_NAME},
|
||||||
|
* {@link UserModel#EMAIL} and {@link UserModel#USERNAME} parameters; if true searching is done using equals
|
||||||
|
* otherwise partial match should be enough to fulfill these parameters</li>
|
||||||
|
* <li>{@link UserModel#INCLUDE_SERVICE_ACCOUNT} - When false, users that have a service account link are not
|
||||||
|
* included in result</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* If possible, implementations should treat the parameter values as partial match patterns i.e. in RDMBS terms use LIKE.
|
* If possible, implementations should treat the parameter values as partial match patterns i.e. in RDMBS terms use LIKE.
|
||||||
|
@ -593,24 +606,6 @@ public interface UserQueryProvider {
|
||||||
return getUsersCount(realm, params, groupIds);
|
return getUsersCount(realm, params, groupIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
default List<UserModel> getUsers(RealmModel realm) {
|
|
||||||
return this.getUsersStream(realm).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
default Stream<UserModel> getUsersStream(RealmModel realm) {
|
|
||||||
return getUsersStream(realm, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@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, Integer firstResult, Integer maxResults);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default List<UserModel> searchForUser(String search, RealmModel realm) {
|
default List<UserModel> searchForUser(String search, RealmModel realm) {
|
||||||
return this.searchForUserStream(realm, search).collect(Collectors.toList());
|
return this.searchForUserStream(realm, search).collect(Collectors.toList());
|
||||||
|
|
|
@ -65,6 +65,7 @@ import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
@ -227,7 +228,7 @@ public class ExportUtils {
|
||||||
|
|
||||||
// Finally users if needed
|
// Finally users if needed
|
||||||
if (options.isUsersIncluded()) {
|
if (options.isUsersIncluded()) {
|
||||||
List<UserRepresentation> users = session.users().getUsersStream(realm, true)
|
List<UserRepresentation> users = session.users().searchForUserStream(realm, Collections.emptyMap())
|
||||||
.map(user -> exportUser(session, realm, user, options, internal))
|
.map(user -> exportUser(session, realm, user, options, internal))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,8 @@ import javax.ws.rs.QueryParam;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
@ -191,7 +193,7 @@ public class IdentityProviderResource {
|
||||||
// Admin changed the ID (alias) of identity provider. We must update all clients and users
|
// Admin changed the ID (alias) of identity provider. We must update all clients and users
|
||||||
logger.debug("Changing providerId in all clients and linked users. oldProviderId=" + oldProviderId + ", newProviderId=" + newProviderId);
|
logger.debug("Changing providerId in all clients and linked users. oldProviderId=" + oldProviderId + ", newProviderId=" + newProviderId);
|
||||||
|
|
||||||
updateUsersAfterProviderAliasChange(session.users().getUsersStream(realm, false),
|
updateUsersAfterProviderAliasChange(session.users().searchForUserStream(realm, Collections.singletonMap(UserModel.INCLUDE_SERVICE_ACCOUNT, Boolean.FALSE.toString())),
|
||||||
oldProviderId, newProviderId, realm, session);
|
oldProviderId, newProviderId, realm, session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -433,7 +433,7 @@ public class UsersResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Stream<UserRepresentation> searchForUser(Map<String, String> attributes, RealmModel realm, UserPermissionEvaluator usersEvaluator, Boolean briefRepresentation, Integer firstResult, Integer maxResults, Boolean includeServiceAccounts) {
|
private Stream<UserRepresentation> searchForUser(Map<String, String> attributes, RealmModel realm, UserPermissionEvaluator usersEvaluator, Boolean briefRepresentation, Integer firstResult, Integer maxResults, Boolean includeServiceAccounts) {
|
||||||
session.setAttribute(UserModel.INCLUDE_SERVICE_ACCOUNT, includeServiceAccounts);
|
attributes.put(UserModel.INCLUDE_SERVICE_ACCOUNT, includeServiceAccounts.toString());
|
||||||
|
|
||||||
if (!auth.users().canView()) {
|
if (!auth.users().canView()) {
|
||||||
Set<String> groupModels = auth.groups().getGroupsWithViewPermission();
|
Set<String> groupModels = auth.groups().getGroupsWithViewPermission();
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class ProfileAssume {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void assumeFeatureDisabled(Profile.Feature feature) {
|
public static void assumeFeatureDisabled(Profile.Feature feature) {
|
||||||
Assume.assumeTrue("Ignoring test as feature " + feature.name() + " is disabled", !isFeatureEnabled(feature));
|
Assume.assumeTrue("Ignoring test as feature " + feature.name() + " is enabled", !isFeatureEnabled(feature));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void assumePreview() {
|
public static void assumePreview() {
|
||||||
|
|
|
@ -307,7 +307,8 @@ public class LDAPSyncTest extends AbstractLDAPTest {
|
||||||
LDAPTestContext ctx = LDAPTestContext.init(session);
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
|
||||||
// Remove all users from model
|
// Remove all users from model
|
||||||
UserStoragePrivateUtil.userLocalStorage(session).getUsersStream(ctx.getRealm(), true)
|
UserStoragePrivateUtil.userLocalStorage(session)
|
||||||
|
.searchForUserStream(ctx.getRealm(), Collections.emptyMap())
|
||||||
.collect(Collectors.toList())
|
.collect(Collectors.toList())
|
||||||
.forEach(user -> UserStoragePrivateUtil.userLocalStorage(session).removeUser(ctx.getRealm(), user));
|
.forEach(user -> UserStoragePrivateUtil.userLocalStorage(session).removeUser(ctx.getRealm(), user));
|
||||||
|
|
||||||
|
@ -356,7 +357,8 @@ public class LDAPSyncTest extends AbstractLDAPTest {
|
||||||
LDAPTestContext ctx = LDAPTestContext.init(session);
|
LDAPTestContext ctx = LDAPTestContext.init(session);
|
||||||
|
|
||||||
// Remove all users from model
|
// Remove all users from model
|
||||||
UserStoragePrivateUtil.userLocalStorage(session).getUsersStream(ctx.getRealm(), true)
|
UserStoragePrivateUtil.userLocalStorage(session)
|
||||||
|
.searchForUserStream(ctx.getRealm(), Collections.emptyMap())
|
||||||
.peek(user -> System.out.println("trying to delete user: " + user.getUsername()))
|
.peek(user -> System.out.println("trying to delete user: " + user.getUsername()))
|
||||||
.collect(Collectors.toList())
|
.collect(Collectors.toList())
|
||||||
.forEach(user -> {
|
.forEach(user -> {
|
||||||
|
|
|
@ -56,6 +56,7 @@ import org.keycloak.testsuite.pages.AppPage;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
import org.keycloak.testsuite.pages.LoginPage;
|
||||||
import org.keycloak.testsuite.util.OAuthClient;
|
import org.keycloak.testsuite.util.OAuthClient;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -345,7 +346,7 @@ public class UserStorageFailureTest extends AbstractTestRealmKeycloakTest {
|
||||||
Assert.assertEquals(1, result.count());
|
Assert.assertEquals(1, result.count());
|
||||||
|
|
||||||
// we run a terminal operation on the stream to make sure it is consumed.
|
// we run a terminal operation on the stream to make sure it is consumed.
|
||||||
session.users().getUsersStream(realm).count();
|
session.users().searchForUserStream(realm, Collections.emptyMap()).count();
|
||||||
session.users().getUsersCount(realm);
|
session.users().getUsersCount(realm);
|
||||||
|
|
||||||
UserModel user = session.users().getUserByUsername(realm, FailableHardcodedStorageProvider.username);
|
UserModel user = session.users().getUserByUsername(realm, FailableHardcodedStorageProvider.username);
|
||||||
|
|
|
@ -479,11 +479,11 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest {
|
||||||
Assert.assertThat(users, hasSize(1));
|
Assert.assertThat(users, hasSize(1));
|
||||||
Assert.assertThat(users, contains(user2));
|
Assert.assertThat(users, contains(user2));
|
||||||
|
|
||||||
users = currentSession.users().getUsersStream(realm, false).collect(Collectors.toList());
|
users = currentSession.users().searchForUserStream(realm, Collections.singletonMap(UserModel.INCLUDE_SERVICE_ACCOUNT, Boolean.FALSE.toString())).collect(Collectors.toList());
|
||||||
Assert.assertThat(users, hasSize(1));
|
Assert.assertThat(users, hasSize(1));
|
||||||
Assert.assertThat(users, contains(user2));
|
Assert.assertThat(users, contains(user2));
|
||||||
|
|
||||||
users = currentSession.users().getUsersStream(realm, true).collect(Collectors.toList());
|
users = currentSession.users().searchForUserStream(realm, Collections.emptyMap()).collect(Collectors.toList());
|
||||||
Assert.assertThat(users, hasSize(2));
|
Assert.assertThat(users, hasSize(2));
|
||||||
Assert.assertThat(users, containsInAnyOrder(user1, user2));
|
Assert.assertThat(users, containsInAnyOrder(user1, user2));
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.RoleContainerModel;
|
import org.keycloak.models.RoleContainerModel;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
|
||||||
*/
|
*/
|
||||||
|
@ -45,7 +47,7 @@ public class TestCacheUtils {
|
||||||
|
|
||||||
realm.getClientScopesStream().map(ClientScopeModel::getId).forEach(realm::getClientScopeById);
|
realm.getClientScopesStream().map(ClientScopeModel::getId).forEach(realm::getClientScopeById);
|
||||||
|
|
||||||
session.users().getUsersStream(realm).forEach(user -> {
|
session.users().searchForUserStream(realm, Collections.emptyMap()).forEach(user -> {
|
||||||
session.users().getUserById(realm, user.getId());
|
session.users().getUserById(realm, user.getId());
|
||||||
if (user.getEmail() != null) {
|
if (user.getEmail() != null) {
|
||||||
session.users().getUserByEmail(realm, user.getEmail());
|
session.users().getUserByEmail(realm, user.getEmail());
|
||||||
|
|
Loading…
Reference in a new issue