KEYCLOAK-15524 Cleanup user related interfaces

This commit is contained in:
Michal Hajas 2020-12-04 08:33:42 +01:00 committed by Hynek Mlnařík
parent dae4a3eaf2
commit ba8e2fef6b
145 changed files with 1625 additions and 1381 deletions

View file

@ -349,7 +349,7 @@ public class UMAPolicyProviderFactory implements PolicyProviderFactory<UmaPermis
UserPolicyRepresentation rep = UserPolicyRepresentation.class.cast(associatedRep);
for (String user : rep.getUsers()) {
representation.addUser(authorization.getKeycloakSession().users().getUserById(user, realm).getUsername());
representation.addUser(authorization.getKeycloakSession().users().getUserById(realm, user).getUsername());
}
}
}

View file

@ -119,7 +119,7 @@ public class UserPolicyProviderFactory implements PolicyProviderFactory<UserPoli
UserProvider userProvider = authorizationProvider.getKeycloakSession().users();
RealmModel realm = authorizationProvider.getRealm();
config.put("users", JsonSerialization.writeValueAsString(userRep.getUsers().stream().map(id -> userProvider.getUserById(id, realm).getUsername()).collect(Collectors.toList())));
config.put("users", JsonSerialization.writeValueAsString(userRep.getUsers().stream().map(id -> userProvider.getUserById(realm, id).getUsername()).collect(Collectors.toList())));
} catch (IOException cause) {
throw new RuntimeException("Failed to export user policy [" + policy.getName() + "]", cause);
}
@ -142,12 +142,12 @@ public class UserPolicyProviderFactory implements PolicyProviderFactory<UserPoli
UserModel user = null;
try {
user = userProvider.getUserByUsername(userId, realm);
user = userProvider.getUserByUsername(realm, userId);
} catch (Exception ignore) {
}
if (user == null) {
user = userProvider.getUserById(userId, realm);
user = userProvider.getUserById(realm, userId);
}
if (user == null) {

View file

@ -48,7 +48,7 @@ import java.util.stream.Stream;
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class KerberosFederationProvider implements UserStorageProvider,
UserLookupProvider,
UserLookupProvider.Streams,
CredentialInputValidator,
CredentialInputUpdater.Streams,
CredentialAuthentication,
@ -83,7 +83,7 @@ public class KerberosFederationProvider implements UserStorageProvider,
}
@Override
public UserModel getUserByUsername(String username, RealmModel realm) {
public UserModel getUserByUsername(RealmModel realm, String username) {
KerberosUsernamePasswordAuthenticator authenticator = factory.createKerberosUsernamePasswordAuthenticator(kerberosConfig);
if (authenticator.isUserAvailable(username)) {
// Case when method was called with username including kerberos realm like john@REALM.ORG . Authenticator already checked that kerberos realm was correct
@ -98,12 +98,12 @@ public class KerberosFederationProvider implements UserStorageProvider,
}
@Override
public UserModel getUserByEmail(String email, RealmModel realm) {
public UserModel getUserByEmail(RealmModel realm, String email) {
return null;
}
@Override
public UserModel getUserById(String id, RealmModel realm) {
public UserModel getUserById(RealmModel realm, String id) {
return null;
}
@ -234,9 +234,9 @@ public class KerberosFederationProvider implements UserStorageProvider,
* @return user if found or successfully created. Null if user with same username already exists, but is not linked to this provider
*/
protected UserModel findOrCreateAuthenticatedUser(RealmModel realm, String username) {
UserModel user = session.userLocalStorage().getUserByUsername(username, realm);
UserModel user = session.userLocalStorage().getUserByUsername(realm, username);
if (user != null) {
user = session.users().getUserById(user.getId(), realm); // make sure we get a cached instance
user = session.users().getUserById(realm, user.getId()); // make sure we get a cached instance
logger.debug("Kerberos authenticated user " + username + " found in Keycloak storage");
if (!model.getId().equals(user.getFederationLink())) {

View file

@ -79,6 +79,8 @@ import org.keycloak.storage.user.UserLookupProvider;
import org.keycloak.storage.user.UserQueryProvider;
import org.keycloak.storage.user.UserRegistrationProvider;
import static org.keycloak.utils.StreamsUtil.paginatedStream;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -88,11 +90,12 @@ public class LDAPStorageProvider implements UserStorageProvider,
CredentialInputValidator,
CredentialInputUpdater.Streams,
CredentialAuthentication,
UserLookupProvider,
UserLookupProvider.Streams,
UserRegistrationProvider,
UserQueryProvider.Streams,
ImportedUserValidation {
private static final Logger logger = Logger.getLogger(LDAPStorageProvider.class);
private static final int DEFAULT_MAX_RESULTS = Integer.MAX_VALUE >> 1;
protected LDAPStorageProviderFactory factory;
protected KeycloakSession session;
@ -176,7 +179,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
// We need to avoid having CachedUserModel as cache is upper-layer then LDAP. Hence having CachedUserModel here may cause StackOverflowError
if (local instanceof CachedUserModel) {
local = session.userStorageManager().getUserById(local.getId(), realm);
local = session.userStorageManager().getUserById(realm, local.getId());
existing = userManager.getManagedProxiedUser(local.getId());
if (existing != null) {
@ -245,7 +248,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
}
@Override
public Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm) {
public Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
try (LDAPQuery ldapQuery = LDAPUtils.createQueryForUserSearch(this, realm)) {
LDAPQueryConditionsBuilder conditionsBuilder = new LDAPQueryConditionsBuilder();
@ -256,7 +259,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
return ldapObjects.stream().map(ldapUser -> {
String ldapUsername = LDAPUtils.getUsername(ldapUser, this.ldapIdentityStore.getConfig());
UserModel localUser = session.userLocalStorage().getUserByUsername(ldapUsername, realm);
UserModel localUser = session.userLocalStorage().getUserByUsername(realm, ldapUsername);
if (localUser == null) {
return importUserFromLDAP(session, realm, ldapUser);
} else {
@ -323,12 +326,12 @@ public class LDAPStorageProvider implements UserStorageProvider,
}
@Override
public UserModel getUserById(String id, RealmModel realm) {
public UserModel getUserById(RealmModel realm, String id) {
UserModel alreadyLoadedInSession = userManager.getManagedProxiedUser(id);
if (alreadyLoadedInSession != null) return alreadyLoadedInSession;
StorageId storageId = new StorageId(id);
return getUserByUsername(storageId.getExternalId(), realm);
return getUserByUsername(realm, storageId.getExternalId());
}
@Override
@ -342,29 +345,20 @@ public class LDAPStorageProvider implements UserStorageProvider,
}
@Override
public Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults) {
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
return Stream.empty();
}
@Override
public Stream<UserModel> searchForUserStream(String search, RealmModel realm) {
return searchForUserStream(search, realm, 0, Integer.MAX_VALUE - 1);
}
@Override
public Stream<UserModel> searchForUserStream(String search, RealmModel realm, Integer firstResult, Integer maxResults) {
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
Map<String, String> attributes = new HashMap<String, String>();
attributes.put(UserModel.SEARCH,search);
return searchForUserStream(attributes, realm, firstResult, maxResults);
return searchForUserStream(realm, attributes, firstResult, maxResults);
}
@Override
public Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm) {
return searchForUserStream(params, realm, 0, Integer.MAX_VALUE - 1);
}
@Override
public Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm, Integer firstResult, Integer maxResults) {
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> params, Integer firstResult, Integer maxResults) {
String search = params.get(UserModel.SEARCH);
if(search!=null) {
int spaceIndex = search.lastIndexOf(' ');
@ -385,41 +379,34 @@ public class LDAPStorageProvider implements UserStorageProvider,
Stream<LDAPObject> stream = searchLDAP(realm, params).stream()
.filter(ldapObject -> {
String ldapUsername = LDAPUtils.getUsername(ldapObject, this.ldapIdentityStore.getConfig());
return (session.userLocalStorage().getUserByUsername(ldapUsername, realm) == null);
return (session.userLocalStorage().getUserByUsername(realm, ldapUsername) == null);
});
if (firstResult > 0)
stream = stream.skip(firstResult);
if (maxResults >= 0)
stream = stream.limit(maxResults);
return stream.map(ldapObject -> importUserFromLDAP(session, realm, ldapObject));
}
@Override
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group) {
return getGroupMembersStream(realm, group, 0, Integer.MAX_VALUE - 1);
return paginatedStream(stream, firstResult, maxResults).map(ldapObject -> importUserFromLDAP(session, realm, ldapObject));
}
@Override
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group, Integer firstResult, Integer maxResults) {
int first = firstResult == null ? 0 : firstResult;
int max = maxResults == null ? DEFAULT_MAX_RESULTS : maxResults;
return realm.getComponentsStream(model.getId(), LDAPStorageMapper.class.getName())
.sorted(ldapMappersComparator.sortAsc())
.map(mapperModel ->
mapperManager.getMapper(mapperModel).getGroupMembers(realm, group, firstResult, maxResults))
mapperManager.getMapper(mapperModel).getGroupMembers(realm, group, first, max))
.filter(((Predicate<List>) List::isEmpty).negate())
.map(List::stream)
.findFirst().orElse(Stream.empty());
}
@Override
public Stream<UserModel> getRoleMembersStream(RealmModel realm, RoleModel role) {
return getRoleMembersStream(realm, role, 0, Integer.MAX_VALUE - 1);
}
@Override
public Stream<UserModel> getRoleMembersStream(RealmModel realm, RoleModel role, Integer firstResult, Integer maxResults) {
int first = firstResult == null ? 0 : firstResult;
int max = maxResults == null ? DEFAULT_MAX_RESULTS : maxResults;
return realm.getComponentsStream(model.getId(), LDAPStorageMapper.class.getName())
.sorted(ldapMappersComparator.sortAsc())
.map(mapperModel -> mapperManager.getMapper(mapperModel).getRoleMembers(realm, role, firstResult, maxResults))
.map(mapperModel -> mapperManager.getMapper(mapperModel).getRoleMembers(realm, role, first, max))
.filter(((Predicate<List>) List::isEmpty).negate())
.map(List::stream)
.findFirst().orElse(Stream.empty());
@ -428,7 +415,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
public List<UserModel> loadUsersByUsernames(List<String> usernames, RealmModel realm) {
List<UserModel> result = new ArrayList<>();
for (String username : usernames) {
UserModel kcUser = session.users().getUserByUsername(username, realm);
UserModel kcUser = session.users().getUserByUsername(realm, username);
if (kcUser == null) {
logger.warnf("User '%s' referenced by membership wasn't found in LDAP", username);
} else if (model.isImportEnabled() && !model.getId().equals(kcUser.getFederationLink())) {
@ -514,7 +501,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
}
@Override
public UserModel getUserByUsername(String username, RealmModel realm) {
public UserModel getUserByUsername(RealmModel realm, String username) {
LDAPObject ldapUser = loadLDAPUserByUsername(realm, username);
if (ldapUser == null) {
return null;
@ -575,7 +562,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
@Override
public UserModel getUserByEmail(String email, RealmModel realm) {
public UserModel getUserByEmail(RealmModel realm, String email) {
LDAPObject ldapUser = queryByEmail(realm, email);
if (ldapUser == null) {
return null;
@ -583,7 +570,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
// Check here if user already exists
String ldapUsername = LDAPUtils.getUsername(ldapUser, ldapIdentityStore.getConfig());
UserModel user = session.userLocalStorage().getUserByUsername(ldapUsername, realm);
UserModel user = session.userLocalStorage().getUserByUsername(realm, ldapUsername);
if (user != null) {
LDAPUtils.checkUuid(ldapUser, ldapIdentityStore.getConfig());
@ -771,7 +758,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
* @return finded or newly created user
*/
protected UserModel findOrCreateAuthenticatedUser(RealmModel realm, String username) {
UserModel user = session.userLocalStorage().getUserByUsername(username, realm);
UserModel user = session.userLocalStorage().getUserByUsername(realm, username);
if (user != null) {
logger.debugf("Kerberos authenticated user [%s] found in Keycloak storage", username);
if (!model.getId().equals(user.getFederationLink())) {
@ -796,7 +783,7 @@ public class LDAPStorageProvider implements UserStorageProvider,
// Creating user to local storage
logger.debugf("Kerberos authenticated user [%s] not in Keycloak storage. Creating him", username);
return getUserByUsername(username, realm);
return getUserByUsername(realm, username);
}
public LDAPObject loadLDAPUserByUsername(RealmModel realm, String username) {

View file

@ -593,7 +593,7 @@ public class LDAPStorageProviderFactory implements UserStorageProviderFactory<LD
String username = LDAPUtils.getUsername(ldapUser, ldapFedProvider.getLdapIdentityStore().getConfig());
exists.value = true;
LDAPUtils.checkUuid(ldapUser, ldapFedProvider.getLdapIdentityStore().getConfig());
UserModel currentUser = session.userLocalStorage().getUserByUsername(username, currentRealm);
UserModel currentUser = session.userLocalStorage().getUserByUsername(currentRealm, username);
if (currentUser == null) {
@ -649,7 +649,7 @@ public class LDAPStorageProviderFactory implements UserStorageProviderFactory<LD
}
if (username != null) {
UserModel existing = session.userLocalStorage().getUserByUsername(username, currentRealm);
UserModel existing = session.userLocalStorage().getUserByUsername(currentRealm, username);
if (existing != null) {
UserCache userCache = session.userCache();
if (userCache != null) {

View file

@ -149,7 +149,7 @@ public class UserAttributeLDAPStorageMapper extends AbstractLDAPStorageMapper {
// lowercase before search
email = KeycloakModelUtils.toLowerCaseSafe(email);
UserModel that = session.userLocalStorage().getUserByEmail(email, realm);
UserModel that = session.userLocalStorage().getUserByEmail(realm, email);
if (that != null && !that.getId().equals(user.getId())) {
session.getTransactionManager().setRollbackOnly();
String exceptionMessage = String.format("Can't import user '%s' from LDAP because email '%s' already exists in Keycloak. Existing user with this email is '%s'", user.getUsername(), email, that.getUsername());
@ -166,7 +166,7 @@ public class UserAttributeLDAPStorageMapper extends AbstractLDAPStorageMapper {
}
boolean usernameChanged = !username.equals(user.getUsername());
if (realm.isEditUsernameAllowed() && usernameChanged) {
UserModel that = session.users().getUserByUsername(username, realm);
UserModel that = session.users().getUserByUsername(realm, username);
if (that != null && !that.getId().equals(user.getId())) {
throw new ModelDuplicateException(
String.format("Cannot change the username to '%s' because the username already exists in keycloak", username),

View file

@ -44,7 +44,7 @@ import java.util.stream.Stream;
* @version $Revision: 1 $
*/
public class SSSDFederationProvider implements UserStorageProvider,
UserLookupProvider,
UserLookupProvider.Streams,
CredentialInputUpdater.Streams,
CredentialInputValidator,
ImportedUserValidation {
@ -68,7 +68,7 @@ public class SSSDFederationProvider implements UserStorageProvider,
@Override
public UserModel getUserByUsername(String username, RealmModel realm) {
public UserModel getUserByUsername(RealmModel realm, String username) {
return findOrCreateAuthenticatedUser(realm, username);
}
@ -85,7 +85,7 @@ public class SSSDFederationProvider implements UserStorageProvider,
* @return user if found or successfully created. Null if user with same username already exists, but is not linked to this provider
*/
protected UserModel findOrCreateAuthenticatedUser(RealmModel realm, String username) {
UserModel user = session.userLocalStorage().getUserByUsername(username, realm);
UserModel user = session.userLocalStorage().getUserByUsername(realm, username);
if (user != null) {
logger.debug("SSSD authenticated user " + username + " found in Keycloak storage");
@ -130,12 +130,12 @@ public class SSSDFederationProvider implements UserStorageProvider,
}
@Override
public UserModel getUserById(String id, RealmModel realm) {
public UserModel getUserById(RealmModel realm, String id) {
return null;
}
@Override
public UserModel getUserByEmail(String email, RealmModel realm) {
public UserModel getUserByEmail(RealmModel realm, String email) {
return null;
}

View file

@ -380,6 +380,6 @@ public class UserAdapter implements CachedUserModel.Streams {
}
private UserModel getUserModel() {
return userProviderCache.getDelegate().getUserById(cached.getId(), realm);
return userProviderCache.getDelegate().getUserById(realm, cached.getId());
}
}

View file

@ -183,11 +183,11 @@ public class UserCacheSession implements UserCache.Streams {
}
@Override
public UserModel getUserById(String id, RealmModel realm) {
public UserModel getUserById(RealmModel realm, String id) {
logger.tracev("getuserById {0}", id);
if (isRegisteredForInvalidation(realm, id)) {
logger.trace("registered for invalidation return delegate");
return getDelegate().getUserById(id, realm);
return getDelegate().getUserById(realm, id);
}
if (managedUsers.containsKey(id)) {
logger.trace("return managedusers");
@ -204,7 +204,7 @@ public class UserCacheSession implements UserCache.Streams {
if (cached == null) {
logger.trace("not cached");
Long loaded = cache.getCurrentRevision(id);
UserModel delegate = getDelegate().getUserById(id, realm);
UserModel delegate = getDelegate().getUserById(realm, id);
if (delegate == null) {
logger.trace("delegate returning null");
return null;
@ -238,17 +238,17 @@ public class UserCacheSession implements UserCache.Streams {
}
@Override
public UserModel getUserByUsername(String username, RealmModel realm) {
public UserModel getUserByUsername(RealmModel realm, String username) {
logger.tracev("getUserByUsername: {0}", username);
username = username.toLowerCase();
if (realmInvalidations.contains(realm.getId())) {
logger.tracev("realmInvalidations");
return getDelegate().getUserByUsername(username, realm);
return getDelegate().getUserByUsername(realm, username);
}
String cacheKey = getUserByUsernameCacheKey(realm.getId(), username);
if (invalidations.contains(cacheKey)) {
logger.tracev("invalidations");
return getDelegate().getUserByUsername(username, realm);
return getDelegate().getUserByUsername(realm, username);
}
UserListQuery query = cache.get(cacheKey, UserListQuery.class);
@ -256,7 +256,7 @@ public class UserCacheSession implements UserCache.Streams {
if (query == null) {
logger.tracev("query null");
Long loaded = cache.getCurrentRevision(cacheKey);
UserModel model = getDelegate().getUserByUsername(username, realm);
UserModel model = getDelegate().getUserByUsername(realm, username);
if (model == null) {
logger.tracev("model from delegate null");
return null;
@ -279,11 +279,11 @@ public class UserCacheSession implements UserCache.Streams {
userId = query.getUsers().iterator().next();
if (invalidations.contains(userId)) {
logger.tracev("invalidated cache return delegate");
return getDelegate().getUserByUsername(username, realm);
return getDelegate().getUserByUsername(realm, username);
}
logger.trace("return getUserById");
return getUserById(userId, realm);
return getUserById(realm, userId);
}
}
@ -312,7 +312,7 @@ public class UserCacheSession implements UserCache.Streams {
// its also hard to test stuff
if (model.shouldInvalidate(cached)) {
registerUserInvalidation(realm, cached);
return getDelegate().getUserById(cached.getId(), realm);
return getDelegate().getUserById(realm, cached.getId());
}
}
return new UserAdapter(cached, this, session, realm);
@ -368,22 +368,22 @@ public class UserCacheSession implements UserCache.Streams {
}
@Override
public UserModel getUserByEmail(String email, RealmModel realm) {
public UserModel getUserByEmail(RealmModel realm, String email) {
if (email == null) return null;
email = email.toLowerCase();
if (realmInvalidations.contains(realm.getId())) {
return getDelegate().getUserByEmail(email, realm);
return getDelegate().getUserByEmail(realm, email);
}
String cacheKey = getUserByEmailCacheKey(realm.getId(), email);
if (invalidations.contains(cacheKey)) {
return getDelegate().getUserByEmail(email, realm);
return getDelegate().getUserByEmail(realm, email);
}
UserListQuery query = cache.get(cacheKey, UserListQuery.class);
String userId = null;
if (query == null) {
Long loaded = cache.getCurrentRevision(cacheKey);
UserModel model = getDelegate().getUserByEmail(email, realm);
UserModel model = getDelegate().getUserByEmail(realm, email);
if (model == null) return null;
userId = model.getId();
if (invalidations.contains(userId)) return model;
@ -399,10 +399,10 @@ public class UserCacheSession implements UserCache.Streams {
} else {
userId = query.getUsers().iterator().next();
if (invalidations.contains(userId)) {
return getDelegate().getUserByEmail(email, realm);
return getDelegate().getUserByEmail(realm, email);
}
return getUserById(userId, realm);
return getUserById(realm, userId);
}
}
@ -412,23 +412,23 @@ public class UserCacheSession implements UserCache.Streams {
}
@Override
public UserModel getUserByFederatedIdentity(FederatedIdentityModel socialLink, RealmModel realm) {
public UserModel getUserByFederatedIdentity(RealmModel realm, FederatedIdentityModel socialLink) {
if (socialLink == null) return null;
if (!realm.isIdentityFederationEnabled()) return null;
if (realmInvalidations.contains(realm.getId())) {
return getDelegate().getUserByFederatedIdentity(socialLink, realm);
return getDelegate().getUserByFederatedIdentity(realm, socialLink);
}
String cacheKey = getUserByFederatedIdentityCacheKey(realm.getId(), socialLink);
if (invalidations.contains(cacheKey)) {
return getDelegate().getUserByFederatedIdentity(socialLink, realm);
return getDelegate().getUserByFederatedIdentity(realm, socialLink);
}
UserListQuery query = cache.get(cacheKey, UserListQuery.class);
String userId = null;
if (query == null) {
Long loaded = cache.getCurrentRevision(cacheKey);
UserModel model = getDelegate().getUserByFederatedIdentity(socialLink, realm);
UserModel model = getDelegate().getUserByFederatedIdentity(realm, socialLink);
if (model == null) return null;
userId = model.getId();
if (invalidations.contains(userId)) return model;
@ -446,10 +446,10 @@ public class UserCacheSession implements UserCache.Streams {
userId = query.getUsers().iterator().next();
if (invalidations.contains(userId)) {
invalidations.add(cacheKey);
return getDelegate().getUserByFederatedIdentity(socialLink, realm);
return getDelegate().getUserByFederatedIdentity(realm, socialLink);
}
return getUserById(userId, realm);
return getUserById(realm, userId);
}
}
@ -527,11 +527,11 @@ public class UserCacheSession implements UserCache.Streams {
userId = query.getUsers().iterator().next();
if (invalidations.contains(userId)) {
logger.tracev("invalidated cache return delegate");
return getDelegate().getUserByUsername(username, realm);
return getDelegate().getUserByUsername(realm, username);
}
logger.trace("return getUserById");
return getUserById(userId, realm);
return getUserById(realm, userId);
}
}
@ -545,34 +545,29 @@ public class UserCacheSession implements UserCache.Streams {
return getDelegate().getUsersCount(realm, includeServiceAccount);
}
@Override
public int getUsersCount(RealmModel realm) {
return getUsersCount(realm, false);
}
@Override
public int getUsersCount(RealmModel realm, Set<String> groupIds) {
return getDelegate().getUsersCount(realm, groupIds);
}
@Override
public int getUsersCount(String search, RealmModel realm) {
return getDelegate().getUsersCount(search, realm);
public int getUsersCount(RealmModel realm, String search) {
return getDelegate().getUsersCount(realm, search);
}
@Override
public int getUsersCount(String search, RealmModel realm, Set<String> groupIds) {
return getDelegate().getUsersCount(search, realm, groupIds);
public int getUsersCount(RealmModel realm, String search, Set<String> groupIds) {
return getDelegate().getUsersCount(realm, search, groupIds);
}
@Override
public int getUsersCount(Map<String, String> params, RealmModel realm) {
return getDelegate().getUsersCount(params, realm);
public int getUsersCount(RealmModel realm, Map<String, String> params) {
return getDelegate().getUsersCount(realm, params);
}
@Override
public int getUsersCount(Map<String, String> params, RealmModel realm, Set<String> groupIds) {
return getDelegate().getUsersCount(params, realm, groupIds);
public int getUsersCount(RealmModel realm, Map<String, String> params, Set<String> groupIds) {
return getDelegate().getUsersCount(realm, params, groupIds);
}
@Override
@ -586,49 +581,49 @@ public class UserCacheSession implements UserCache.Streams {
}
@Override
public Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults) {
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
return getUsersStream(realm, firstResult, maxResults, false);
}
@Override
public Stream<UserModel> searchForUserStream(String search, RealmModel realm) {
return getDelegate().searchForUserStream(search, realm);
public Stream<UserModel> searchForUserStream(RealmModel realm, String search) {
return getDelegate().searchForUserStream(realm, search);
}
@Override
public Stream<UserModel> searchForUserStream(String search, RealmModel realm, Integer firstResult, Integer maxResults) {
return getDelegate().searchForUserStream(search, realm, firstResult, maxResults);
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
return getDelegate().searchForUserStream(realm, search, firstResult, maxResults);
}
@Override
public Stream<UserModel> searchForUserStream(Map<String, String> attributes, RealmModel realm) {
return getDelegate().searchForUserStream(attributes, realm);
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> attributes) {
return getDelegate().searchForUserStream(realm, attributes);
}
@Override
public Stream<UserModel> searchForUserStream(Map<String, String> attributes, RealmModel realm, Integer firstResult, Integer maxResults) {
return getDelegate().searchForUserStream(attributes, realm, firstResult, maxResults);
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> attributes, Integer firstResult, Integer maxResults) {
return getDelegate().searchForUserStream(realm, attributes, firstResult, maxResults);
}
@Override
public Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm) {
return getDelegate().searchForUserByUserAttributeStream(attrName, attrValue, realm);
public Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
return getDelegate().searchForUserByUserAttributeStream(realm, attrName, attrValue);
}
@Override
public Stream<FederatedIdentityModel> getFederatedIdentitiesStream(UserModel user, RealmModel realm) {
public Stream<FederatedIdentityModel> getFederatedIdentitiesStream(RealmModel realm, UserModel user) {
logger.tracev("getFederatedIdentities: {0}", user.getUsername());
String cacheKey = getFederatedIdentityLinksCacheKey(user.getId());
if (realmInvalidations.contains(realm.getId()) || invalidations.contains(user.getId()) || invalidations.contains(cacheKey)) {
return getDelegate().getFederatedIdentitiesStream(user, realm);
return getDelegate().getFederatedIdentitiesStream(realm, user);
}
CachedFederatedIdentityLinks cachedLinks = cache.get(cacheKey, CachedFederatedIdentityLinks.class);
if (cachedLinks == null) {
Long loaded = cache.getCurrentRevision(cacheKey);
Set<FederatedIdentityModel> federatedIdentities = getDelegate().getFederatedIdentitiesStream(user, realm)
Set<FederatedIdentityModel> federatedIdentities = getDelegate().getFederatedIdentitiesStream(realm, user)
.collect(Collectors.toSet());
cachedLinks = new CachedFederatedIdentityLinks(loaded, cacheKey, realm, federatedIdentities);
cache.addRevisioned(cachedLinks, startupRevision);
@ -639,15 +634,15 @@ public class UserCacheSession implements UserCache.Streams {
}
@Override
public FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm) {
public FederatedIdentityModel getFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) {
logger.tracev("getFederatedIdentity: {0} {1}", user.getUsername(), socialProvider);
String cacheKey = getFederatedIdentityLinksCacheKey(user.getId());
if (realmInvalidations.contains(realm.getId()) || invalidations.contains(user.getId()) || invalidations.contains(cacheKey)) {
return getDelegate().getFederatedIdentity(user, socialProvider, realm);
return getDelegate().getFederatedIdentity(realm, user, socialProvider);
}
return getFederatedIdentitiesStream(user, realm)
return getFederatedIdentitiesStream(realm, user)
.filter(socialLink -> Objects.equals(socialLink.getIdentityProvider(), socialProvider))
.findFirst().orElse(null);
}
@ -748,7 +743,7 @@ public class UserCacheSession implements UserCache.Streams {
@Override
public void setNotBeforeForUser(RealmModel realm, UserModel user, int notBefore) {
if (!isRegisteredForInvalidation(realm, user.getId())) {
UserModel foundUser = getUserById(user.getId(), realm);
UserModel foundUser = getUserById(realm, user.getId());
if (foundUser instanceof UserAdapter) {
((UserAdapter) foundUser).invalidate();
}
@ -764,7 +759,7 @@ public class UserCacheSession implements UserCache.Streams {
return getDelegate().getNotBeforeOfUser(realm, user);
}
UserModel foundUser = getUserById(user.getId(), realm);
UserModel foundUser = getUserById(realm, user.getId());
if (foundUser instanceof UserAdapter) {
return ((UserAdapter) foundUser).cached.getNotBefore();
} else {
@ -793,7 +788,7 @@ public class UserCacheSession implements UserCache.Streams {
// just in case the transaction is rolled back you need to invalidate the user and all cache queries for that user
protected void fullyInvalidateUser(RealmModel realm, UserModel user) {
Stream<FederatedIdentityModel> federatedIdentities = realm.isIdentityFederationEnabled() ?
getFederatedIdentitiesStream(user, realm) : Stream.empty();
getFederatedIdentitiesStream(realm, user) : Stream.empty();
UserFullInvalidationEvent event = UserFullInvalidationEvent.create(user.getId(), user.getUsername(), user.getEmail(), realm.getId(), realm.isIdentityFederationEnabled(), federatedIdentities);
@ -827,7 +822,7 @@ public class UserCacheSession implements UserCache.Streams {
@Override
public boolean removeFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) {
// Needs to invalidate both directions
FederatedIdentityModel socialLink = getFederatedIdentity(user, socialProvider, realm);
FederatedIdentityModel socialLink = getFederatedIdentity(realm, user, socialProvider);
UserFederationLinkRemovedEvent event = UserFederationLinkRemovedEvent.create(user.getId(), realm.getId(), socialLink);
cache.federatedIdentityLinkRemovedInvalidation(user.getId(), realm.getId(), event.getIdentityProviderId(), event.getSocialUserId(), invalidations);

View file

@ -282,7 +282,7 @@ public class AuthenticationSessionAdapter implements AuthenticationSessionModel
@Override
public UserModel getAuthenticatedUser() {
return entity.getAuthUserId() == null ? null : session.users().getUserById(entity.getAuthUserId(), getRealm()); }
return entity.getAuthUserId() == null ? null : session.users().getUserById(getRealm(), entity.getAuthUserId()); }
@Override
public void setAuthenticatedUser(UserModel user) {

View file

@ -175,7 +175,7 @@ public class UserSessionAdapter implements UserSessionModel {
return entity.getBrokerUserId();
}
public UserModel getUser() {
return session.users().getUserById(entity.getUser(), realm);
return session.users().getUserById(realm, entity.getUser());
}
@Override

View file

@ -57,6 +57,7 @@ import java.util.stream.Stream;
import org.keycloak.models.ModelException;
import static org.keycloak.common.util.StackUtil.getShortStackTrace;
import static org.keycloak.models.jpa.PaginationUtils.paginateQuery;
import static org.keycloak.utils.StreamsUtil.closing;
@ -288,12 +289,7 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro
}
protected Stream<RoleModel> getRolesStream(TypedQuery<RoleEntity> query, RealmModel realm, Integer first, Integer max) {
if(Objects.nonNull(first) && Objects.nonNull(max)
&& first >= 0 && max >= 0) {
query= query.setFirstResult(first).setMaxResults(max);
}
Stream<RoleEntity> results = query.getResultStream();
Stream<RoleEntity> results = paginateQuery(query, first, max).getResultStream();
return closing(results.map(role -> new RoleAdapter(session, realm, em, role)));
}
@ -452,18 +448,6 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro
.map(g -> session.groups().getGroupById(realm, g));
}
private static <T> TypedQuery<T> paginateQuery(TypedQuery<T> query, Integer first, Integer max) {
if (first != null && first > 0) {
query = query.setFirstResult(first);
}
if (max != null && max >= 0) {
query = query.setMaxResults(max);
}
return query;
}
@Override
public Stream<GroupModel> getGroupsStream(RealmModel realm, Stream<String> ids) {
return ids.map(id -> session.groups().getGroupById(realm, id)).sorted(GroupModel.COMPARE_BY_NAME);
@ -515,13 +499,8 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro
public Stream<GroupModel> getGroupsByRoleStream(RealmModel realm, RoleModel role, Integer firstResult, Integer maxResults) {
TypedQuery<GroupEntity> query = em.createNamedQuery("groupsInRole", GroupEntity.class);
query.setParameter("roleId", role.getId());
if (firstResult != null && firstResult > 0) {
query = query.setFirstResult(firstResult);
}
if (maxResults != null && maxResults > 0) {
query = query.setMaxResults(maxResults);
}
Stream<GroupEntity> results = query.getResultStream();
Stream<GroupEntity> results = paginateQuery(query, firstResult, maxResults).getResultStream();
return closing(results
.map(g -> (GroupModel) new GroupAdapter(realm, em, g))
@ -657,14 +636,9 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro
@Override
public Stream<ClientModel> getClientsStream(RealmModel realm, Integer firstResult, Integer maxResults) {
TypedQuery<String> query = em.createNamedQuery("getClientIdsByRealm", String.class);
if (firstResult != null && firstResult > 0) {
query.setFirstResult(firstResult);
}
if (maxResults != null && maxResults > 0) {
query.setMaxResults(maxResults);
}
query.setParameter("realm", realm.getId());
Stream<String> clients = query.getResultStream();
Stream<String> clients = paginateQuery(query, firstResult, maxResults).getResultStream();
return closing(clients.map(c -> session.clients().getClientById(realm, c)).filter(Objects::nonNull));
}
@ -706,15 +680,10 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro
@Override
public Stream<ClientModel> searchClientsByClientIdStream(RealmModel realm, String clientId, Integer firstResult, Integer maxResults) {
TypedQuery<String> query = em.createNamedQuery("searchClientsByClientId", String.class);
if (firstResult != null && firstResult > 0) {
query.setFirstResult(firstResult);
}
if (maxResults != null && maxResults > 0) {
query.setMaxResults(maxResults);
}
query.setParameter("clientId", clientId);
query.setParameter("realm", realm.getId());
Stream<String> results = query.getResultStream();
Stream<String> results = paginateQuery(query, firstResult, maxResults).getResultStream();
return closing(results.map(c -> session.clients().getClientById(realm, c)));
}

View file

@ -65,12 +65,12 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Stream;
import javax.persistence.LockModeType;
import static org.keycloak.models.jpa.PaginationUtils.paginateQuery;
import static org.keycloak.utils.StreamsUtil.closing;
@ -97,18 +97,6 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
credentialStore = new JpaUserCredentialStore(session, em);
}
private static <T> TypedQuery<T> paginateQuery(TypedQuery<T> query, Integer first, Integer max) {
if (first != null && first > 0) {
query = query.setFirstResult(first);
}
if (max != null && max >= 0) {
query = query.setMaxResults(max);
}
return query;
}
@Override
public UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles, boolean addDefaultRequiredActions) {
if (id == null) {
@ -364,12 +352,18 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
@Override
public void setNotBeforeForUser(RealmModel realm, UserModel user, int notBefore) {
UserEntity entity = em.getReference(UserEntity.class, user.getId());
if (entity == null) {
throw new ModelException("User does not exists");
}
entity.setNotBefore(notBefore);
}
@Override
public int getNotBeforeOfUser(RealmModel realm, UserModel user) {
UserEntity entity = em.getReference(UserEntity.class, user.getId());
if (entity == null) {
throw new ModelException("User does not exists");
}
return entity.getNotBefore();
}
@ -514,14 +508,14 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
}
@Override
public UserModel getUserById(String id, RealmModel realm) {
public UserModel getUserById(RealmModel realm, String id) {
UserEntity userEntity = em.find(UserEntity.class, id);
if (userEntity == null || !realm.getId().equals(userEntity.getRealmId())) return null;
return new UserAdapter(session, realm, em, userEntity);
}
@Override
public UserModel getUserByUsername(String username, RealmModel realm) {
public UserModel getUserByUsername(RealmModel realm, String username) {
TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUserByUsername", UserEntity.class);
query.setParameter("username", username.toLowerCase());
query.setParameter("realmId", realm.getId());
@ -531,7 +525,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
}
@Override
public UserModel getUserByEmail(String email, RealmModel realm) {
public UserModel getUserByEmail(RealmModel realm, String email) {
TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUserByEmail", UserEntity.class);
query.setParameter("email", email.toLowerCase());
query.setParameter("realmId", realm.getId());
@ -549,7 +543,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
}
@Override
public UserModel getUserByFederatedIdentity(FederatedIdentityModel identity, RealmModel realm) {
public UserModel getUserByFederatedIdentity(RealmModel realm, FederatedIdentityModel identity) {
TypedQuery<UserEntity> query = em.createNamedQuery("findUserByFederatedIdentityAndRealm", UserEntity.class);
query.setParameter("realmId", realm.getId());
query.setParameter("identityProvider", identity.getIdentityProvider());
@ -583,11 +577,6 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
}
}
@Override
public Stream<UserModel> getUsersStream(RealmModel realm, boolean includeServiceAccounts) {
return getUsersStream(realm, -1, -1, includeServiceAccounts);
}
@Override
public int getUsersCount(RealmModel realm, boolean includeServiceAccount) {
String namedQuery = "getRealmUserCountExcludeServiceAccount";
@ -602,11 +591,6 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
return ((Number)count).intValue();
}
@Override
public int getUsersCount(RealmModel realm) {
return getUsersCount(realm, false);
}
@Override
public int getUsersCount(RealmModel realm, Set<String> groupIds) {
if (groupIds == null || groupIds.isEmpty()) {
@ -622,7 +606,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
}
@Override
public int getUsersCount(String search, RealmModel realm) {
public int getUsersCount(RealmModel realm, String search) {
TypedQuery<Long> query = em.createNamedQuery("searchForUserCount", Long.class);
query.setParameter("realmId", realm.getId());
query.setParameter("search", "%" + search.toLowerCase() + "%");
@ -632,7 +616,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
}
@Override
public int getUsersCount(String search, RealmModel realm, Set<String> groupIds) {
public int getUsersCount(RealmModel realm, String search, Set<String> groupIds) {
if (groupIds == null || groupIds.isEmpty()) {
return 0;
}
@ -647,7 +631,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
}
@Override
public int getUsersCount(Map<String, String> params, RealmModel realm) {
public int getUsersCount(RealmModel realm, Map<String, String> params) {
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Long> userQuery = qb.createQuery(Long.class);
Root<UserEntity> from = userQuery.from(UserEntity.class);
@ -691,7 +675,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
}
@Override
public int getUsersCount(Map<String, String> params, RealmModel realm, Set<String> groupIds) {
public int getUsersCount(RealmModel realm, Map<String, String> params, Set<String> groupIds) {
if (groupIds == null || groupIds.isEmpty()) {
return 0;
}
@ -740,12 +724,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
}
@Override
public Stream<UserModel> getUsersStream(RealmModel realm) {
return getUsersStream(realm, false);
}
@Override
public Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults) {
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
return getUsersStream(realm, firstResult, maxResults, false);
}
@ -776,25 +755,15 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
}
@Override
public Stream<UserModel> searchForUserStream(String search, RealmModel realm) {
return searchForUserStream(search, realm, -1, -1);
}
@Override
public Stream<UserModel> searchForUserStream(String search, RealmModel realm, Integer firstResult, Integer maxResults) {
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
Map<String, String> attributes = new HashMap<>();
attributes.put(UserModel.SEARCH, search);
session.setAttribute(UserModel.INCLUDE_SERVICE_ACCOUNT, false);
return searchForUserStream(attributes, realm, firstResult, maxResults);
return searchForUserStream(realm, attributes, firstResult, maxResults);
}
@Override
public Stream<UserModel> searchForUserStream(Map<String, String> attributes, RealmModel realm) {
return searchForUserStream(attributes, realm, -1, -1);
}
@Override
public Stream<UserModel> searchForUserStream(Map<String, String> attributes, RealmModel realm, Integer firstResult, Integer maxResults) {
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> attributes, Integer firstResult, Integer maxResults) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<UserEntity> queryBuilder = builder.createQuery(UserEntity.class);
Root<UserEntity> root = queryBuilder.from(UserEntity.class);
@ -903,11 +872,11 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
UserProvider users = session.users();
return closing(paginateQuery(query, firstResult, maxResults).getResultStream())
.map(userEntity -> users.getUserById(userEntity.getId(), realm));
.map(userEntity -> users.getUserById(realm, userEntity.getId()));
}
@Override
public Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm) {
public Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
TypedQuery<UserEntity> query = em.createNamedQuery("getRealmUsersByAttributeNameAndValue", UserEntity.class);
query.setParameter("name", attrName);
query.setParameter("value", attrValue);
@ -928,7 +897,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
@Override
public Stream<FederatedIdentityModel> getFederatedIdentitiesStream(UserModel user, RealmModel realm) {
public Stream<FederatedIdentityModel> getFederatedIdentitiesStream(RealmModel realm, UserModel user) {
TypedQuery<FederatedIdentityEntity> query = em.createNamedQuery("findFederatedIdentityByUser", FederatedIdentityEntity.class);
UserEntity userEntity = em.getReference(UserEntity.class, user.getId());
query.setParameter("user", userEntity);
@ -938,7 +907,7 @@ public class JpaUserProvider implements UserProvider.Streams, UserCredentialStor
}
@Override
public FederatedIdentityModel getFederatedIdentity(UserModel user, String identityProvider, RealmModel realm) {
public FederatedIdentityModel getFederatedIdentity(RealmModel realm, UserModel user, String identityProvider) {
FederatedIdentityEntity entity = findFederatedIdentity(user, identityProvider, LockModeType.NONE);
return (entity != null) ? new FederatedIdentityModel(entity.getIdentityProvider(), entity.getUserId(), entity.getUserName(), entity.getToken()) : null;
}

View file

@ -0,0 +1,43 @@
/*
* Copyright 2020 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.models.jpa;
import javax.persistence.TypedQuery;
public class PaginationUtils {
public static final int DEFAULT_MAX_RESULTS = Integer.MAX_VALUE >> 1;
public static <T> TypedQuery<T> paginateQuery(TypedQuery<T> query, Integer first, Integer max) {
if (first != null && first > 0) {
query = query.setFirstResult(first);
// Workaround for https://hibernate.atlassian.net/browse/HHH-14295
if (max == null || max < 0) {
max = DEFAULT_MAX_RESULTS;
}
}
if (max != null && max >= 0) {
query = query.setMaxResults(max);
}
return query;
}
}

View file

@ -77,7 +77,7 @@ public class MapAuthenticationSessionAdapter implements AuthenticationSessionMod
@Override
public UserModel getAuthenticatedUser() {
return entity.getAuthUserId() == null ? null : session.users().getUserById(entity.getAuthUserId(), getRealm());
return entity.getAuthUserId() == null ? null : session.users().getUserById(getRealm(), entity.getAuthUserId());
}
@Override

View file

@ -38,7 +38,9 @@ import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.keycloak.models.map.storage.MapStorage;
import static org.keycloak.common.util.StackUtil.getShortStackTrace;
import static org.keycloak.utils.StreamsUtil.paginatedStream;
public class MapClientProvider implements ClientProvider {
@ -130,14 +132,7 @@ public class MapClientProvider implements ClientProvider {
@Override
public Stream<ClientModel> getClientsStream(RealmModel realm, Integer firstResult, Integer maxResults) {
Stream<ClientModel> s = getClientsStream(realm);
if (firstResult != null && firstResult >= 0) {
s = s.skip(firstResult);
}
if (maxResults != null && maxResults >= 0) {
s = s.limit(maxResults);
}
return s;
return paginatedStream(getClientsStream(realm), firstResult, maxResults);
}
private Stream<MapClientEntity> getNotRemovedUpdatedClientsStream() {
@ -281,14 +276,7 @@ public class MapClientProvider implements ClientProvider {
.filter(entity -> entity.getClientId() != null && entity.getClientId().toLowerCase().contains(clientIdLower))
.sorted(COMPARE_BY_CLIENT_ID);
if (firstResult != null && firstResult >= 0) {
s = s.skip(firstResult);
}
if (maxResults != null && maxResults >= 0) {
s = s.limit(maxResults);
}
return s.map(entityToAdapterFunc(realm));
return paginatedStream(s, firstResult, maxResults).map(entityToAdapterFunc(realm));
}
@Override

View file

@ -36,6 +36,7 @@ import java.util.function.Predicate;
import java.util.stream.Stream;
import static org.keycloak.common.util.StackUtil.getShortStackTrace;
import static org.keycloak.utils.StreamsUtil.paginatedStream;
public class MapGroupProvider implements GroupProvider {
@ -124,15 +125,7 @@ public class MapGroupProvider implements GroupProvider {
groupModelStream = groupModelStream.filter(groupModel -> groupModel.getName().toLowerCase().contains(s));
}
if (first != null && first > 0) {
groupModelStream = groupModelStream.skip(first);
}
if (max != null && max >= 0) {
groupModelStream = groupModelStream.limit(max);
}
return groupModelStream;
return paginatedStream(groupModelStream, first, max);
}
@Override
@ -157,15 +150,7 @@ public class MapGroupProvider implements GroupProvider {
LOG.tracef("getGroupsByRole(%s, %s, %d, %d)%s", realm, role, firstResult, maxResults, getShortStackTrace());
Stream<GroupModel> groupModelStream = getGroupsStream(realm).filter(groupModel -> groupModel.hasRole(role));
if (firstResult != null && firstResult > 0) {
groupModelStream = groupModelStream.skip(firstResult);
}
if (maxResults != null && maxResults >= 0) {
groupModelStream = groupModelStream.limit(maxResults);
}
return groupModelStream;
return paginatedStream(groupModelStream, firstResult, maxResults);
}
@Override
@ -179,15 +164,7 @@ public class MapGroupProvider implements GroupProvider {
public Stream<GroupModel> getTopLevelGroupsStream(RealmModel realm, Integer firstResult, Integer maxResults) {
Stream<GroupModel> groupModelStream = getTopLevelGroupsStream(realm);
if (firstResult != null && firstResult > 0) {
groupModelStream = groupModelStream.skip(firstResult);
}
if (maxResults != null && maxResults >= 0) {
groupModelStream = groupModelStream.limit(maxResults);
}
return groupModelStream;
return paginatedStream(groupModelStream, firstResult, maxResults);
}
@ -197,15 +174,8 @@ public class MapGroupProvider implements GroupProvider {
Stream<GroupModel> groupModelStream = getGroupsStream(realm)
.filter(groupModel -> groupModel.getName().contains(search));
if (firstResult != null && firstResult > 0) {
groupModelStream = groupModelStream.skip(firstResult);
}
if (maxResults != null && maxResults >= 0) {
groupModelStream = groupModelStream.limit(maxResults);
}
return groupModelStream;
return paginatedStream(groupModelStream, firstResult, maxResults);
}
@Override

View file

@ -35,6 +35,8 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.keycloak.models.map.storage.MapStorage;
import static org.keycloak.common.util.StackUtil.getShortStackTrace;
import static org.keycloak.utils.StreamsUtil.paginatedStream;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleProvider;
import org.keycloak.models.map.common.StreamUtils;
@ -126,14 +128,7 @@ public class MapRoleProvider implements RoleProvider {
@Override
public Stream<RoleModel> getRealmRolesStream(RealmModel realm, Integer first, Integer max) {
Stream<RoleModel> s = getRealmRolesStream(realm);
if (first != null && first >= 0) {
s = s.skip(first);
}
if (max != null && max >= 0) {
s = s.limit(max);
}
return s;
return paginatedStream(getRealmRolesStream(realm), first, max);
}
@Override
@ -171,14 +166,7 @@ public class MapRoleProvider implements RoleProvider {
@Override
public Stream<RoleModel> getClientRolesStream(ClientModel client, Integer first, Integer max) {
Stream<RoleModel> s = getClientRolesStream(client);
if (first != null && first > 0) {
s = s.skip(first);
}
if (max != null && max >= 0) {
s = s.limit(max);
}
return s;
return paginatedStream(getClientRolesStream(client), first, max);
}
@Override
@ -326,14 +314,7 @@ public class MapRoleProvider implements RoleProvider {
)
.sorted(COMPARE_BY_NAME);
if (first != null && first > 0) {
s = s.skip(first);
}
if (max != null && max >= 0) {
s = s.limit(max);
}
return s.map(entityToAdapterFunc(realm));
return paginatedStream(s.map(entityToAdapterFunc(realm)), first, max);
}
@Override
@ -350,14 +331,7 @@ public class MapRoleProvider implements RoleProvider {
)
.sorted(COMPARE_BY_NAME);
if (first != null && first > 0) {
s = s.skip(first);
}
if (max != null && max >= 0) {
s = s.limit(max);
}
return s.map(entityToAdapterFunc(client.getRealm()));
return paginatedStream(s,first, max).map(entityToAdapterFunc(client.getRealm()));
}
@Override

View file

@ -68,6 +68,7 @@ import static org.keycloak.models.UserModel.EMAIL_VERIFIED;
import static org.keycloak.models.UserModel.FIRST_NAME;
import static org.keycloak.models.UserModel.LAST_NAME;
import static org.keycloak.models.UserModel.USERNAME;
import static org.keycloak.utils.StreamsUtil.paginatedStream;
public class MapUserProvider implements UserProvider.Streams, UserCredentialStore.Streams {
@ -96,12 +97,12 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
@Override
public boolean checkEmailUniqueness(RealmModel realm, String email) {
return getUserByEmail(email, realm) != null;
return getUserByEmail(realm, email) != null;
}
@Override
public boolean checkUsernameUniqueness(RealmModel realm, String username) {
return getUserByUsername(username, realm) != null;
return getUserByUsername(realm, username) != null;
}
};
}
@ -157,18 +158,6 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
.filter(entityRealmFilter(realm));
}
private <T> Stream<T> paginatedStream(Stream<T> originalStream, Integer first, Integer max) {
if (first != null && first > 0) {
originalStream = originalStream.skip(first);
}
if (max != null && max >= 0) {
originalStream = originalStream.limit(max);
}
return originalStream;
}
@Override
public void addFederatedIdentity(RealmModel realm, UserModel user, FederatedIdentityModel socialLink) {
if (user == null || user.getId() == null) {
@ -206,7 +195,7 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
}
@Override
public Stream<FederatedIdentityModel> getFederatedIdentitiesStream(UserModel user, RealmModel realm) {
public Stream<FederatedIdentityModel> getFederatedIdentitiesStream(RealmModel realm, UserModel user) {
LOG.tracef("getFederatedIdentitiesStream(%s, %s)%s", realm, user.getId(), getShortStackTrace());
return getEntityById(realm, user.getId())
.map(AbstractUserEntity::getFederatedIdentities).orElseGet(Stream::empty)
@ -214,7 +203,7 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
}
@Override
public FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm) {
public FederatedIdentityModel getFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) {
LOG.tracef("getFederatedIdentity(%s, %s, %s)%s", realm, user.getId(), socialProvider, getShortStackTrace());
return getEntityById(realm, user.getId())
.map(userEntity -> userEntity.getFederatedIdentity(socialProvider))
@ -223,7 +212,7 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
}
@Override
public UserModel getUserByFederatedIdentity(FederatedIdentityModel socialLink, RealmModel realm) {
public UserModel getUserByFederatedIdentity(RealmModel realm, FederatedIdentityModel socialLink) {
LOG.tracef("getUserByFederatedIdentity(%s, %s)%s", realm, socialLink, getShortStackTrace());
return getUnsortedUserEntitiesStream(realm)
.filter(userEntity -> Objects.nonNull(userEntity.getFederatedIdentity(socialLink.getIdentityProvider())))
@ -231,7 +220,7 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
.collect(Collectors.collectingAndThen(
Collectors.toList(),
list -> {
if (list.size() == 0) {
if (list.isEmpty()) {
return null;
} else if (list.size() != 1) {
throw new IllegalStateException("More results found for identityProvider=" + socialLink.getIdentityProvider() +
@ -246,8 +235,8 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
public void addConsent(RealmModel realm, String userId, UserConsentModel consent) {
LOG.tracef("addConsent(%s, %s, %s)%s", realm, userId, consent, getShortStackTrace());
UserConsentEntity consentEntity = UserConsentEntity.fromModel(consent);
getRegisteredEntityById(realm, userId).ifPresent(userEntity -> userEntity.addUserConsent(consentEntity));
getRegisteredEntityByIdOrThrow(realm, userId)
.addUserConsent(UserConsentEntity.fromModel(consent));
}
@Override
@ -298,15 +287,15 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
@Override
public void setNotBeforeForUser(RealmModel realm, UserModel user, int notBefore) {
LOG.tracef("setNotBeforeForUser(%s, %s, %d)%s", realm, user.getId(), notBefore, getShortStackTrace());
getRegisteredEntityById(realm, user.getId()).ifPresent(userEntity -> userEntity.setNotBefore(notBefore));
getRegisteredEntityByIdOrThrow(realm, user.getId()).setNotBefore(notBefore);
}
@Override
public int getNotBeforeOfUser(RealmModel realm, UserModel user) {
LOG.tracef("getNotBeforeOfUser(%s, %s)%s", realm, user.getId(), getShortStackTrace());
return getEntityById(realm, user.getId())
.map(AbstractUserEntity::getNotBefore)
.orElse(0);
.orElseThrow(this::userDoesntExistException)
.getNotBefore();
}
@Override
@ -317,7 +306,7 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
.collect(Collectors.collectingAndThen(
Collectors.toList(),
list -> {
if (list.size() == 0) {
if (list.isEmpty()) {
return null;
} else if (list.size() != 1) {
throw new IllegalStateException("More service account linked users found for client=" + client.getClientId() +
@ -479,13 +468,13 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
}
@Override
public UserModel getUserById(String id, RealmModel realm) {
public UserModel getUserById(RealmModel realm, String id) {
LOG.tracef("getUserById(%s, %s)%s", realm, id, getShortStackTrace());
return getEntityById(realm, id).map(entityToAdapterFunc(realm)).orElse(null);
}
@Override
public UserModel getUserByUsername(String username, RealmModel realm) {
public UserModel getUserByUsername(RealmModel realm, String username) {
if (username == null) return null;
final String usernameLowercase = username.toLowerCase();
@ -497,12 +486,12 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
}
@Override
public UserModel getUserByEmail(String email, RealmModel realm) {
public UserModel getUserByEmail(RealmModel realm, String email) {
LOG.tracef("getUserByEmail(%s, %s)%s", realm, email, getShortStackTrace());
List<MapUserEntity> usersWithEmail = getUnsortedUserEntitiesStream(realm)
.filter(userEntity -> Objects.equals(userEntity.getEmail(), email))
.filter(userEntity -> Objects.equals(userEntity.getEmail(), email.toLowerCase()))
.collect(Collectors.toList());
if (usersWithEmail.size() == 0) return null;
if (usersWithEmail.isEmpty()) return null;
if (usersWithEmail.size() > 1) {
// Realm settings have been changed from allowing duplicate emails to not allowing them
@ -523,21 +512,15 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
return new MapUserAdapter(session, realm, userEntity) {
@Override
public boolean checkEmailUniqueness(RealmModel realm, String email) {
return getUserByEmail(email, realm) != null;
return getUserByEmail(realm, email) != null;
}
@Override
public boolean checkUsernameUniqueness(RealmModel realm, String username) {
return getUserByUsername(username, realm) != null;
return getUserByUsername(realm, username) != null;
}
};
}
@Override
public int getUsersCount(RealmModel realm) {
LOG.tracef("getUsersCount(%s)%s", realm, getShortStackTrace());
return getUsersCount(realm, false);
}
@Override
public int getUsersCount(RealmModel realm, boolean includeServiceAccount) {
LOG.tracef("getUsersCount(%s, %s)%s", realm, includeServiceAccount, getShortStackTrace());
@ -564,46 +547,22 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
}
@Override
public Stream<UserModel> getUsersStream(RealmModel realm) {
LOG.tracef("getUsersStream(%s)%s", realm, getShortStackTrace());
return getUsersStream(realm, null, null, false);
}
@Override
public Stream<UserModel> getUsersStream(RealmModel realm, boolean includeServiceAccounts) {
LOG.tracef("getUsersStream(%s)%s", realm, getShortStackTrace());
return getUsersStream(realm, null, null, includeServiceAccounts);
}
@Override
public Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults) {
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
public Stream<UserModel> searchForUserStream(String search, RealmModel realm) {
LOG.tracef("searchForUserStream(%s, %s)%s", realm, search, getShortStackTrace());
return searchForUserStream(search, realm, null, null);
}
@Override
public Stream<UserModel> searchForUserStream(String search, RealmModel realm, 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());
Map<String, String> attributes = new HashMap<>();
attributes.put(UserModel.SEARCH, search);
session.setAttribute(UserModel.INCLUDE_SERVICE_ACCOUNT, false);
return searchForUserStream(attributes, realm, firstResult, maxResults);
return searchForUserStream(realm, attributes, firstResult, maxResults);
}
@Override
public Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm) {
LOG.tracef("searchForUserStream(%s, %s)%s", realm, params, getShortStackTrace());
return searchForUserStream(params, realm, null, null);
}
@Override
public Stream<UserModel> searchForUserStream(Map<String, String> attributes, RealmModel realm, Integer firstResult, Integer maxResults) {
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> attributes, Integer firstResult, Integer maxResults) {
LOG.tracef("searchForUserStream(%s, %s, %d, %d)%s", realm, attributes, firstResult, maxResults, getShortStackTrace());
/* Find all predicates based on attributes map */
List<Predicate<MapUserEntity>> predicatesList = new ArrayList<>();
@ -735,13 +694,7 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
}
@Override
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group) {
LOG.tracef("getGroupMembersStream(%s, %s)%s", realm, group.getId(), getShortStackTrace());
return getGroupMembersStream(realm, group, null, null);
}
@Override
public Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm) {
public Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
LOG.tracef("searchForUserByUserAttributeStream(%s, %s, %s)%s", realm, attrName, attrValue, getShortStackTrace());
return getUnsortedUserEntitiesStream(realm)
.filter(userEntity -> userEntity.getAttribute(attrName).contains(attrValue))

View file

@ -61,7 +61,6 @@ import org.keycloak.models.UserModel;
import org.keycloak.models.UserProvider;
import org.keycloak.models.dblock.DBLockManager;
import org.keycloak.models.dblock.DBLockProvider;
import org.keycloak.models.utils.DefaultKeyProviders;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.models.utils.RepresentationToModel;
import org.keycloak.provider.ServerInfoAwareProviderFactory;
@ -497,7 +496,7 @@ public class QuarkusJpaConnectionProviderFactory implements JpaConnectionProvide
UserProvider users = session.users();
if (users.getUserByUsername(userRep.getUsername(), realm) != null) {
if (users.getUserByUsername(realm, userRep.getUsername()) != null) {
ServicesLogger.LOGGER.notCreatingExistingUser(userRep.getUsername());
} else {
UserModel user = users.addUser(realm, userRep.getUsername());

View file

@ -165,13 +165,13 @@ public class DefaultEvaluation implements Evaluation {
private UserModel getUser(String id, KeycloakSession session) {
RealmModel realm = session.getContext().getRealm();
UserModel user = session.users().getUserById(id, realm);
UserModel user = session.users().getUserById(realm, id);
if (Objects.isNull(user)) {
user = session.users().getUserByUsername(id, realm);
user = session.users().getUserByUsername(realm ,id);
}
if (Objects.isNull(user)) {
user = session.users().getUserByEmail(id, realm);
user = session.users().getUserByEmail(realm, id);
}
if (Objects.isNull(user)) {
user = session.users().getServiceAccount(realm.getClientById(id));

View file

@ -120,7 +120,7 @@ public class PersistentUserSessionAdapter implements OfflineUserSessionModel {
@Override
public UserModel getUser() {
if (user == null) {
user = session.users().getUserById(userId, realm);
user = session.users().getUserById(realm, userId);
}
return user;
}

View file

@ -205,13 +205,13 @@ public final class KeycloakModelUtils {
*/
public static UserModel findUserByNameOrEmail(KeycloakSession session, RealmModel realm, String username) {
if (realm.isLoginWithEmailAllowed() && username.indexOf('@') != -1) {
UserModel user = session.users().getUserByEmail(username, realm);
UserModel user = session.users().getUserByEmail(realm, username);
if (user != null) {
return user;
}
}
return session.users().getUserByUsername(username, realm);
return session.users().getUserByUsername(realm, username);
}
/**

View file

@ -885,7 +885,7 @@ public class ModelToRepresentation {
ClientModel clientModel = realm.getClientById(resourceServer);
owner.setName(clientModel.getClientId());
} else {
UserModel userModel = keycloakSession.users().getUserById(owner.getId(), realm);
UserModel userModel = keycloakSession.users().getUserById(realm, owner.getId());
if (userModel == null) {
throw new RuntimeException("Could not find the user [" + owner.getId() + "] who owns the Resource [" + resource.getId() + "].");
@ -934,8 +934,8 @@ public class ModelToRepresentation {
representation.setResourceName(resource.getName());
KeycloakSession keycloakSession = authorization.getKeycloakSession();
RealmModel realm = authorization.getRealm();
UserModel userOwner = keycloakSession.users().getUserById(ticket.getOwner(), realm);
UserModel requester = keycloakSession.users().getUserById(ticket.getRequester(), realm);
UserModel userOwner = keycloakSession.users().getUserById(realm, ticket.getOwner());
UserModel requester = keycloakSession.users().getUserById(realm, ticket.getRequester());
representation.setRequesterName(requester.getUsername());
if (userOwner != null) {
representation.setOwnerName(userOwner.getUsername());

View file

@ -2257,7 +2257,7 @@ public class RepresentationToModel {
owner.setId(resourceServer.getId());
resource.setOwner(owner);
} else if (owner.getName() != null) {
UserModel user = session.users().getUserByUsername(owner.getName(), realm);
UserModel user = session.users().getUserByUsername(realm, owner.getName());
if (user != null) {
owner.setId(user.getId());
@ -2572,10 +2572,10 @@ public class RepresentationToModel {
RealmModel realm = authorization.getRealm();
KeycloakSession keycloakSession = authorization.getKeycloakSession();
UserProvider users = keycloakSession.users();
UserModel ownerModel = users.getUserById(ownerId, realm);
UserModel ownerModel = users.getUserById(realm, ownerId);
if (ownerModel == null) {
ownerModel = users.getUserByUsername(ownerId, realm);
ownerModel = users.getUserByUsername(realm, ownerId);
}
if (ownerModel == null) {

View file

@ -24,6 +24,15 @@ import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class StreamsUtil {
/**
* Returns the original stream that is closed on terminating operation.
*
* It is used, for example, for closing hibernate provided streams since it is required by hibernate documentation.
*
* @param stream the stream which is expected to be closed on termination
* @return stream that will be closed on terminating operation
*/
public static <T> Stream<T> closing(Stream<T> stream) {
return Stream.of(stream).flatMap(Function.identity());
}
@ -42,4 +51,26 @@ public class StreamsUtil {
throw ex;
}
}
/**
* Returns the original stream that is limited with {@link Stream#skip(long) skip} and
* {@link Stream#limit(long) limit} functions based on values of {@code first} and {@code max} parameters.
*
* @param originalStream Stream to be limited.
* @param first Index of first item to be returned by the stream. Ignored if negative, zero {@code null}.
* @param max Maximum number of items to be returned by the stream. Ignored if negative or {@code null}.
* @param <T> Type of items in the stream
* @return Stream
*/
public static <T> Stream<T> paginatedStream(Stream<T> originalStream, Integer first, Integer max) {
if (first != null && first > 0) {
originalStream = originalStream.skip(first);
}
if (max != null && max >= 0) {
originalStream = originalStream.limit(max);
}
return originalStream;
}
}

View file

@ -38,7 +38,7 @@ public interface GroupProvider extends Provider, GroupLookupProvider {
* @param id Id.
* @param realm Realm.
* @return GroupModel with the corresponding id.
* @deprecated Use method {@code getGroupById(realm, id)}
* @deprecated Use method {@link #getGroupById(RealmModel, String) getGroupById}
*/
default GroupModel getGroupById(String id, RealmModel realm) {
return getGroupById(realm, id);
@ -140,7 +140,7 @@ public interface GroupProvider extends Provider, GroupLookupProvider {
* @param firstResult First result to return. Ignored if negative.
* @param maxResults Maximum number of results to return. Ignored if negative.
* @return List of groups with the given role.
* @deprecated Use {@link #getGroupsByRoleStream(RealmModel, RoleModel, int, int) getGroupsByRoleStream} instead.
* @deprecated Use {@link #getGroupsByRoleStream(RealmModel, RoleModel, Integer, Integer) getGroupsByRoleStream} instead.
*/
@Deprecated
default List<GroupModel> getGroupsByRole(RealmModel realm, RoleModel role, int firstResult, int maxResults) {

View file

@ -38,73 +38,35 @@ public interface UserProvider extends Provider,
UserQueryProvider,
UserRegistrationProvider,
UserBulkUpdateProvider {
// Note: The reason there are so many query methods here is for layering a cache on top of an persistent KeycloakSession
void addFederatedIdentity(RealmModel realm, UserModel user, FederatedIdentityModel socialLink);
boolean removeFederatedIdentity(RealmModel realm, UserModel user, String socialProvider);
void preRemove(RealmModel realm, IdentityProviderModel provider);
void updateFederatedIdentity(RealmModel realm, UserModel federatedUser, FederatedIdentityModel federatedIdentityModel);
/**
* @deprecated Use {@link #getFederatedIdentitiesStream(UserModel, RealmModel) getFederatedIdentitiesStream} instead.
*/
@Deprecated
Set<FederatedIdentityModel> getFederatedIdentities(UserModel user, RealmModel realm);
/**
* Obtains the federated identities of the specified user.
* Sets the notBefore value for the given user
*
* @param user a reference to the user.
* @param realm a reference to the realm.
* @return a non-null {@link Stream} of federated identities associated with the user.
*/
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);
void addConsent(RealmModel realm, String userId, UserConsentModel consent);
UserConsentModel getConsentByClient(RealmModel realm, String userId, String clientInternalId);
/**
* @deprecated Use {@link #getConsentsStream(RealmModel, String) getConsentsStream} instead.
*/
@Deprecated
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 user the user model
* @param notBefore new value for notBefore
*
* @param realm a reference to the realm.
* @param userId the user identifier.
* @return a non-null {@link Stream} of consents associated with the user.
* @throws ModelException when user doesn't exist in the storage
*/
default Stream<UserConsentModel> getConsentsStream(RealmModel realm, String userId) {
List<UserConsentModel> value = this.getConsents(realm, userId);
return value != null ? value.stream() : Stream.empty();
}
/**
*
* @param realm
* @param userId
* @param consent
* @throws ModelException when consent doesn't exist for the userId
*/
void updateConsent(RealmModel realm, String userId, UserConsentModel consent);
boolean revokeConsentForClient(RealmModel realm, String userId, String clientInternalId);
void setNotBeforeForUser(RealmModel realm, UserModel user, int notBefore);
/**
* Gets the notBefore value for the given user
*
* @param realm a reference to the realm
* @param user the user model
* @return the value of notBefore
*
* @throws ModelException when user doesn't exist in the storage
*/
int getNotBeforeOfUser(RealmModel realm, UserModel user);
/**
* Return a UserModel representing service account of the client
*
* @param client
* @param client the client model
* @throws IllegalArgumentException when there are more service accounts associated with the given clientId
* @return
* @return userModel representing service account of the client
*/
UserModel getServiceAccount(ClientModel client);
@ -136,8 +98,8 @@ public interface UserProvider extends Provider,
* Obtains the users associated with the specified realm.
*
* @param realm a reference to the realm being used for the search.
* @param firstResult first result to return. Ignored if negative.
* @param maxResults maximum number of results to return. Ignored if negative.
* @param firstResult first result to return. Ignored if negative, zero, 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.
* @return a non-null {@link Stream} of users associated withe the realm.
*/
@ -147,53 +109,297 @@ public interface UserProvider extends Provider,
}
/**
* Adds a new user into the storage.
* <p/>
* only used for local storage
*
* @param realm
* @param id
* @param username
* @param addDefaultRoles
* @param addDefaultRequiredActions
* @return
* @param realm the realm that user will be created in
* @param id id of the new user. Should be generated to a random value if {@code null}.
* @param username username
* @param addDefaultRoles if {@code true}, the user should join all realm default roles
* @param addDefaultRequiredActions if {@code true}, all default required actions are added to the created user
* @return model of created user
*
* @throws NullPointerException when username or realm is {@code null}
* @throws ModelDuplicateException when a user with given id or username already exists
*/
UserModel addUser(RealmModel realm, String id, String username, boolean addDefaultRoles, boolean addDefaultRequiredActions);
void preRemove(RealmModel realm);
/**
* Removes any imported users from a specific User Storage Provider.
*
* @param realm
* @param storageProviderId
* @param realm a reference to the realm
* @param storageProviderId id of the user storage provider
*/
void removeImportedUsers(RealmModel realm, String storageProviderId);
/**
* Set federation link to null to imported users of a specific User Storage Provider
* Set federation link to {@code null} to imported users of a specific User Storage Provider
*
* @param realm
* @param storageProviderId
* @param realm a reference to the realm
* @param storageProviderId id of the storage provider
*/
void unlinkUsers(RealmModel realm, String storageProviderId);
/* USER CONSENTS methods */
/**
* Add user consent for the user.
*
* @param realm a reference to the realm
* @param userId id of the user
* @param consent all details corresponding to the granted consent
*
* @throws ModelException If there is no user with userId
*/
void addConsent(RealmModel realm, String userId, UserConsentModel consent);
/**
* Returns UserConsentModel given by a user with the userId for the client with clientInternalId
*
* @param realm a reference to the realm
* @param userId id of the user
* @param clientInternalId id of the client
* @return consent given by the user to the client or {@code null} if no consent or user exists
*
* @throws ModelException when there are more consents fulfilling specified parameters
*/
UserConsentModel getConsentByClient(RealmModel realm, String userId, String clientInternalId);
/**
* @deprecated Use {@link #getConsentsStream(RealmModel, String) getConsentsStream} instead.
*/
@Deprecated
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 {@link Stream} of consents associated with the user.
*/
default Stream<UserConsentModel> getConsentsStream(RealmModel realm, String userId) {
List<UserConsentModel> value = this.getConsents(realm, userId);
return value != null ? value.stream() : Stream.empty();
}
/**
* Update client scopes in the stored user consent
*
* @param realm a reference to the realm
* @param userId id of the user
* @param consent new details of the user consent
*
* @throws ModelException when consent doesn't exist for the userId
*/
void updateConsent(RealmModel realm, String userId, UserConsentModel consent);
/**
* Remove a user consent given by the user id and client id
*
* @param realm a reference to the realm
* @param userId id of the user
* @param clientInternalId id of the client
* @return {@code true} if the consent was removed, {@code false} otherwise
*/
boolean revokeConsentForClient(RealmModel realm, String userId, String clientInternalId);
/* FEDERATED IDENTITIES methods */
/**
* Adds a federated identity link for the user within the realm
*
* @param realm a reference to the realm
* @param user the user model
* @param socialLink the federated identity model containing all details of the association between the user and
* the identity provider
*/
void addFederatedIdentity(RealmModel realm, UserModel user, FederatedIdentityModel socialLink);
/**
* Removes federation link between the user and the identity provider given by its id
*
* @param realm a reference to the realm
* @param user the user model
* @param socialProvider alias of the identity provider, see {@link IdentityProviderModel#getAlias()}
* @return {@code true} if the association was removed, {@code false} otherwise
*/
boolean removeFederatedIdentity(RealmModel realm, UserModel user, String socialProvider);
/**
* Update details of association between the federatedUser and the idp given by the federatedIdentityModel
*
* @param realm a reference to the realm
* @param federatedUser the user model
* @param federatedIdentityModel the federated identity model containing all details of the association between
* the user and the identity provider
*/
void updateFederatedIdentity(RealmModel realm, UserModel federatedUser, FederatedIdentityModel federatedIdentityModel);
/**
* @deprecated Use {@link #getFederatedIdentitiesStream(RealmModel, UserModel) getFederatedIdentitiesStream} instead.
*/
@Deprecated
Set<FederatedIdentityModel> getFederatedIdentities(UserModel user, RealmModel realm);
/**
* Obtains the federated identities of the specified user.
*
* @param realm a reference to the realm.
* @param user the reference to the user.
* @return a non-null {@link Stream} of federated identities associated with the user.
*/
default Stream<FederatedIdentityModel> getFederatedIdentitiesStream(RealmModel realm, UserModel user) {
Set<FederatedIdentityModel> value = this.getFederatedIdentities(user, realm);
return value != null ? value.stream() : Stream.empty();
}
/**
* Returns details of the association between the user and the socialProvider.
*
* @param realm a reference to the realm
* @param user the user model
* @param socialProvider the id of the identity provider
* @return federatedIdentityModel or {@code null} if no association exists
*/
default FederatedIdentityModel getFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) {
return getFederatedIdentity(user, socialProvider, realm);
}
/**
* @deprecated Use {@link #getFederatedIdentity(RealmModel, UserModel, String) getFederatedIdentity} instead.
*/
@Deprecated
FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm);
/**
* Returns a userModel that corresponds to the given socialLink.
*
* @param realm a reference to the realm
* @param socialLink the socialLink
* @return the user corresponding to socialLink and {@code null} if no such user exists
*
* @throws IllegalStateException when there are more users for the given socialLink
*/
default UserModel getUserByFederatedIdentity(RealmModel realm, FederatedIdentityModel socialLink) {
return getUserByFederatedIdentity(socialLink, realm);
}
/**
* @deprecated Use {@link #getUserByFederatedIdentity(RealmModel, FederatedIdentityModel) getUserByFederatedIdentity} instead.
*/
@Deprecated
UserModel getUserByFederatedIdentity(FederatedIdentityModel socialLink, RealmModel realm);
/* PRE REMOVE methods - for cleaning user related properties when some other entity is removed */
/**
* Called when a realm is removed.
* Should remove all users that belong to the realm.
*
* @param realm a reference to the realm
*/
void preRemove(RealmModel realm);
/**
* Called when an identity provider is removed.
* Should remove all federated identities assigned to users from the provider.
*
* @param realm a reference to the realm
* @param provider provider model
*/
void preRemove(RealmModel realm, IdentityProviderModel provider);
/**
* Called when a role is removed.
* Should remove the role membership for each user.
*
* @param realm a reference to the realm
* @param role the role model
*/
void preRemove(RealmModel realm, RoleModel role);
/**
* Called when a group is removed.
* Should remove the group membership for each user.
*
* @param realm a reference to the realm
* @param group the group model
*/
void preRemove(RealmModel realm, GroupModel group);
/**
* Called when a client is removed.
* Should remove all user consents associated with the client
*
* @param realm a reference to the realm
* @param client the client model
*/
void preRemove(RealmModel realm, ClientModel client);
/**
* Called when a protocolMapper is removed
*
* @param protocolMapper the protocolMapper model
*/
void preRemove(ProtocolMapperModel protocolMapper);
/**
* Called when a client scope is removed.
* Should remove the clientScope from each user consent
*
* @param clientScope the clientScope model
*/
void preRemove(ClientScopeModel clientScope);
/**
* Called when a component is removed.
* Should remove all data in UserStorage associated with removed component.
* For example,
* <ul>
* <li>if component corresponds to UserStorageProvider all imported users from the provider should be removed,</li>
* <li>if component corresponds to ClientStorageProvider all consents granted for clients imported from the
* provider should be removed</li>
* </ul>
*
* @param realm a reference to the realm
* @param component the component model
*/
void preRemove(RealmModel realm, ComponentModel component);
void close();
void preRemove(RealmModel realm, ComponentModel component);
/**
* The {@link UserProvider.Streams} interface makes all collection-based methods in {@link UserProvider} 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 UserProvider, UserQueryProvider.Streams, UserLookupProvider.Streams {
interface Streams extends UserProvider, UserQueryProvider.Streams {
@Override
default Set<FederatedIdentityModel> getFederatedIdentities(UserModel user, RealmModel realm) {
return this.getFederatedIdentitiesStream(user, realm).collect(Collectors.toSet());
FederatedIdentityModel getFederatedIdentity(RealmModel realm, UserModel user, String socialProvider);
@Override
default FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm) {
return getFederatedIdentity(realm, user, socialProvider);
}
@Override
Stream<FederatedIdentityModel> getFederatedIdentitiesStream(UserModel user, RealmModel realm);
UserModel getUserByFederatedIdentity(RealmModel realm, FederatedIdentityModel socialLink);
@Override
default UserModel getUserByFederatedIdentity(FederatedIdentityModel socialLink, RealmModel realm) {
return getUserByFederatedIdentity(realm, socialLink);
}
@Override
default Set<FederatedIdentityModel> getFederatedIdentities(UserModel user, RealmModel realm) {
return this.getFederatedIdentitiesStream(realm, user).collect(Collectors.toSet());
}
@Override
Stream<FederatedIdentityModel> getFederatedIdentitiesStream(RealmModel realm, UserModel user);
@Override
default List<UserConsentModel> getConsents(RealmModel realm, String userId) {
@ -209,7 +415,9 @@ public interface UserProvider extends Provider,
}
@Override
Stream<UserModel> getUsersStream(RealmModel realm, boolean includeServiceAccounts);
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) {

View file

@ -22,6 +22,19 @@ import org.keycloak.models.RoleModel;
import org.keycloak.provider.Provider;
/**
* A class implementing this interface represents a user storage provider to Keycloak.
* <p/>
* This interface contains only very basic methods for manipulating users. However, the storage provider capabilities
* are extended by implementing one or more of the following capability interfaces:
* <ul>
* <li>{@link org.keycloak.storage.user.UserLookupProvider UserLookupProvider} - Provide basic lookup methods. After implementing it is possible to login using users from the storage.</li>
* <li>{@link org.keycloak.storage.user.UserQueryProvider UserQueryProvider} - Provide complex lookup methods. After implementing it is possible to manage users from admin console.</li>
* <li>{@link org.keycloak.storage.user.UserRegistrationProvider UserRegistrationProvider} - Provide methods for adding users. After implementing it is possible to store registered users in the storage.</li>
* <li>{@link org.keycloak.storage.user.UserBulkUpdateProvider UserBulkUpdateProvider} - After implementing it is possible to perform bulk operations on all users from storage (for example, addition of a role to all users).</li>
* <li>{@link org.keycloak.storage.user.ImportedUserValidation ImportedUserValidation} - Provider method for validating users within Keycloak local storage that are imported from the storage.</li>
* <li>{@link org.keycloak.storage.user.ImportSynchronization ImportSynchronization} - Provider methods for synchronization of the storage with Keycloak local storage. After implementing it is possible to sync users in the Admin console.</li>
* </ul>
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/

View file

@ -22,6 +22,11 @@ import org.keycloak.storage.UserStorageProviderModel;
import java.util.Date;
/**
*
* This is an optional capability interface that is intended to be implemented by any
* {@link org.keycloak.storage.UserStorageProvider UserStorageProvider} that supports syncing users to keycloak local
* storage. You must implement this interface if you want to be able to use sync functionality within the Admin console.
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/

View file

@ -20,8 +20,12 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
/**
* If your UserStorageProvider is importing users into local storage, you can validate that import whenever the
* user is queried from local storage.
* This is an optional capability interface that is intended to be implemented by any
* {@link org.keycloak.storage.UserStorageProvider UserStorageProvider} that supports validating users. You must
* implement this interface if your storage imports users into the Keycloak local storage and you want to sync these
* users with your storage. The idea is, that whenever keycloak queries users imported from your storage, the method
* {@link #validate(RealmModel, UserModel) validate()} is called and if it returns null, the user is removed from
* local storage and reloaded from your storage by corresponding method.
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $

View file

@ -20,6 +20,9 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
/**
* This is an optional capability interface that is intended to be implemented by any
* {@link org.keycloak.storage.UserStorageProvider UserStorageProvider} that supports bulk operations.
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/

View file

@ -20,23 +20,93 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
/**
* Optional capability interface implemented by UserStorageProviders. This interface is required
* if you want the UserStorageProvider to support basic login capabilities.
* This is an optional capability interface that is intended to be implemented by any
* {@link org.keycloak.storage.UserStorageProvider UserStorageProvider} that supports basic user querying. You must
* implement this interface if you want to be able to log in to keycloak using users from your storage.
* <p/>
* Note that all methods in this interface should limit search only to data available within the storage that is
* represented by this provider. They should not lookup other storage providers for additional information.
* Optional capability interface implemented by UserStorageProviders.
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public interface UserLookupProvider {
/**
* Returns a user with the given id belonging to the realm
*
* @param id id of the user
* @param realm the realm model
* @return found user model, or {@code null} if no such user exists
*/
default UserModel getUserById(RealmModel realm, String id) {
return getUserById(id, realm);
}
/**
* @deprecated Use {@link #getUserById(RealmModel, String) getUserById} instead.
*/
@Deprecated
UserModel getUserById(String id, RealmModel realm);
/**
* Returns a user with the given username belonging to the realm
*
* @param username case insensitive username (case-sensitivity is controlled by storage)
* @param realm the realm model
* @return found user model, or {@code null} if no such user exists
*/
default UserModel getUserByUsername(RealmModel realm, String username) {
return getUserByUsername(username, realm);
}
/**
* @deprecated Use {@link #getUserByUsername(RealmModel, String) getUserByUsername} instead.
*/
@Deprecated
UserModel getUserByUsername(String username, RealmModel realm);
/**
* Returns a user with the given email belonging to the realm
*
* @param email case insensitive email address (case-sensitivity is controlled by storage)
* @param realm the realm model
* @return found user model, or {@code null} if no such user exists
*
* @param email
* @param realm
* @throws org.keycloak.models.ModelDuplicateException when there are more users with same email
* @return
*/
UserModel getUserByEmail(String email, RealmModel realm);
default UserModel getUserByEmail(RealmModel realm, String email) {
return getUserByEmail(email, realm);
}
/**
* @deprecated Use {@link #getUserByEmail(RealmModel, String) getUserByEmail} instead.
*/
@Deprecated
UserModel getUserByEmail(String email, RealmModel realm);
interface Streams extends UserLookupProvider {
@Override
UserModel getUserById(RealmModel realm, String id);
@Override
default UserModel getUserById(String id, RealmModel realm) {
return getUserById(realm, id);
}
@Override
UserModel getUserByUsername(RealmModel realm, String username);
@Override
default UserModel getUserByUsername(String username, RealmModel realm) {
return getUserByUsername(realm, username);
}
@Override
UserModel getUserByEmail(RealmModel realm, String email);
@Override
default UserModel getUserByEmail(String email, RealmModel realm) {
return getUserByEmail(realm, email);
}
}
}

View file

@ -21,6 +21,7 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -28,9 +29,13 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Optional capability interface implemented by UserStorageProviders.
* Defines complex queries that are used to locate one or more users. You must implement this interface
* if you want to view and manager users from the administration console.
*
* This is an optional capability interface that is intended to be implemented by any
* {@link org.keycloak.storage.UserStorageProvider UserStorageProvider} that supports complex user querying. You must
* implement this interface if you want to view and manage users from the administration console.
* <p/>
* Note that all methods in this interface should limit search only to data available within the storage that is
* represented by this provider. They should not lookup other storage providers for additional information.
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
@ -43,14 +48,16 @@ public interface UserQueryProvider {
* @param realm the realm
* @return the number of users
*/
int getUsersCount(RealmModel realm);
default int getUsersCount(RealmModel realm) {
return getUsersCount(realm, false);
}
/**
* Returns the number of users that are in at least one of the groups
* given.
*
* @param realm the realm
* @param groupIds set of groups id to check for
* @param groupIds set of groups IDs, the returned user needs to belong to at least one of them
* @return the number of users that are in at least one of the groups
*/
default int getUsersCount(RealmModel realm, Set<String> groupIds) {
@ -61,41 +68,64 @@ public interface UserQueryProvider {
}
/**
* Returns the number of users that match the given criteria.
* Returns the number of users that would be returned by a call to {@link #searchForUserStream(RealmModel, String) searchForUserStream}
*
* @param search search criteria
* @param realm the realm
* @param search case insensitive list of strings separated by whitespaces.
* @return number of users that match the search
*/
default int getUsersCount(String search, RealmModel realm) {
return (int) searchForUserStream(search, realm).count();
default int getUsersCount(RealmModel realm, String search) {
return getUsersCount(search, realm);
}
/**
* Returns the number of users that match the given criteria and are in
* at least one of the groups given.
* @deprecated Use {@link #getUsersCount(RealmModel, String) getUsersCount}
*/
@Deprecated
default int getUsersCount(String search, RealmModel realm) {
return (int) searchForUserStream(realm, search).count();
}
/**
* Returns the number of users that would be returned by a call to {@link #searchForUserStream(RealmModel, String) searchForUserStream}
* and are members of at least one of the groups given by the {@code groupIds} set.
*
* @param search search criteria
* @param realm the realm
* @param groupIds set of groups to check for
* @param search case insensitive list of strings separated by whitespaces.
* @param groupIds set of groups IDs, the returned user needs to belong to at least one of them
* @return number of users that match the search and given groups
*/
default int getUsersCount(RealmModel realm, String search, Set<String> groupIds) {
return getUsersCount(search, realm, groupIds);
}
/**
* @deprecated Use {@link #getUsersCount(RealmModel, String, Set) getUsersCount} instead.
*/
@Deprecated
default int getUsersCount(String search, RealmModel realm, Set<String> groupIds) {
if (groupIds == null || groupIds.isEmpty()) {
return 0;
}
return countUsersInGroups(searchForUserStream(search, realm), groupIds);
return countUsersInGroups(searchForUserStream(realm, search), groupIds);
}
/**
* Returns the number of users that match the given filter parameters.
*
* @param params filter parameters
* @param realm the realm
* @param params filter parameters
* @return number of users that match the given filters
*/
default int getUsersCount(RealmModel realm, Map<String, String> params) {
return getUsersCount(params, realm);
}
/**
* @deprecated Use {@link #getUsersCount(RealmModel, Set) getUsersCount} instead.
*/
@Deprecated
default int getUsersCount(Map<String, String> params, RealmModel realm) {
return (int) searchForUserStream(params, realm).count();
return (int) searchForUserStream(realm, params).count();
}
/**
@ -107,13 +137,21 @@ public interface UserQueryProvider {
* @param groupIds set if groups to check for
* @return number of users that match the given filters and groups
*/
default int getUsersCount(RealmModel realm, Map<String, String> params, Set<String> groupIds) {
return getUsersCount(params, realm, groupIds);
}
/**
* @deprecated Use {@link #getUsersCount(RealmModel, Map, Set) getUsersCount} instead.
*/
@Deprecated
default int getUsersCount(Map<String, String> params, RealmModel realm, Set<String> groupIds) {
if (groupIds == null || groupIds.isEmpty()) {
return 0;
}
return countUsersInGroups(searchForUserStream(params, realm), groupIds);
return countUsersInGroups(searchForUserStream(realm, params), groupIds);
}
/**
* Returns the number of users from the given list of users that are in at
* least one of the groups given in the groups set.
@ -154,7 +192,7 @@ public interface UserQueryProvider {
}
/**
* @deprecated Use {@link #getUsersStream(RealmModel, int, int) getUsersStream} instead.
* @deprecated Use {@link #getUsersStream(RealmModel, Integer, Integer) getUsersStream} instead.
*/
@Deprecated
List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults);
@ -163,184 +201,221 @@ public interface UserQueryProvider {
* Searches all users in the realm, starting from the {@code firstResult} and containing at most {@code maxResults}.
*
* @param realm a reference to the realm.
* @param firstResult first result to return. Ignored if negative.
* @param firstResult first result to return. Ignored if negative or zero.
* @param maxResults maximum number of results to return. Ignored if negative.
* @return a non-null {@link Stream} of users.
*/
default Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults) {
List<UserModel> value = this.getUsers(realm, firstResult, maxResults);
default Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
List<UserModel> value = this.getUsers(realm, firstResult == null ? -1 : firstResult,
maxResults == null ? -1 : maxResults);
return value != null ? value.stream() : Stream.empty();
}
/**
* Search for users with username, email or first + last name that is like search string.
*
* Searches for users whose username, email, first name or last name contain any of the strings in {@code search} separated by whitespace.
* <p/>
* If possible, implementations should treat the parameter values as partial match patterns i.e. in RDMBS terms use LIKE.
*
* <p/>
* This method is used by the admin console search box
*
* @param search
* @param realm
* @return
* @deprecated Use {@link #searchForUserStream(String, RealmModel) searchForUserStream} instead.
* @param search case insensitive list of string separated by whitespaces.
* @param realm realm to search within
* @return list of users that satisfies the given search condition
*
* @deprecated Use {@link #searchForUserStream(RealmModel, String) searchForUserStream} instead.
*/
@Deprecated
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
* should treat the parameter values as partial match patterns (i.e. in RDMBS terms use LIKE).
* Searches for users whose username, email, first name or last name contain any of the strings in {@code search} separated by whitespace.
* <p/>
* If possible, implementations should treat the parameter values as partial match patterns (i.e. in RDMBS terms use LIKE).
* <p/>
* This method is used by the admin console search box
*
* @param search case sensitive search string.
* @param realm a reference to the realm.
* @param search case insensitive list of string separated by whitespaces.
* @return a non-null {@link Stream} of users that match the search string.
*/
default Stream<UserModel> searchForUserStream(String search, RealmModel realm) {
default Stream<UserModel> searchForUserStream(RealmModel realm, String search) {
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.
*
* Searches for users whose username, email, first name or last name contain any of the strings in {@code search} separated by whitespace.
* The resulting user list should be paginated with respect to parameters {@code firstResult} and {@code maxResults}
* <p/>
* If possible, implementations should treat the parameter values as partial match patterns i.e. in RDMBS terms use LIKE.
*
* <p/>
* This method is used by the admin console search box
*
* @param search
* @param realm
* @param firstResult
* @param maxResults
* @return
* @deprecated Use {@link #searchForUserStream(String, RealmModel, Integer, Integer) searchForUserStream} instead.
* @param search case insensitive list of string separated by whitespaces.
* @param realm a reference to the realm
* @param firstResult first result to return. Ignored if negative or zero.
* @param maxResults maximum number of results to return. Ignored if negative.
* @return paginated list of users from the realm that satisfies given search
*
* @deprecated Use {@link #searchForUserStream(RealmModel, String, Integer, Integer) searchForUserStream} instead.
*/
@Deprecated
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
* should treat the parameter values as partial match patterns (i.e. in RDMBS terms use LIKE).
* Searches for users whose username, email, first name or last name contain any of the strings in {@code search} separated by whitespace.
* <p/>
* If possible, implementations should treat the parameter values as partial match patterns (i.e. in RDMBS terms use LIKE).
* <p/>
* This method is used by the admin console search box
*
* @param search case sensitive search string.
* @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.
* @param search case insensitive list of string separated by whitespaces.
* @param firstResult first result to return. Ignored if negative, zero, 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 that match the search criteria.
*/
default Stream<UserModel> searchForUserStream(String search, RealmModel realm, Integer firstResult, Integer maxResults) {
default Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
List<UserModel> value = this.searchForUser(search, realm, firstResult == null ? -1 : firstResult, maxResults == null ? -1 : maxResults);
return value != null ? value.stream() : Stream.empty();
}
/**
* Search for user by parameter. Valid parameters are:
* "first" - first name
* "last" - last name
* "email" - email
* "username" - username
* Search for user by a map of parameters.
* <p/>
* Valid parameters are:
* <ul>
* <li>{@link UserModel#FIRST_NAME} - first name (case insensitive string)</li>
* <li>{@link UserModel#LAST_NAME} - last name (case insensitive string)</li>
* <li>{@link UserModel#EMAIL} - email (case insensitive string)</li>
* <li>{@link UserModel#USERNAME} - username (case insensitive string)</li>
* <li>{@link UserModel#EMAIL_VERIFIED} - search only for users with verified/non-verified email (true/false)</li>
* <li>{@link UserModel#ENABLED} - search only for enabled/disabled users (true/false)</li>
* <li>{@link UserModel#IDP_ALIAS} - search only for users that have a federated identity
* from idp with the given alias configured (case sensitive string)</li>
* <li>{@link UserModel#IDP_USER_ID} - search for users with federated identity with
* the given userId (case sensitive string)</li>
* </ul>
*
* If possible, implementations should treat the parameter values as partial match patterns i.e. in RDMBS terms use LIKE.
*
* <p/>
* This method is used by the REST API when querying users.
*
* @param params a map containing the search parameters
* @param realm a reference to the realm
* @return list of users that satisfies given search conditions
*
* @param params
* @param realm
* @return
* @deprecated Use {@link #searchForUserStream(Map, RealmModel) searchForUserStream} instead.
* @deprecated Use {@link #searchForUserStream(RealmModel, Map) searchForUserStream} instead.
*/
@Deprecated
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
* (i.e. in RDMBS terms use LIKE). Valid parameters are:
* Searches for user by parameter.
* If possible, implementations should treat the parameter values as partial match patterns (i.e. in RDMBS terms use LIKE).
* <p/>
* Valid parameters are:
* <ul>
* <li><b>first</b> - first name</li>
* <li><b>last</b> - last name</li>
* <li><b>email</b> - email</li>
* <li><b>username</b> - username</li>
* <li><b>enabled</b> - if user is enabled (true/false)</li>
* <li>{@link UserModel#FIRST_NAME} - first name (case insensitive string)</li>
* <li>{@link UserModel#LAST_NAME} - last name (case insensitive string)</li>
* <li>{@link UserModel#EMAIL} - email (case insensitive string)</li>
* <li>{@link UserModel#USERNAME} - username (case insensitive string)</li>
* <li>{@link UserModel#EMAIL_VERIFIED} - search only for users with verified/non-verified email (true/false)</li>
* <li>{@link UserModel#ENABLED} - search only for enabled/disabled users (true/false)</li>
* <li>{@link UserModel#IDP_ALIAS} - search only for users that have a federated identity
* from idp with the given alias configured (case sensitive string)</li>
* <li>{@link UserModel#IDP_USER_ID} - search for users with federated identity with
* the given userId (case sensitive string)</li>
* </ul>
*
* This method is used by the REST API when querying users.
*
* @param params a map containing the search parameters.
* @param realm a reference to the realm.
* @param params a map containing the search parameters.
* @return a non-null {@link Stream} of users that match the search parameters.
*/
default Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm) {
default Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> params) {
List<UserModel> value = this.searchForUser(params, realm);
return value != null ? value.stream() : Stream.empty();
}
/**
* Search for user by parameter. Valid parameters are:
* "first" - first name
* "last" - last name
* "email" - email
* "username" - username
* "enabled" - is user enabled (true/false)
* Search for user by parameter.
* <p/>
* Valid parameters are:
* <ul>
* <li>{@link UserModel#FIRST_NAME} - first name (case insensitive string)</li>
* <li>{@link UserModel#LAST_NAME} - last name (case insensitive string)</li>
* <li>{@link UserModel#EMAIL} - email (case insensitive string)</li>
* <li>{@link UserModel#USERNAME} - username (case insensitive string)</li>
* <li>{@link UserModel#EMAIL_VERIFIED} - search only for users with verified/non-verified email (true/false)</li>
* <li>{@link UserModel#ENABLED} - search only for enabled/disabled users (true/false)</li>
* <li>{@link UserModel#IDP_ALIAS} - search only for users that have a federated identity
* from idp with the given alias configured (case sensitive string)</li>
* <li>{@link UserModel#IDP_USER_ID} - search for users with federated identity with
* the given userId (case sensitive string)</li>
* </ul>
*
* If possible, implementations should treat the parameter values as patterns i.e. in RDMBS terms use LIKE.
* <p/>
* This method is used by the REST API when querying users.
*
* @param params a map containing the search parameters.
* @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 {@link Stream} of users that match the search criteria.
*
* @param params
* @param realm
* @param firstResult
* @param maxResults
* @return
* @deprecated Use {@link #searchForUserStream(Map, RealmModel, Integer, Integer) searchForUserStream} instead.
* @deprecated Use {@link #searchForUserStream(RealmModel, Map, Integer, Integer) searchForUserStream} instead.
*/
@Deprecated
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
* (i.e. in RDMBS terms use LIKE). Valid parameters are:
* (i.e. in RDMBS terms use LIKE).
* <p/>
* Valid parameters are:
* <ul>
* <li><b>first</b> - first name</li>
* <li><b>last</b> - last name</li>
* <li><b>email</b> - email</li>
* <li><b>username</b> - username</li>
* <li><b>enabled</b> - if user is enabled (true/false)</li>
* <li>{@link UserModel#FIRST_NAME} - first name (case insensitive string)</li>
* <li>{@link UserModel#LAST_NAME} - last name (case insensitive string)</li>
* <li>{@link UserModel#EMAIL} - email (case insensitive string)</li>
* <li>{@link UserModel#USERNAME} - username (case insensitive string)</li>
* <li>{@link UserModel#EMAIL_VERIFIED} - search only for users with verified/non-verified email (true/false)</li>
* <li>{@link UserModel#ENABLED} - search only for enabled/disabled users (true/false)</li>
* <li>{@link UserModel#IDP_ALIAS} - search only for users that have a federated identity
* from idp with the given alias configured (case sensitive string)</li>
* <li>{@link UserModel#IDP_USER_ID} - search for users with federated identity with
* the given userId (case sensitive string)</li>
* </ul>
*
* This method is used by the REST API when querying users.
*
* @param params a map containing the search parameters.
* @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.
* @param params a map containing the search parameters.
* @param firstResult first result to return. Ignored if negative, zero, 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 that match the search criteria.
*/
default Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm, Integer firstResult, Integer maxResults) {
default Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> params, Integer firstResult, Integer maxResults) {
List<UserModel> value = this.searchForUser(params, realm, firstResult == null ? -1 : firstResult, maxResults == null ? -1 : maxResults);
return value != null ? value.stream() : Stream.empty();
}
/**
* Get users that belong to a specific group. Implementations do not have to search in UserFederatedStorageProvider
* as this is done automatically.
* Get users that belong to a specific group.
*
* @see org.keycloak.storage.federated.UserFederatedStorageProvider
* @param realm a reference to the realm
* @param group a reference to the group
* @return a list of all users that are members of the given group
*
* @param realm
* @param group
* @return
* @deprecated Use {@link #getGroupMembersStream(RealmModel, GroupModel) getGroupMembersStream} instead.
*/
@Deprecated
List<UserModel> getGroupMembers(RealmModel realm, GroupModel group);
/**
* Obtains users that belong to a specific group. Implementations do not have to search in {@code UserFederatedStorageProvider}
* as this is done automatically.
*
* @see org.keycloak.storage.federated.UserFederatedStorageProvider
* Obtains users that belong to a specific group.
*
* @param realm a reference to the realm.
* @param group a reference to the group.
@ -352,31 +427,26 @@ public interface UserQueryProvider {
}
/**
* Get users that belong to a specific group. Implementations do not have to search in UserFederatedStorageProvider
* as this is done automatically.
* Gets paginated list of users that belong to a specific group.
*
* @see org.keycloak.storage.federated.UserFederatedStorageProvider
* @param realm a reference to the realm
* @param group a reference to the group
* @param firstResult first result to return. Ignored if negative or zero.
* @param maxResults maximum number of results to return. Ignored if negative.
* @return paginated list of members of the given group
*
* @param realm
* @param group
* @param firstResult
* @param maxResults
* @return
* @deprecated Use {@link #getGroupMembersStream(RealmModel, GroupModel, Integer, Integer) getGroupMembersStream} instead.
*/
@Deprecated
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}
* as this is done automatically.
*
* @see org.keycloak.storage.federated.UserFederatedStorageProvider
* Obtains users that belong to a specific group.
*
* @param realm a reference to the realm.
* @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.
* @param firstResult first result to return. Ignored if negative, zero, 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 that belong to the group.
*/
default Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group, Integer firstResult, Integer maxResults) {
@ -387,9 +457,10 @@ public interface UserQueryProvider {
/**
* Get users that belong to a specific role.
*
* @param realm
* @param role
* @return
* @param realm a reference to the realm
* @param role a reference to the role
* @return a list of users that has the given role assigned
*
* @deprecated Use {@link #getRoleMembersStream(RealmModel, RoleModel) getRoleMembersStream} instead.
*/
@Deprecated
@ -411,15 +482,17 @@ public interface UserQueryProvider {
/**
* Search for users that have a specific role with a specific roleId.
*
* @param role
* @param firstResult
* @param maxResults
* @return
* @param realm a reference to the realm
* @param role a reference to the role
* @param firstResult first result to return. Ignored if negative or zero.
* @param maxResults maximum number of results to return. Ignored if negative.
* @return a paginated list of users that has the given role assigned
*
* @deprecated Use {@link #getRoleMembersStream(RealmModel, RoleModel, Integer, Integer) getRoleMembersStream} instead.
*/
@Deprecated
default List<UserModel> getRoleMembers(RealmModel realm, RoleModel role, int firstResult, int maxResults) {
return this.getRoleMembersStream(realm, role, firstResult, maxResults).collect(Collectors.toList());
return Collections.emptyList();
}
/**
@ -432,38 +505,33 @@ public interface UserQueryProvider {
* @return a non-null {@link Stream} of users that have the specified role.
*/
default Stream<UserModel> getRoleMembersStream(RealmModel realm, RoleModel role, Integer firstResult, Integer maxResults) {
return Stream.empty();
return getRoleMembers(realm, role, firstResult == null ? -1 : firstResult, maxResults== null ? -1 : maxResults)
.stream();
}
/**
* Search for users that have a specific attribute with a specific value.
* Implementations do not have to search in UserFederatedStorageProvider
* as this is done automatically.
*
* @see org.keycloak.storage.federated.UserFederatedStorageProvider
* @param attrName a name of the attribute that will be searched
* @param attrValue a value of the attribute that will be searched
* @param realm a reference to the realm
* @return list of users with the given attribute name and value
*
* @param attrName
* @param attrValue
* @param realm
* @return
* @deprecated Use {@link #searchForUserByUserAttributeStream(String, String, RealmModel) searchForUserByUserAttributeStream}
* @deprecated Use {@link #searchForUserByUserAttributeStream(RealmModel, String, String) searchForUserByUserAttributeStream}
* instead.
*/
@Deprecated
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
* {@code UserFederatedStorageProvider} as this is done automatically.
*
* @see org.keycloak.storage.federated.UserFederatedStorageProvider
* Searches for users that have a specific attribute with a specific value.
*
* @param realm a reference to the realm.
* @param attrName the attribute name.
* @param attrValue the attribute value.
* @param realm a reference to the realm.
* @return a non-null {@link Stream} of users that match the search criteria.
*/
default Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm) {
default Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
List<UserModel> value = this.searchForUserByUserAttribute(attrName, attrValue, realm);
return value != null ? value.stream() : Stream.empty();
}
@ -476,13 +544,62 @@ public interface UserQueryProvider {
* from the potential memory and performance optimizations of that approach.
*/
interface Streams extends UserQueryProvider {
@Override
default int getUsersCount(RealmModel realm, String search) {
return (int) searchForUserStream(realm, search).count();
}
@Override
default int getUsersCount(String search, RealmModel realm) {
return getUsersCount(realm, search);
}
@Override
default int getUsersCount(RealmModel realm, String search, Set<String> groupIds) {
if (groupIds == null || groupIds.isEmpty()) {
return 0;
}
return countUsersInGroups(searchForUserStream(realm, search), groupIds);
}
@Override
default int getUsersCount(String search, RealmModel realm, Set<String> groupIds) {
return getUsersCount(realm, search, groupIds);
}
@Override
default int getUsersCount(RealmModel realm, Map<String, String> params) {
return (int) searchForUserStream(realm, params).count();
}
@Override
default int getUsersCount( Map<String, String> params, RealmModel realm) {
return getUsersCount(realm, params);
}
@Override
default int getUsersCount(RealmModel realm, Map<String, String> params, Set<String> groupIds) {
if (groupIds == null || groupIds.isEmpty()) {
return 0;
}
return countUsersInGroups(searchForUserStream(realm, params), groupIds);
}
@Override
default int getUsersCount(Map<String, String> params, RealmModel realm, Set<String> groupIds) {
return getUsersCount(realm, params, groupIds);
}
@Override
default List<UserModel> getUsers(RealmModel realm) {
return this.getUsersStream(realm).collect(Collectors.toList());
}
@Override
Stream<UserModel> getUsersStream(RealmModel realm);
default Stream<UserModel> getUsersStream(RealmModel realm) {
return getUsersStream(realm, null, null);
}
@Override
default List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults) {
@ -490,39 +607,43 @@ public interface UserQueryProvider {
}
@Override
Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults);
Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults);
@Override
default List<UserModel> searchForUser(String search, RealmModel realm) {
return this.searchForUserStream(search, realm).collect(Collectors.toList());
return this.searchForUserStream(realm, search).collect(Collectors.toList());
}
@Override
Stream<UserModel> searchForUserStream(String search, RealmModel realm);
default Stream<UserModel> searchForUserStream(RealmModel realm, String search) {
return searchForUserStream(realm, search, null, null);
}
@Override
default List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults) {
return this.searchForUserStream(search, realm, firstResult, maxResults).collect(Collectors.toList());
return this.searchForUserStream(realm, search, firstResult, maxResults).collect(Collectors.toList());
}
@Override
Stream<UserModel> searchForUserStream(String search, RealmModel realm, Integer firstResult, Integer maxResults);
Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults);
@Override
default List<UserModel> searchForUser(Map<String, String> params, RealmModel realm) {
return this.searchForUserStream(params, realm).collect(Collectors.toList());
return this.searchForUserStream(realm, params).collect(Collectors.toList());
}
@Override
Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm);
default Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> params) {
return searchForUserStream(realm, params, null, null);
}
@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());
return this.searchForUserStream(realm, params, firstResult, maxResults).collect(Collectors.toList());
}
@Override
Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm, Integer firstResult, Integer maxResults);
Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> params, Integer firstResult, Integer maxResults);
@Override
default List<UserModel> getGroupMembers(RealmModel realm, GroupModel group) {
@ -530,7 +651,9 @@ public interface UserQueryProvider {
}
@Override
Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group);
default Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group) {
return this.getGroupMembersStream(realm, group, null, null);
}
@Override
default List<UserModel> getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults) {
@ -542,10 +665,10 @@ public interface UserQueryProvider {
@Override
default List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
return this.searchForUserByUserAttributeStream(attrName, attrValue, realm).collect(Collectors.toList());
return this.searchForUserByUserAttributeStream(realm, attrName, attrValue).collect(Collectors.toList());
}
@Override
Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm);
Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue);
}
}

View file

@ -21,8 +21,9 @@ import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
/**
* Optional capability interface implemented by UserStorageProviders.
* Implement this interface if your provider supports adding and removing users.
* This is an optional capability interface that is intended to be implemented by any
* {@link org.keycloak.storage.UserStorageProvider UserStorageProvider} that supports addition of new users. You must
* implement this interface if you want to use this storage for registering new users.
*
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
@ -37,9 +38,9 @@ public interface UserRegistrationProvider {
* Returning null is useful when you want optional support for adding users. For example,
* our LDAP provider can enable and disable the ability to add users.
*
* @param realm
* @param username
* @return
* @param realm a reference to the realm
* @param username a username the created user will be assigned
* @return a model of created user
*/
UserModel addUser(RealmModel realm, String username);
@ -54,9 +55,9 @@ public interface UserRegistrationProvider {
* this method will be called before local storage's removeUser() method is invoked. Also,
* you DO NOT need to remove the imported user. The runtime will handle this for you.
*
* @param realm
* @param user
* @return
* @param realm a reference to the realm
* @param user a reference to the user that is removed
* @return true if the user was removed, false otherwise
*/
boolean removeUser(RealmModel realm, UserModel user);

View file

@ -123,7 +123,7 @@ public abstract class AbstractIdpAuthenticator implements Authenticator {
ExistingUserInfo duplication = ExistingUserInfo.deserialize(existingUserId);
UserModel existingUser = session.users().getUserById(duplication.getExistingUserId(), realm);
UserModel existingUser = session.users().getUserById(realm, duplication.getExistingUserId());
if (existingUser == null) {
throw new AuthenticationFlowException("User with ID '" + existingUserId + "' not found.", AuthenticationFlowError.INVALID_USER);
}

View file

@ -120,13 +120,13 @@ public class IdpCreateUserIfUniqueAuthenticator extends AbstractIdpAuthenticator
protected ExistingUserInfo checkExistingUser(AuthenticationFlowContext context, String username, SerializedBrokeredIdentityContext serializedCtx, BrokeredIdentityContext brokerContext) {
if (brokerContext.getEmail() != null && !context.getRealm().isDuplicateEmailsAllowed()) {
UserModel existingUser = context.getSession().users().getUserByEmail(brokerContext.getEmail(), context.getRealm());
UserModel existingUser = context.getSession().users().getUserByEmail(context.getRealm(), brokerContext.getEmail());
if (existingUser != null) {
return new ExistingUserInfo(existingUser.getId(), UserModel.EMAIL, existingUser.getEmail());
}
}
UserModel existingUser = context.getSession().users().getUserByUsername(username, context.getRealm());
UserModel existingUser = context.getSession().users().getUserByUsername(context.getRealm(), username);
if (existingUser != null) {
return new ExistingUserInfo(existingUser.getId(), UserModel.USERNAME, existingUser.getUsername());
}

View file

@ -180,7 +180,7 @@ public class WebAuthnAuthenticator implements Authenticator, CredentialValidator
String userVerificationRequirement = getWebAuthnPolicy(context).getUserVerificationRequirement();
if (WebAuthnConstants.OPTION_REQUIRED.equals(userVerificationRequirement)) isUVFlagChecked = true;
UserModel user = session.users().getUserById(userId, context.getRealm());
UserModel user = session.users().getUserById(context.getRealm(), userId);
AuthenticationRequest authenticationRequest = new AuthenticationRequest(
credentialId,

View file

@ -65,7 +65,7 @@ public class ResetCredentialChooseUser implements Authenticator, AuthenticatorFa
String actionTokenUserId = context.getAuthenticationSession().getAuthNote(DefaultActionTokenKey.ACTION_TOKEN_USER_ID);
if (actionTokenUserId != null) {
UserModel existingUser = context.getSession().users().getUserById(actionTokenUserId, context.getRealm());
UserModel existingUser = context.getSession().users().getUserById(context.getRealm(), actionTokenUserId);
// Action token logics handles checks for user ID validity and user being enabled
@ -96,9 +96,9 @@ public class ResetCredentialChooseUser implements Authenticator, AuthenticatorFa
username = username.trim();
RealmModel realm = context.getRealm();
UserModel user = context.getSession().users().getUserByUsername(username, realm);
UserModel user = context.getSession().users().getUserByUsername(realm, username);
if (user == null && realm.isLoginWithEmailAllowed() && username.contains("@")) {
user = context.getSession().users().getUserByEmail(username, realm);
user = context.getSession().users().getUserByEmail(realm, username);
}
context.getAuthenticationSession().setAuthNote(AbstractUsernameFormAuthenticator.ATTEMPTED_USERNAME, username);

View file

@ -63,7 +63,7 @@ public abstract class UserIdentityToModelMapper {
if (_customAttributes.isEmpty() || userIdentityValues.isEmpty() || (_customAttributes.size() != userIdentityValues.size())) {
return null;
}
Stream<UserModel> usersStream = session.users().searchForUserByUserAttributeStream(_customAttributes.get(0), userIdentityValues.get(0), context.getRealm());
Stream<UserModel> usersStream = session.users().searchForUserByUserAttributeStream(context.getRealm(), _customAttributes.get(0), userIdentityValues.get(0));
for (int i = 1; i <_customAttributes.size(); ++i) {
String customAttribute = _customAttributes.get(i);

View file

@ -244,10 +244,10 @@ public class PolicyEvaluationService {
UserSessionModel userSession = null;
if (subject != null) {
UserModel userModel = keycloakSession.users().getUserById(subject, realm);
UserModel userModel = keycloakSession.users().getUserById(realm, subject);
if (userModel == null) {
userModel = keycloakSession.users().getUserByUsername(subject, realm);
userModel = keycloakSession.users().getUserByUsername(realm, subject);
}
if (userModel != null) {

View file

@ -387,7 +387,7 @@ public class ResourceSetService {
if (clientModel != null) {
owner = clientModel.getId();
} else {
UserModel user = authorization.getKeycloakSession().users().getUserByUsername(owner, realm);
UserModel user = authorization.getKeycloakSession().users().getUserByUsername(realm, owner);
if (user != null) {
owner = user.getId();

View file

@ -199,8 +199,8 @@ public class PolicyEvaluationResponseBuilder {
KeycloakSession keycloakSession = authorization.getKeycloakSession();
RealmModel realm = authorization.getRealm();
PermissionTicket ticket = tickets.get(0);
UserModel userOwner = keycloakSession.users().getUserById(ticket.getOwner(), realm);
UserModel requester = keycloakSession.users().getUserById(ticket.getRequester(), realm);
UserModel userOwner = keycloakSession.users().getUserById(realm, ticket.getOwner());
UserModel requester = keycloakSession.users().getUserById(realm, ticket.getRequester());
String resourceOwner;
if (userOwner != null) {
resourceOwner = getUserEmailOrUserName(userOwner);

View file

@ -91,9 +91,9 @@ public class PermissionTicketService {
UserModel user = null;
if(representation.getRequester() != null)
user = this.authorization.getKeycloakSession().userStorageManager().getUserById(representation.getRequester(), this.authorization.getRealm());
user = this.authorization.getKeycloakSession().userStorageManager().getUserById(this.authorization.getRealm(), representation.getRequester());
else
user = this.authorization.getKeycloakSession().userStorageManager().getUserByUsername(representation.getRequesterName(), this.authorization.getRealm());
user = this.authorization.getKeycloakSession().userStorageManager().getUserByUsername(this.authorization.getRealm(), representation.getRequesterName());
if (user == null)
throw new ErrorResponseException("invalid_permission", "Requester does not exists in this server as user.", Response.Status.BAD_REQUEST);
@ -229,13 +229,13 @@ public class PermissionTicketService {
private String getUserId(String userIdOrName) {
UserProvider userProvider = authorization.getKeycloakSession().users();
RealmModel realm = authorization.getRealm();
UserModel userModel = userProvider.getUserById(userIdOrName, realm);
UserModel userModel = userProvider.getUserById(realm, userIdOrName);
if (userModel != null) {
return userModel.getId();
}
userModel = userProvider.getUserByUsername(userIdOrName, realm);
userModel = userProvider.getUserByUsername(realm, userIdOrName);
if (userModel != null) {
return userModel.getId();

View file

@ -250,7 +250,7 @@ public abstract class AbstractOAuth2IdentityProvider<C extends OAuth2IdentityPro
}
protected Response exchangeStoredToken(UriInfo uriInfo, EventBuilder event, ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject) {
FederatedIdentityModel model = session.users().getFederatedIdentity(tokenSubject, getConfig().getAlias(), authorizedClient.getRealm());
FederatedIdentityModel model = session.users().getFederatedIdentity(authorizedClient.getRealm(), tokenSubject, getConfig().getAlias());
if (model == null || model.getToken() == null) {
event.detail(Details.REASON, "requested_issuer is not linked");
event.error(Errors.INVALID_TOKEN);

View file

@ -169,7 +169,7 @@ public class OIDCIdentityProvider extends AbstractOAuth2IdentityProvider<OIDCIde
@Override
protected Response exchangeStoredToken(UriInfo uriInfo, EventBuilder event, ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject) {
FederatedIdentityModel model = session.users().getFederatedIdentity(tokenSubject, getConfig().getAlias(), authorizedClient.getRealm());
FederatedIdentityModel model = session.users().getFederatedIdentity(authorizedClient.getRealm(), tokenSubject, getConfig().getAlias());
if (model == null || model.getToken() == null) {
event.detail(Details.REASON, "requested_issuer is not linked");
event.error(Errors.INVALID_TOKEN);

View file

@ -63,7 +63,7 @@ public class EmailEventListenerProvider implements EventListenerProvider {
private void sendEmail(Event event) {
RealmModel realm = model.getRealm(event.getRealmId());
UserModel user = session.users().getUserById(event.getUserId(), realm);
UserModel user = session.users().getUserById(realm, event.getUserId());
if (user != null && user.getEmail() != null && user.isEmailVerified()) {
try {
emailTemplateProvider.setRealm(realm).setUser(user).sendEvent(event);

View file

@ -458,7 +458,7 @@ public class ExportUtils {
UserRepresentation userRep = ModelToRepresentation.toRepresentation(session, realm, user);
// Social links
List<FederatedIdentityRepresentation> socialLinkReps = session.users().getFederatedIdentitiesStream(user, realm)
List<FederatedIdentityRepresentation> socialLinkReps = session.users().getFederatedIdentitiesStream(realm, user)
.map(ExportUtils::exportSocialLink).collect(Collectors.toList());
if (socialLinkReps.size() > 0) {
userRep.setFederatedIdentities(socialLinkReps);

View file

@ -54,7 +54,7 @@ public class AccountFederatedIdentityBean {
.map(provider -> {
String providerId = provider.getAlias();
FederatedIdentityModel identity = getIdentity(session.users().getFederatedIdentitiesStream(user, realm), providerId);
FederatedIdentityModel identity = getIdentity(session.users().getFederatedIdentitiesStream(realm, user), providerId);
if (identity != null) {
availableIdentities.getAndIncrement();

View file

@ -150,7 +150,7 @@ public class AuthorizationBean {
private boolean granted;
public RequesterBean(PermissionTicket ticket, AuthorizationProvider authorization) {
this.requester = authorization.getKeycloakSession().users().getUserById(ticket.getRequester(), authorization.getRealm());
this.requester = authorization.getKeycloakSession().users().getUserById(authorization.getRealm(), ticket.getRequester());
granted = ticket.isGranted();
createdTimestamp = ticket.getCreatedTimestamp();
grantedTimestamp = ticket.getGrantedTimestamp();
@ -236,7 +236,7 @@ public class AuthorizationBean {
RealmModel realm = authorization.getRealm();
resourceServer = new ResourceServerBean(realm.getClientById(resource.getResourceServer()));
this.resource = resource;
userOwner = authorization.getKeycloakSession().users().getUserById(resource.getOwner(), realm);
userOwner = authorization.getKeycloakSession().users().getUserById(realm, resource.getOwner());
if (userOwner == null) {
clientOwner = realm.getClientById(resource.getOwner());
ownerName = clientOwner.getClientId();

View file

@ -54,12 +54,12 @@ public class LoginFormsUtil {
throw new IllegalStateException("USERNAME_EDIT_DISABLED but username not known");
}
UserModel user = session.users().getUserByUsername(username, realm);
UserModel user = session.users().getUserByUsername(realm, username);
if (user == null || !user.isEnabled()) {
throw new IllegalStateException("User " + username + " not found or disabled");
}
Set<String> federatedIdentities = session.users().getFederatedIdentitiesStream(user, realm)
Set<String> federatedIdentities = session.users().getFederatedIdentitiesStream(realm, user)
.map(federatedIdentityModel -> federatedIdentityModel.getIdentityProvider())
.collect(Collectors.toSet());

View file

@ -59,10 +59,10 @@ public class UsersPartialImport extends AbstractPartialImport<UserRepresentation
String userName = user.getUsername();
if (userName != null) {
return session.users().getUserByUsername(userName, realm).getId();
return session.users().getUserByUsername(realm, userName).getId();
} else if (!realm.isDuplicateEmailsAllowed()) {
String email = user.getEmail();
return session.users().getUserByEmail(email, realm).getId();
return session.users().getUserByEmail(realm, email).getId();
}
return null;
@ -74,12 +74,12 @@ public class UsersPartialImport extends AbstractPartialImport<UserRepresentation
}
private boolean userNameExists(RealmModel realm, KeycloakSession session, UserRepresentation user) {
return session.users().getUserByUsername(user.getUsername(), realm) != null;
return session.users().getUserByUsername(realm, user.getUsername()) != null;
}
private boolean userEmailExists(RealmModel realm, KeycloakSession session, UserRepresentation user) {
return (user.getEmail() != null) && !realm.isDuplicateEmailsAllowed() &&
(session.users().getUserByEmail(user.getEmail(), realm) != null);
(session.users().getUserByEmail(realm, user.getEmail()) != null);
}
@Override
@ -98,9 +98,9 @@ public class UsersPartialImport extends AbstractPartialImport<UserRepresentation
@Override
public void remove(RealmModel realm, KeycloakSession session, UserRepresentation user) {
UserModel userModel = session.users().getUserByUsername(user.getUsername(), realm);
UserModel userModel = session.users().getUserByUsername(realm, user.getUsername());
if (userModel == null && !realm.isDuplicateEmailsAllowed()) {
userModel = session.users().getUserByEmail(user.getEmail(), realm);
userModel = session.users().getUserByEmail(realm, user.getEmail());
}
if (userModel != null) {
boolean success = new UserManager(session).removeUser(realm, userModel);

View file

@ -294,14 +294,14 @@ public class TokenManager {
*/
public static UserModel lookupUserFromStatelessToken(KeycloakSession session, RealmModel realm, AccessToken token) {
// Try to lookup user based on "sub" claim. It should work for most cases with some rare exceptions (EG. OIDC "pairwise" subjects)
UserModel user = session.users().getUserById(token.getSubject(), realm);
UserModel user = session.users().getUserById(realm, token.getSubject());
if (user != null) {
return user;
}
// Fallback to lookup user based on username (preferred_username claim)
if (token.getPreferredUsername() != null) {
user = session.users().getUserByUsername(token.getPreferredUsername(), realm);
user = session.users().getUserByUsername(realm, token.getPreferredUsername());
if (user != null) {
return user;
}

View file

@ -834,9 +834,9 @@ public class TokenEndpoint {
String requestedSubject = formParams.getFirst(OAuth2Constants.REQUESTED_SUBJECT);
if (requestedSubject != null) {
event.detail(Details.REQUESTED_SUBJECT, requestedSubject);
UserModel requestedUser = session.users().getUserByUsername(requestedSubject, realm);
UserModel requestedUser = session.users().getUserByUsername(realm, requestedSubject);
if (requestedUser == null) {
requestedUser = session.users().getUserById(requestedSubject, realm);
requestedUser = session.users().getUserById(realm, requestedSubject);
}
if (requestedUser == null) {
@ -1135,7 +1135,7 @@ public class TokenEndpoint {
FederatedIdentityModel federatedIdentityModel = new FederatedIdentityModel(providerId, context.getId(),
context.getUsername(), context.getToken());
UserModel user = this.session.users().getUserByFederatedIdentity(federatedIdentityModel, realm);
UserModel user = this.session.users().getUserByFederatedIdentity(realm, federatedIdentityModel);
if (user == null) {
@ -1154,14 +1154,14 @@ public class TokenEndpoint {
username = username.trim();
context.setModelUsername(username);
if (context.getEmail() != null && !realm.isDuplicateEmailsAllowed()) {
UserModel existingUser = session.users().getUserByEmail(context.getEmail(), realm);
UserModel existingUser = session.users().getUserByEmail(realm, context.getEmail());
if (existingUser != null) {
event.error(Errors.FEDERATED_IDENTITY_EXISTS);
throw new CorsErrorResponseException(cors, Errors.INVALID_TOKEN, "User already exists", Response.Status.BAD_REQUEST);
}
}
UserModel existingUser = session.users().getUserByUsername(username, realm);
UserModel existingUser = session.users().getUserByUsername(realm, username);
if (existingUser != null) {
event.error(Errors.FEDERATED_IDENTITY_EXISTS);
throw new CorsErrorResponseException(cors, Errors.INVALID_TOKEN, "User already exists", Response.Status.BAD_REQUEST);

View file

@ -34,7 +34,7 @@ public class HttpBasicAuthenticator implements Authenticator {
if (usernameAndPassword != null) {
final RealmModel realm = context.getRealm();
final String username = usernameAndPassword[0];
final UserModel user = context.getSession().users().getUserByUsername(username, realm);
final UserModel user = context.getSession().users().getUserByUsername(realm, username);
// to allow success/failure logging for brute force
context.getEvent().detail(Details.USERNAME, username);

View file

@ -38,7 +38,7 @@ public class DynamicClientRegisterContext implements ClientUpdateContext {
this.token = token;
if (token != null) {
if (token.getSubject() != null) {
this.user = context.getSession().users().getUserById(token.getSubject(), realm);
this.user = context.getSession().users().getUserById(realm, token.getSubject());
}
if (token.getIssuedFor() != null) {
this.client = realm.getClientByClientId(token.getIssuedFor());

View file

@ -40,7 +40,7 @@ public class DynamicClientUpdateContext implements ClientUpdateContext {
this.token = token;
if (token != null) {
if (token.getSubject() != null) {
this.user = context.getSession().users().getUserById(token.getSubject(), realm);
this.user = context.getSession().users().getUserById(realm, token.getSubject());
}
if (token.getIssuedFor() != null) {
this.client = realm.getClientByClientId(token.getIssuedFor());

View file

@ -100,7 +100,7 @@ public class ClientUpdateSourceGroupsCondition implements ClientPolicyConditionP
private boolean isGroupMatched(String subjectId) {
if (subjectId == null) return false;
return isGroupsMatched(session.users().getUserById(subjectId, session.getContext().getRealm()));
return isGroupsMatched(session.users().getUserById(session.getContext().getRealm(), subjectId));
}
private boolean isGroupsMatched(UserModel user) {

View file

@ -99,7 +99,7 @@ public class ClientUpdateSourceRolesCondition implements ClientPolicyConditionPr
private boolean isRoleMatched(String subjectId) {
if (subjectId == null) return false;
return isRolesMatched(session.users().getUserById(subjectId, session.getContext().getRealm()));
return isRolesMatched(session.users().getUserById(session.getContext().getRealm(), subjectId));
}
private boolean isRolesMatched(UserModel user) {

View file

@ -291,7 +291,7 @@ public class ClientRegistrationAuth {
private boolean hasRoleInModel(String[] roles) {
ClientModel roleNamespace;
UserModel user = session.users().getUserById(jwt.getSubject(), realm);
UserModel user = session.users().getUserById(realm, jwt.getSubject());
if (user == null) {
return false;
}

View file

@ -103,7 +103,7 @@ public class DefaultBruteForceProtector implements Runnable, BruteForceProtector
logFailure(event);
String userId = event.userId;
UserModel user = session.users().getUserById(userId, realm);
UserModel user = session.users().getUserById(realm, userId);
if (user == null) {
return;
}
@ -251,7 +251,7 @@ public class DefaultBruteForceProtector implements Runnable, BruteForceProtector
private void success(KeycloakSession session, LoginEvent event) {
String userId = event.userId;
UserModel model = session.users().getUserById(userId, getRealmModel(session, event));
UserModel model = session.users().getUserById(getRealmModel(session, event), userId);
UserLoginFailureModel user = getUserModel(session, event);
if(user == null) return;

View file

@ -485,7 +485,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
IdentityProviderModel identityProviderConfig = getIdentityProviderConfig(providerId);
if (identityProviderConfig.isStoreToken()) {
FederatedIdentityModel identity = this.session.users().getFederatedIdentity(authResult.getUser(), providerId, this.realmModel);
FederatedIdentityModel identity = this.session.users().getFederatedIdentity(this.realmModel, authResult.getUser(), providerId);
if (identity == null) {
return corsResponse(badRequest("User [" + authResult.getUser().getId() + "] is not associated with identity provider [" + providerId + "]."), clientModel);
@ -557,12 +557,12 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
.detail(Details.IDENTITY_PROVIDER, providerId)
.detail(Details.IDENTITY_PROVIDER_USERNAME, context.getUsername());
UserModel federatedUser = this.session.users().getUserByFederatedIdentity(federatedIdentityModel, this.realmModel);
UserModel federatedUser = this.session.users().getUserByFederatedIdentity(this.realmModel, federatedIdentityModel);
boolean shouldMigrateId = false;
// try to find the user using legacy ID
if (federatedUser == null && context.getLegacyId() != null) {
federatedIdentityModel = new FederatedIdentityModel(federatedIdentityModel, context.getLegacyId());
federatedUser = this.session.users().getUserByFederatedIdentity(federatedIdentityModel, this.realmModel);
federatedUser = this.session.users().getUserByFederatedIdentity(this.realmModel, federatedIdentityModel);
shouldMigrateId = true;
}
@ -962,7 +962,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
if (federatedUser != null) {
if (context.getIdpConfig().isStoreToken()) {
FederatedIdentityModel oldModel = this.session.users().getFederatedIdentity(federatedUser, context.getIdpConfig().getAlias(), this.realmModel);
FederatedIdentityModel oldModel = this.session.users().getFederatedIdentity(this.realmModel, federatedUser, context.getIdpConfig().getAlias());
if (!ObjectUtil.isEqualOrBothNull(context.getToken(), oldModel.getToken())) {
this.session.users().updateFederatedIdentity(this.realmModel, federatedUser, newModel);
if (isDebugEnabled()) {
@ -1010,7 +1010,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
private void updateFederatedIdentity(BrokeredIdentityContext context, UserModel federatedUser) {
FederatedIdentityModel federatedIdentityModel = this.session.users().getFederatedIdentity(federatedUser, context.getIdpConfig().getAlias(), this.realmModel);
FederatedIdentityModel federatedIdentityModel = this.session.users().getFederatedIdentity(this.realmModel, federatedUser, context.getIdpConfig().getAlias());
if (context.getIdpConfig().getSyncMode() == IdentityProviderSyncMode.FORCE) {
setBasicUserAttributes(context, federatedUser);
@ -1041,7 +1041,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
}
private void migrateFederatedIdentityId(BrokeredIdentityContext context, UserModel federatedUser) {
FederatedIdentityModel identityModel = this.session.users().getFederatedIdentity(federatedUser, context.getIdpConfig().getAlias(), this.realmModel);
FederatedIdentityModel identityModel = this.session.users().getFederatedIdentity(this.realmModel, federatedUser, context.getIdpConfig().getAlias());
FederatedIdentityModel migratedIdentityModel = new FederatedIdentityModel(identityModel, context.getId());
// since ID is a partial key we need to recreate the identity

View file

@ -18,7 +18,6 @@ package org.keycloak.services.resources;
import com.fasterxml.jackson.core.type.TypeReference;
import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.Config;
import org.keycloak.common.util.Resteasy;
import org.keycloak.config.ConfigProviderFactory;
@ -371,7 +370,7 @@ public class KeycloakApplication extends Application {
UserProvider users = session.users();
if (users.getUserByUsername(userRep.getUsername(), realm) != null) {
if (users.getUserByUsername(realm, userRep.getUsername()) != null) {
ServicesLogger.LOGGER.notCreatingExistingUser(userRep.getUsername());
} else {
UserModel user = users.addUser(realm, userRep.getUsername());

View file

@ -137,7 +137,7 @@ public class LoginActionsServiceChecks {
* it optionally also injects the user using the given function (e.g. into session context).
*/
public static void checkIsUserValid(KeycloakSession session, RealmModel realm, String userId, Consumer<UserModel> userSetter) throws VerificationException {
UserModel user = userId == null ? null : session.users().getUserById(userId, realm);
UserModel user = userId == null ? null : session.users().getUserById(realm, userId);
if (user == null) {
throw new ExplainedVerificationException(Errors.USER_NOT_FOUND, Messages.INVALID_USER);

View file

@ -709,11 +709,11 @@ public class AccountFormService extends AbstractSecuredLocalService {
return account.setError(Response.Status.INTERNAL_SERVER_ERROR, Messages.IDENTITY_PROVIDER_REDIRECT_ERROR).createResponse(AccountPages.FEDERATED_IDENTITY);
}
case REMOVE:
FederatedIdentityModel link = session.users().getFederatedIdentity(user, providerId, realm);
FederatedIdentityModel link = session.users().getFederatedIdentity(realm, user, providerId);
if (link != null) {
// Removing last social provider is not possible if you don't have other possibility to authenticate
if (session.users().getFederatedIdentitiesStream(user, realm).count() > 1 || user.getFederationLink() != null || isPasswordSet(session, realm, user)) {
if (session.users().getFederatedIdentitiesStream(realm, user).count() > 1 || user.getFederationLink() != null || isPasswordSet(session, realm, user)) {
session.users().removeFederatedIdentity(realm, user, providerId);
logger.debugv("Social provider {0} removed successfully from user {1}", providerId, user.getUsername());
@ -833,7 +833,7 @@ public class AccountFormService extends AbstractSecuredLocalService {
Map<String, String> filters = new HashMap<>();
filters.put(PermissionTicket.RESOURCE, resource.getId());
filters.put(PermissionTicket.REQUESTER, session.users().getUserByUsername(requester, realm).getId());
filters.put(PermissionTicket.REQUESTER, session.users().getUserByUsername(realm, requester).getId());
if (isRevoke) {
filters.put(PermissionTicket.GRANTED, Boolean.TRUE.toString());
@ -909,14 +909,14 @@ public class AccountFormService extends AbstractSecuredLocalService {
}
for (String id : userIds) {
UserModel user = session.users().getUserById(id, realm);
UserModel user = session.users().getUserById(realm, id);
if (user == null) {
user = session.users().getUserByUsername(id, realm);
user = session.users().getUserByUsername(realm, id);
}
if (user == null) {
user = session.users().getUserByEmail(id, realm);
user = session.users().getUserByEmail(realm, id);
}
if (user == null) {

View file

@ -119,7 +119,7 @@ public class LinkedAccountsResource {
public SortedSet<LinkedAccountRepresentation> getLinkedAccounts(KeycloakSession session, RealmModel realm, UserModel user) {
Set<String> socialIds = findSocialIds();
return realm.getIdentityProvidersStream().filter(IdentityProviderModel::isEnabled)
.map(provider -> toLinkedAccountRepresentation(provider, socialIds, session.users().getFederatedIdentitiesStream(user, realm)))
.map(provider -> toLinkedAccountRepresentation(provider, socialIds, session.users().getFederatedIdentitiesStream(realm, user)))
.collect(Collectors.toCollection(TreeSet::new));
}
@ -209,13 +209,13 @@ public class LinkedAccountsResource {
return ErrorResponse.error(errorMessage, Response.Status.BAD_REQUEST);
}
FederatedIdentityModel link = session.users().getFederatedIdentity(user, providerId, realm);
FederatedIdentityModel link = session.users().getFederatedIdentity(realm, user, providerId);
if (link == null) {
return ErrorResponse.error(Messages.FEDERATED_IDENTITY_NOT_ACTIVE, Response.Status.BAD_REQUEST);
}
// Removing last social provider is not possible if you don't have other possibility to authenticate
if (!(session.users().getFederatedIdentitiesStream(user, realm).count() > 1 || user.getFederationLink() != null || isPasswordSet())) {
if (!(session.users().getFederatedIdentitiesStream(realm, user).count() > 1 || user.getFederationLink() != null || isPasswordSet())) {
return ErrorResponse.error(Messages.FEDERATED_IDENTITY_REMOVING_LAST_PROVIDER, Response.Status.BAD_REQUEST);
}

View file

@ -149,7 +149,7 @@ public abstract class AbstractResourceService {
}
Permission(String userId, AuthorizationProvider provider) {
UserModel user = provider.getKeycloakSession().users().getUserById(userId, provider.getRealm());
UserModel user = provider.getKeycloakSession().users().getUserById(provider.getRealm(), userId);
setUsername(user.getUsername());
setFirstName(user.getFirstName());

View file

@ -220,10 +220,10 @@ public class ResourceService extends AbstractResourceService {
private UserModel getUser(String requester) {
UserProvider users = provider.getKeycloakSession().users();
UserModel user = users.getUserByUsername(requester, provider.getRealm());
UserModel user = users.getUserByUsername(provider.getRealm(), requester);
if (user == null) {
user = users.getUserByEmail(requester, provider.getRealm());
user = users.getUserByEmail(provider.getRealm(), requester);
}
if (user == null) {

View file

@ -79,7 +79,7 @@ public class AttackDetectionResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public Map<String, Object> bruteForceUserStatus(@PathParam("userId") String userId) {
UserModel user = session.users().getUserById(userId, realm);
UserModel user = session.users().getUserById(realm, userId);
if (user == null) {
auth.users().requireView();
} else {
@ -123,7 +123,7 @@ public class AttackDetectionResource {
@Path("brute-force/users/{userId}")
@DELETE
public void clearBruteForceForUser(@PathParam("userId") String userId) {
UserModel user = session.users().getUserById(userId, realm);
UserModel user = session.users().getUserById(realm, userId);
if (user == null) {
auth.users().requireManage();
} else {

View file

@ -160,7 +160,7 @@ public class ClientScopeEvaluateResource {
throw new NotFoundException("No userId provided");
}
UserModel user = session.users().getUserById(userId, realm);
UserModel user = session.users().getUserById(realm, userId);
if (user == null) {
throw new NotFoundException("No user found");
}

View file

@ -215,7 +215,7 @@ public class IdentityProviderResource {
private static void updateUsersAfterProviderAliasChange(Stream<UserModel> users, String oldProviderId, String newProviderId, RealmModel realm, KeycloakSession session) {
users.forEach(user -> {
FederatedIdentityModel federatedIdentity = session.users().getFederatedIdentity(user, oldProviderId, realm);
FederatedIdentityModel federatedIdentity = session.users().getFederatedIdentity(realm, user, oldProviderId);
if (federatedIdentity != null) {
// Remove old link first
session.users().removeFederatedIdentity(realm, user, oldProviderId);

View file

@ -380,7 +380,7 @@ public class UserResource {
private Stream<FederatedIdentityRepresentation> getFederatedIdentities(UserModel user) {
Set<String> idps = realm.getIdentityProvidersStream().map(IdentityProviderModel::getAlias).collect(Collectors.toSet());
return session.users().getFederatedIdentitiesStream(user, realm)
return session.users().getFederatedIdentitiesStream(realm, user)
.filter(identity -> idps.contains(identity.getIdentityProvider()))
.map(ModelToRepresentation::toRepresentation);
}
@ -397,7 +397,7 @@ public class UserResource {
@NoCache
public Response addFederatedIdentity(final @PathParam("provider") String provider, FederatedIdentityRepresentation rep) {
auth.users().requireManage(user);
if (session.users().getFederatedIdentity(user, provider, realm) != null) {
if (session.users().getFederatedIdentity(realm, user, provider) != null) {
return ErrorResponse.exists("User is already linked with provider");
}

View file

@ -133,12 +133,12 @@ public class UsersResource {
}
// Double-check duplicated username and email here due to federation
if (session.users().getUserByUsername(username, realm) != null) {
if (session.users().getUserByUsername(realm, username) != null) {
return ErrorResponse.exists("User exists with same username");
}
if (rep.getEmail() != null && !realm.isDuplicateEmailsAllowed()) {
try {
if(session.users().getUserByEmail(rep.getEmail(), realm) != null) {
if(session.users().getUserByEmail(realm, rep.getEmail()) != null) {
return ErrorResponse.exists("User exists with same email");
}
} catch (ModelDuplicateException e) {
@ -192,7 +192,7 @@ public class UsersResource {
*/
@Path("{id}")
public UserResource user(final @PathParam("id") String id) {
UserModel user = session.users().getUserById(id, realm);
UserModel user = session.users().getUserById(realm, id);
if (user == null) {
// we do this to make sure somebody can't phish ids
if (auth.users().canQuery()) throw new NotFoundException("User not found");
@ -251,7 +251,7 @@ public class UsersResource {
if (search != null) {
if (search.startsWith(SEARCH_ID_PARAMETER)) {
UserModel userModel =
session.users().getUserById(search.substring(SEARCH_ID_PARAMETER.length()).trim(), realm);
session.users().getUserById(realm, search.substring(SEARCH_ID_PARAMETER.length()).trim());
if (userModel != null) {
userModels = Stream.of(userModel);
}
@ -341,12 +341,12 @@ public class UsersResource {
if (search != null) {
if (search.startsWith(SEARCH_ID_PARAMETER)) {
UserModel userModel = session.users().getUserById(search.substring(SEARCH_ID_PARAMETER.length()).trim(), realm);
UserModel userModel = session.users().getUserById(realm, search.substring(SEARCH_ID_PARAMETER.length()).trim());
return userModel != null && userPermissionEvaluator.canView(userModel) ? 1 : 0;
} else if (userPermissionEvaluator.canView()) {
return session.users().getUsersCount(search.trim(), realm);
return session.users().getUsersCount(realm, search.trim());
} else {
return session.users().getUsersCount(search.trim(), realm, auth.groups().getGroupsWithViewPermission());
return session.users().getUsersCount(realm, search.trim(), auth.groups().getGroupsWithViewPermission());
}
} else if (last != null || first != null || email != null || username != null || emailVerified != null) {
Map<String, String> parameters = new HashMap<>();
@ -366,9 +366,9 @@ public class UsersResource {
parameters.put(UserModel.EMAIL_VERIFIED, emailVerified.toString());
}
if (userPermissionEvaluator.canView()) {
return session.users().getUsersCount(parameters, realm);
return session.users().getUsersCount(realm, parameters);
} else {
return session.users().getUsersCount(parameters, realm, auth.groups().getGroupsWithViewPermission());
return session.users().getUsersCount(realm, parameters, auth.groups().getGroupsWithViewPermission());
}
} else if (userPermissionEvaluator.canView()) {
return session.users().getUsersCount(realm);
@ -388,7 +388,7 @@ public class UsersResource {
}
}
Stream<UserModel> userModels = session.users().searchForUserStream(attributes, realm, firstResult, maxResults);
Stream<UserModel> userModels = session.users().searchForUserStream(realm, attributes, firstResult, maxResults);
return toRepresentation(realm, usersEvaluator, briefRepresentation, userModels);
}

View file

@ -122,7 +122,7 @@ public class TwitterIdentityProvider extends AbstractIdentityProvider<OAuth2Iden
}
protected Response exchangeStoredToken(UriInfo uriInfo, ClientModel authorizedClient, UserSessionModel tokenUserSession, UserModel tokenSubject) {
FederatedIdentityModel model = session.users().getFederatedIdentity(tokenSubject, getConfig().getAlias(), authorizedClient.getRealm());
FederatedIdentityModel model = session.users().getFederatedIdentity(authorizedClient.getRealm(), tokenSubject, getConfig().getAlias());
if (model == null || model.getToken() == null) {
return exchangeNotLinked(uriInfo, authorizedClient, tokenUserSession, tokenSubject);
}

View file

@ -58,6 +58,7 @@ import java.util.function.Predicate;
import java.util.stream.Stream;
import static org.keycloak.models.utils.KeycloakModelUtils.runJobInTransaction;
import static org.keycloak.utils.StreamsUtil.paginatedStream;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -136,7 +137,7 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
runJobInTransaction(session.getKeycloakSessionFactory(), session -> {
RealmModel realmModel = session.realms().getRealm(realm.getId());
if (realmModel == null) return;
UserModel deletedUser = session.userLocalStorage().getUserById(userId, realmModel);
UserModel deletedUser = session.userLocalStorage().getUserById(realmModel, userId);
if (deletedUser != null) {
try {
new UserManager(session).removeUser(realmModel, deletedUser, session.userLocalStorage());
@ -161,10 +162,8 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
Stream<UserModel> query(Object provider);
}
protected Stream<UserModel> query(PaginatedQuery pagedQuery, RealmModel realm, int firstResult, int maxResults) {
if (maxResults == 0) return Stream.empty();
if (firstResult < 0) firstResult = 0;
if (maxResults < 0) maxResults = Integer.MAX_VALUE - 1;
protected Stream<UserModel> query(PaginatedQuery pagedQuery, RealmModel realm, Integer firstResult, Integer maxResults) {
if (maxResults != null && maxResults == 0) return Stream.empty();
Stream<Object> providersStream = Stream.concat(Stream.of((Object) localStorage()), getEnabledStorageProviders(realm, UserQueryProvider.class));
@ -173,9 +172,7 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
providersStream = Stream.concat(providersStream, Stream.of(federatedStorageProvider));
}
return providersStream.flatMap(pagedQuery::query)
.skip(firstResult)
.limit(maxResults);
return paginatedStream(providersStream.flatMap(pagedQuery::query), firstResult, maxResults);
}
/**
@ -232,33 +229,33 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
{@link UserLookupProvider} methods implementations start here */
@Override
public UserModel getUserById(String id, RealmModel realm) {
public UserModel getUserById(RealmModel realm, String id) {
StorageId storageId = new StorageId(id);
if (storageId.getProviderId() == null) {
UserModel user = localStorage().getUserById(id, realm);
UserModel user = localStorage().getUserById(realm, id);
return importValidation(realm, user);
}
UserLookupProvider provider = getStorageProviderInstance(realm, storageId.getProviderId(), UserLookupProvider.class);
if (provider == null) return null;
return provider.getUserById(id, realm);
return provider.getUserById(realm, id);
}
@Override
public UserModel getUserByUsername(String username, RealmModel realm) {
UserModel user = localStorage().getUserByUsername(username, realm);
public UserModel getUserByUsername(RealmModel realm, String username) {
UserModel user = localStorage().getUserByUsername(realm, username);
if (user != null) {
return importValidation(realm, user);
}
return mapEnabledStorageProvidersWithTimeout(realm, UserLookupProvider.class,
provider -> provider.getUserByUsername(username, realm)).findFirst().orElse(null);
provider -> provider.getUserByUsername(realm, username)).findFirst().orElse(null);
}
@Override
public UserModel getUserByEmail(String email, RealmModel realm) {
UserModel user = localStorage().getUserByEmail(email, realm);
public UserModel getUserByEmail(RealmModel realm, String email) {
UserModel user = localStorage().getUserByEmail(realm, email);
if (user != null) {
user = importValidation(realm, user);
// Case when email was changed directly in the userStorage and doesn't correspond anymore to the email from local DB
@ -268,17 +265,12 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
}
return mapEnabledStorageProvidersWithTimeout(realm, UserLookupProvider.class,
provider -> provider.getUserByEmail(email, realm)).findFirst().orElse(null);
provider -> provider.getUserByEmail(realm, email)).findFirst().orElse(null);
}
/** {@link UserLookupProvider} methods implementations end here
{@link UserQueryProvider} methods implementation start here */
@Override
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group) {
return getGroupMembersStream(realm, group, -1, -1);
}
@Override
public Stream<UserModel> getGroupMembersStream(final RealmModel realm, final GroupModel group, Integer firstResult, Integer maxResults) {
Stream<UserModel> results = query((provider) -> {
@ -287,7 +279,7 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
} else if (provider instanceof UserFederatedStorageProvider) {
return ((UserFederatedStorageProvider)provider).getMembershipStream(realm, group, -1, -1).
map(id -> getUserById(id, realm));
map(id -> getUserById(realm, id));
}
return Stream.empty();
}, realm, firstResult, maxResults);
@ -295,11 +287,6 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
return importValidation(realm, results);
}
@Override
public Stream<UserModel> getRoleMembersStream(RealmModel realm, RoleModel role) {
return getRoleMembersStream(realm, role, -1, -1);
}
@Override
public Stream<UserModel> getRoleMembersStream(final RealmModel realm, final RoleModel role, Integer firstResult, Integer maxResults) {
Stream<UserModel> results = query((provider) -> {
@ -314,19 +301,14 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
@Override
public Stream<UserModel> getUsersStream(RealmModel realm) {
return getUsersStream(realm, false);
return getUsersStream(realm, null, null, false);
}
@Override
public Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults) {
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
return getUsersStream(realm, firstResult, maxResults, false);
}
@Override
public Stream<UserModel> getUsersStream(RealmModel realm, boolean includeServiceAccounts) {
return getUsersStream(realm, 0, Integer.MAX_VALUE - 1, includeServiceAccounts);
}
@Override
public Stream<UserModel> getUsersStream(final RealmModel realm, Integer firstResult, Integer maxResults, final boolean includeServiceAccounts) {
Stream<UserModel> results = query((provider) -> {
@ -362,35 +344,30 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
}
@Override // TODO: missing storageProviders count?
public int getUsersCount(String search, RealmModel realm) {
return localStorage().getUsersCount(search, realm);
public int getUsersCount(RealmModel realm, String search) {
return localStorage().getUsersCount(realm, search);
}
@Override // TODO: missing storageProviders count?
public int getUsersCount(String search, RealmModel realm, Set<String> groupIds) {
return localStorage().getUsersCount(search, realm, groupIds);
public int getUsersCount(RealmModel realm, String search, Set<String> groupIds) {
return localStorage().getUsersCount(realm, search, groupIds);
}
@Override // TODO: missing storageProviders count?
public int getUsersCount(Map<String, String> params, RealmModel realm) {
return localStorage().getUsersCount(params, realm);
public int getUsersCount(RealmModel realm, Map<String, String> params) {
return localStorage().getUsersCount(realm, params);
}
@Override // TODO: missing storageProviders count?
public int getUsersCount(Map<String, String> params, RealmModel realm, Set<String> groupIds) {
return localStorage().getUsersCount(params, realm, groupIds);
public int getUsersCount(RealmModel realm, Map<String, String> params, Set<String> groupIds) {
return localStorage().getUsersCount(realm, params, groupIds);
}
@Override
public Stream<UserModel> searchForUserStream(String search, RealmModel realm) {
return searchForUserStream(search, realm, 0, Integer.MAX_VALUE - 1);
}
@Override
public Stream<UserModel> searchForUserStream(String search, RealmModel realm, Integer firstResult, Integer maxResults) {
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
Stream<UserModel> results = query((provider) -> {
if (provider instanceof UserQueryProvider) {
return ((UserQueryProvider)provider).searchForUserStream(search, realm);
return ((UserQueryProvider)provider).searchForUserStream(realm, search);
}
return Stream.empty();
}, realm, firstResult, maxResults);
@ -398,18 +375,13 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
}
@Override
public Stream<UserModel> searchForUserStream(Map<String, String> attributes, RealmModel realm) {
return searchForUserStream(attributes, realm, 0, Integer.MAX_VALUE - 1);
}
@Override
public Stream<UserModel> searchForUserStream(Map<String, String> attributes, RealmModel realm, Integer firstResult, Integer maxResults) {
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> attributes, Integer firstResult, Integer maxResults) {
Stream<UserModel> results = query((provider) -> {
if (provider instanceof UserQueryProvider) {
if (attributes.containsKey(UserModel.SEARCH)) {
return ((UserQueryProvider)provider).searchForUserStream(attributes.get(UserModel.SEARCH), realm);
return ((UserQueryProvider)provider).searchForUserStream(realm, attributes.get(UserModel.SEARCH));
} else {
return ((UserQueryProvider)provider).searchForUserStream(attributes, realm);
return ((UserQueryProvider)provider).searchForUserStream(realm, attributes);
}
}
return Stream.empty();
@ -419,18 +391,18 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
}
@Override
public Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm) {
public Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
Stream<UserModel> results = query((provider) -> {
if (provider instanceof UserQueryProvider) {
return ((UserQueryProvider)provider).searchForUserByUserAttributeStream(attrName, attrValue, realm);
return ((UserQueryProvider)provider).searchForUserByUserAttributeStream(realm, attrName, attrValue);
} else if (provider instanceof UserFederatedStorageProvider) {
return ((UserFederatedStorageProvider)provider).getUsersByUserAttributeStream(realm, attrName, attrValue)
.map(id -> getUserById(id, realm))
.map(id -> getUserById(realm, id))
.filter(Objects::nonNull);
}
return Stream.empty();
}, realm,0, Integer.MAX_VALUE - 1);
}, realm,null, null);
// removeDuplicates method may cause concurrent issues, it should not be used on parallel streams
results = removeDuplicates(results);
@ -594,14 +566,14 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
}
@Override
public UserModel getUserByFederatedIdentity(FederatedIdentityModel socialLink, RealmModel realm) {
UserModel user = localStorage().getUserByFederatedIdentity(socialLink, realm);
public UserModel getUserByFederatedIdentity(RealmModel realm, FederatedIdentityModel socialLink) {
UserModel user = localStorage().getUserByFederatedIdentity(realm, socialLink);
if (user != null) {
return importValidation(realm, user);
}
if (getFederatedStorage() == null) return null;
String id = getFederatedStorage().getUserByFederatedIdentity(socialLink, realm);
if (id != null) return getUserById(id, realm);
if (id != null) return getUserById(realm, id);
return null;
}
@ -611,20 +583,20 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
}
@Override
public Stream<FederatedIdentityModel> getFederatedIdentitiesStream(UserModel user, RealmModel realm) {
public Stream<FederatedIdentityModel> getFederatedIdentitiesStream(RealmModel realm, UserModel user) {
if (user == null) throw new IllegalStateException("Federated user no longer valid");
Stream<FederatedIdentityModel> stream = StorageId.isLocalStorage(user) ?
localStorage().getFederatedIdentitiesStream(user, realm) : Stream.empty();
localStorage().getFederatedIdentitiesStream(realm, user) : Stream.empty();
if (getFederatedStorage() != null)
stream = Stream.concat(stream, getFederatedStorage().getFederatedIdentitiesStream(user.getId(), realm));
return stream.distinct();
}
@Override
public FederatedIdentityModel getFederatedIdentity(UserModel user, String socialProvider, RealmModel realm) {
public FederatedIdentityModel getFederatedIdentity(RealmModel realm, UserModel user, String socialProvider) {
if (user == null) throw new IllegalStateException("Federated user no longer valid");
if (StorageId.isLocalStorage(user)) {
FederatedIdentityModel model = localStorage().getFederatedIdentity(user, socialProvider, realm);
FederatedIdentityModel model = localStorage().getFederatedIdentity(realm, user, socialProvider);
if (model != null) return model;
}
if (getFederatedStorage() != null) return getFederatedStorage().getFederatedIdentity(user.getId(), socialProvider, realm);

View file

@ -95,7 +95,7 @@ public class LegacyUserProfileProvider implements UserProfileProvider {
builder.addAttributeValidator().forAttribute(UserModel.USERNAME)
.addSingleAttributeValueValidationFunction(Messages.MISSING_USERNAME, StaticValidators.isBlank())
.addSingleAttributeValueValidationFunction(Messages.USERNAME_EXISTS,
(value, o) -> session.users().getUserByUsername(value, realm) == null)
(value, o) -> session.users().getUserByUsername(realm, value) == null)
.build();
}
}

View file

@ -55,7 +55,7 @@ public class StaticValidators {
if (Validation.isBlank(value)) return true;
return !(context.getCurrentProfile() != null
&& !value.equals(context.getCurrentProfile().getAttributes().getFirstAttribute(UserModel.USERNAME))
&& session.users().getUserByUsername(value, session.getContext().getRealm()) != null);
&& session.users().getUserByUsername(session.getContext().getRealm(), value) != null);
};
}
@ -80,7 +80,7 @@ public class StaticValidators {
if (Validation.isBlank(value)) return true;
RealmModel realm = session.getContext().getRealm();
if (!realm.isDuplicateEmailsAllowed()) {
UserModel userByEmail = session.users().getUserByEmail(value, realm);
UserModel userByEmail = session.users().getUserByEmail(realm, value);
return !(realm.isRegistrationEmailAsUsername() && userByEmail != null && context.getCurrentProfile() != null && !userByEmail.getId().equals(context.getCurrentProfile().getId()));
}
return true;
@ -92,7 +92,7 @@ public class StaticValidators {
if (Validation.isBlank(value)) return true;
RealmModel realm = session.getContext().getRealm();
if (!realm.isDuplicateEmailsAllowed()) {
UserModel userByEmail = session.users().getUserByEmail(value, realm);
UserModel userByEmail = session.users().getUserByEmail(realm, value);
// check for duplicated email
return !(userByEmail != null && (context.getCurrentProfile() == null || !userByEmail.getId().equals(context.getCurrentProfile().getId())));
}
@ -104,7 +104,7 @@ public class StaticValidators {
return (value, context) ->
!(value != null
&& !session.getContext().getRealm().isDuplicateEmailsAllowed()
&& session.users().getUserByEmail(value, session.getContext().getRealm()) != null);
&& session.users().getUserByEmail(session.getContext().getRealm(), value) != null);
}
public static BiFunction<List<String>, UserProfileContext, Boolean> isAttributeUnchanged(String attributeName) {

View file

@ -49,7 +49,7 @@ public class ExpectedParamAuthenticator implements Authenticator {
if (loggedUser == null) {
logger.info("Successfully authenticated, but don't set any authenticated user");
} else {
UserModel user = context.getSession().users().getUserByUsername(loggedUser, context.getRealm());
UserModel user = context.getSession().users().getUserByUsername(context.getRealm(), loggedUser);
logger.info("Successfully authenticated as user " + user.getUsername());
context.setUser(user);
}

View file

@ -342,7 +342,7 @@ public class BackwardsCompatibilityUserStorage implements UserLookupProvider, Us
@Override
public List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults) {
UserModel user = getUserByUsername(search, realm);
UserModel user = getUserByUsername(realm, search);
return user == null ? Collections.emptyList() : Arrays.asList(user);
}

View file

@ -20,12 +20,10 @@ package org.keycloak.testsuite.federation;
import org.keycloak.component.ComponentModel;
import org.keycloak.credential.CredentialInput;
import org.keycloak.credential.CredentialInputValidator;
import org.keycloak.credential.CredentialModel;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.credential.OTPCredentialModel;
import org.keycloak.models.credential.PasswordCredentialModel;
@ -34,7 +32,6 @@ import org.keycloak.storage.user.UserLookupProvider;
import org.keycloak.storage.user.UserRegistrationProvider;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@ -44,7 +41,7 @@ import java.util.Set;
* @version $Revision: 1 $
*/
public class DummyUserFederationProvider implements UserStorageProvider,
UserLookupProvider,
UserLookupProvider.Streams,
UserRegistrationProvider,
CredentialInputValidator {
@ -83,17 +80,17 @@ public class DummyUserFederationProvider implements UserStorageProvider,
}
@Override
public UserModel getUserById(String id, RealmModel realm) {
public UserModel getUserById(RealmModel realm, String id) {
return null;
}
@Override
public UserModel getUserByUsername(String username, RealmModel realm) {
public UserModel getUserByUsername(RealmModel realm, String username) {
return users.get(username);
}
@Override
public UserModel getUserByEmail(String email, RealmModel realm) {
public UserModel getUserByEmail(RealmModel realm, String email) {
return null;
}

View file

@ -41,7 +41,7 @@ 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.Streams,
public class FailableHardcodedStorageProvider implements UserStorageProvider, UserLookupProvider.Streams, UserQueryProvider.Streams,
ImportedUserValidation, CredentialInputUpdater.Streams, CredentialInputValidator {
public static String username = "billb";
@ -172,16 +172,16 @@ public class FailableHardcodedStorageProvider implements UserStorageProvider, Us
}
@Override
public UserModel getUserById(String id, RealmModel realm) {
public UserModel getUserById(RealmModel realm, String id) {
checkForceFail();
throw new RuntimeException("THIS IMPORTS SHOULD NEVER BE CALLED");
}
@Override
public UserModel getUserByUsername(String uname, RealmModel realm) {
public UserModel getUserByUsername(RealmModel realm, String uname) {
checkForceFail();
if (!username.equals(uname)) return null;
UserModel local = session.userLocalStorage().getUserByUsername(uname, realm);
UserModel local = session.userLocalStorage().getUserByUsername(realm, uname);
if (local != null && !model.getId().equals(local.getFederationLink())) {
throw new RuntimeException("local storage has wrong federation link");
}
@ -201,7 +201,7 @@ public class FailableHardcodedStorageProvider implements UserStorageProvider, Us
}
@Override
public UserModel getUserByEmail(String email, RealmModel realm) {
public UserModel getUserByEmail(RealmModel realm, String email) {
checkForceFail();
return null;
}
@ -223,46 +223,46 @@ public class FailableHardcodedStorageProvider implements UserStorageProvider, Us
@Override
public Stream<UserModel> getUsersStream(RealmModel realm) {
checkForceFail();
UserModel model = getUserByUsername(username, realm);
UserModel model = getUserByUsername(realm, username);
return model != null ? Stream.of(model) : Stream.empty();
}
@Override
public Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults) {
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
checkForceFail();
UserModel model = getUserByUsername(username, realm);
UserModel model = getUserByUsername(realm, username);
return model != null ? Stream.of(model) : Stream.empty();
}
@Override
public Stream<UserModel> searchForUserStream(String search, RealmModel realm) {
public Stream<UserModel> searchForUserStream(RealmModel realm, String search) {
checkForceFail();
if (!search.equals(username)) return Stream.empty();
UserModel model = getUserByUsername(username, realm);
UserModel model = getUserByUsername(realm, username);
return model != null ? Stream.of(model) : Stream.empty();
}
@Override
public Stream<UserModel> searchForUserStream(String search, RealmModel realm, Integer firstResult, Integer maxResults) {
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
checkForceFail();
if (!search.equals(username)) return Stream.empty();
UserModel model = getUserByUsername(username, realm);
UserModel model = getUserByUsername(realm, username);
return model != null ? Stream.of(model) : Stream.empty();
}
@Override
public Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm) {
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> params) {
checkForceFail();
if (!username.equals(params.get("username")))return Stream.empty();
UserModel model = getUserByUsername(username, realm);
UserModel model = getUserByUsername(realm, username);
return model != null ? Stream.of(model) : Stream.empty();
}
@Override
public Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm, Integer firstResult, Integer maxResults) {
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> params, Integer firstResult, Integer maxResults) {
checkForceFail();
if (!username.equals(params.get("username")))return Stream.empty();
UserModel model = getUserByUsername(username, realm);
UserModel model = getUserByUsername(realm, username);
return model != null ? Stream.of(model) : Stream.empty();
}
@ -279,7 +279,7 @@ public class FailableHardcodedStorageProvider implements UserStorageProvider, Us
}
@Override
public Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm) {
public Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
checkForceFail();
return Stream.empty();
}

View file

@ -45,7 +45,7 @@ import java.util.stream.Collectors;
*/
public class PassThroughFederatedUserStorageProvider implements
UserStorageProvider,
UserLookupProvider,
UserLookupProvider.Streams,
CredentialInputValidator,
CredentialInputUpdater
{
@ -130,20 +130,20 @@ public class PassThroughFederatedUserStorageProvider implements
}
@Override
public UserModel getUserById(String id, RealmModel realm) {
public UserModel getUserById(RealmModel realm, String id) {
if (!StorageId.externalId(id).equals(PASSTHROUGH_USERNAME)) return null;
return getUserModel(realm);
}
@Override
public UserModel getUserByUsername(String username, RealmModel realm) {
public UserModel getUserByUsername(RealmModel realm, String username) {
if (!PASSTHROUGH_USERNAME.equals(username)) return null;
return getUserModel(realm);
}
@Override
public UserModel getUserByEmail(String email, RealmModel realm) {
public UserModel getUserByEmail(RealmModel realm, String email) {
Optional<StorageId> result = session.userFederatedStorage()
.getUsersByUserAttributeStream(realm, AbstractUserAdapterFederatedStorage.EMAIL_ATTRIBUTE, email)
.map(StorageId::new)

View file

@ -48,12 +48,13 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;
import org.jboss.logging.Logger;
import static org.keycloak.storage.UserStorageProviderModel.IMPORT_ENABLED;
import static org.keycloak.utils.StreamsUtil.paginatedStream;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class UserMapStorage implements UserLookupProvider, UserStorageProvider, UserRegistrationProvider, CredentialInputUpdater.Streams,
public class UserMapStorage implements UserLookupProvider.Streams, UserStorageProvider, UserRegistrationProvider, CredentialInputUpdater.Streams,
CredentialInputValidator, UserGroupMembershipFederatedStorage.Streams, UserQueryProvider.Streams, ImportedUserValidation {
private static final Logger log = Logger.getLogger(UserMapStorage.class);
@ -91,7 +92,7 @@ public class UserMapStorage implements UserLookupProvider, UserStorageProvider,
}
@Override
public UserModel getUserById(String id, RealmModel realm) {
public UserModel getUserById(RealmModel realm, String id) {
StorageId storageId = new StorageId(id);
final String username = storageId.getExternalId();
if (!userPasswords.containsKey(translateUserName(username))) {
@ -199,7 +200,7 @@ public class UserMapStorage implements UserLookupProvider, UserStorageProvider,
}
@Override
public UserModel getUserByUsername(String username, RealmModel realm) {
public UserModel getUserByUsername(RealmModel realm, String username) {
if (!userPasswords.containsKey(translateUserName(username))) {
return null;
}
@ -208,7 +209,7 @@ public class UserMapStorage implements UserLookupProvider, UserStorageProvider,
}
@Override
public UserModel getUserByEmail(String email, RealmModel realm) {
public UserModel getUserByEmail(RealmModel realm, String email) {
return null;
}
@ -296,17 +297,14 @@ public class UserMapStorage implements UserLookupProvider, UserStorageProvider,
}
@Override
public Stream<UserModel> getUsersStream(RealmModel realm, int firstResult, int maxResults) {
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
Stream<String> userStream = userPasswords.keySet().stream().sorted();
if (firstResult > 0)
userStream = userStream.skip(firstResult);
if (maxResults >= 0)
userStream = userStream.limit(maxResults);
return userStream.map(userName -> createUser(realm, userName));
return paginatedStream(userStream, firstResult, maxResults).map(userName -> createUser(realm, userName));
}
@Override
public Stream<UserModel> searchForUserStream(String search, RealmModel realm) {
public Stream<UserModel> searchForUserStream(RealmModel realm, String search) {
String tSearch = translateUserName(search);
return userPasswords.keySet().stream()
.sorted()
@ -315,25 +313,17 @@ public class UserMapStorage implements UserLookupProvider, UserStorageProvider,
}
@Override
public Stream<UserModel> searchForUserStream(String search, RealmModel realm, Integer firstResult, Integer maxResults) {
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
String tSearch = translateUserName(search);
Stream<String> userStream = userPasswords.keySet().stream()
.sorted()
.filter(userName -> translateUserName(userName).contains(search));
if (firstResult != null && firstResult > 0)
userStream = userStream.skip(firstResult);
if (maxResults != null && maxResults >= 0)
userStream = userStream.limit(maxResults);
return userStream.map(userName -> createUser(realm, userName));
return paginatedStream(userStream, firstResult, maxResults).map(userName -> createUser(realm, userName));
}
@Override
public Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm) {
return searchForUserStream(params, realm, 0, Integer.MAX_VALUE - 1);
}
@Override
public Stream<UserModel> searchForUserStream(Map<String, String> params, RealmModel realm, Integer firstResult, Integer maxResults) {
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> params, Integer firstResult, Integer maxResults) {
Stream<String> userStream = userPasswords.keySet().stream()
.sorted();
@ -356,28 +346,19 @@ public class UserMapStorage implements UserLookupProvider, UserStorageProvider,
}
}
if (firstResult != null && firstResult > 0)
userStream = userStream.skip(firstResult);
if (maxResults != null && maxResults >= 0)
userStream = userStream.limit(maxResults);
return userStream.map(userName -> createUser(realm, userName));
return paginatedStream(userStream, firstResult, maxResults).map(userName -> createUser(realm, userName));
}
@Override
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group, Integer firstResult, Integer maxResults) {
return getMembershipStream(realm, group, firstResult, maxResults)
return getMembershipStream(realm, group, firstResult == null ? -1 : firstResult, maxResults == null ? -1 : maxResults)
.map(userName -> createUser(realm, userName));
}
@Override
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group) {
return getGroupMembersStream(realm, group, 0, Integer.MAX_VALUE - 1);
}
@Override
public Stream<UserModel> searchForUserByUserAttributeStream(String attrName, String attrValue, RealmModel realm) {
public Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
if (isImportEnabled()) {
return session.userLocalStorage().searchForUserByUserAttributeStream(attrName, attrValue, realm);
return session.userLocalStorage().searchForUserByUserAttributeStream(realm, attrName, attrValue);
} else {
return session.userFederatedStorage().getUsersByUserAttributeStream(realm, attrName, attrValue)
.map(userName -> createUser(realm, userName));
@ -409,15 +390,12 @@ public class UserMapStorage implements UserLookupProvider, UserStorageProvider,
@Override
public Stream<String> getMembershipStream(RealmModel realm, GroupModel group, int firstResult, int max) {
Stream<String> userStream = userGroups.entrySet().stream()
Stream<String> userStream = paginatedStream(userGroups.entrySet().stream(), firstResult, max)
.filter(me -> me.getValue().contains(group.getId()))
.map(Map.Entry::getKey)
.filter(realmUser -> realmUser.startsWith(realm.getId()))
.map(realmUser -> realmUser.substring(realmUser.indexOf("/") + 1));
if (firstResult > 0)
userStream = userStream.skip(firstResult);
if (max >= 0)
userStream = userStream.limit(max);
return userStream;
}

View file

@ -40,12 +40,15 @@ import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.function.Predicate;
import java.util.stream.Stream;
import static org.keycloak.utils.StreamsUtil.paginatedStream;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
*/
public class UserPropertyFileStorage implements UserLookupProvider, UserStorageProvider, UserQueryProvider, CredentialInputValidator {
public class UserPropertyFileStorage implements UserLookupProvider.Streams, UserStorageProvider, UserQueryProvider.Streams, CredentialInputValidator {
protected Properties userPasswords;
protected ComponentModel model;
@ -61,7 +64,7 @@ public class UserPropertyFileStorage implements UserLookupProvider, UserStorageP
@Override
public UserModel getUserById(String id, RealmModel realm) {
public UserModel getUserById(RealmModel realm, String id) {
StorageId storageId = new StorageId(id);
final String username = storageId.getExternalId();
if (!userPasswords.containsKey(username)) return null;
@ -92,14 +95,14 @@ public class UserPropertyFileStorage implements UserLookupProvider, UserStorageP
}
}
public UserModel getUserByUsername(String username, RealmModel realm) {
public UserModel getUserByUsername(RealmModel realm, String username) {
if (!userPasswords.containsKey(username)) return null;
return createUser(realm, username);
}
@Override
public UserModel getUserByEmail(String email, RealmModel realm) {
public UserModel getUserByEmail(RealmModel realm, String email) {
return null;
}
@ -145,67 +148,47 @@ public class UserPropertyFileStorage implements UserLookupProvider, UserStorageP
}
@Override
public List<UserModel> getUsers(RealmModel realm) {
List<UserModel> users = new LinkedList<>();
for (Object username : userPasswords.keySet()) {
users.add(createUser(realm, (String)username));
}
return users;
public Stream<UserModel> getUsersStream(RealmModel realm) {
return userPasswords.keySet().stream()
.map(username -> createUser(realm, (String) username));
}
@Override
public List<UserModel> searchForUser(Map<String, String> attributes, RealmModel realm) {
return searchForUser(attributes, realm, 0, Integer.MAX_VALUE - 1);
public Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
if (maxResults != null && maxResults == 0) return Stream.empty();
return paginatedStream(userPasswords.keySet().stream(), firstResult, maxResults)
.map(username -> createUser(realm, (String) username));
}
@Override
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;
public Stream<UserModel> searchForUserStream(RealmModel realm, String search, Integer firstResult, Integer maxResults) {
return searchForUser(realm, search, firstResult, maxResults, username -> username.contains(search));
}
@Override
public List<UserModel> searchForUser(String search, RealmModel realm, int firstResult, int maxResults) {
return searchForUser(search, realm, firstResult, maxResults, username -> username.contains(search));
}
@Override
public List<UserModel> searchForUser(Map<String, String> attributes, RealmModel realm, int firstResult, int maxResults) {
public Stream<UserModel> searchForUserStream(RealmModel realm, Map<String, String> attributes, Integer firstResult, Integer maxResults) {
String search = Optional.ofNullable(attributes.get(UserModel.USERNAME))
.orElseGet(()-> attributes.get(UserModel.SEARCH));
if (search == null) return Collections.EMPTY_LIST;
if (search == null) return Stream.empty();
Predicate<String> p = Boolean.valueOf(attributes.getOrDefault(UserModel.EXACT, Boolean.FALSE.toString()))
? username -> username.equals(search)
: username -> username.contains(search);
return searchForUser(search, realm, firstResult, maxResults, p);
return searchForUser(realm, search, firstResult, maxResults, p);
}
@Override
public List<UserModel> getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults) {
return Collections.EMPTY_LIST;
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group, Integer firstResult, Integer maxResults) {
return Stream.empty();
}
@Override
public List<UserModel> getGroupMembers(RealmModel realm, GroupModel group) {
return Collections.EMPTY_LIST;
public Stream<UserModel> getGroupMembersStream(RealmModel realm, GroupModel group) {
return Stream.empty();
}
@Override
public List<UserModel> searchForUser(String search, RealmModel realm) {
return searchForUser(search, realm, 0, Integer.MAX_VALUE - 1);
}
@Override
public List<UserModel> searchForUserByUserAttribute(String attrName, String attrValue, RealmModel realm) {
return Collections.EMPTY_LIST;
public Stream<UserModel> searchForUserByUserAttributeStream(RealmModel realm, String attrName, String attrValue) {
return Stream.empty();
}
@Override
@ -213,20 +196,11 @@ public class UserPropertyFileStorage implements UserLookupProvider, UserStorageP
}
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;
private Stream<UserModel> searchForUser(RealmModel realm, String search, Integer firstResult, Integer maxResults, Predicate<String> matcher) {
if (maxResults != null && maxResults == 0) return Stream.empty();
return paginatedStream(userPasswords.keySet().stream(), firstResult, maxResults)
.map(String.class::cast)
.filter(matcher)
.map(username -> createUser(realm, username));
}
}

View file

@ -90,7 +90,7 @@ public class SyncDummyUserFederationProviderFactory extends DummyUserFederationP
// KEYCLOAK-2412 : Just remove and add some users for testing purposes
for (int i = 0; i < 10; i++) {
String username = "dummyuser-" + i;
UserModel user = session.userLocalStorage().getUserByUsername(username, realm);
UserModel user = session.userLocalStorage().getUserByUsername(realm, username);
if (user != null) {
session.userLocalStorage().removeUser(realm, user);

View file

@ -592,7 +592,7 @@ public class TestingResourceProvider implements RealmResourceProvider {
RealmModel realm = session.realms().getRealm(realmName);
if (realm == null) return false;
UserProvider userProvider = session.getProvider(UserProvider.class);
UserModel user = userProvider.getUserByUsername(userName, realm);
UserModel user = userProvider.getUserByUsername(realm, userName);
return session.userCredentialManager().isValid(realm, user, UserCredentialModel.password(password));
}
@ -604,7 +604,7 @@ public class TestingResourceProvider implements RealmResourceProvider {
@QueryParam("userId") String userId,
@QueryParam("userName") String userName) {
RealmModel realm = getRealmByName(realmName);
UserModel foundFederatedUser = session.users().getUserByFederatedIdentity(new FederatedIdentityModel(identityProvider, userId, userName), realm);
UserModel foundFederatedUser = session.users().getUserByFederatedIdentity(realm, new FederatedIdentityModel(identityProvider, userId, userName));
if (foundFederatedUser == null) return null;
return ModelToRepresentation.toRepresentation(session, realm, foundFederatedUser);
}
@ -616,7 +616,7 @@ public class TestingResourceProvider implements RealmResourceProvider {
@QueryParam("userName") String userName) {
RealmModel realm = getRealmByName(realmName);
DummyUserFederationProviderFactory factory = (DummyUserFederationProviderFactory) session.getKeycloakSessionFactory().getProviderFactory(UserStorageProvider.class, "dummy");
UserModel user = factory.create(session, null).getUserByUsername(userName, realm);
UserModel user = factory.create(session, null).getUserByUsername(realm, userName);
if (user == null) return null;
return ModelToRepresentation.toRepresentation(session, realm, user);
}

View file

@ -55,7 +55,7 @@ public class RunHelpers {
public FetchOnServer getRunOnServer() {
return (FetchOnServer) session -> {
RealmModel realm = session.getContext().getRealm();
UserModel user = session.users().getUserByUsername(username, realm);
UserModel user = session.users().getUserByUsername(realm, username);
List<CredentialModel> storedCredentialsByType = session.userCredentialManager()
.getStoredCredentialsByTypeStream(realm, user, CredentialRepresentation.PASSWORD)
.collect(Collectors.toList());

View file

@ -481,7 +481,7 @@ public class AccountFormServiceTest extends AbstractTestRealmKeycloakTest {
final String uId = userId; // Needed for run-on-server
testingClient.server("test").run(session -> {
RealmModel realm = session.getContext().getRealm();
UserModel user = session.users().getUserById(uId, realm);
UserModel user = session.users().getUserById(realm, uId);
assertThat(user, Matchers.notNullValue());
List<CredentialModel> storedCredentials = session.userCredentialManager()
.getStoredCredentialsStream(realm, user).collect(Collectors.toList());

View file

@ -65,7 +65,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static org.hamcrest.Matchers.hasItem;
import static org.junit.Assert.assertThat;
@ -331,7 +330,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
// test authorized
{
UserModel user = session.users().getUserByUsername("authorized", realm);
UserModel user = session.users().getUserByUsername(realm, "authorized");
AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, user);
Assert.assertTrue(permissionsForAdmin.users().canManage());
Assert.assertTrue(permissionsForAdmin.roles().canMapRole(realmRole));
@ -340,7 +339,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
}
// test composite role
{
UserModel user = session.users().getUserByUsername("authorizedComposite", realm);
UserModel user = session.users().getUserByUsername(realm, "authorizedComposite");
AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, user);
Assert.assertTrue(permissionsForAdmin.users().canManage());
Assert.assertTrue(permissionsForAdmin.roles().canMapRole(realmRole));
@ -350,7 +349,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
// test unauthorized
{
UserModel user = session.users().getUserByUsername("unauthorized", realm);
UserModel user = session.users().getUserByUsername(realm, "unauthorized");
AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, user);
Assert.assertFalse(permissionsForAdmin.users().canManage());
Assert.assertFalse(permissionsForAdmin.roles().canMapRole(realmRole));
@ -359,7 +358,7 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
}
// test unauthorized mapper
{
UserModel user = session.users().getUserByUsername("unauthorizedMapper", realm);
UserModel user = session.users().getUserByUsername(realm, "unauthorizedMapper");
AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, user);
Assert.assertTrue(permissionsForAdmin.users().canManage());
Assert.assertFalse(permissionsForAdmin.roles().canMapRole(realmRole));
@ -369,12 +368,12 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
}
// test group management
{
UserModel admin = session.users().getUserByUsername("groupManager", realm);
UserModel admin = session.users().getUserByUsername(realm, "groupManager");
AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, admin);
UserModel user = session.users().getUserByUsername("authorized", realm);
UserModel user = session.users().getUserByUsername(realm, "authorized");
Assert.assertFalse(permissionsForAdmin.users().canManage(user));
Assert.assertFalse(permissionsForAdmin.users().canView(user));
UserModel member = session.users().getUserByUsername("groupMember", realm);
UserModel member = session.users().getUserByUsername(realm, "groupMember");
Assert.assertTrue(permissionsForAdmin.users().canManage(member));
Assert.assertTrue(permissionsForAdmin.users().canManageGroupMembership(member));
Assert.assertTrue(permissionsForAdmin.users().canView(member));
@ -385,9 +384,9 @@ public class FineGrainAdminUnitTest extends AbstractKeycloakTest {
}
// test client.mapRoles
{
UserModel admin = session.users().getUserByUsername("clientMapper", realm);
UserModel admin = session.users().getUserByUsername(realm, "clientMapper");
AdminPermissionEvaluator permissionsForAdmin = AdminPermissions.evaluator(session, realm, realm, admin);
UserModel user = session.users().getUserByUsername("authorized", realm);
UserModel user = session.users().getUserByUsername(realm, "authorized");
Assert.assertTrue(permissionsForAdmin.users().canManage(user));
Assert.assertFalse(permissionsForAdmin.roles().canMapRole(realmRole));
Assert.assertTrue(permissionsForAdmin.roles().canMapRole(clientRole));

View file

@ -281,7 +281,7 @@ public class ImpersonationTest extends AbstractKeycloakTest {
final String userId = impersonatedUserId;
final UserSessionNotesHolder notesHolder = testingClient.server("test").fetch(session -> {
final RealmModel realm = session.realms().getRealmByName("test");
final UserModel user = session.users().getUserById(userId, realm);
final UserModel user = session.users().getUserById(realm, userId);
final UserSessionModel userSession = session.sessions().getUserSessionsStream(realm, user).findFirst().get();
return new UserSessionNotesHolder(userSession.getNotes());
}, UserSessionNotesHolder.class);

View file

@ -563,7 +563,7 @@ public class PolicyEvaluationTest extends AbstractAuthzTest {
public static void testCheckUserAttributes(KeycloakSession session) {
RealmModel realm = session.realms().getRealmByName("authz-test");
UserModel jdoe = session.users().getUserByUsername("jdoe", realm);
UserModel jdoe = session.users().getUserByUsername(realm, "jdoe");
jdoe.setAttribute("a1", Arrays.asList("1", "2"));
jdoe.setSingleAttribute("a2", "3");

View file

@ -1,6 +1,5 @@
package org.keycloak.testsuite.authz;
import org.jboss.resteasy.spi.ResteasyUriInfo;
import org.junit.Assert;
import org.junit.Test;
import org.keycloak.admin.client.resource.RealmResource;
@ -16,8 +15,6 @@ import org.keycloak.representations.idm.authorization.*;
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
@AuthServerContainerExclude(AuthServer.REMOTE)
@ -141,7 +138,7 @@ public class UmaRepresentationTest extends AbstractResourceServerTest {
AuthorizationBean authorizationBean = new AuthorizationBean(session, null, session.getContext().getUri());
ClientModel client = session.getContext().getRealm().getClientByClientId("resource-server-test");
UserModel user = session.userStorageManager().getUserByUsername("marta", session.getContext().getRealm());
UserModel user = session.userStorageManager().getUserByUsername(session.getContext().getRealm(), "marta");
ResourceBean resourceBean = authorizationBean.new ResourceBean(
authorization.getStoreFactory().getResourceStore().findByName(
"Resource A", user.getId(), client.getId()

View file

@ -169,9 +169,9 @@ public class AccountLinkTest extends AbstractKeycloakTest {
private static void checkEmptyFederatedIdentities(KeycloakSession session) {
RealmModel realm = session.getContext().getRealm();
UserModel user = session.users().getUserByUsername("child", realm);
assertEquals(0, session.users().getFederatedIdentitiesStream(user, realm).count());
assertNull(session.users().getFederatedIdentity(user, PARENT_IDP, realm));
UserModel user = session.users().getUserByUsername(realm, "child");
assertEquals(0, session.users().getFederatedIdentitiesStream(realm, user).count());
assertNull(session.users().getFederatedIdentity(realm, user, PARENT_IDP));
}
protected void testAccountLink(String childUsername, String childPassword, String childIdp) {

View file

@ -83,7 +83,7 @@ final class BrokerRunOnServerUtil {
RealmModel realm = session.getContext().getRealm();
ClientModel brokerClient = realm.getClientByClientId(Constants.BROKER_SERVICE_CLIENT_ID);
RoleModel readTokenRole = brokerClient.getRole(Constants.READ_TOKEN_ROLE);
UserModel user = session.users().getUserByUsername(username, realm);
UserModel user = session.users().getUserByUsername(realm, username);
user.grantRole(readTokenRole);
};
}
@ -93,7 +93,7 @@ final class BrokerRunOnServerUtil {
RealmModel realm = session.getContext().getRealm();
ClientModel brokerClient = realm.getClientByClientId(Constants.BROKER_SERVICE_CLIENT_ID);
RoleModel readTokenRole = brokerClient.getRole(Constants.READ_TOKEN_ROLE);
UserModel user = session.users().getUserByUsername(username, realm);
UserModel user = session.users().getUserByUsername(realm, username);
user.deleteRoleMapping(readTokenRole);
};
}
@ -134,7 +134,7 @@ final class BrokerRunOnServerUtil {
static RunOnServer assertHardCodedSessionNote() {
return (session) -> {
RealmModel realm = session.realms().getRealmByName("consumer");
UserModel user = session.users().getUserByUsername("testuser", realm);
UserModel user = session.users().getUserByUsername(realm, "testuser");
UserSessionModel sessions = session.sessions().getUserSessionsStream(realm, user).findFirst().get();
assertEquals("sessionvalue", sessions.getNote("user-session-attr"));
};

View file

@ -28,7 +28,6 @@ import org.keycloak.authentication.requiredactions.TermsAndConditions;
import org.keycloak.authorization.model.Policy;
import org.keycloak.authorization.model.ResourceServer;
import org.keycloak.common.Profile;
import org.keycloak.credential.CredentialModel;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.AuthenticationFlowBindings;
import org.keycloak.models.AuthenticationFlowModel;
@ -294,7 +293,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
public void testBrowserContinueRequiredAction() throws Exception {
testingClient.server().run(session -> {
RealmModel realm = session.realms().getRealmByName("test");
UserModel user = session.users().getUserByUsername("wburke", realm);
UserModel user = session.users().getUserByUsername(realm, "wburke");
user.addRequiredAction("dummy");
});
testInstall();
@ -439,7 +438,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
public void testTerms() throws Exception {
testingClient.server().run(session -> {
RealmModel realm = session.realms().getRealmByName("test");
UserModel user = session.users().getUserByUsername("wburke", realm);
UserModel user = session.users().getUserByUsername(realm, "wburke");
user.addRequiredAction(TermsAndConditions.PROVIDER_ID);
});
@ -466,7 +465,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
// expects that updateProfile is a passthrough
testingClient.server().run(session -> {
RealmModel realm = session.realms().getRealmByName("test");
UserModel user = session.users().getUserByUsername("wburke", realm);
UserModel user = session.users().getUserByUsername(realm, "wburke");
user.addRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE);
});
@ -496,7 +495,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
testingClient.server().run(session -> {
RealmModel realm = session.realms().getRealmByName("test");
UserModel user = session.users().getUserByUsername("wburke", realm);
UserModel user = session.users().getUserByUsername(realm, "wburke");
user.removeRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE);
});
}
@ -507,7 +506,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
public void testUpdatePassword() throws Exception {
testingClient.server().run(session -> {
RealmModel realm = session.realms().getRealmByName("test");
UserModel user = session.users().getUserByUsername("wburke", realm);
UserModel user = session.users().getUserByUsername(realm, "wburke");
user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
});
@ -548,7 +547,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
testingClient.server().run(session -> {
RealmModel realm = session.realms().getRealmByName("test");
UserModel user = session.users().getUserByUsername("wburke", realm);
UserModel user = session.users().getUserByUsername(realm, "wburke");
session.userCredentialManager().updateCredential(realm, user, UserCredentialModel.password("password"));
});
}
@ -562,7 +561,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
public void testConfigureTOTP() throws Exception {
testingClient.server().run(session -> {
RealmModel realm = session.realms().getRealmByName("test");
UserModel user = session.users().getUserByUsername("wburke", realm);
UserModel user = session.users().getUserByUsername(realm, "wburke");
user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
});
@ -631,7 +630,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
} finally {
testingClient.server().run(session -> {
RealmModel realm = session.realms().getRealmByName("test");
UserModel user = session.users().getUserByUsername("wburke", realm);
UserModel user = session.users().getUserByUsername(realm, "wburke");
session.userCredentialManager().getStoredCredentialsByTypeStream(realm, user, OTPCredentialModel.TYPE)
.collect(Collectors.toList())
.forEach(model -> session.userCredentialManager().removeStoredCredential(realm, user, model.getId()));
@ -648,7 +647,7 @@ public class KcinitTest extends AbstractTestRealmKeycloakTest {
public void testVerifyEmail() throws Exception {
testingClient.server().run(session -> {
RealmModel realm = session.realms().getRealmByName("test");
UserModel user = session.users().getUserByUsername("test-user@localhost", realm);
UserModel user = session.users().getUserByUsername(realm, "test-user@localhost");
user.addRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL);
});

View file

@ -162,7 +162,7 @@ public class LDAPBinaryAttributesTest extends AbstractLDAPTest {
String joeId = joe.getId();
testingClient.server().run(session -> {
RealmModel test = session.realms().getRealmByName("test");
UserModel userById = session.userLocalStorage().getUserById(joeId, test);
UserModel userById = session.userLocalStorage().getUserById(test, joeId);
assertThat(userById.getAttributes().get(LDAPConstants.JPEG_PHOTO), is(nullValue()));
});

View file

@ -48,7 +48,6 @@ import org.keycloak.testsuite.util.LDAPTestUtils;
import javax.ws.rs.BadRequestException;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@ -338,7 +337,7 @@ public class LDAPGroupMapperSyncTest extends AbstractLDAPTest {
Assert.assertNull(KeycloakModelUtils.findGroupByPath(realm, "/group12"));
// Load user from LDAP to Keycloak DB
UserModel john = session.users().getUserByUsername("johnkeycloak", realm);
UserModel john = session.users().getUserByUsername(realm, "johnkeycloak");
Set<GroupModel> johnGroups = john.getGroupsStream().collect(Collectors.toSet());
// Assert just those groups, which john was memberOf exists because they were lazily created

View file

@ -87,8 +87,8 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
LDAPTestUtils.updateGroupMapperConfigOptions(mapperModel, GroupMapperConfig.MODE, LDAPGroupMapperMode.LDAP_ONLY.toString());
appRealm.updateComponent(mapperModel);
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
UserModel john = session.users().getUserByUsername(appRealm, "johnkeycloak");
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
// 1 - Grant some groups in LDAP
@ -127,7 +127,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
UserModel johnDb = session.userLocalStorage().getUserByUsername("johnkeycloak", appRealm);
UserModel johnDb = session.userLocalStorage().getUserByUsername(appRealm, "johnkeycloak");
Assert.assertEquals(2, johnDb.getGroupsStream().count());
Assert.assertEquals(2, johnDb.getGroupsStream("Gr", 0, 10).count());
Assert.assertEquals(1, johnDb.getGroupsStream("Gr", 1, 10).count());
@ -150,8 +150,8 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
GroupModel groupTeam20162017 = KeycloakModelUtils.findGroupByPath(appRealm, "Team 2016/2017");
GroupModel groupTeamChild20182019 = KeycloakModelUtils.findGroupByPath(appRealm, "defaultGroup1/Team Child 2018/2019");
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
UserModel john = session.users().getUserByUsername(appRealm, "johnkeycloak");
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
Set<GroupModel> johnGroups = john.getGroupsStream().collect(Collectors.toSet());
Assert.assertEquals(4, johnGroups.size());
@ -239,7 +239,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
@ -267,7 +267,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
// Add some group mapping to model. This should fail with no-import mode for LDAP provider READ_ONLY mode for the group mapper
@ -284,7 +284,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
@ -316,7 +316,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
UserModel maryDB = session.userLocalStorage().getUserByUsername("marykeycloak", appRealm);
UserModel maryDB = session.userLocalStorage().getUserByUsername(appRealm, "marykeycloak");
Set<GroupModel> maryDBGroups = maryDB.getGroupsStream().collect(Collectors.toSet());
Assert.assertFalse(maryDBGroups.contains(group1));
@ -337,7 +337,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
Assert.assertEquals(1, group12Members.size());
Assert.assertEquals("marykeycloak", group12Members.get(0).getUsername());
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
mary.leaveGroup(group12);
});
} else {
@ -362,8 +362,8 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
GroupModel group11 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group11");
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
UserModel john = session.users().getUserByUsername(appRealm, "johnkeycloak");
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
ComponentModel mapperModel = LDAPTestUtils.getSubcomponentByName(appRealm, ctx.getLdapModel(), "groupsMapper");
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ctx.getLdapProvider(), appRealm);
@ -417,7 +417,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
groupMapper.addGroupMappingInLDAP(appRealm, group12, robLdap);
// Get user and check that he has requested groups from LDAP
UserModel rob = session.users().getUserByUsername("robkeycloak", appRealm);
UserModel rob = session.users().getUserByUsername(appRealm, "robkeycloak");
Set<GroupModel> robGroups = rob.getGroupsStream().collect(Collectors.toSet());
Assert.assertFalse(robGroups.contains(group1));
@ -563,7 +563,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
RealmModel appRealm = ctx.getRealm();
// Get user in Keycloak. Ensure that he is member of requested group
UserModel carlos = session.users().getUserByUsername("carloskeycloak", appRealm);
UserModel carlos = session.users().getUserByUsername(appRealm, "carloskeycloak");
Set<GroupModel> carlosGroups = carlos.getGroupsStream().collect(Collectors.toSet());
GroupModel group1 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1");
@ -608,7 +608,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
UserModel john = session.users().getUserByUsername(appRealm, "johnkeycloak");
GroupModel group4 = KeycloakModelUtils.findGroupByPath(appRealm, "/group4");
john.joinGroup(group4);
@ -628,7 +628,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
UserModel john = session.users().getUserByUsername("johnkeycloak", appRealm);
UserModel john = session.users().getUserByUsername(appRealm, "johnkeycloak");
GroupModel group14 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group14");
GroupModel group3 = KeycloakModelUtils.findGroupByPath(appRealm, "/group3");
@ -747,7 +747,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
GroupModel kcBigGroup = KeycloakModelUtils.findGroupByPath(appRealm, "/biggroup");
// check all the users have the group assigned
for (int i = 0; i < membersToTest; i++) {
UserModel kcUser = session.users().getUserByUsername(String.format("user%02d", i), appRealm);
UserModel kcUser = session.users().getUserByUsername(appRealm, String.format("user%02d", i));
Assert.assertTrue("User contains biggroup " + i, kcUser.getGroupsStream().collect(Collectors.toSet()).contains(kcBigGroup));
}
// check the group contains all the users as member
@ -794,7 +794,7 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
// check everything is OK
GroupModel kcDeleteGroup = KeycloakModelUtils.findGroupByPath(appRealm, "/deletegroup");
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
UserModel mary = session.users().getUserByUsername(appRealm, "marykeycloak");
List<UserModel> groupMembers = session.users().getGroupMembersStream(appRealm, kcDeleteGroup, 0, 5)
.collect(Collectors.toList());
Assert.assertEquals(1, groupMembers.size());

View file

@ -84,7 +84,7 @@ public class LDAPHardcodedAttributeTest extends AbstractLDAPTest {
LDAPTestContext ctx = LDAPTestContext.init(session);
RealmModel appRealm = ctx.getRealm();
UserModel user = session.users().getUserByUsername("johnkeycloak", appRealm);
UserModel user = session.users().getUserByUsername(appRealm, "johnkeycloak");
Assert.assertNotNull(user);
Assert.assertTrue(user.isEmailVerified());
Assert.assertEquals("en", user.getFirstAttribute("locale"));

Some files were not shown because too many files have changed in this diff Show more