[KEYCLOAK-16232] Replace usages of deprecated collection-based methods with the respective stream variants

This commit is contained in:
Stefan Guilhen 2020-11-11 23:09:27 -03:00 committed by Hynek Mlnařík
parent 87cedeaac6
commit 73d0bb34c4
58 changed files with 524 additions and 591 deletions

View file

@ -20,6 +20,7 @@ package org.keycloak.storage.ldap;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.utils.UserModelDelegate; import org.keycloak.models.utils.UserModelDelegate;
@ -68,21 +69,21 @@ public class ReadonlyLDAPUserModelDelegate extends UserModelDelegate {
@Override @Override
public void setSingleAttribute(String name, String value) { public void setSingleAttribute(String name, String value) {
if (!Objects.equals(getAttribute(name), Collections.singletonList(value))) { if (!Objects.equals(getAttributeStream(name).collect(Collectors.toList()), Collections.singletonList(value))) {
throw new ReadOnlyException("Federated storage is not writable"); throw new ReadOnlyException("Federated storage is not writable");
} }
} }
@Override @Override
public void setAttribute(String name, List<String> values) { public void setAttribute(String name, List<String> values) {
if (!Objects.equals(getAttribute(name), values)) { if (!Objects.equals(getAttributeStream(name).collect(Collectors.toList()), values)) {
throw new ReadOnlyException("Federated storage is not writable"); throw new ReadOnlyException("Federated storage is not writable");
} }
} }
@Override @Override
public void removeAttribute(String name) { public void removeAttribute(String name) {
if (getAttribute(name) != null) { if (getAttributeStream(name).count() > 0) {
throw new ReadOnlyException("Federated storage is not writable"); throw new ReadOnlyException("Federated storage is not writable");
} }
} }

View file

@ -42,6 +42,7 @@ import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
@ -121,13 +122,13 @@ public class UserAttributeLDAPStorageMapper extends AbstractLDAPStorageMapper {
} else { } else {
// we don't have java property. Let's set attribute // we don't have java property. Let's set attribute
List<String> attrValues = localUser.getAttribute(userModelAttrName); List<String> attrValues = localUser.getAttributeStream(userModelAttrName).collect(Collectors.toList());
if (attrValues.size() == 0) { if (attrValues.isEmpty()) {
if (isMandatoryInLdap) { if (isMandatoryInLdap) {
ldapUser.setSingleAttribute(ldapAttrName, LDAPConstants.EMPTY_ATTRIBUTE_VALUE); ldapUser.setSingleAttribute(ldapAttrName, LDAPConstants.EMPTY_ATTRIBUTE_VALUE);
} else { } else {
ldapUser.setAttribute(ldapAttrName, new LinkedHashSet<String>()); ldapUser.setAttribute(ldapAttrName, new LinkedHashSet<>());
} }
} else { } else {
ldapUser.setAttribute(ldapAttrName, new LinkedHashSet<>(attrValues)); ldapUser.setAttribute(ldapAttrName, new LinkedHashSet<>(attrValues));

View file

@ -34,8 +34,7 @@ import org.keycloak.storage.ldap.mappers.PasswordUpdateCallback;
import org.keycloak.storage.ldap.mappers.TxAwareLDAPUserModelDelegate; import org.keycloak.storage.ldap.mappers.TxAwareLDAPUserModelDelegate;
import javax.naming.AuthenticationException; import javax.naming.AuthenticationException;
import java.util.HashSet; import java.util.Objects;
import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -142,7 +141,7 @@ public class MSADUserAccountControlStorageMapper extends AbstractLDAPStorageMapp
if (ldapProvider.getEditMode() == UserStorageProvider.EditMode.WRITABLE) { if (ldapProvider.getEditMode() == UserStorageProvider.EditMode.WRITABLE) {
if (errorCode.equals("532") || errorCode.equals("773")) { if (errorCode.equals("532") || errorCode.equals("773")) {
// User needs to change his MSAD password. Allow him to login, but add UPDATE_PASSWORD required action // User needs to change his MSAD password. Allow him to login, but add UPDATE_PASSWORD required action
if (!user.getRequiredActions().contains(UserModel.RequiredAction.UPDATE_PASSWORD.name())) { if (user.getRequiredActionsStream().noneMatch(action -> Objects.equals(action, UserModel.RequiredAction.UPDATE_PASSWORD.name()))) {
user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD); user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
} }
return true; return true;

View file

@ -34,8 +34,7 @@ import org.keycloak.storage.ldap.mappers.LDAPOperationDecorator;
import org.keycloak.storage.ldap.mappers.PasswordUpdateCallback; import org.keycloak.storage.ldap.mappers.PasswordUpdateCallback;
import javax.naming.AuthenticationException; import javax.naming.AuthenticationException;
import java.util.HashSet; import java.util.Objects;
import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -133,7 +132,7 @@ public class MSADLDSUserAccountControlStorageMapper extends AbstractLDAPStorageM
if (ldapProvider.getEditMode() == UserStorageProvider.EditMode.WRITABLE) { if (ldapProvider.getEditMode() == UserStorageProvider.EditMode.WRITABLE) {
if (errorCode.equals("532") || errorCode.equals("773")) { if (errorCode.equals("532") || errorCode.equals("773")) {
// User needs to change his MSAD password. Allow him to login, but add UPDATE_PASSWORD required action // User needs to change his MSAD password. Allow him to login, but add UPDATE_PASSWORD required action
if (!user.getRequiredActions().contains(UserModel.RequiredAction.UPDATE_PASSWORD.name())) { if (user.getRequiredActionsStream().noneMatch(action -> Objects.equals(action, UserModel.RequiredAction.UPDATE_PASSWORD.name()))) {
user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD); user.addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
} }
return true; return true;

View file

@ -647,13 +647,9 @@ public class UserCacheSession implements UserCache.Streams {
return getDelegate().getFederatedIdentity(user, socialProvider, realm); return getDelegate().getFederatedIdentity(user, socialProvider, realm);
} }
Set<FederatedIdentityModel> federatedIdentities = getFederatedIdentities(user, realm); return getFederatedIdentitiesStream(user, realm)
for (FederatedIdentityModel socialLink : federatedIdentities) { .filter(socialLink -> Objects.equals(socialLink.getIdentityProvider(), socialProvider))
if (socialLink.getIdentityProvider().equals(socialProvider)) { .findFirst().orElse(null);
return socialLink;
}
}
return null;
} }
@Override @Override
@ -697,7 +693,7 @@ public class UserCacheSession implements UserCache.Streams {
if (cached == null) { if (cached == null) {
Long loaded = cache.getCurrentRevision(cacheKey); Long loaded = cache.getCurrentRevision(cacheKey);
List<UserConsentModel> consents = getDelegate().getConsents(realm, userId); List<UserConsentModel> consents = getDelegate().getConsentsStream(realm, userId).collect(Collectors.toList());
cached = new CachedUserConsents(loaded, cacheKey, realm, consents); cached = new CachedUserConsents(loaded, cacheKey, realm, consents);
cache.addRevisioned(cached, startupRevision); cache.addRevisioned(cached, startupRevision);
} }
@ -796,7 +792,8 @@ 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 // 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) { protected void fullyInvalidateUser(RealmModel realm, UserModel user) {
Set<FederatedIdentityModel> federatedIdentities = realm.isIdentityFederationEnabled() ? getFederatedIdentities(user, realm) : null; Stream<FederatedIdentityModel> federatedIdentities = realm.isIdentityFederationEnabled() ?
getFederatedIdentitiesStream(user, realm) : Stream.empty();
UserFullInvalidationEvent event = UserFullInvalidationEvent.create(user.getId(), user.getUsername(), user.getEmail(), realm.getId(), realm.isIdentityFederationEnabled(), federatedIdentities); UserFullInvalidationEvent event = UserFullInvalidationEvent.create(user.getId(), user.getUsername(), user.getEmail(), realm.getId(), realm.isIdentityFederationEnabled(), federatedIdentities);

View file

@ -28,6 +28,9 @@ import org.keycloak.models.sessions.infinispan.util.KeycloakMarshallUtil;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInput; import java.io.ObjectInput;
import java.io.ObjectOutput; import java.io.ObjectOutput;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.infinispan.commons.marshall.Externalizer; import org.infinispan.commons.marshall.Externalizer;
import org.infinispan.commons.marshall.MarshallUtil; import org.infinispan.commons.marshall.MarshallUtil;
import org.infinispan.commons.marshall.SerializeWith; import org.infinispan.commons.marshall.SerializeWith;
@ -47,7 +50,7 @@ public class UserFullInvalidationEvent extends InvalidationEvent implements User
private boolean identityFederationEnabled; private boolean identityFederationEnabled;
private Map<String, String> federatedIdentities; private Map<String, String> federatedIdentities;
public static UserFullInvalidationEvent create(String userId, String username, String email, String realmId, boolean identityFederationEnabled, Collection<FederatedIdentityModel> federatedIdentities) { public static UserFullInvalidationEvent create(String userId, String username, String email, String realmId, boolean identityFederationEnabled, Stream<FederatedIdentityModel> federatedIdentities) {
UserFullInvalidationEvent event = new UserFullInvalidationEvent(); UserFullInvalidationEvent event = new UserFullInvalidationEvent();
event.userId = userId; event.userId = userId;
event.username = username; event.username = username;
@ -56,10 +59,8 @@ public class UserFullInvalidationEvent extends InvalidationEvent implements User
event.identityFederationEnabled = identityFederationEnabled; event.identityFederationEnabled = identityFederationEnabled;
if (identityFederationEnabled) { if (identityFederationEnabled) {
event.federatedIdentities = new HashMap<>(); event.federatedIdentities = federatedIdentities.collect(Collectors.toMap(socialLink -> socialLink.getIdentityProvider(),
for (FederatedIdentityModel socialLink : federatedIdentities) { socialLink -> socialLink.getUserId()));
event.federatedIdentities.put(socialLink.getIdentityProvider(), socialLink.getUserId());
}
} }
return event; return event;

View file

@ -691,12 +691,12 @@ public class JpaUserFederatedStorageProvider implements
@Override @Override
public List<CredentialModel> getStoredCredentials(RealmModel realm, UserModel user) { public List<CredentialModel> getStoredCredentials(RealmModel realm, UserModel user) {
return getStoredCredentials(realm, user.getId()); return getStoredCredentialsStream(realm, user.getId()).collect(Collectors.toList());
} }
@Override @Override
public List<CredentialModel> getStoredCredentialsByType(RealmModel realm, UserModel user, String type) { public List<CredentialModel> getStoredCredentialsByType(RealmModel realm, UserModel user, String type) {
return getStoredCredentialsByType(realm, user.getId(), type); return getStoredCredentialsByTypeStream(realm, user.getId(), type).collect(Collectors.toList());
} }
@Override @Override

View file

@ -79,10 +79,9 @@ public class MigrateTo1_4_0 implements Migration {
} }
private void migrateUsers(KeycloakSession session, RealmModel realm) { private void migrateUsers(KeycloakSession session, RealmModel realm) {
List<UserModel> users = session.userLocalStorage().getUsers(realm, false); session.userLocalStorage().getUsersStream(realm, false)
for (UserModel user : users) { .forEach(user -> {
String email = user.getEmail(); String email = KeycloakModelUtils.toLowerCaseSafe(user.getEmail());
email = KeycloakModelUtils.toLowerCaseSafe(email);
if (email != null && !email.equals(user.getEmail())) { if (email != null && !email.equals(user.getEmail())) {
user.setEmail(email); user.setEmail(email);
UserCache userCache = session.userCache(); UserCache userCache = session.userCache();
@ -90,6 +89,6 @@ public class MigrateTo1_4_0 implements Migration {
userCache.evict(realm, user); userCache.evict(realm, user);
} }
} }
} });
} }
} }

View file

@ -394,7 +394,7 @@ public final class KeycloakModelUtils {
public static Collection<String> resolveAttribute(UserModel user, String name, boolean aggregateAttrs) { public static Collection<String> resolveAttribute(UserModel user, String name, boolean aggregateAttrs) {
List<String> values = user.getAttribute(name); List<String> values = user.getAttributeStream(name).collect(Collectors.toList());
Set<String> aggrValues = new HashSet<String>(); Set<String> aggrValues = new HashSet<String>();
if (!values.isEmpty()) { if (!values.isEmpty()) {
if (!aggregateAttrs) { if (!aggregateAttrs) {

View file

@ -190,13 +190,8 @@ public class ModelToRepresentation {
rep.setTotp(session.userCredentialManager().isConfiguredFor(realm, user, OTPCredentialModel.TYPE)); rep.setTotp(session.userCredentialManager().isConfiguredFor(realm, user, OTPCredentialModel.TYPE));
rep.setDisableableCredentialTypes(session.userCredentialManager().getDisableableCredentialTypes(realm, user)); rep.setDisableableCredentialTypes(session.userCredentialManager().getDisableableCredentialTypes(realm, user));
rep.setFederationLink(user.getFederationLink()); rep.setFederationLink(user.getFederationLink());
rep.setNotBefore(session.users().getNotBeforeOfUser(realm, user)); rep.setNotBefore(session.users().getNotBeforeOfUser(realm, user));
rep.setRequiredActions(user.getRequiredActionsStream().collect(Collectors.toList()));
Set<String> requiredActions = user.getRequiredActions();
List<String> reqActions = new ArrayList<>(requiredActions);
rep.setRequiredActions(reqActions);
Map<String, List<String>> attributes = user.getAttributes(); Map<String, List<String>> attributes = user.getAttributes();
Map<String, List<String>> copy = null; Map<String, List<String>> copy = null;

View file

@ -19,6 +19,9 @@
package org.keycloak.storage.adapter; package org.keycloak.storage.adapter;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.keycloak.models.GroupModel; import org.keycloak.models.GroupModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
@ -61,29 +64,28 @@ public class UpdateOnlyChangeUserModelDelegate extends UserModelDelegate {
@Override @Override
public void setAttribute(String name, List<String> values) { public void setAttribute(String name, List<String> values) {
if (!isEqualOrBothNull(getAttribute(name), values)) { if (!isEqualOrBothNull(getAttributeStream(name).collect(Collectors.toList()), values)) {
delegate.setAttribute(name, values); delegate.setAttribute(name, values);
} }
} }
@Override @Override
public void removeAttribute(String name) { public void removeAttribute(String name) {
List<String> currentVal = getAttribute(name); if (getAttributeStream(name).count() > 0) {
if (currentVal != null && !currentVal.isEmpty()) {
delegate.removeAttribute(name); delegate.removeAttribute(name);
} }
} }
@Override @Override
public void addRequiredAction(String action) { public void addRequiredAction(String action) {
if (!getRequiredActions().contains(action)) { if (action != null && getRequiredActionsStream().noneMatch(action::equals)) {
delegate.addRequiredAction(action); delegate.addRequiredAction(action);
} }
} }
@Override @Override
public void removeRequiredAction(String action) { public void removeRequiredAction(String action) {
if (getRequiredActions().contains(action)) { if (action != null && getRequiredActionsStream().anyMatch(action::equals)) {
delegate.removeRequiredAction(action); delegate.removeRequiredAction(action);
} }
} }

View file

@ -30,7 +30,6 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelException; import org.keycloak.models.ModelException;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.protocol.openshift.OpenShiftTokenReviewResponseRepresentation;
import org.keycloak.services.resources.IdentityBrokerService; import org.keycloak.services.resources.IdentityBrokerService;
import org.keycloak.sessions.AuthenticationSessionModel; import org.keycloak.sessions.AuthenticationSessionModel;
import org.keycloak.util.JsonSerialization; import org.keycloak.util.JsonSerialization;
@ -40,6 +39,8 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -218,18 +219,23 @@ public class SerializedBrokeredIdentityContext implements UpdateProfileContext {
@JsonIgnore @JsonIgnore
@Override @Override
public List<String> getAttribute(String key) { public List<String> getAttribute(String key) {
return this.getAttributeStream(key).collect(Collectors.toList());
}
@JsonIgnore
@Override
public Stream<String> getAttributeStream(String key) {
ContextDataEntry ctxEntry = this.contextData.get(Constants.USER_ATTRIBUTES_PREFIX + key); ContextDataEntry ctxEntry = this.contextData.get(Constants.USER_ATTRIBUTES_PREFIX + key);
if (ctxEntry != null) { if (ctxEntry != null) {
try { try {
String asString = ctxEntry.getData(); String asString = ctxEntry.getData();
byte[] asBytes = Base64Url.decode(asString); byte[] asBytes = Base64Url.decode(asString);
List<String> asList = JsonSerialization.readValue(asBytes, List.class); return JsonSerialization.readValue(asBytes, List.class).stream();
return asList;
} catch (IOException ioe) { } catch (IOException ioe) {
throw new RuntimeException(ioe); throw new RuntimeException(ioe);
} }
} else { } else {
return null; return Stream.empty();
} }
} }

View file

@ -26,6 +26,7 @@ import org.keycloak.models.UserModel;
import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.MultivaluedMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static org.keycloak.authentication.authenticators.browser.ConditionalOtpFormAuthenticator.OtpDecision.ABSTAIN; import static org.keycloak.authentication.authenticators.browser.ConditionalOtpFormAuthenticator.OtpDecision.ABSTAIN;
@ -189,15 +190,12 @@ public class ConditionalOtpFormAuthenticator extends OTPFormAuthenticator {
return ABSTAIN; return ABSTAIN;
} }
List<String> values = user.getAttribute(attributeName); Optional<String> value = user.getAttributeStream(attributeName).findFirst();
if (!value.isPresent()) {
if (values.isEmpty()) {
return ABSTAIN; return ABSTAIN;
} }
String value = values.get(0).trim(); switch (value.get().trim()) {
switch (value) {
case SKIP: case SKIP:
return SKIP_OTP; return SKIP_OTP;
case FORCE: case FORCE:
@ -326,7 +324,7 @@ public class ConditionalOtpFormAuthenticator extends OTPFormAuthenticator {
public void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user) { public void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user) {
if (!isOTPRequired(session, realm, user)) { if (!isOTPRequired(session, realm, user)) {
user.removeRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP); user.removeRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP);
} else if (!user.getRequiredActions().contains(UserModel.RequiredAction.CONFIGURE_TOTP.name())) { } else if (user.getRequiredActionsStream().noneMatch(UserModel.RequiredAction.CONFIGURE_TOTP.name()::equals)) {
user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP.name()); user.addRequiredAction(UserModel.RequiredAction.CONFIGURE_TOTP.name());
} }
} }

View file

@ -21,6 +21,7 @@ package org.keycloak.authentication.authenticators.x509;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.keycloak.authentication.AuthenticationFlowContext; import org.keycloak.authentication.AuthenticationFlowContext;
import org.keycloak.models.Constants; import org.keycloak.models.Constants;
@ -61,18 +62,18 @@ public abstract class UserIdentityToModelMapper {
if (_customAttributes.isEmpty() || userIdentityValues.isEmpty() || (_customAttributes.size() != userIdentityValues.size())) { if (_customAttributes.isEmpty() || userIdentityValues.isEmpty() || (_customAttributes.size() != userIdentityValues.size())) {
return null; return null;
} }
List<UserModel> users = session.users().searchForUserByUserAttribute(_customAttributes.get(0), userIdentityValues.get(0), context.getRealm()); Stream<UserModel> usersStream = session.users().searchForUserByUserAttributeStream(_customAttributes.get(0), userIdentityValues.get(0), context.getRealm());
for (int i = 1; i <_customAttributes.size(); ++i) { for (int i = 1; i <_customAttributes.size(); ++i) {
String customAttribute = _customAttributes.get(i); String customAttribute = _customAttributes.get(i);
String userIdentityValue = userIdentityValues.get(i); String userIdentityValue = userIdentityValues.get(i);
usersStream = usersStream.filter(user -> user.getFirstAttribute(customAttribute).equals(userIdentityValue));
users = users.stream().filter(user -> user.getFirstAttribute(customAttribute).equals(userIdentityValue)).collect(Collectors.toList());
} }
if (users != null && users.size() > 1) { List<UserModel> users = usersStream.collect(Collectors.toList());
if (users.size() > 1) {
throw new ModelDuplicateException(); throw new ModelDuplicateException();
} }
return users != null && users.size() == 1 ? users.get(0) : null; return users.size() == 1 ? users.get(0) : null;
} }
} }

View file

@ -19,6 +19,8 @@ package org.keycloak.authentication.requiredactions.util;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* Abstraction, which allows to display updateProfile page in various contexts (Required action of already existing user, or first identity provider * Abstraction, which allows to display updateProfile page in various contexts (Required action of already existing user, or first identity provider
@ -54,6 +56,19 @@ public interface UpdateProfileContext {
String getFirstAttribute(String name); String getFirstAttribute(String name);
List<String> getAttribute(String key); /**
* @deprecated Use {@link #getAttributeStream(String) getAttributeStream} instead.
*/
@Deprecated
default List<String> getAttribute(String key) {
return this.getAttributeStream(key).collect(Collectors.toList());
}
/**
* Obtains all values associated with the specified attribute name.
*
* @param name the name of the attribute.
* @return a non-null {@link Stream} of attribute values.
*/
Stream<String> getAttributeStream(String name);
} }

View file

@ -22,6 +22,8 @@ import org.keycloak.models.UserModel;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -102,7 +104,7 @@ public class UserUpdateProfileContext implements UpdateProfileContext {
} }
@Override @Override
public List<String> getAttribute(String key) { public Stream<String> getAttributeStream(String key) {
return user.getAttribute(key); return user.getAttributeStream(key);
} }
} }

View file

@ -160,7 +160,7 @@ public class UserAttributeMapper extends AbstractClaimMapper {
} else if (LAST_NAME.equalsIgnoreCase(attribute)) { } else if (LAST_NAME.equalsIgnoreCase(attribute)) {
setIfNotEmpty(user::setLastName, values); setIfNotEmpty(user::setLastName, values);
} else { } else {
List<String> current = user.getAttribute(attribute); List<String> current = user.getAttributeStream(attribute).collect(Collectors.toList());
if (!CollectionUtil.collectionEquals(values, current)) { if (!CollectionUtil.collectionEquals(values, current)) {
user.setAttribute(attribute, values); user.setAttribute(attribute, values);
} else if (values.isEmpty()) { } else if (values.isEmpty()) {

View file

@ -51,7 +51,6 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel; import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.UserConsentModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.ClientRepresentation;
@ -226,22 +225,16 @@ public class ExportUtils {
// Finally users if needed // Finally users if needed
if (options.isUsersIncluded()) { if (options.isUsersIncluded()) {
List<UserModel> allUsers = session.users().getUsers(realm, true); List<UserRepresentation> users = session.users().getUsersStream(realm, true)
List<UserRepresentation> users = new LinkedList<>(); .map(user -> exportUser(session, realm, user, options, internal))
for (UserModel user : allUsers) { .collect(Collectors.toList());
UserRepresentation userRep = exportUser(session, realm, user, options, internal);
users.add(userRep);
}
if (users.size() > 0) { if (users.size() > 0) {
rep.setUsers(users); rep.setUsers(users);
} }
List<UserRepresentation> federatedUsers = new LinkedList<>(); List<UserRepresentation> federatedUsers = session.userFederatedStorage().getStoredUsersStream(realm, 0, -1)
for (String userId : session.userFederatedStorage().getStoredUsers(realm, 0, -1)) { .map(user -> exportFederatedUser(session, realm, user, options)).collect(Collectors.toList());
UserRepresentation userRep = exportFederatedUser(session, realm, userId, options);
federatedUsers.add(userRep);
}
if (federatedUsers.size() > 0) { if (federatedUsers.size() > 0) {
rep.setFederatedUsers(federatedUsers); rep.setFederatedUsers(federatedUsers);
} }
@ -465,12 +458,8 @@ public class ExportUtils {
UserRepresentation userRep = ModelToRepresentation.toRepresentation(session, realm, user); UserRepresentation userRep = ModelToRepresentation.toRepresentation(session, realm, user);
// Social links // Social links
Set<FederatedIdentityModel> socialLinks = session.users().getFederatedIdentities(user, realm); List<FederatedIdentityRepresentation> socialLinkReps = session.users().getFederatedIdentitiesStream(user, realm)
List<FederatedIdentityRepresentation> socialLinkReps = new ArrayList<>(); .map(ExportUtils::exportSocialLink).collect(Collectors.toList());
for (FederatedIdentityModel socialLink : socialLinks) {
FederatedIdentityRepresentation socialLinkRep = exportSocialLink(socialLink);
socialLinkReps.add(socialLinkRep);
}
if (socialLinkReps.size() > 0) { if (socialLinkReps.size() > 0) {
userRep.setFederatedIdentities(socialLinkReps); userRep.setFederatedIdentities(socialLinkReps);
} }
@ -518,12 +507,8 @@ public class ExportUtils {
userRep.setFederationLink(user.getFederationLink()); userRep.setFederationLink(user.getFederationLink());
// Grants // Grants
List<UserConsentModel> consents = session.users().getConsents(realm, user.getId()); List<UserConsentRepresentation> consentReps = session.users().getConsentsStream(realm, user.getId())
LinkedList<UserConsentRepresentation> consentReps = new LinkedList<>(); .map(ModelToRepresentation::toRepresentation).collect(Collectors.toList());
for (UserConsentModel consent : consents) {
UserConsentRepresentation consentRep = ModelToRepresentation.toRepresentation(consent);
consentReps.add(consentRep);
}
if (consentReps.size() > 0) { if (consentReps.size() > 0) {
userRep.setClientConsents(consentReps); userRep.setClientConsents(consentReps);
} }
@ -636,21 +621,15 @@ public class ExportUtils {
userRep.setAttributes(attrs); userRep.setAttributes(attrs);
} }
Set<String> requiredActions = session.userFederatedStorage().getRequiredActions(realm, id); List<String> requiredActions = session.userFederatedStorage().getRequiredActionsStream(realm, id).collect(Collectors.toList());
if (requiredActions.size() > 0) { if (requiredActions.size() > 0) {
List<String> actions = new LinkedList<>(); userRep.setRequiredActions(requiredActions);
actions.addAll(requiredActions);
userRep.setRequiredActions(actions);
} }
// Social links // Social links
Set<FederatedIdentityModel> socialLinks = session.userFederatedStorage().getFederatedIdentities(id, realm); List<FederatedIdentityRepresentation> socialLinkReps = session.userFederatedStorage().getFederatedIdentitiesStream(id, realm)
List<FederatedIdentityRepresentation> socialLinkReps = new ArrayList<>(); .map(ExportUtils::exportSocialLink).collect(Collectors.toList());
for (FederatedIdentityModel socialLink : socialLinks) {
FederatedIdentityRepresentation socialLinkRep = exportSocialLink(socialLink);
socialLinkReps.add(socialLinkRep);
}
if (socialLinkReps.size() > 0) { if (socialLinkReps.size() > 0) {
userRep.setFederatedIdentities(socialLinkReps); userRep.setFederatedIdentities(socialLinkReps);
} }
@ -685,21 +664,13 @@ public class ExportUtils {
} }
// Credentials // Credentials
List<CredentialModel> creds = session.userFederatedStorage().getStoredCredentials(realm, id); List<CredentialRepresentation> credReps = session.userFederatedStorage().getStoredCredentialsStream(realm, id)
List<CredentialRepresentation> credReps = new ArrayList<>(); .map(ExportUtils::exportCredential).collect(Collectors.toList());
for (CredentialModel cred : creds) {
CredentialRepresentation credRep = exportCredential(cred);
credReps.add(credRep);
}
userRep.setCredentials(credReps); userRep.setCredentials(credReps);
// Grants // Grants
List<UserConsentModel> consents = session.users().getConsents(realm, id); List<UserConsentRepresentation> consentReps = session.users().getConsentsStream(realm, id)
LinkedList<UserConsentRepresentation> consentReps = new LinkedList<>(); .map(ModelToRepresentation::toRepresentation).collect(Collectors.toList());
for (UserConsentModel consent : consents) {
UserConsentRepresentation consentRep = ModelToRepresentation.toRepresentation(consent);
consentReps.add(consentRep);
}
if (consentReps.size() > 0) { if (consentReps.size() > 0) {
userRep.setClientConsents(consentReps); userRep.setClientConsents(consentReps);
} }

View file

@ -108,7 +108,9 @@ public abstract class MultipleStepsExportProvider implements ExportProvider {
@Override @Override
protected void runExportImportTask(KeycloakSession session) throws IOException { protected void runExportImportTask(KeycloakSession session) throws IOException {
RealmModel realm = session.realms().getRealmByName(realmName); RealmModel realm = session.realms().getRealmByName(realmName);
usersHolder.users = session.users().getUsers(realm, usersHolder.currentPageStart, usersHolder.currentPageEnd - usersHolder.currentPageStart, true); usersHolder.users = session.users()
.getUsersStream(realm, usersHolder.currentPageStart, usersHolder.currentPageEnd - usersHolder.currentPageStart, true)
.collect(Collectors.toList());
writeUsers(realmName + "-users-" + (usersHolder.currentPageStart / countPerPage) + ".json", session, realm, usersHolder.users); writeUsers(realmName + "-users-" + (usersHolder.currentPageStart / countPerPage) + ".json", session, realm, usersHolder.users);
@ -139,7 +141,9 @@ public abstract class MultipleStepsExportProvider implements ExportProvider {
@Override @Override
protected void runExportImportTask(KeycloakSession session) throws IOException { protected void runExportImportTask(KeycloakSession session) throws IOException {
RealmModel realm = session.realms().getRealmByName(realmName); RealmModel realm = session.realms().getRealmByName(realmName);
federatedUsersHolder.users = session.userFederatedStorage().getStoredUsers(realm, federatedUsersHolder.currentPageStart, federatedUsersHolder.currentPageEnd - federatedUsersHolder.currentPageStart); federatedUsersHolder.users = session.userFederatedStorage()
.getStoredUsersStream(realm, federatedUsersHolder.currentPageStart, federatedUsersHolder.currentPageEnd - federatedUsersHolder.currentPageStart)
.collect(Collectors.toList());
writeFederatedUsers(realmName + "-federated-users-" + (federatedUsersHolder.currentPageStart / countPerPage) + ".json", session, realm, federatedUsersHolder.users); writeFederatedUsers(realmName + "-federated-users-" + (federatedUsersHolder.currentPageStart / countPerPage) + ".json", session, realm, federatedUsersHolder.users);

View file

@ -28,9 +28,10 @@ import org.keycloak.services.resources.account.AccountFormService;
import java.net.URI; import java.net.URI;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -47,15 +48,13 @@ public class AccountFederatedIdentityBean {
public AccountFederatedIdentityBean(KeycloakSession session, RealmModel realm, UserModel user, URI baseUri, String stateChecker) { public AccountFederatedIdentityBean(KeycloakSession session, RealmModel realm, UserModel user, URI baseUri, String stateChecker) {
this.session = session; this.session = session;
Set<FederatedIdentityModel> identities = session.users().getFederatedIdentities(user, realm);
AtomicInteger availableIdentities = new AtomicInteger(0); AtomicInteger availableIdentities = new AtomicInteger(0);
this.identities = realm.getIdentityProvidersStream() this.identities = realm.getIdentityProvidersStream()
.filter(IdentityProviderModel::isEnabled) .filter(IdentityProviderModel::isEnabled)
.map(provider -> { .map(provider -> {
String providerId = provider.getAlias(); String providerId = provider.getAlias();
FederatedIdentityModel identity = getIdentity(identities, providerId); FederatedIdentityModel identity = getIdentity(session.users().getFederatedIdentitiesStream(user, realm), providerId);
if (identity != null) { if (identity != null) {
availableIdentities.getAndIncrement(); availableIdentities.getAndIncrement();
@ -72,13 +71,9 @@ public class AccountFederatedIdentityBean {
this.removeLinkPossible = availableIdentities.get() > 1 || user.getFederationLink() != null || AccountFormService.isPasswordSet(session, realm, user); this.removeLinkPossible = availableIdentities.get() > 1 || user.getFederationLink() != null || AccountFormService.isPasswordSet(session, realm, user);
} }
private FederatedIdentityModel getIdentity(Set<FederatedIdentityModel> identities, String providerId) { private FederatedIdentityModel getIdentity(Stream<FederatedIdentityModel> identities, String providerId) {
for (FederatedIdentityModel link : identities) { return identities.filter(federatedIdentityModel -> Objects.equals(federatedIdentityModel.getIdentityProvider(), providerId))
if (providerId.equals(link.getIdentityProvider())) { .findFirst().orElse(null);
return link;
}
}
return null;
} }
public List<FederatedIdentityEntry> getIdentities() { public List<FederatedIdentityEntry> getIdentities() {

View file

@ -34,9 +34,9 @@ import org.keycloak.services.util.ResolveRelative;
import org.keycloak.storage.StorageId; import org.keycloak.storage.StorageId;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -52,10 +52,9 @@ public class ApplicationsBean {
public ApplicationsBean(KeycloakSession session, RealmModel realm, UserModel user) { public ApplicationsBean(KeycloakSession session, RealmModel realm, UserModel user) {
Set<ClientModel> offlineClients = new UserSessionManager(session).findClientsWithOfflineToken(realm, user); Set<ClientModel> offlineClients = new UserSessionManager(session).findClientsWithOfflineToken(realm, user);
for (ClientModel client : getApplications(session, realm, user)) { this.applications = this.getApplications(session, realm, user)
if (isAdminClient(client) && ! AdminPermissions.realms(session, realm, user).isAdmin()) { .filter(client -> !isAdminClient(client) || AdminPermissions.realms(session, realm, user).isAdmin())
continue; .map(client -> {
}
// Construct scope parameter with all optional scopes to see all potentially available roles // Construct scope parameter with all optional scopes to see all potentially available roles
Stream<ClientScopeModel> allClientScopes = Stream.concat( Stream<ClientScopeModel> allClientScopes = Stream.concat(
@ -68,7 +67,7 @@ public class ApplicationsBean {
// Don't show applications, which user doesn't have access into (any available roles) // Don't show applications, which user doesn't have access into (any available roles)
// unless this is can be changed by approving/revoking consent // unless this is can be changed by approving/revoking consent
if (! isAdminClient(client) && availableRoles.isEmpty() && ! client.isConsentRequired()) { if (! isAdminClient(client) && availableRoles.isEmpty() && ! client.isConsentRequired()) {
continue; return null;
} }
List<RoleModel> realmRolesAvailable = new LinkedList<>(); List<RoleModel> realmRolesAvailable = new LinkedList<>();
@ -92,9 +91,10 @@ public class ApplicationsBean {
if (offlineClients.contains(client)) { if (offlineClients.contains(client)) {
additionalGrants.add("${offlineToken}"); additionalGrants.add("${offlineToken}");
} }
return new ApplicationEntry(session, realmRolesAvailable, resourceRolesAvailable, client, clientScopesGranted, additionalGrants);
applications.add(new ApplicationEntry(session, realmRolesAvailable, resourceRolesAvailable, client, clientScopesGranted, additionalGrants)); })
} .filter(Objects::nonNull)
.collect(Collectors.toList());
} }
public static boolean isAdminClient(ClientModel client) { public static boolean isAdminClient(ClientModel client) {
@ -102,22 +102,14 @@ public class ApplicationsBean {
|| client.getClientId().equals(Constants.ADMIN_CONSOLE_CLIENT_ID); || client.getClientId().equals(Constants.ADMIN_CONSOLE_CLIENT_ID);
} }
private Set<ClientModel> getApplications(KeycloakSession session, RealmModel realm, UserModel user) { private Stream<ClientModel> getApplications(KeycloakSession session, RealmModel realm, UserModel user) {
Set<ClientModel> clients = new HashSet<>();
Predicate<ClientModel> bearerOnly = ClientModel::isBearerOnly; Predicate<ClientModel> bearerOnly = ClientModel::isBearerOnly;
clients.addAll(realm.getClientsStream().filter(bearerOnly.negate()).collect(Collectors.toSet())); Stream<ClientModel> clients = realm.getClientsStream().filter(bearerOnly.negate());
List<UserConsentModel> consents = session.users().getConsents(realm, user.getId()); Predicate<ClientModel> isLocal = client -> new StorageId(client.getId()).isLocal();
return Stream.concat(clients, session.users().getConsentsStream(realm, user.getId())
for (UserConsentModel consent : consents) { .map(UserConsentModel::getClient)
ClientModel client = consent.getClient(); .filter(isLocal.negate())).distinct();
if (!new StorageId(client.getId()).isLocal()) {
clients.add(client);
}
}
return clients;
} }
private void processRoles(Set<RoleModel> inputRoles, List<RoleModel> realmRoles, MultivaluedHashMap<String, ClientRoleEntry> clientRoles) { private void processRoles(Set<RoleModel> inputRoles, List<RoleModel> realmRoles, MultivaluedHashMap<String, ClientRoleEntry> clientRoles) {

View file

@ -151,7 +151,7 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
page = LoginFormsPages.LOGIN_UPDATE_PROFILE; page = LoginFormsPages.LOGIN_UPDATE_PROFILE;
break; break;
case UPDATE_PASSWORD: case UPDATE_PASSWORD:
boolean isRequestedByAdmin = user.getRequiredActions().stream().filter(Objects::nonNull).anyMatch(UPDATE_PASSWORD.toString()::contains); boolean isRequestedByAdmin = user.getRequiredActionsStream().filter(Objects::nonNull).anyMatch(UPDATE_PASSWORD.toString()::contains);
actionMessage = isRequestedByAdmin ? Messages.UPDATE_PASSWORD : Messages.RESET_PASSWORD; actionMessage = isRequestedByAdmin ? Messages.UPDATE_PASSWORD : Messages.RESET_PASSWORD;
page = LoginFormsPages.LOGIN_UPDATE_PASSWORD; page = LoginFormsPages.LOGIN_UPDATE_PASSWORD;
break; break;

View file

@ -21,7 +21,6 @@ import org.keycloak.authentication.AuthenticationFlowContext;
import org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator; import org.keycloak.authentication.authenticators.broker.AbstractIdpAuthenticator;
import org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext; import org.keycloak.authentication.authenticators.broker.util.SerializedBrokeredIdentityContext;
import org.keycloak.forms.login.LoginFormsProvider; import org.keycloak.forms.login.LoginFormsProvider;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.IdentityProviderModel; import org.keycloak.models.IdentityProviderModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
@ -29,7 +28,6 @@ import org.keycloak.models.UserModel;
import org.keycloak.sessions.AuthenticationSessionModel; import org.keycloak.sessions.AuthenticationSessionModel;
import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.MultivaluedMap;
import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -61,11 +59,9 @@ public class LoginFormsUtil {
throw new IllegalStateException("User " + username + " not found or disabled"); throw new IllegalStateException("User " + username + " not found or disabled");
} }
Set<FederatedIdentityModel> fedLinks = session.users().getFederatedIdentities(user, realm); Set<String> federatedIdentities = session.users().getFederatedIdentitiesStream(user, realm)
Set<String> federatedIdentities = new HashSet<>(); .map(federatedIdentityModel -> federatedIdentityModel.getIdentityProvider())
for (FederatedIdentityModel fedLink : fedLinks) { .collect(Collectors.toSet());
federatedIdentities.add(fedLink.getIdentityProvider());
}
List<IdentityProviderModel> result = new LinkedList<>(); List<IdentityProviderModel> result = new LinkedList<>();
for (IdentityProviderModel idp : providers) { for (IdentityProviderModel idp : providers) {

View file

@ -644,7 +644,7 @@ public class TokenEndpoint {
} }
processor.evaluateRequiredActionTriggers(); processor.evaluateRequiredActionTriggers();
UserModel user = authSession.getAuthenticatedUser(); UserModel user = authSession.getAuthenticatedUser();
if (user.getRequiredActions() != null && user.getRequiredActions().size() > 0) { if (user.getRequiredActionsStream().count() > 0) {
// Remove authentication session as "Resource Owner Password Credentials Grant" is single-request scoped authentication // Remove authentication session as "Resource Owner Password Credentials Grant" is single-request scoped authentication
new AuthenticationSessionManager(session).removeAuthenticationSession(realm, authSession, false); new AuthenticationSessionManager(session).removeAuthenticationSession(realm, authSession, false);
event.error(Errors.RESOLVE_REQUIRED_ACTIONS); event.error(Errors.RESOLVE_REQUIRED_ACTIONS);

View file

@ -98,6 +98,7 @@ import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.keycloak.common.util.ServerCookie.SameSiteAttributeValue; import static org.keycloak.common.util.ServerCookie.SameSiteAttributeValue;
import static org.keycloak.services.util.CookieHelper.getCookie; import static org.keycloak.services.util.CookieHelper.getCookie;
@ -969,8 +970,9 @@ public class AuthenticationManager {
evaluateRequiredActionTriggers(session, authSession, request, event, realm, user); evaluateRequiredActionTriggers(session, authSession, request, event, realm, user);
if (!user.getRequiredActions().isEmpty()) { Optional<String> reqAction = user.getRequiredActionsStream().findFirst();
return user.getRequiredActions().iterator().next(); if (reqAction.isPresent()) {
return reqAction.get();
} }
if (!authSession.getRequiredActions().isEmpty()) { if (!authSession.getRequiredActions().isEmpty()) {
return authSession.getRequiredActions().iterator().next(); return authSession.getRequiredActions().iterator().next();
@ -1028,13 +1030,12 @@ public class AuthenticationManager {
event.detail(Details.CODE_ID, authSession.getParentSession().getId()); event.detail(Details.CODE_ID, authSession.getParentSession().getId());
Set<String> requiredActions = user.getRequiredActions(); Stream<String> requiredActions = user.getRequiredActionsStream();
Response action = executionActions(session, authSession, request, event, realm, user, requiredActions); Response action = executionActions(session, authSession, request, event, realm, user, requiredActions);
if (action != null) return action; if (action != null) return action;
// executionActions() method should remove any duplicate actions that might be in the clientSession // executionActions() method should remove any duplicate actions that might be in the clientSession
requiredActions = authSession.getRequiredActions(); action = executionActions(session, authSession, request, event, realm, user, authSession.getRequiredActions().stream());
action = executionActions(session, authSession, request, event, realm, user, requiredActions);
if (action != null) return action; if (action != null) return action;
if (client.isConsentRequired()) { if (client.isConsentRequired()) {
@ -1125,16 +1126,13 @@ public class AuthenticationManager {
protected static Response executionActions(KeycloakSession session, AuthenticationSessionModel authSession, protected static Response executionActions(KeycloakSession session, AuthenticationSessionModel authSession,
HttpRequest request, EventBuilder event, RealmModel realm, UserModel user, HttpRequest request, EventBuilder event, RealmModel realm, UserModel user,
Set<String> requiredActions) { Stream<String> requiredActions) {
List<RequiredActionProviderModel> sortedRequiredActions = sortRequiredActionsByPriority(realm, requiredActions); Optional<Response> response = sortRequiredActionsByPriority(realm, requiredActions)
.map(model -> executeAction(session, authSession, model, request, event, realm, user, false))
for (RequiredActionProviderModel model : sortedRequiredActions) { .filter(Objects::nonNull).findFirst();
Response response = executeAction(session, authSession, model, request, event, realm, user, false); if (response.isPresent())
if (response != null) { return response.get();
return response;
}
}
String kcAction = authSession.getClientNote(Constants.KC_ACTION); String kcAction = authSession.getClientNote(Constants.KC_ACTION);
if (kcAction != null) { if (kcAction != null) {
@ -1210,21 +1208,17 @@ public class AuthenticationManager {
return null; return null;
} }
private static List<RequiredActionProviderModel> sortRequiredActionsByPriority(RealmModel realm, Set<String> requiredActions) { private static Stream<RequiredActionProviderModel> sortRequiredActionsByPriority(RealmModel realm, Stream<String> requiredActions) {
List<RequiredActionProviderModel> actions = new ArrayList<>(); return requiredActions.map(action -> {
for (String action : requiredActions) {
RequiredActionProviderModel model = realm.getRequiredActionProviderByAlias(action); RequiredActionProviderModel model = realm.getRequiredActionProviderByAlias(action);
if (model == null) { if (model == null) {
logger.warnv("Could not find configuration for Required Action {0}, did you forget to register it?", action); logger.warnv("Could not find configuration for Required Action {0}, did you forget to register it?", action);
continue;
} }
if (!model.isEnabled()) { return model;
continue; })
} .filter(Objects::nonNull)
actions.add(model); .filter(RequiredActionProviderModel::isEnabled)
} .sorted(RequiredActionProviderModel.RequiredActionComparator.SINGLETON);
Collections.sort(actions, RequiredActionProviderModel.RequiredActionComparator.SINGLETON);
return actions;
} }
public static void evaluateRequiredActionTriggers(final KeycloakSession session, final AuthenticationSessionModel authSession, public static void evaluateRequiredActionTriggers(final KeycloakSession session, final AuthenticationSessionModel authSession,

View file

@ -689,24 +689,6 @@ public class RealmManager {
return false; return false;
} }
/**
* Query users based on a search string:
* <p/>
* "Bill Burke" first and last name
* "bburke@redhat.com" email
* "Burke" lastname or username
*
* @param searchString
* @param realmModel
* @return
*/
public List<UserModel> searchUsers(String searchString, RealmModel realmModel) {
if (searchString == null) {
return Collections.emptyList();
}
return session.users().searchForUser(searchString.trim(), realmModel);
}
private void setupAuthorizationServices(RealmModel realm) { private void setupAuthorizationServices(RealmModel realm) {
KeycloakModelUtils.setupAuthorizationServices(realm); KeycloakModelUtils.setupAuthorizationServices(realm);
} }

View file

@ -28,7 +28,6 @@ import org.keycloak.models.*;
import org.keycloak.protocol.oidc.utils.RedirectUtils; import org.keycloak.protocol.oidc.utils.RedirectUtils;
import org.keycloak.representations.JsonWebToken; import org.keycloak.representations.JsonWebToken;
import org.keycloak.services.managers.AuthenticationManager; import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.managers.AuthenticationSessionManager;
import org.keycloak.services.messages.Messages; import org.keycloak.services.messages.Messages;
import org.keycloak.sessions.AuthenticationSessionCompoundId; import org.keycloak.sessions.AuthenticationSessionCompoundId;
import org.keycloak.sessions.AuthenticationSessionModel; import org.keycloak.sessions.AuthenticationSessionModel;
@ -36,7 +35,6 @@ import org.keycloak.sessions.CommonClientSessionModel.Action;
import java.util.Objects; import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.keycloak.sessions.RootAuthenticationSessionModel;
/** /**
* *
@ -118,7 +116,7 @@ public class LoginActionsServiceChecks {
UserSessionModel userSession = context.getSession().sessions().getUserSession(context.getRealm(), authSessionId); UserSessionModel userSession = context.getSession().sessions().getUserSession(context.getRealm(), authSessionId);
boolean hasNoRequiredActions = boolean hasNoRequiredActions =
(userSession == null || userSession.getUser().getRequiredActions() == null || userSession.getUser().getRequiredActions().isEmpty()) (userSession == null || userSession.getUser().getRequiredActionsStream().count() == 0)
&& &&
(authSessionFromCookie == null || authSessionFromCookie.getRequiredActions() == null || authSessionFromCookie.getRequiredActions().isEmpty()); (authSessionFromCookie == null || authSessionFromCookie.getRequiredActions() == null || authSessionFromCookie.getRequiredActions().isEmpty());

View file

@ -719,7 +719,7 @@ public class AccountFormService extends AbstractSecuredLocalService {
if (link != null) { if (link != null) {
// Removing last social provider is not possible if you don't have other possibility to authenticate // Removing last social provider is not possible if you don't have other possibility to authenticate
if (session.users().getFederatedIdentities(user, realm).size() > 1 || user.getFederationLink() != null || isPasswordSet(session, realm, user)) { if (session.users().getFederatedIdentitiesStream(user, realm).count() > 1 || user.getFederationLink() != null || isPasswordSet(session, realm, user)) {
session.users().removeFederatedIdentity(realm, user, providerId); session.users().removeFederatedIdentity(realm, user, providerId);
logger.debugv("Social provider {0} removed successfully from user {1}", providerId, user.getUsername()); logger.debugv("Social provider {0} removed successfully from user {1}", providerId, user.getUsername());

View file

@ -405,8 +405,8 @@ public class AccountRestService {
checkAccountApiEnabled(); checkAccountApiEnabled();
auth.requireOneOf(AccountRoles.MANAGE_ACCOUNT, AccountRoles.VIEW_APPLICATIONS); auth.requireOneOf(AccountRoles.MANAGE_ACCOUNT, AccountRoles.VIEW_APPLICATIONS);
Set<ClientModel> clients = new HashSet<ClientModel>(); Set<ClientModel> clients = new HashSet<>();
List<String> inUseClients = new LinkedList<String>(); List<String> inUseClients = new LinkedList<>();
List<UserSessionModel> sessions = session.sessions().getUserSessions(realm, user); List<UserSessionModel> sessions = session.sessions().getUserSessions(realm, user);
for(UserSessionModel s : sessions) { for(UserSessionModel s : sessions) {
for (AuthenticatedClientSessionModel a : s.getAuthenticatedClientSessions().values()) { for (AuthenticatedClientSessionModel a : s.getAuthenticatedClientSessions().values()) {
@ -416,7 +416,7 @@ public class AccountRestService {
} }
} }
List<String> offlineClients = new LinkedList<String>(); List<String> offlineClients = new LinkedList<>();
List<UserSessionModel> offlineSessions = session.sessions().getOfflineUserSessions(realm, user); List<UserSessionModel> offlineSessions = session.sessions().getOfflineUserSessions(realm, user);
for(UserSessionModel s : offlineSessions) { for(UserSessionModel s : offlineSessions) {
for(AuthenticatedClientSessionModel a : s.getAuthenticatedClientSessions().values()) { for(AuthenticatedClientSessionModel a : s.getAuthenticatedClientSessions().values()) {
@ -426,17 +426,16 @@ public class AccountRestService {
} }
} }
Map<String, UserConsentModel> consentModels = new HashMap<String, UserConsentModel>(); Map<String, UserConsentModel> consentModels = new HashMap<>();
List<UserConsentModel> consents = session.users().getConsents(realm, user.getId()); session.users().getConsentsStream(realm, user.getId()).forEach(consent -> {
for (UserConsentModel consent : consents) {
ClientModel client = consent.getClient(); ClientModel client = consent.getClient();
clients.add(client); clients.add(client);
consentModels.put(client.getClientId(), consent); consentModels.put(client.getClientId(), consent);
} });
realm.getAlwaysDisplayInConsoleClientsStream().forEach(clients::add); realm.getAlwaysDisplayInConsoleClientsStream().forEach(clients::add);
List<ClientRepresentation> apps = new LinkedList<ClientRepresentation>(); List<ClientRepresentation> apps = new LinkedList<>();
for (ClientModel client : clients) { for (ClientModel client : clients) {
if (client.isBearerOnly() || client.getBaseUrl() == null || client.getBaseUrl().isEmpty()) { if (client.isBearerOnly() || client.getBaseUrl() == null || client.getBaseUrl().isEmpty()) {
continue; continue;

View file

@ -21,6 +21,8 @@ import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.ws.rs.DELETE; import javax.ws.rs.DELETE;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.Path; import javax.ws.rs.Path;
@ -110,14 +112,13 @@ public class LinkedAccountsResource {
public SortedSet<LinkedAccountRepresentation> getLinkedAccounts(KeycloakSession session, RealmModel realm, UserModel user) { public SortedSet<LinkedAccountRepresentation> getLinkedAccounts(KeycloakSession session, RealmModel realm, UserModel user) {
Set<String> socialIds = findSocialIds(); Set<String> socialIds = findSocialIds();
Set<FederatedIdentityModel> identities = session.users().getFederatedIdentities(user, realm);
return realm.getIdentityProvidersStream().filter(IdentityProviderModel::isEnabled) return realm.getIdentityProvidersStream().filter(IdentityProviderModel::isEnabled)
.map(provider -> toLinkedAccountRepresentation(provider, socialIds, identities)) .map(provider -> toLinkedAccountRepresentation(provider, socialIds, session.users().getFederatedIdentitiesStream(user, realm)))
.collect(Collectors.toCollection(TreeSet::new)); .collect(Collectors.toCollection(TreeSet::new));
} }
private LinkedAccountRepresentation toLinkedAccountRepresentation(IdentityProviderModel provider, Set<String> socialIds, private LinkedAccountRepresentation toLinkedAccountRepresentation(IdentityProviderModel provider, Set<String> socialIds,
Set<FederatedIdentityModel> identities) { Stream<FederatedIdentityModel> identities) {
String providerId = provider.getAlias(); String providerId = provider.getAlias();
FederatedIdentityModel identity = getIdentity(identities, providerId); FederatedIdentityModel identity = getIdentity(identities, providerId);
@ -138,13 +139,9 @@ public class LinkedAccountsResource {
return rep; return rep;
} }
private FederatedIdentityModel getIdentity(Set<FederatedIdentityModel> identities, String providerId) { private FederatedIdentityModel getIdentity(Stream<FederatedIdentityModel> identities, String providerId) {
for (FederatedIdentityModel link : identities) { return identities.filter(model -> Objects.equals(model.getIdentityProvider(), providerId))
if (providerId.equals(link.getIdentityProvider())) { .findFirst().orElse(null);
return link;
}
}
return null;
} }
@GET @GET
@ -212,7 +209,7 @@ public class LinkedAccountsResource {
} }
// Removing last social provider is not possible if you don't have other possibility to authenticate // Removing last social provider is not possible if you don't have other possibility to authenticate
if (!(session.users().getFederatedIdentities(user, realm).size() > 1 || user.getFederationLink() != null || isPasswordSet())) { if (!(session.users().getFederatedIdentitiesStream(user, realm).count() > 1 || user.getFederationLink() != null || isPasswordSet())) {
return ErrorResponse.error(Messages.FEDERATED_IDENTITY_REMOVING_LAST_PROVIDER, Response.Status.BAD_REQUEST); return ErrorResponse.error(Messages.FEDERATED_IDENTITY_REMOVING_LAST_PROVIDER, Response.Status.BAD_REQUEST);
} }

View file

@ -25,7 +25,6 @@ import org.keycloak.models.Constants;
import org.keycloak.models.GroupModel; import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.representations.idm.GroupRepresentation; import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.ManagementPermissionReference; import org.keycloak.representations.idm.ManagementPermissionReference;
@ -46,13 +45,11 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.net.URI; import java.net.URI;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
@ -201,20 +198,20 @@ public class GroupResource {
/** /**
* Get users * Get users
* *
* Returns a list of users, filtered according to query parameters * Returns a stream of users, filtered according to query parameters
* *
* @param firstResult Pagination offset * @param firstResult Pagination offset
* @param maxResults Maximum results size (defaults to 100) * @param maxResults Maximum results size (defaults to 100)
* @param briefRepresentation Only return basic information (only guaranteed to return id, username, created, first and last name, * @param briefRepresentation Only return basic information (only guaranteed to return id, username, created, first and last name,
* email, enabled state, email verification state, federation link, and access. * email, enabled state, email verification state, federation link, and access.
* Note that it means that namely user attributes, required actions, and not before are not returned.) * Note that it means that namely user attributes, required actions, and not before are not returned.)
* @return * @return a non-null {@code Stream} of users
*/ */
@GET @GET
@NoCache @NoCache
@Path("members") @Path("members")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public List<UserRepresentation> getMembers(@QueryParam("first") Integer firstResult, public Stream<UserRepresentation> getMembers(@QueryParam("first") Integer firstResult,
@QueryParam("max") Integer maxResults, @QueryParam("max") Integer maxResults,
@QueryParam("briefRepresentation") Boolean briefRepresentation) { @QueryParam("briefRepresentation") Boolean briefRepresentation) {
this.auth.groups().requireViewMembers(group); this.auth.groups().requireViewMembers(group);
@ -223,17 +220,10 @@ public class GroupResource {
maxResults = maxResults != null ? maxResults : Constants.DEFAULT_MAX_RESULTS; maxResults = maxResults != null ? maxResults : Constants.DEFAULT_MAX_RESULTS;
boolean briefRepresentationB = briefRepresentation != null && briefRepresentation; boolean briefRepresentationB = briefRepresentation != null && briefRepresentation;
List<UserRepresentation> results = new ArrayList<UserRepresentation>(); return session.users().getGroupMembersStream(realm, group, firstResult, maxResults)
List<UserModel> userModels = session.users().getGroupMembers(realm, group, firstResult, maxResults); .map(user -> briefRepresentationB
for (UserModel user : userModels) {
UserRepresentation userRep = briefRepresentationB
? ModelToRepresentation.toBriefRepresentation(user) ? ModelToRepresentation.toBriefRepresentation(user)
: ModelToRepresentation.toRepresentation(session, realm, user); : ModelToRepresentation.toRepresentation(session, realm, user));
results.add(userRep);
}
return results;
} }
/** /**

View file

@ -190,7 +190,8 @@ public class IdentityProviderResource {
// Admin changed the ID (alias) of identity provider. We must update all clients and users // Admin changed the ID (alias) of identity provider. We must update all clients and users
logger.debug("Changing providerId in all clients and linked users. oldProviderId=" + oldProviderId + ", newProviderId=" + newProviderId); logger.debug("Changing providerId in all clients and linked users. oldProviderId=" + oldProviderId + ", newProviderId=" + newProviderId);
updateUsersAfterProviderAliasChange(session.users().getUsers(realm, false), oldProviderId, newProviderId, realm, session); updateUsersAfterProviderAliasChange(session.users().getUsersStream(realm, false),
oldProviderId, newProviderId, realm, session);
} }
} }
@ -212,8 +213,8 @@ public class IdentityProviderResource {
providerRep.setInternalId(identityProviderModel.getInternalId()); providerRep.setInternalId(identityProviderModel.getInternalId());
} }
private static void updateUsersAfterProviderAliasChange(List<UserModel> users, String oldProviderId, String newProviderId, RealmModel realm, KeycloakSession session) { private static void updateUsersAfterProviderAliasChange(Stream<UserModel> users, String oldProviderId, String newProviderId, RealmModel realm, KeycloakSession session) {
for (UserModel user : users) { users.forEach(user -> {
FederatedIdentityModel federatedIdentity = session.users().getFederatedIdentity(user, oldProviderId, realm); FederatedIdentityModel federatedIdentity = session.users().getFederatedIdentity(user, oldProviderId, realm);
if (federatedIdentity != null) { if (federatedIdentity != null) {
// Remove old link first // Remove old link first
@ -224,7 +225,7 @@ public class IdentityProviderResource {
federatedIdentity.getToken()); federatedIdentity.getToken());
session.users().addFederatedIdentity(realm, user, newFederatedIdentity); session.users().addFederatedIdentity(realm, user, newFederatedIdentity);
} }
} });
} }

View file

@ -389,19 +389,19 @@ public class RoleContainerResource extends RoleResource {
} }
/** /**
* Return List of Users that have the specified role name * Returns a stream of users that have the specified role name.
* *
* *
* @param roleName * @param roleName the role name.
* @param firstResult * @param firstResult first result to return. Ignored if negative or {@code null}.
* @param maxResults * @param maxResults maximum number of results to return. Ignored if negative or {@code null}.
* @return initialized manage permissions reference * @return a non-empty {@code Stream} of users.
*/ */
@Path("{role-name}/users") @Path("{role-name}/users")
@GET @GET
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@NoCache @NoCache
public List<UserRepresentation> getUsersInRole(final @PathParam("role-name") String roleName, public Stream<UserRepresentation> getUsersInRole(final @PathParam("role-name") String roleName,
@QueryParam("first") Integer firstResult, @QueryParam("first") Integer firstResult,
@QueryParam("max") Integer maxResults) { @QueryParam("max") Integer maxResults) {
@ -410,30 +410,23 @@ public class RoleContainerResource extends RoleResource {
maxResults = maxResults != null ? maxResults : Constants.DEFAULT_MAX_RESULTS; maxResults = maxResults != null ? maxResults : Constants.DEFAULT_MAX_RESULTS;
RoleModel role = roleContainer.getRole(roleName); RoleModel role = roleContainer.getRole(roleName);
if (role == null) { if (role == null) {
throw new NotFoundException("Could not find role"); throw new NotFoundException("Could not find role");
} }
List<UserRepresentation> results = new ArrayList<UserRepresentation>(); return session.users().getRoleMembersStream(realm, role, firstResult, maxResults)
List<UserModel> userModels = session.users().getRoleMembers(realm, role, firstResult, maxResults); .map(user -> ModelToRepresentation.toRepresentation(session, realm, user));
for (UserModel user : userModels) {
results.add(ModelToRepresentation.toRepresentation(session, realm, user));
}
return results;
} }
/** /**
* Return List of Groups that have the specified role name * Returns a stream of groups that have the specified role name
* *
* *
* @param roleName * @param roleName the role name.
* @param firstResult * @param firstResult first result to return. Ignored if negative or {@code null}.
* @param maxResults * @param maxResults maximum number of results to return. Ignored if negative or {@code null}.
* @param briefRepresentation if false, return a full representation of the GroupRepresentation objects * @param briefRepresentation if false, return a full representation of the {@code GroupRepresentation} objects.
* @return * @return a non-empty {@code Stream} of groups.
*/ */
@Path("{role-name}/groups") @Path("{role-name}/groups")
@GET @GET
@ -449,13 +442,11 @@ public class RoleContainerResource extends RoleResource {
maxResults = maxResults != null ? maxResults : Constants.DEFAULT_MAX_RESULTS; maxResults = maxResults != null ? maxResults : Constants.DEFAULT_MAX_RESULTS;
RoleModel role = roleContainer.getRole(roleName); RoleModel role = roleContainer.getRole(roleName);
if (role == null) { if (role == null) {
throw new NotFoundException("Could not find role"); throw new NotFoundException("Could not find role");
} }
Stream<GroupModel> groupsModel = session.groups().getGroupsByRoleStream(realm, role, firstResult, maxResults); return session.groups().getGroupsByRoleStream(realm, role, firstResult, maxResults)
.map(g -> ModelToRepresentation.toRepresentation(g, !briefRepresentation));
return groupsModel.map(g -> ModelToRepresentation.toRepresentation(g, !briefRepresentation));
} }
} }

View file

@ -240,7 +240,7 @@ public class UserResource {
UserRepresentation rep = ModelToRepresentation.toRepresentation(session, realm, user); UserRepresentation rep = ModelToRepresentation.toRepresentation(session, realm, user);
if (realm.isIdentityFederationEnabled()) { if (realm.isIdentityFederationEnabled()) {
List<FederatedIdentityRepresentation> reps = getFederatedIdentities(user); List<FederatedIdentityRepresentation> reps = getFederatedIdentities(user).collect(Collectors.toList());
rep.setFederatedIdentities(reps); rep.setFederatedIdentities(reps);
} }
@ -358,30 +358,22 @@ public class UserResource {
/** /**
* Get social logins associated with the user * Get social logins associated with the user
* *
* @return * @return a non-null {@code Stream} of social logins (federated identities).
*/ */
@Path("federated-identity") @Path("federated-identity")
@GET @GET
@NoCache @NoCache
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public List<FederatedIdentityRepresentation> getFederatedIdentity() { public Stream<FederatedIdentityRepresentation> getFederatedIdentity() {
auth.users().requireView(user); auth.users().requireView(user);
return getFederatedIdentities(user); return getFederatedIdentities(user);
} }
private List<FederatedIdentityRepresentation> getFederatedIdentities(UserModel user) { private Stream<FederatedIdentityRepresentation> getFederatedIdentities(UserModel user) {
Set<FederatedIdentityModel> identities = session.users().getFederatedIdentities(user, realm);
List<FederatedIdentityRepresentation> result = new ArrayList<FederatedIdentityRepresentation>();
Set<String> idps = realm.getIdentityProvidersStream().map(IdentityProviderModel::getAlias).collect(Collectors.toSet()); Set<String> idps = realm.getIdentityProvidersStream().map(IdentityProviderModel::getAlias).collect(Collectors.toSet());
return session.users().getFederatedIdentitiesStream(user, realm)
for (FederatedIdentityModel identity : identities) { .filter(identity -> idps.contains(identity.getIdentityProvider()))
if (idps.contains(identity.getIdentityProvider())) { .map(ModelToRepresentation::toRepresentation);
FederatedIdentityRepresentation rep = ModelToRepresentation.toRepresentation(identity);
result.add(rep);
}
}
return result;
} }
/** /**
@ -431,15 +423,14 @@ public class UserResource {
@GET @GET
@NoCache @NoCache
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public List<Map<String, Object>> getConsents() { public Stream<Map<String, Object>> getConsents() {
auth.users().requireView(user); auth.users().requireView(user);
Set<ClientModel> offlineClients = new UserSessionManager(session).findClientsWithOfflineToken(realm, user); Set<ClientModel> offlineClients = new UserSessionManager(session).findClientsWithOfflineToken(realm, user);
return realm.getClientsStream() return realm.getClientsStream()
.map(client -> toConsent(client, offlineClients)) .map(client -> toConsent(client, offlineClients))
.filter(Objects::nonNull) .filter(Objects::nonNull);
.collect(Collectors.toList());
} }
private Map<String, Object> toConsent(ClientModel client, Set<ClientModel> offlineClients) { private Map<String, Object> toConsent(ClientModel client, Set<ClientModel> offlineClients) {
@ -607,11 +598,11 @@ public class UserResource {
@Path("credentials") @Path("credentials")
@NoCache @NoCache
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public List<CredentialRepresentation> credentials(){ public Stream<CredentialRepresentation> credentials(){
auth.users().requireManage(user); auth.users().requireManage(user);
List<CredentialModel> models = session.userCredentialManager().getStoredCredentials(realm, user); return session.userCredentialManager().getStoredCredentials(realm, user).stream()
models.forEach(c -> c.setSecretData(null)); .peek(model -> model.setSecretData(null))
return models.stream().map(ModelToRepresentation::toRepresentation).collect(Collectors.toList()); .map(ModelToRepresentation::toRepresentation);
} }

View file

@ -25,7 +25,6 @@ import org.keycloak.events.admin.OperationType;
import org.keycloak.events.admin.ResourceType; import org.keycloak.events.admin.ResourceType;
import org.keycloak.models.Constants; import org.keycloak.models.Constants;
import org.keycloak.models.GroupModel; import org.keycloak.models.GroupModel;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.ModelException; import org.keycloak.models.ModelException;
@ -53,12 +52,10 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Stream;
/** /**
* Base resource for managing users * Base resource for managing users
@ -205,7 +202,7 @@ public class UsersResource {
/** /**
* Get users * Get users
* *
* Returns a list of users, filtered according to query parameters * Returns a stream of users, filtered according to query parameters
* *
* @param search A String contained in username, first or last name, or email * @param search A String contained in username, first or last name, or email
* @param last A String contained in lastName, or the complete lastName, if param "exact" is true * @param last A String contained in lastName, or the complete lastName, if param "exact" is true
@ -220,12 +217,12 @@ public class UsersResource {
* @param enabled Boolean representing if user is enabled or not * @param enabled Boolean representing if user is enabled or not
* @param briefRepresentation Boolean which defines whether brief representations are returned (default: false) * @param briefRepresentation Boolean which defines whether brief representations are returned (default: false)
* @param exact Boolean which defines whether the params "last", "first", "email" and "username" must match exactly * @param exact Boolean which defines whether the params "last", "first", "email" and "username" must match exactly
* @return the list of users * @return a non-null {@code Stream} of users
*/ */
@GET @GET
@NoCache @NoCache
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public List<UserRepresentation> getUsers(@QueryParam("search") String search, public Stream<UserRepresentation> getUsers(@QueryParam("search") String search,
@QueryParam("lastName") String last, @QueryParam("lastName") String last,
@QueryParam("firstName") String first, @QueryParam("firstName") String first,
@QueryParam("email") String email, @QueryParam("email") String email,
@ -245,13 +242,13 @@ public class UsersResource {
firstResult = firstResult != null ? firstResult : -1; firstResult = firstResult != null ? firstResult : -1;
maxResults = maxResults != null ? maxResults : Constants.DEFAULT_MAX_RESULTS; maxResults = maxResults != null ? maxResults : Constants.DEFAULT_MAX_RESULTS;
List<UserModel> userModels = Collections.emptyList(); Stream<UserModel> userModels = Stream.empty();
if (search != null) { if (search != null) {
if (search.startsWith(SEARCH_ID_PARAMETER)) { if (search.startsWith(SEARCH_ID_PARAMETER)) {
UserModel userModel = UserModel userModel =
session.users().getUserById(search.substring(SEARCH_ID_PARAMETER.length()).trim(), realm); session.users().getUserById(search.substring(SEARCH_ID_PARAMETER.length()).trim(), realm);
if (userModel != null) { if (userModel != null) {
userModels = Collections.singletonList(userModel); userModels = Stream.of(userModel);
} }
} else { } else {
Map<String, String> attributes = new HashMap<>(); Map<String, String> attributes = new HashMap<>();
@ -375,7 +372,7 @@ public class UsersResource {
} }
} }
private List<UserRepresentation> searchForUser(Map<String, String> attributes, RealmModel realm, UserPermissionEvaluator usersEvaluator, Boolean briefRepresentation, Integer firstResult, Integer maxResults, Boolean includeServiceAccounts) { private Stream<UserRepresentation> searchForUser(Map<String, String> attributes, RealmModel realm, UserPermissionEvaluator usersEvaluator, Boolean briefRepresentation, Integer firstResult, Integer maxResults, Boolean includeServiceAccounts) {
session.setAttribute(UserModel.INCLUDE_SERVICE_ACCOUNT, includeServiceAccounts); session.setAttribute(UserModel.INCLUDE_SERVICE_ACCOUNT, includeServiceAccounts);
if (!auth.users().canView()) { if (!auth.users().canView()) {
@ -386,30 +383,22 @@ public class UsersResource {
} }
} }
List<UserModel> userModels = session.users().searchForUser(attributes, realm, firstResult, maxResults); Stream<UserModel> userModels = session.users().searchForUserStream(attributes, realm, firstResult, maxResults);
return toRepresentation(realm, usersEvaluator, briefRepresentation, userModels); return toRepresentation(realm, usersEvaluator, briefRepresentation, userModels);
} }
private List<UserRepresentation> toRepresentation(RealmModel realm, UserPermissionEvaluator usersEvaluator, Boolean briefRepresentation, List<UserModel> userModels) { private Stream<UserRepresentation> toRepresentation(RealmModel realm, UserPermissionEvaluator usersEvaluator, Boolean briefRepresentation, Stream<UserModel> userModels) {
boolean briefRepresentationB = briefRepresentation != null && briefRepresentation; boolean briefRepresentationB = briefRepresentation != null && briefRepresentation;
List<UserRepresentation> results = new ArrayList<>();
boolean canViewGlobal = usersEvaluator.canView(); boolean canViewGlobal = usersEvaluator.canView();
usersEvaluator.grantIfNoPermission(session.getAttribute(UserModel.GROUPS) != null); usersEvaluator.grantIfNoPermission(session.getAttribute(UserModel.GROUPS) != null);
return userModels.filter(user -> canViewGlobal || usersEvaluator.canView(user))
for (UserModel user : userModels) { .map(user -> {
if (!canViewGlobal) {
if (!usersEvaluator.canView(user)) {
continue;
}
}
UserRepresentation userRep = briefRepresentationB UserRepresentation userRep = briefRepresentationB
? ModelToRepresentation.toBriefRepresentation(user) ? ModelToRepresentation.toBriefRepresentation(user)
: ModelToRepresentation.toRepresentation(session, realm, user); : ModelToRepresentation.toRepresentation(session, realm, user);
userRep.setAccess(usersEvaluator.getAccess(user)); userRep.setAccess(usersEvaluator.getAccess(user));
results.add(userRep); return userRep;
} });
return results;
} }
} }

View file

@ -29,6 +29,7 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
/** /**
* @author <a href="mailto:markus.till@bosch.io">Markus Till</a> * @author <a href="mailto:markus.till@bosch.io">Markus Till</a>
@ -115,10 +116,10 @@ public class UserUpdateHelper {
private static void updateAttributes(UserModel currentUser, Map<String, List<String>> updatedUser, boolean removeMissingAttributes) { private static void updateAttributes(UserModel currentUser, Map<String, List<String>> updatedUser, boolean removeMissingAttributes) {
for (Map.Entry<String, List<String>> attr : updatedUser.entrySet()) { for (Map.Entry<String, List<String>> attr : updatedUser.entrySet()) {
List<String> currentValue = currentUser.getAttribute(attr.getKey()); List<String> currentValue = currentUser.getAttributeStream(attr.getKey()).collect(Collectors.toList());
//In case of username we need to provide lower case values //In case of username we need to provide lower case values
List<String> updatedValue = attr.getKey().equals(UserModel.USERNAME) ? AttributeToLower(attr.getValue()) : attr.getValue(); List<String> updatedValue = attr.getKey().equals(UserModel.USERNAME) ? AttributeToLower(attr.getValue()) : attr.getValue();
if ((currentValue == null || currentValue.size() != updatedValue.size() || !currentValue.containsAll(updatedValue))) { if (currentValue.size() != updatedValue.size() || !currentValue.containsAll(updatedValue)) {
currentUser.setAttribute(attr.getKey(), updatedValue); currentUser.setAttribute(attr.getKey(), updatedValue);
} }
} }

View file

@ -10,6 +10,7 @@ import org.keycloak.models.UserModel;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
public class ConditionalUserAttributeValue implements ConditionalAuthenticator { public class ConditionalUserAttributeValue implements ConditionalAuthenticator {
@ -31,11 +32,7 @@ public class ConditionalUserAttributeValue implements ConditionalAuthenticator {
throw new AuthenticationFlowException("authenticator: " + ConditionalUserAttributeValueFactory.PROVIDER_ID, AuthenticationFlowError.UNKNOWN_USER); throw new AuthenticationFlowException("authenticator: " + ConditionalUserAttributeValueFactory.PROVIDER_ID, AuthenticationFlowError.UNKNOWN_USER);
} }
List<String> lstValues = user.getAttribute(attributeName); result = user.getAttributeStream(attributeName).anyMatch(attr -> Objects.equals(attr, attributeValue));
if (lstValues != null) {
result = lstValues.contains(attributeValue);
}
if (negateOutput) { if (negateOutput) {
result = !result; result = !result;
} }

View file

@ -7,9 +7,9 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
public class SetUserAttributeAuthenticator implements Authenticator { public class SetUserAttributeAuthenticator implements Authenticator {
@Override @Override
@ -20,11 +20,11 @@ public class SetUserAttributeAuthenticator implements Authenticator {
String attrValue = config.get(SetUserAttributeAuthenticatorFactory.CONF_ATTR_VALUE); String attrValue = config.get(SetUserAttributeAuthenticatorFactory.CONF_ATTR_VALUE);
UserModel user = context.getUser(); UserModel user = context.getUser();
if (user.getAttribute(attrName) == null) { List<String> attrValues = user.getAttributeStream(attrName).collect(Collectors.toList());
if (attrValues.isEmpty()) {
user.setSingleAttribute(attrName, attrValue); user.setSingleAttribute(attrName, attrValue);
} }
else { else {
List<String> attrValues = new ArrayList<>(user.getAttribute(attrName));
if (!attrValues.contains(attrValue)) { if (!attrValues.contains(attrValue)) {
attrValues.add(attrValue); attrValues.add(attrValue);
} }

View file

@ -33,7 +33,10 @@ import org.keycloak.storage.user.UserLookupProvider;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
/** /**
* Provides one user where everything is stored in user federated storage * Provides one user where everything is stored in user federated storage
@ -80,9 +83,12 @@ public class PassThroughFederatedUserStorageProvider implements
if (INITIAL_PASSWORD.equals(input.getChallengeResponse())) { if (INITIAL_PASSWORD.equals(input.getChallengeResponse())) {
return true; return true;
} }
List<CredentialModel> existing = session.userFederatedStorage().getStoredCredentialsByType(realm, user.getId(), "CLEAR_TEXT_PASSWORD"); Optional<CredentialModel> existing = session.userFederatedStorage()
if (existing.isEmpty()) return false; .getStoredCredentialsByTypeStream(realm, user.getId(), "CLEAR_TEXT_PASSWORD")
return existing.get(0).getSecretData().equals("{\"value\":\"" + input.getChallengeResponse() + "\"}"); .findFirst();
if (existing.isPresent())
return existing.get().getSecretData().equals("{\"value\":\"" + input.getChallengeResponse() + "\"}");
return false;
} }
return false; return false;
} }
@ -91,18 +97,19 @@ public class PassThroughFederatedUserStorageProvider implements
public boolean updateCredential(RealmModel realm, UserModel user, CredentialInput input) { public boolean updateCredential(RealmModel realm, UserModel user, CredentialInput input) {
// testing federated credential attributes // testing federated credential attributes
if (input.getType().equals(PasswordCredentialModel.TYPE)) { if (input.getType().equals(PasswordCredentialModel.TYPE)) {
List<CredentialModel> existing = session.userFederatedStorage().getStoredCredentialsByType(realm, user.getId(), "CLEAR_TEXT_PASSWORD"); Optional<CredentialModel> existing = session.userFederatedStorage()
if (existing.isEmpty()) { .getStoredCredentialsByTypeStream(realm, user.getId(), "CLEAR_TEXT_PASSWORD")
.findFirst();
if (existing.isPresent()) {
CredentialModel model = existing.get();
model.setType("CLEAR_TEXT_PASSWORD");
model.setSecretData("{\"value\":\"" + input.getChallengeResponse() + "\"}");
session.userFederatedStorage().updateCredential(realm, user.getId(), model);
} else {
CredentialModel model = new CredentialModel(); CredentialModel model = new CredentialModel();
model.setType("CLEAR_TEXT_PASSWORD"); model.setType("CLEAR_TEXT_PASSWORD");
model.setSecretData("{\"value\":\"" + input.getChallengeResponse() + "\"}"); model.setSecretData("{\"value\":\"" + input.getChallengeResponse() + "\"}");
session.userFederatedStorage().createCredential(realm, user.getId(), model); session.userFederatedStorage().createCredential(realm, user.getId(), model);
} else {
CredentialModel model = existing.get(0);
model.setType("CLEAR_TEXT_PASSWORD");
model.setSecretData("{\"value\":\"" + input.getChallengeResponse() + "\"}");
session.userFederatedStorage().updateCredential(realm, user.getId(), model);
} }
return true; return true;
} }
@ -111,10 +118,9 @@ public class PassThroughFederatedUserStorageProvider implements
@Override @Override
public void disableCredentialType(RealmModel realm, UserModel user, String credentialType) { public void disableCredentialType(RealmModel realm, UserModel user, String credentialType) {
List<CredentialModel> existing = session.userFederatedStorage().getStoredCredentialsByType(realm, user.getId(), "CLEAR_TEXT_PASSWORD"); session.userFederatedStorage().getStoredCredentialsByTypeStream(realm, user.getId(), "CLEAR_TEXT_PASSWORD")
for (CredentialModel model : existing) { .collect(Collectors.toList())
session.userFederatedStorage().removeStoredCredential(realm, user.getId(), model.getId()); .forEach(credModel -> session.userFederatedStorage().removeStoredCredential(realm, user.getId(), credModel.getId()));
}
} }
@Override @Override
@ -142,15 +148,13 @@ public class PassThroughFederatedUserStorageProvider implements
@Override @Override
public UserModel getUserByEmail(String email, RealmModel realm) { public UserModel getUserByEmail(String email, RealmModel realm) {
List<String> list = session.userFederatedStorage().getUsersByUserAttribute(realm, AbstractUserAdapterFederatedStorage.EMAIL_ATTRIBUTE, email); Optional<StorageId> result = session.userFederatedStorage()
for (String user : list) { .getUsersByUserAttributeStream(realm, AbstractUserAdapterFederatedStorage.EMAIL_ATTRIBUTE, email)
StorageId storageId = new StorageId(user); .map(StorageId::new)
if (!storageId.getExternalId().equals(PASSTHROUGH_USERNAME)) continue; .filter(storageId -> Objects.equals(storageId.getExternalId(), PASSTHROUGH_USERNAME))
if (!storageId.getProviderId().equals(component.getId())) continue; .filter(storageId -> Objects.equals(storageId.getProviderId(), component.getId()))
return getUserModel(realm); .findFirst();
return result.isPresent() ? getUserModel(realm) : null;
}
return null;
} }
private UserModel getUserModel(final RealmModel realm) { private UserModel getUserModel(final RealmModel realm) {

View file

@ -23,7 +23,6 @@ import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.UsersResource; import org.keycloak.admin.client.resource.UsersResource;
import org.keycloak.common.Profile; import org.keycloak.common.Profile;
import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
@ -41,8 +40,8 @@ import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.UpdateAccountInformationPage; import org.keycloak.testsuite.pages.UpdateAccountInformationPage;
import java.util.List; import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
@ -171,9 +170,7 @@ public class AccountLinkTest extends AbstractKeycloakTest {
private static void checkEmptyFederatedIdentities(KeycloakSession session) { private static void checkEmptyFederatedIdentities(KeycloakSession session) {
RealmModel realm = session.getContext().getRealm(); RealmModel realm = session.getContext().getRealm();
UserModel user = session.users().getUserByUsername("child", realm); UserModel user = session.users().getUserByUsername("child", realm);
Set<FederatedIdentityModel> identities1 = session.users() assertEquals(0, session.users().getFederatedIdentitiesStream(user, realm).count());
.getFederatedIdentities(user, realm);
assertTrue(identities1.isEmpty());
assertNull(session.users().getFederatedIdentity(user, PARENT_IDP, realm)); assertNull(session.users().getFederatedIdentity(user, PARENT_IDP, realm));
} }

View file

@ -47,6 +47,7 @@ import javax.naming.directory.SearchControls;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.keycloak.testsuite.util.LDAPTestUtils.getGroupDescriptionLDAPAttrName; import static org.keycloak.testsuite.util.LDAPTestUtils.getGroupDescriptionLDAPAttrName;
@ -170,19 +171,21 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
Assert.assertEquals(1, john.getGroupsStream("2018", 0, 10).count()); Assert.assertEquals(1, john.getGroupsStream("2018", 0, 10).count());
// 4 - Check through userProvider // 4 - Check through userProvider
List<UserModel> group1Members = session.users().getGroupMembers(appRealm, group1, 0, 10); List<UserModel> group1Members = session.users().getGroupMembersStream(appRealm, group1, 0, 10)
List<UserModel> group11Members = session.users().getGroupMembers(appRealm, group11, 0, 10); .collect(Collectors.toList());
List<UserModel> group12Members = session.users().getGroupMembers(appRealm, group12, 0, 10); List<UserModel> group11Members = session.users().getGroupMembersStream(appRealm, group11, 0, 10)
List<UserModel> groupTeam20162017Members = session.users().getGroupMembers(appRealm, groupTeam20162017, 0, 10); .collect(Collectors.toList());
List<UserModel> groupTeam20182019Members = session.users().getGroupMembers(appRealm, groupTeamChild20182019, 0, 10); Stream<UserModel> group12Members = session.users().getGroupMembersStream(appRealm, group12, 0, 10);
Stream<UserModel> groupTeam20162017Members = session.users().getGroupMembersStream(appRealm, groupTeam20162017, 0, 10);
Stream<UserModel> groupTeam20182019Members = session.users().getGroupMembersStream(appRealm, groupTeamChild20182019, 0, 10);
Assert.assertEquals(1, group1Members.size()); Assert.assertEquals(1, group1Members.size());
Assert.assertEquals("johnkeycloak", group1Members.get(0).getUsername()); Assert.assertEquals("johnkeycloak", group1Members.get(0).getUsername());
Assert.assertEquals(1, group11Members.size()); Assert.assertEquals(1, group11Members.size());
Assert.assertEquals("marykeycloak", group11Members.get(0).getUsername()); Assert.assertEquals("marykeycloak", group11Members.get(0).getUsername());
Assert.assertEquals(2, group12Members.size()); Assert.assertEquals(2, group12Members.count());
Assert.assertEquals(2, groupTeam20162017Members.size()); Assert.assertEquals(2, groupTeam20162017Members.count());
Assert.assertEquals(2, groupTeam20182019Members.size()); Assert.assertEquals(2, groupTeam20182019Members.count());
// 4 - Delete some group mappings and check they are deleted // 4 - Delete some group mappings and check they are deleted
@ -329,7 +332,8 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
Assert.assertEquals(3, dbGroupCount); Assert.assertEquals(3, dbGroupCount);
// Test the group mapping available for group12 // Test the group mapping available for group12
List<UserModel> group12Members = session.users().getGroupMembers(appRealm, group12, 0, 10); List<UserModel> group12Members = session.users().getGroupMembersStream(appRealm, group12, 0, 10)
.collect(Collectors.toList());
Assert.assertEquals(1, group12Members.size()); Assert.assertEquals(1, group12Members.size());
Assert.assertEquals("marykeycloak", group12Members.get(0).getUsername()); Assert.assertEquals("marykeycloak", group12Members.get(0).getUsername());
@ -344,8 +348,8 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12"); GroupModel group12 = KeycloakModelUtils.findGroupByPath(appRealm, "/group1/group12");
// Test the group mapping NOT available for group12 // Test the group mapping NOT available for group12
List<UserModel> group12Members = session.users().getGroupMembers(appRealm, group12, 0, 10); Stream<UserModel> group12Members = session.users().getGroupMembersStream(appRealm, group12, 0, 10);
Assert.assertEquals(0, group12Members.size()); Assert.assertEquals(0, group12Members.count());
}); });
} }
@ -365,9 +369,10 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ctx.getLdapProvider(), appRealm); GroupLDAPStorageMapper groupMapper = LDAPTestUtils.getGroupMapper(mapperModel, ctx.getLdapProvider(), appRealm);
LDAPObject maryLdap = ctx.getLdapProvider().loadLDAPUserByUsername(appRealm, "marykeycloak"); LDAPObject maryLdap = ctx.getLdapProvider().loadLDAPUserByUsername(appRealm, "marykeycloak");
List<UserModel> group1Members = session.users().getGroupMembers(appRealm, group1, 0, 10); List<UserModel> group1Members = session.users().getGroupMembersStream(appRealm, group1, 0, 10)
List<UserModel> group11Members = session.users().getGroupMembers(appRealm, group11, 0, 10); .collect(Collectors.toList());
List<UserModel> group12Members = session.users().getGroupMembers(appRealm, group12, 0, 10); List<UserModel> group11Members = session.users().getGroupMembersStream(appRealm, group11, 0, 10)
.collect(Collectors.toList());
Assert.assertEquals(1, group1Members.size()); Assert.assertEquals(1, group1Members.size());
Assert.assertEquals("marykeycloak", group1Members.get(0).getUsername()); Assert.assertEquals("marykeycloak", group1Members.get(0).getUsername());
Assert.assertEquals(1, group11Members.size()); Assert.assertEquals(1, group11Members.size());
@ -428,11 +433,13 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
Assert.assertEquals(4, dbGroupCount); Assert.assertEquals(4, dbGroupCount);
// Check getGroupMembers // Check getGroupMembers
List<UserModel> group1Members = session.users().getGroupMembers(appRealm, group1, 0, 10); Stream<UserModel> group1Members = session.users().getGroupMembersStream(appRealm, group1, 0, 10);
List<UserModel> group11Members = session.users().getGroupMembers(appRealm, group11, 0, 10); List<UserModel> group11Members = session.users().getGroupMembersStream(appRealm, group11, 0, 10)
List<UserModel> group12Members = session.users().getGroupMembers(appRealm, group12, 0, 10); .collect(Collectors.toList());
List<UserModel> group12Members = session.users().getGroupMembersStream(appRealm, group12, 0, 10)
.collect(Collectors.toList());
Assert.assertEquals(0, group1Members.size()); Assert.assertEquals(0, group1Members.count());
Assert.assertEquals(1, group11Members.size()); Assert.assertEquals(1, group11Members.size());
Assert.assertEquals("robkeycloak", group11Members.get(0).getUsername()); Assert.assertEquals("robkeycloak", group11Members.get(0).getUsername());
Assert.assertEquals(1, group12Members.size()); Assert.assertEquals(1, group12Members.size());
@ -450,11 +457,13 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
Assert.assertTrue(robGroups.contains(group12)); Assert.assertTrue(robGroups.contains(group12));
// Check getGroupMembers // Check getGroupMembers
group1Members = session.users().getGroupMembers(appRealm, group1, 0, 10); group1Members = session.users().getGroupMembersStream(appRealm, group1, 0, 10);
group11Members = session.users().getGroupMembers(appRealm, group11, 0, 10); group11Members = session.users().getGroupMembersStream(appRealm, group11, 0, 10)
group12Members = session.users().getGroupMembers(appRealm, group12, 0, 10); .collect(Collectors.toList());
group12Members = session.users().getGroupMembersStream(appRealm, group12, 0, 10)
.collect(Collectors.toList());
Assert.assertEquals(0, group1Members.size()); Assert.assertEquals(0, group1Members.count());
Assert.assertEquals(1, group11Members.size()); Assert.assertEquals(1, group11Members.size());
Assert.assertEquals("robkeycloak", group11Members.get(0).getUsername()); Assert.assertEquals("robkeycloak", group11Members.get(0).getUsername());
Assert.assertEquals(1, group12Members.size()); Assert.assertEquals(1, group12Members.size());
@ -506,7 +515,8 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
// 4 - Check group members. Just existing user rob should be present // 4 - Check group members. Just existing user rob should be present
groupMapper.syncDataFromFederationProviderToKeycloak(appRealm); groupMapper.syncDataFromFederationProviderToKeycloak(appRealm);
GroupModel kcGroup2 = KeycloakModelUtils.findGroupByPath(appRealm, "/group2"); GroupModel kcGroup2 = KeycloakModelUtils.findGroupByPath(appRealm, "/group2");
List<UserModel> groupUsers = session.users().getGroupMembers(appRealm, kcGroup2, 0, 5); List<UserModel> groupUsers = session.users().getGroupMembersStream(appRealm, kcGroup2, 0, 5)
.collect(Collectors.toList());
Assert.assertEquals(1, groupUsers.size()); Assert.assertEquals(1, groupUsers.size());
UserModel rob = groupUsers.get(0); UserModel rob = groupUsers.get(0);
Assert.assertEquals("jameskeycloak", rob.getUsername()); Assert.assertEquals("jameskeycloak", rob.getUsername());
@ -741,7 +751,8 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
Assert.assertTrue("User contains biggroup " + i, kcUser.getGroupsStream().collect(Collectors.toSet()).contains(kcBigGroup)); Assert.assertTrue("User contains biggroup " + i, kcUser.getGroupsStream().collect(Collectors.toSet()).contains(kcBigGroup));
} }
// check the group contains all the users as member // check the group contains all the users as member
List<UserModel> groupMembers = session.users().getGroupMembers(appRealm, kcBigGroup, 0, membersToTest); List<UserModel> groupMembers = session.users().getGroupMembersStream(appRealm, kcBigGroup, 0, membersToTest)
.collect(Collectors.toList());
Assert.assertEquals(membersToTest, groupMembers.size()); Assert.assertEquals(membersToTest, groupMembers.size());
Set<String> usernames = groupMembers.stream().map(u -> u.getUsername()).collect(Collectors.toSet()); Set<String> usernames = groupMembers.stream().map(u -> u.getUsername()).collect(Collectors.toSet());
for (int i = 0; i < membersToTest; i++) { for (int i = 0; i < membersToTest; i++) {
@ -784,9 +795,10 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest {
// check everything is OK // check everything is OK
GroupModel kcDeleteGroup = KeycloakModelUtils.findGroupByPath(appRealm, "/deletegroup"); GroupModel kcDeleteGroup = KeycloakModelUtils.findGroupByPath(appRealm, "/deletegroup");
UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm); UserModel mary = session.users().getUserByUsername("marykeycloak", appRealm);
List<UserModel> groupMembers = session.users().getGroupMembers(appRealm, kcDeleteGroup, 0, 5); List<UserModel> groupMembers = session.users().getGroupMembersStream(appRealm, kcDeleteGroup, 0, 5)
.collect(Collectors.toList());
Assert.assertEquals(1, groupMembers.size()); Assert.assertEquals(1, groupMembers.size());
Assert.assertEquals("marykeycloak", groupMembers.iterator().next().getUsername()); Assert.assertEquals("marykeycloak", groupMembers.get(0).getUsername());
Set<GroupModel> maryGroups = mary.getGroupsStream().collect(Collectors.toSet()); Set<GroupModel> maryGroups = mary.getGroupsStream().collect(Collectors.toSet());
Assert.assertEquals(1, maryGroups.size()); Assert.assertEquals(1, maryGroups.size());
Assert.assertEquals("deletegroup", maryGroups.iterator().next().getName()); Assert.assertEquals("deletegroup", maryGroups.iterator().next().getName());

View file

@ -139,7 +139,7 @@ public class LDAPMSADMapperTest extends AbstractLDAPTest {
Assert.assertEquals("firstName", user.getFirstName()); Assert.assertEquals("firstName", user.getFirstName());
Assert.assertEquals("lastName", user.getLastName()); Assert.assertEquals("lastName", user.getLastName());
Assert.assertTrue(user.isEnabled()); Assert.assertTrue(user.isEnabled());
Assert.assertEquals(0, user.getRequiredActions().size()); Assert.assertEquals(0, user.getRequiredActionsStream().count());
}); });
} }
} }

View file

@ -42,6 +42,7 @@ import java.util.Collection;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -132,7 +133,7 @@ public class LDAPMultipleAttributesTest extends AbstractLDAPTest {
Assert.assertTrue("Wilson".equals(user.getLastName()) || "Schneider".equals(user.getLastName())); Assert.assertTrue("Wilson".equals(user.getLastName()) || "Schneider".equals(user.getLastName()));
// Actually there are 2 postalCodes // Actually there are 2 postalCodes
List<String> postalCodes = user.getAttribute("postal_code"); List<String> postalCodes = user.getAttributeStream("postal_code").collect(Collectors.toList());
assertPostalCodes(postalCodes, "88441", "77332"); assertPostalCodes(postalCodes, "88441", "77332");
List<String> tmp = new LinkedList<>(); List<String> tmp = new LinkedList<>();
tmp.addAll(postalCodes); tmp.addAll(postalCodes);
@ -147,7 +148,7 @@ public class LDAPMultipleAttributesTest extends AbstractLDAPTest {
RealmModel appRealm = ctx.getRealm(); RealmModel appRealm = ctx.getRealm();
UserModel user = session.users().getUserByUsername("bwilson", appRealm); UserModel user = session.users().getUserByUsername("bwilson", appRealm);
List<String> postalCodes = user.getAttribute("postal_code"); List<String> postalCodes = user.getAttributeStream("postal_code").collect(Collectors.toList());
assertPostalCodes(postalCodes, "88441"); assertPostalCodes(postalCodes, "88441");
List<String> tmp = new LinkedList<>(); List<String> tmp = new LinkedList<>();
tmp.addAll(postalCodes); tmp.addAll(postalCodes);
@ -161,7 +162,7 @@ public class LDAPMultipleAttributesTest extends AbstractLDAPTest {
RealmModel appRealm = ctx.getRealm(); RealmModel appRealm = ctx.getRealm();
UserModel user = session.users().getUserByUsername("bwilson", appRealm); UserModel user = session.users().getUserByUsername("bwilson", appRealm);
assertPostalCodes(user.getAttribute("postal_code"), "88441", "77332"); assertPostalCodes(user.getAttributeStream("postal_code").collect(Collectors.toList()), "88441", "77332");
}); });
} }

View file

@ -20,6 +20,7 @@ package org.keycloak.testsuite.federation.ldap;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import javax.mail.MessagingException; import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage;
@ -231,7 +232,8 @@ public class LDAPNoCacheTest extends AbstractLDAPTest {
assumeThat(user, is(nullValue())); assumeThat(user, is(nullValue()));
// trigger import // trigger import
List<UserModel> byEmail = ldapProvider.searchForUserByUserAttribute("email", "john_old@email.org", realm); List<UserModel> byEmail = ldapProvider.searchForUserByUserAttributeStream("email", "john_old@email.org", realm)
.collect(Collectors.toList());
assumeThat(byEmail, hasSize(1)); assumeThat(byEmail, hasSize(1));
// assume that user has been imported // assume that user has been imported
@ -239,7 +241,8 @@ public class LDAPNoCacheTest extends AbstractLDAPTest {
assumeThat(user, is(not(nullValue()))); assumeThat(user, is(not(nullValue())));
// search a second time // search a second time
byEmail = ldapProvider.searchForUserByUserAttribute("email", "john_old@email.org", realm); byEmail = ldapProvider.searchForUserByUserAttributeStream("email", "john_old@email.org", realm)
.collect(Collectors.toList());
assertThat(byEmail, hasSize(1)); assertThat(byEmail, hasSize(1));
}); });
} }

View file

@ -34,6 +34,7 @@ import org.keycloak.testsuite.util.LDAPTestUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.stream.Collectors;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.empty;
@ -155,9 +156,9 @@ public class LDAPProvidersFullNameMapperTest extends AbstractLDAPTest {
LDAPTestAsserts.assertUserImported(session.users(), appRealm, "fullname", "James", "Dee", "fullname@email.org", "4578"); LDAPTestAsserts.assertUserImported(session.users(), appRealm, "fullname", "James", "Dee", "fullname@email.org", "4578");
UserModel fullnameUser = session.users().getUserByUsername("fullname", appRealm); UserModel fullnameUser = session.users().getUserByUsername("fullname", appRealm);
assertThat(fullnameUser.getAttribute("myAttribute"), contains("test")); assertThat(fullnameUser.getAttributeStream("myAttribute").collect(Collectors.toList()), contains("test"));
assertThat(fullnameUser.getAttribute("myEmptyAttribute"), is(empty())); assertThat(fullnameUser.getAttributeStream("myEmptyAttribute").collect(Collectors.toList()), is(empty()));
assertThat(fullnameUser.getAttribute("myNullAttribute"), is(empty())); assertThat(fullnameUser.getAttributeStream("myNullAttribute").collect(Collectors.toList()), is(empty()));
// Remove "fullnameUser" to assert he is removed from LDAP. // Remove "fullnameUser" to assert he is removed from LDAP.
session.users().removeUser(appRealm, fullnameUser); session.users().removeUser(appRealm, fullnameUser);

View file

@ -71,11 +71,11 @@ import javax.ws.rs.core.Response;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -468,9 +468,7 @@ public class LDAPProvidersIntegrationTest extends AbstractLDAPTest {
LDAPTestUtils.removeLDAPUserByUsername(ctx.getLdapProvider(), ctx.getRealm(), config, "maryjane"); LDAPTestUtils.removeLDAPUserByUsername(ctx.getLdapProvider(), ctx.getRealm(), config, "maryjane");
// Make sure the deletion took place. // Make sure the deletion took place.
List<UserModel> deletedUsers = session.users().searchForUser("mary yram", ctx.getRealm()); Assert.assertEquals(0, session.users().searchForUserStream("mary yram", ctx.getRealm()).count());
Assert.assertTrue(deletedUsers.isEmpty());
}); });
} }
@ -818,20 +816,20 @@ public class LDAPProvidersIntegrationTest extends AbstractLDAPTest {
Assert.assertNull(session.userLocalStorage().getUserByUsername("username3", appRealm)); Assert.assertNull(session.userLocalStorage().getUserByUsername("username3", appRealm));
Assert.assertNull(session.userLocalStorage().getUserByUsername("username4", appRealm)); Assert.assertNull(session.userLocalStorage().getUserByUsername("username4", appRealm));
// search by username // search by username (we use a terminal operation on the stream to ensure it is consumed)
session.users().searchForUser("username1", appRealm); session.users().searchForUserStream("username1", appRealm).count();
LDAPTestAsserts.assertUserImported(session.userLocalStorage(), appRealm, "username1", "John1", "Doel1", "user1@email.org", "121"); LDAPTestAsserts.assertUserImported(session.userLocalStorage(), appRealm, "username1", "John1", "Doel1", "user1@email.org", "121");
// search by email // search by email (we use a terminal operation on the stream to ensure it is consumed)
session.users().searchForUser("user2@email.org", appRealm); session.users().searchForUserStream("user2@email.org", appRealm).count();
LDAPTestAsserts.assertUserImported(session.userLocalStorage(), appRealm, "username2", "John2", "Doel2", "user2@email.org", "122"); LDAPTestAsserts.assertUserImported(session.userLocalStorage(), appRealm, "username2", "John2", "Doel2", "user2@email.org", "122");
// search by lastName // search by lastName (we use a terminal operation on the stream to ensure it is consumed)
session.users().searchForUser("Doel3", appRealm); session.users().searchForUserStream("Doel3", appRealm).count();
LDAPTestAsserts.assertUserImported(session.userLocalStorage(), appRealm, "username3", "John3", "Doel3", "user3@email.org", "123"); LDAPTestAsserts.assertUserImported(session.userLocalStorage(), appRealm, "username3", "John3", "Doel3", "user3@email.org", "123");
// search by firstName + lastName // search by firstName + lastName (we use a terminal operation on the stream to ensure it is consumed)
session.users().searchForUser("John4 Doel4", appRealm); session.users().searchForUserStream("John4 Doel4", appRealm).count();
LDAPTestAsserts.assertUserImported(session.userLocalStorage(), appRealm, "username4", "John4", "Doel4", "user4@email.org", "124"); LDAPTestAsserts.assertUserImported(session.userLocalStorage(), appRealm, "username4", "John4", "Doel4", "user4@email.org", "124");
}); });
} }
@ -855,15 +853,15 @@ public class LDAPProvidersIntegrationTest extends AbstractLDAPTest {
LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "username6", "John6", "Doel6", "user6@email.org", null, "126"); LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "username6", "John6", "Doel6", "user6@email.org", null, "126");
LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "username7", "John7", "Doel7", "user7@email.org", null, "127"); LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "username7", "John7", "Doel7", "user7@email.org", null, "127");
// search by email // search by email (we use a terminal operation on the stream to ensure it is consumed)
List<UserModel> list = session.users().searchForUser("user5@email.org", appRealm); session.users().searchForUserStream("user5@email.org", appRealm).count();
LDAPTestAsserts.assertUserImported(session.userLocalStorage(), appRealm, "username5", "John5", "Doel5", "user5@email.org", "125"); LDAPTestAsserts.assertUserImported(session.userLocalStorage(), appRealm, "username5", "John5", "Doel5", "user5@email.org", "125");
session.users().searchForUser("John6 Doel6", appRealm); session.users().searchForUserStream("John6 Doel6", appRealm).count();
LDAPTestAsserts.assertUserImported(session.userLocalStorage(), appRealm, "username6", "John6", "Doel6", "user6@email.org", "126"); LDAPTestAsserts.assertUserImported(session.userLocalStorage(), appRealm, "username6", "John6", "Doel6", "user6@email.org", "126");
session.users().searchForUser("user7@email.org", appRealm); session.users().searchForUserStream("user7@email.org", appRealm).count();
session.users().searchForUser("John7 Doel7", appRealm); session.users().searchForUserStream("John7 Doel7", appRealm).count();
Assert.assertNull(session.userLocalStorage().getUserByUsername("username7", appRealm)); Assert.assertNull(session.userLocalStorage().getUserByUsername("username7", appRealm));
// Remove custom filter // Remove custom filter
@ -966,15 +964,16 @@ public class LDAPProvidersIntegrationTest extends AbstractLDAPTest {
Assert.assertNull(session.userLocalStorage().getUserByUsername("username10", appRealm)); Assert.assertNull(session.userLocalStorage().getUserByUsername("username10", appRealm));
// search for user by attribute // search for user by attribute
List<UserModel> users = ctx.getLdapProvider().searchForUserByUserAttribute(ATTRIBUTE, ATTRIBUTE_VALUE, appRealm); List<UserModel> users = ctx.getLdapProvider().searchForUserByUserAttributeStream(ATTRIBUTE, ATTRIBUTE_VALUE, appRealm)
.collect(Collectors.toList());
assertEquals(2, users.size()); assertEquals(2, users.size());
assertNotNull(users.get(0).getAttribute(ATTRIBUTE)); List<String> attrList = users.get(0).getAttributeStream(ATTRIBUTE).collect(Collectors.toList());
assertEquals(1, users.get(0).getAttribute(ATTRIBUTE).size()); assertEquals(1, attrList.size());
assertEquals(ATTRIBUTE_VALUE, users.get(0).getAttribute(ATTRIBUTE).get(0)); assertEquals(ATTRIBUTE_VALUE, attrList.get(0));
assertNotNull(users.get(1).getAttribute(ATTRIBUTE)); attrList = users.get(1).getAttributeStream(ATTRIBUTE).collect(Collectors.toList());
assertEquals(1, users.get(1).getAttribute(ATTRIBUTE).size()); assertEquals(1, attrList.size());
assertEquals(ATTRIBUTE_VALUE, users.get(1).getAttribute(ATTRIBUTE).get(0)); assertEquals(ATTRIBUTE_VALUE, attrList.get(0));
// user are now imported to local store // user are now imported to local store
LDAPTestAsserts.assertUserImported(session.userLocalStorage(), appRealm, "username8", "John8", "Doel8", "user8@email.org", ATTRIBUTE_VALUE); LDAPTestAsserts.assertUserImported(session.userLocalStorage(), appRealm, "username8", "John8", "Doel8", "user8@email.org", ATTRIBUTE_VALUE);
@ -1130,8 +1129,8 @@ public class LDAPProvidersIntegrationTest extends AbstractLDAPTest {
testingClient.server().run(session -> { testingClient.server().run(session -> {
RealmModel appRealm = session.realms().getRealmByName(TEST_REALM_NAME); RealmModel appRealm = session.realms().getRealmByName(TEST_REALM_NAME);
List<UserModel> userVerified = session.users().searchForUser("john@test.com", appRealm); Optional<UserModel> userVerified = session.users().searchForUserStream("john@test.com", appRealm).findFirst();
Assert.assertTrue(userVerified.get(0).isEmailVerified()); Assert.assertTrue(userVerified.get().isEmailVerified());
}); });
//Test untrusted email option //Test untrusted email option
@ -1147,8 +1146,8 @@ public class LDAPProvidersIntegrationTest extends AbstractLDAPTest {
testingClient.server().run(session -> { testingClient.server().run(session -> {
RealmModel appRealm = session.realms().getRealmByName(TEST_REALM_NAME); RealmModel appRealm = session.realms().getRealmByName(TEST_REALM_NAME);
List<UserModel> userNotVerified = session.users().searchForUser("john2@test.com", appRealm); Optional<UserModel> userNotVerified = session.users().searchForUserStream("john2@test.com", appRealm).findFirst();
Assert.assertFalse(userNotVerified.get(0).isEmailVerified()); Assert.assertFalse(userNotVerified.get().isEmailVerified());
}); });
} }

View file

@ -76,15 +76,15 @@ public class LDAPRoleMapperTest extends AbstractLDAPTest {
// check groups // check groups
RoleModel group1 = appRealm.getRole("group1"); RoleModel group1 = appRealm.getRole("group1");
Assert.assertNotNull(group1); Assert.assertNotNull(group1);
Assert.assertThat(session.users().getRoleMembers(appRealm, group1).stream().map(UserModel::getUsername).collect(Collectors.toSet()), Assert.assertThat(session.users().getRoleMembersStream(appRealm, group1).map(UserModel::getUsername).collect(Collectors.toSet()),
Matchers.containsInAnyOrder("johnkeycloak", "marykeycloak", "robkeycloak")); Matchers.containsInAnyOrder("johnkeycloak", "marykeycloak", "robkeycloak"));
RoleModel group2 = appRealm.getRole("group2"); RoleModel group2 = appRealm.getRole("group2");
Assert.assertNotNull(group2); Assert.assertNotNull(group2);
Assert.assertThat(session.users().getRoleMembers(appRealm, group2).stream().map(UserModel::getUsername).collect(Collectors.toSet()), Assert.assertThat(session.users().getRoleMembersStream(appRealm, group2).map(UserModel::getUsername).collect(Collectors.toSet()),
Matchers.containsInAnyOrder("johnkeycloak", "marykeycloak")); Matchers.containsInAnyOrder("johnkeycloak", "marykeycloak"));
RoleModel group3 = appRealm.getRole("group3"); RoleModel group3 = appRealm.getRole("group3");
Assert.assertNotNull(group3); Assert.assertNotNull(group3);
Assert.assertThat(session.users().getRoleMembers(appRealm, group3), Matchers.empty()); Assert.assertThat(session.users().getRoleMembersStream(appRealm, group3).collect(Collectors.toSet()), Matchers.empty());
}); });
} }
@ -124,15 +124,15 @@ public class LDAPRoleMapperTest extends AbstractLDAPTest {
// check groups // check groups
RoleModel group1 = rolesClient.getRole("group1"); RoleModel group1 = rolesClient.getRole("group1");
Assert.assertNotNull(group1); Assert.assertNotNull(group1);
Assert.assertThat(session.users().getRoleMembers(appRealm, group1).stream().map(UserModel::getUsername).collect(Collectors.toSet()), Assert.assertThat(session.users().getRoleMembersStream(appRealm, group1).map(UserModel::getUsername).collect(Collectors.toSet()),
Matchers.containsInAnyOrder("johnkeycloak", "marykeycloak", "robkeycloak")); Matchers.containsInAnyOrder("johnkeycloak", "marykeycloak", "robkeycloak"));
RoleModel group2 = rolesClient.getRole("group2"); RoleModel group2 = rolesClient.getRole("group2");
Assert.assertNotNull(group2); Assert.assertNotNull(group2);
Assert.assertThat(session.users().getRoleMembers(appRealm, group2).stream().map(UserModel::getUsername).collect(Collectors.toSet()), Assert.assertThat(session.users().getRoleMembersStream(appRealm, group2).map(UserModel::getUsername).collect(Collectors.toSet()),
Matchers.containsInAnyOrder("johnkeycloak", "marykeycloak")); Matchers.containsInAnyOrder("johnkeycloak", "marykeycloak"));
RoleModel group3 = rolesClient.getRole("group3"); RoleModel group3 = rolesClient.getRole("group3");
Assert.assertNotNull(group3); Assert.assertNotNull(group3);
Assert.assertThat(session.users().getRoleMembers(appRealm, group3), Matchers.empty()); Assert.assertThat(session.users().getRoleMembersStream(appRealm, group3).collect(Collectors.toSet()), Matchers.empty());
} finally { } finally {
appRealm.removeClient(rolesClient.getId()); appRealm.removeClient(rolesClient.getId());

View file

@ -168,12 +168,14 @@ public class LDAPSpecialCharsTest extends AbstractLDAPTest {
Assert.assertTrue(userGroups.contains(specialGroup)); Assert.assertTrue(userGroups.contains(specialGroup));
// 3 - Check through userProvider // 3 - Check through userProvider
List<UserModel> groupMembers = session.users().getGroupMembers(appRealm, specialGroup, 0, 10); List<UserModel> groupMembers = session.users().getGroupMembersStream(appRealm, specialGroup, 0, 10)
.collect(Collectors.toList());
Assert.assertEquals(1, groupMembers.size()); Assert.assertEquals(1, groupMembers.size());
Assert.assertEquals("jamees,key*cložak)ppp", groupMembers.get(0).getUsername()); Assert.assertEquals("jamees,key*cložak)ppp", groupMembers.get(0).getUsername());
groupMembers = session.users().getGroupMembers(appRealm, groupWithSlashes, 0, 10); groupMembers = session.users().getGroupMembersStream(appRealm, groupWithSlashes, 0, 10)
.collect(Collectors.toList());
Assert.assertEquals(1, groupMembers.size()); Assert.assertEquals(1, groupMembers.size());
Assert.assertEquals("jamees,key*cložak)ppp", groupMembers.get(0).getUsername()); Assert.assertEquals("jamees,key*cložak)ppp", groupMembers.get(0).getUsername());

View file

@ -17,6 +17,8 @@
package org.keycloak.testsuite.federation.ldap; package org.keycloak.testsuite.federation.ldap;
import java.util.stream.Collectors;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.junit.Assert; import org.junit.Assert;
import org.junit.ClassRule; import org.junit.ClassRule;
@ -246,9 +248,9 @@ public class LDAPSyncTest extends AbstractLDAPTest {
LDAPTestContext ctx = LDAPTestContext.init(session); LDAPTestContext ctx = LDAPTestContext.init(session);
// Remove all users from model // Remove all users from model
for (UserModel user : session.userLocalStorage().getUsers(ctx.getRealm(), true)) { session.userLocalStorage().getUsersStream(ctx.getRealm(), true)
session.userLocalStorage().removeUser(ctx.getRealm(), user); .collect(Collectors.toList())
} .forEach(user -> session.userLocalStorage().removeUser(ctx.getRealm(), user));
// Change name of UUID attribute to same like usernameAttribute // Change name of UUID attribute to same like usernameAttribute
String uidAttrName = ctx.getLdapProvider().getLdapIdentityStore().getConfig().getUsernameLdapAttribute(); String uidAttrName = ctx.getLdapProvider().getLdapIdentityStore().getConfig().getUsernameLdapAttribute();
@ -296,14 +298,16 @@ public class LDAPSyncTest extends AbstractLDAPTest {
LDAPTestContext ctx = LDAPTestContext.init(session); LDAPTestContext ctx = LDAPTestContext.init(session);
// Remove all users from model // Remove all users from model
for (UserModel user : session.userLocalStorage().getUsers(ctx.getRealm(), true)) { session.userLocalStorage().getUsersStream(ctx.getRealm(), true)
System.out.println("trying to delete user: " + user.getUsername()); .peek(user -> System.out.println("trying to delete user: " + user.getUsername()))
.collect(Collectors.toList())
.forEach(user -> {
UserCache userCache = session.userCache(); UserCache userCache = session.userCache();
if (userCache != null) { if (userCache != null) {
userCache.evict(ctx.getRealm(), user); userCache.evict(ctx.getRealm(), user);
} }
session.userLocalStorage().removeUser(ctx.getRealm(), user); session.userLocalStorage().removeUser(ctx.getRealm(), user);
} });
// Add street mapper and add some user including street // Add street mapper and add some user including street
ComponentModel streetMapper = LDAPTestUtils.addUserAttributeMapper(ctx.getRealm(), ctx.getLdapModel(), "streetMapper", "street", LDAPConstants.STREET); ComponentModel streetMapper = LDAPTestUtils.addUserAttributeMapper(ctx.getRealm(), ctx.getLdapModel(), "streetMapper", "street", LDAPConstants.STREET);

View file

@ -97,19 +97,19 @@ public class LDAPProvidersIntegrationNoImportTest extends LDAPProvidersIntegrati
LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "username4", "John4", "Doel4", "user4@email.org", null, "124"); LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "username4", "John4", "Doel4", "user4@email.org", null, "124");
// search by username // search by username
UserModel user = session.users().searchForUser("username1", appRealm).get(0); UserModel user = session.users().searchForUserStream("username1", appRealm).findFirst().get();
LDAPTestAsserts.assertLoaded(user, "username1", "John1", "Doel1", "user1@email.org", "121"); LDAPTestAsserts.assertLoaded(user, "username1", "John1", "Doel1", "user1@email.org", "121");
// search by email // search by email
user = session.users().searchForUser("user2@email.org", appRealm).get(0); user = session.users().searchForUserStream("user2@email.org", appRealm).findFirst().get();
LDAPTestAsserts.assertLoaded(user, "username2", "John2", "Doel2", "user2@email.org", "122"); LDAPTestAsserts.assertLoaded(user, "username2", "John2", "Doel2", "user2@email.org", "122");
// search by lastName // search by lastName
user = session.users().searchForUser("Doel3", appRealm).get(0); user = session.users().searchForUserStream("Doel3", appRealm).findFirst().get();
LDAPTestAsserts.assertLoaded(user, "username3", "John3", "Doel3", "user3@email.org", "123"); LDAPTestAsserts.assertLoaded(user, "username3", "John3", "Doel3", "user3@email.org", "123");
// search by firstName + lastName // search by firstName + lastName
user = session.users().searchForUser("John4 Doel4", appRealm).get(0); user = session.users().searchForUserStream("John4 Doel4", appRealm).findFirst().get();
LDAPTestAsserts.assertLoaded(user, "username4", "John4", "Doel4", "user4@email.org", "124"); LDAPTestAsserts.assertLoaded(user, "username4", "John4", "Doel4", "user4@email.org", "124");
}); });
} }
@ -144,14 +144,14 @@ public class LDAPProvidersIntegrationNoImportTest extends LDAPProvidersIntegrati
LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "username7", "John7", "Doel7", "user7@email.org", null, "127"); LDAPTestUtils.addLDAPUser(ctx.getLdapProvider(), appRealm, "username7", "John7", "Doel7", "user7@email.org", null, "127");
// search by email // search by email
UserModel user = session.users().searchForUser("user5@email.org", appRealm).get(0); UserModel user = session.users().searchForUserStream("user5@email.org", appRealm).findFirst().get();
LDAPTestAsserts.assertLoaded(user, "username5", "John5", "Doel5", "user5@email.org", "125"); LDAPTestAsserts.assertLoaded(user, "username5", "John5", "Doel5", "user5@email.org", "125");
user = session.users().searchForUser("John6 Doel6", appRealm).get(0); user = session.users().searchForUserStream("John6 Doel6", appRealm).findFirst().get();
LDAPTestAsserts.assertLoaded(user, "username6", "John6", "Doel6", "user6@email.org", "126"); LDAPTestAsserts.assertLoaded(user, "username6", "John6", "Doel6", "user6@email.org", "126");
Assert.assertTrue(session.users().searchForUser("user7@email.org", appRealm).isEmpty()); Assert.assertEquals(0, session.users().searchForUserStream("user7@email.org", appRealm).count());
Assert.assertTrue(session.users().searchForUser("John7 Doel7", appRealm).isEmpty()); Assert.assertEquals(0, session.users().searchForUserStream("John7 Doel7", appRealm).count());
// Remove custom filter // Remove custom filter
ctx.getLdapModel().getConfig().remove(LDAPConstants.CUSTOM_USER_SEARCH_FILTER); ctx.getLdapModel().getConfig().remove(LDAPConstants.CUSTOM_USER_SEARCH_FILTER);

View file

@ -42,6 +42,7 @@ import javax.ws.rs.NotFoundException;
import java.io.File; import java.io.File;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer; import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
@ -148,11 +149,12 @@ public class FederatedStorageExportImportTest extends AbstractAuthTest {
Assert.assertEquals("value1", attributes.getFirst("single1")); Assert.assertEquals("value1", attributes.getFirst("single1"));
Assert.assertTrue(attributes.getList("list1").contains("1")); Assert.assertTrue(attributes.getList("list1").contains("1"));
Assert.assertTrue(attributes.getList("list1").contains("2")); Assert.assertTrue(attributes.getList("list1").contains("2"));
Assert.assertTrue(session.userFederatedStorage().getRequiredActions(realm, userId).contains("UPDATE_PASSWORD")); Assert.assertTrue(session.userFederatedStorage().getRequiredActionsStream(realm, userId)
.collect(Collectors.toSet()).contains("UPDATE_PASSWORD"));
Assert.assertTrue(session.userFederatedStorage().getRoleMappingsStream(realm, userId) Assert.assertTrue(session.userFederatedStorage().getRoleMappingsStream(realm, userId)
.collect(Collectors.toSet()).contains(role)); .collect(Collectors.toSet()).contains(role));
Assert.assertTrue(session.userFederatedStorage().getGroupsStream(realm, userId).collect(Collectors.toSet()).contains(group)); Assert.assertTrue(session.userFederatedStorage().getGroupsStream(realm, userId).collect(Collectors.toSet()).contains(group));
List<CredentialModel> creds = session.userFederatedStorage().getStoredCredentials(realm, userId); List<CredentialModel> creds = session.userFederatedStorage().getStoredCredentialsStream(realm, userId).collect(Collectors.toList());
Assert.assertEquals(1, creds.size()); Assert.assertEquals(1, creds.size());
Assert.assertTrue(FederatedStorageExportImportTest.getHashProvider(session, realm.getPasswordPolicy()) Assert.assertTrue(FederatedStorageExportImportTest.getHashProvider(session, realm.getPasswordPolicy())
.verify("password", PasswordCredentialModel.createFromCredentialModel(creds.get(0)))); .verify("password", PasswordCredentialModel.createFromCredentialModel(creds.get(0))));
@ -216,12 +218,13 @@ public class FederatedStorageExportImportTest extends AbstractAuthTest {
Assert.assertEquals("value1", attributes.getFirst("single1")); Assert.assertEquals("value1", attributes.getFirst("single1"));
Assert.assertTrue(attributes.getList("list1").contains("1")); Assert.assertTrue(attributes.getList("list1").contains("1"));
Assert.assertTrue(attributes.getList("list1").contains("2")); Assert.assertTrue(attributes.getList("list1").contains("2"));
Assert.assertTrue(session.userFederatedStorage().getRequiredActions(realm, userId).contains("UPDATE_PASSWORD")); Assert.assertTrue(session.userFederatedStorage().getRequiredActionsStream(realm, userId)
.collect(Collectors.toSet()).contains("UPDATE_PASSWORD"));
Assert.assertTrue(session.userFederatedStorage().getRoleMappingsStream(realm, userId) Assert.assertTrue(session.userFederatedStorage().getRoleMappingsStream(realm, userId)
.collect(Collectors.toSet()).contains(role)); .collect(Collectors.toSet()).contains(role));
Assert.assertTrue(session.userFederatedStorage().getGroupsStream(realm, userId).collect(Collectors.toSet()).contains(group)); Assert.assertTrue(session.userFederatedStorage().getGroupsStream(realm, userId).collect(Collectors.toSet()).contains(group));
Assert.assertEquals(50, session.userFederatedStorage().getNotBeforeOfUser(realm, userId)); Assert.assertEquals(50, session.userFederatedStorage().getNotBeforeOfUser(realm, userId));
List<CredentialModel> creds = session.userFederatedStorage().getStoredCredentials(realm, userId); List<CredentialModel> creds = session.userFederatedStorage().getStoredCredentialsStream(realm, userId).collect(Collectors.toList());
Assert.assertEquals(1, creds.size()); Assert.assertEquals(1, creds.size());
Assert.assertTrue(FederatedStorageExportImportTest.getHashProvider(session, realm.getPasswordPolicy()) Assert.assertTrue(FederatedStorageExportImportTest.getHashProvider(session, realm.getPasswordPolicy())
.verify("password", PasswordCredentialModel.createFromCredentialModel(creds.get(0)))); .verify("password", PasswordCredentialModel.createFromCredentialModel(creds.get(0))));

View file

@ -55,8 +55,9 @@ import org.keycloak.testsuite.util.OAuthClient;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Stream;
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer; import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
import org.keycloak.testsuite.util.ContainerAssume; import org.keycloak.testsuite.util.ContainerAssume;
@ -308,34 +309,33 @@ public class UserStorageFailureTest extends AbstractTestRealmKeycloakTest {
UserModel local = session.users().getUserByUsername(LOCAL_USER, realm); UserModel local = session.users().getUserByUsername(LOCAL_USER, realm);
Assert.assertNotNull(local); Assert.assertNotNull(local);
List<UserModel> result; Stream<UserModel> result;
result = session.users().searchForUser(LOCAL_USER, realm); result = session.users().searchForUserStream(LOCAL_USER, realm);
Assert.assertEquals(1, result.size()); Assert.assertEquals(1, result.count());
session.users().searchForUser(FailableHardcodedStorageProvider.username, realm); result = session.users().searchForUserStream(FailableHardcodedStorageProvider.username, realm);
Assert.assertEquals(1, result.size()); Assert.assertEquals(1, result.count());
session.users().searchForUser(LOCAL_USER, realm, 0, 2); result = session.users().searchForUserStream(LOCAL_USER, realm, 0, 2);
Assert.assertEquals(1, result.size()); Assert.assertEquals(1, result.count());
session.users().searchForUser(FailableHardcodedStorageProvider.username, realm, 0, 2); result = session.users().searchForUserStream(FailableHardcodedStorageProvider.username, realm, 0, 2);
Assert.assertEquals(1, result.size()); Assert.assertEquals(1, result.count());
Map<String, String> localParam = new HashMap<>(); Map<String, String> localParam = new HashMap<>();
localParam.put("username", LOCAL_USER); localParam.put("username", LOCAL_USER);
Map<String, String> hardcodedParam = new HashMap<>(); Map<String, String> hardcodedParam = new HashMap<>();
hardcodedParam.put("username", FailableHardcodedStorageProvider.username); hardcodedParam.put("username", FailableHardcodedStorageProvider.username);
result = session.users().searchForUser(localParam, realm); result = session.users().searchForUserStream(localParam, realm);
Assert.assertEquals(1, result.size()); Assert.assertEquals(1, result.count());
session.users().searchForUser(hardcodedParam, realm); result = session.users().searchForUserStream(hardcodedParam, realm);
Assert.assertEquals(1, result.size()); Assert.assertEquals(1, result.count());
session.users().searchForUser(localParam, realm, 0, 2); result = session.users().searchForUserStream(localParam, realm, 0, 2);
Assert.assertEquals(1, result.size()); Assert.assertEquals(1, result.count());
session.users().searchForUser(hardcodedParam, realm, 0, 2); result = session.users().searchForUserStream(hardcodedParam, realm, 0, 2);
Assert.assertEquals(1, result.size()); Assert.assertEquals(1, result.count());
session.users().getUsers(realm); // we run a terminal operation on the stream to make sure it is consumed.
session.users().getUsersStream(realm).count();
session.users().getUsersCount(realm); session.users().getUsersCount(realm);
UserModel user = session.users().getUserByUsername(FailableHardcodedStorageProvider.username, realm); UserModel user = session.users().getUserByUsername(FailableHardcodedStorageProvider.username, realm);
Assert.assertFalse(user instanceof CachedUserModel); Assert.assertFalse(user instanceof CachedUserModel);
Assert.assertEquals(FailableHardcodedStorageProvider.username, user.getUsername()); Assert.assertEquals(FailableHardcodedStorageProvider.username, user.getUsername());

View file

@ -1,7 +1,6 @@
package org.keycloak.testsuite.federation.storage; package org.keycloak.testsuite.federation.storage;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.hamcrest.Matchers;
import org.jboss.arquillian.graphene.page.Page; import org.jboss.arquillian.graphene.page.Page;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
@ -76,7 +75,6 @@ import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.keycloak.models.UserModel.RequiredAction.UPDATE_PROFILE; import static org.keycloak.models.UserModel.RequiredAction.UPDATE_PROFILE;
import org.keycloak.provider.ProviderFactory;
import static org.keycloak.storage.UserStorageProviderModel.CACHE_POLICY; import static org.keycloak.storage.UserStorageProviderModel.CACHE_POLICY;
import static org.keycloak.storage.UserStorageProviderModel.EVICTION_DAY; import static org.keycloak.storage.UserStorageProviderModel.EVICTION_DAY;
import static org.keycloak.storage.UserStorageProviderModel.EVICTION_HOUR; import static org.keycloak.storage.UserStorageProviderModel.EVICTION_HOUR;
@ -85,7 +83,6 @@ import static org.keycloak.storage.UserStorageProviderModel.IMPORT_ENABLED;
import static org.keycloak.storage.UserStorageProviderModel.MAX_LIFESPAN; import static org.keycloak.storage.UserStorageProviderModel.MAX_LIFESPAN;
import static org.keycloak.testsuite.actions.RequiredActionEmailVerificationTest.getPasswordResetEmailLink; import static org.keycloak.testsuite.actions.RequiredActionEmailVerificationTest.getPasswordResetEmailLink;
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer; import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
import org.keycloak.testsuite.util.WaitUtils;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlDoesntStartWith; import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlDoesntStartWith;
import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith; import static org.keycloak.testsuite.util.URLAssert.assertCurrentUrlStartsWith;
@ -472,11 +469,8 @@ public class UserStorageTest extends AbstractAuthTest {
UserModel userModel = session.users().getUserByUsername("thor", realm); UserModel userModel = session.users().getUserByUsername("thor", realm);
userModel.setSingleAttribute("weapon", "hammer"); userModel.setSingleAttribute("weapon", "hammer");
List<UserModel> userModels = session.users().searchForUserByUserAttribute("weapon", "hammer", realm); List<UserModel> userModels = session.users().searchForUserByUserAttributeStream("weapon", "hammer", realm)
for (UserModel u : userModels) { .peek(System.out::println).collect(Collectors.toList());
System.out.println(u.getUsername());
}
Assert.assertEquals(1, userModels.size()); Assert.assertEquals(1, userModels.size());
Assert.assertEquals("thor", userModels.get(0).getUsername()); Assert.assertEquals("thor", userModels.get(0).getUsername());
}); });

View file

@ -91,7 +91,7 @@ public class MultipleRealmsTest extends AbstractTestRealmKeycloakTest {
Assert.assertTrue(currentSession.userCredentialManager().isValid(realm2, r2user1, UserCredentialModel.password("pass2"))); Assert.assertTrue(currentSession.userCredentialManager().isValid(realm2, r2user1, UserCredentialModel.password("pass2")));
// Test searching // Test searching
Assert.assertEquals(2, currentSession.users().searchForUser("user", realm1).size()); Assert.assertEquals(2, currentSession.users().searchForUserStream("user", realm1).count());
}); });
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionTestUser2) -> { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionTestUser2) -> {
@ -105,8 +105,8 @@ public class MultipleRealmsTest extends AbstractTestRealmKeycloakTest {
currentSession.users().removeUser(realm1, r1user1); currentSession.users().removeUser(realm1, r1user1);
UserModel user2 = currentSession.users().getUserByUsername("user2", realm1); UserModel user2 = currentSession.users().getUserByUsername("user2", realm1);
currentSession.users().removeUser(realm1, user2); currentSession.users().removeUser(realm1, user2);
Assert.assertEquals(0, currentSession.users().searchForUser("user", realm1).size()); Assert.assertEquals(0, currentSession.users().searchForUserStream("user", realm1).count());
Assert.assertEquals(2, currentSession.users().searchForUser("user", realm2).size()); Assert.assertEquals(2, currentSession.users().searchForUserStream("user", realm2).count());
UserModel user1 = currentSession.users().getUserByUsername("user1", realm1); UserModel user1 = currentSession.users().getUserByUsername("user1", realm1);

View file

@ -42,6 +42,7 @@ import org.keycloak.testsuite.federation.HardcodedClientStorageProviderFactory;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer; import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
@ -207,12 +208,12 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest {
UserModel john = currentSession.users().getUserByUsername("john", realm); UserModel john = currentSession.users().getUserByUsername("john", realm);
UserModel mary = currentSession.users().getUserByUsername("mary", realm); UserModel mary = currentSession.users().getUserByUsername("mary", realm);
List<UserConsentModel> johnConsents = currentSession.users().getConsents(realm, john.getId()); Assert.assertEquals(2, currentSession.users().getConsentsStream(realm, john.getId()).count());
Assert.assertEquals(2, johnConsents.size());
ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client"); ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client");
List<UserConsentModel> maryConsents = currentSession.users().getConsents(realm, mary.getId()); List<UserConsentModel> maryConsents = currentSession.users().getConsentsStream(realm, mary.getId())
.collect(Collectors.toList());
Assert.assertEquals(2, maryConsents.size()); Assert.assertEquals(2, maryConsents.size());
UserConsentModel maryConsent = maryConsents.get(0); UserConsentModel maryConsent = maryConsents.get(0);
UserConsentModel maryHardcodedConsent = maryConsents.get(1); UserConsentModel maryHardcodedConsent = maryConsents.get(1);
@ -388,9 +389,7 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest {
Assert.assertNull(hardcodedClient); Assert.assertNull(hardcodedClient);
UserModel mary = currentSession.users().getUserByUsername("mary", realm); UserModel mary = currentSession.users().getUserByUsername("mary", realm);
Assert.assertEquals(1, currentSession.users().getConsentsStream(realm, mary.getId()).count());
List<UserConsentModel> maryConsents = currentSession.users().getConsents(realm, mary.getId());
Assert.assertEquals(1, maryConsents.size());
}); });
} }

View file

@ -44,6 +44,7 @@ import org.keycloak.testsuite.federation.UserMapStorageFactory;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import static org.keycloak.storage.UserStorageProviderModel.IMPORT_ENABLED; import static org.keycloak.storage.UserStorageProviderModel.IMPORT_ENABLED;
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer; import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
@ -58,9 +59,7 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo
@Before @Before
public void before() { public void before() {
testingClient.server().run(currentSession -> { testingClient.server().run(UserConsentWithUserStorageModelTest::setupEnv);
setupEnv(currentSession);
});
} }
@After @After
@ -217,12 +216,12 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo
UserModel john = currentSessionACT.users().getUserByUsername("john", realm); UserModel john = currentSessionACT.users().getUserByUsername("john", realm);
UserModel mary = currentSessionACT.users().getUserByUsername("mary", realm); UserModel mary = currentSessionACT.users().getUserByUsername("mary", realm);
List<UserConsentModel> johnConsents = currentSession.users().getConsents(realm, john.getId()); Assert.assertEquals(2, currentSession.users().getConsentsStream(realm, john.getId()).count());
Assert.assertEquals(2, johnConsents.size());
ClientModel hardcodedClient = currentSessionACT.clients().getClientByClientId(realm, "hardcoded-client"); ClientModel hardcodedClient = currentSessionACT.clients().getClientByClientId(realm, "hardcoded-client");
List<UserConsentModel> maryConsents = currentSession.users().getConsents(realm, mary.getId()); List<UserConsentModel> maryConsents = currentSession.users().getConsentsStream(realm, mary.getId())
.collect(Collectors.toList());
Assert.assertEquals(2, maryConsents.size()); Assert.assertEquals(2, maryConsents.size());
UserConsentModel maryConsent = maryConsents.get(0); UserConsentModel maryConsent = maryConsents.get(0);
UserConsentModel maryHardcodedConsent = maryConsents.get(1); UserConsentModel maryHardcodedConsent = maryConsents.get(1);
@ -400,9 +399,7 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo
Assert.assertNull(hardcodedClient); Assert.assertNull(hardcodedClient);
UserModel mary = currentSession.users().getUserByUsername("mary", realm); UserModel mary = currentSession.users().getUserByUsername("mary", realm);
Assert.assertEquals(1, currentSession.users().getConsentsStream(realm, mary.getId()).count());
List<UserConsentModel> maryConsents = currentSession.users().getConsents(realm, mary.getId());
Assert.assertEquals(1, maryConsents.size());
}); });
} }

View file

@ -41,6 +41,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsInAnyOrder;
@ -99,20 +100,22 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest {
Map<String, String> attributes = new HashMap<>(); Map<String, String> attributes = new HashMap<>();
attributes.put(UserModel.LAST_NAME, "last-name"); attributes.put(UserModel.LAST_NAME, "last-name");
List<UserModel> search = currentSession.users().searchForUser(attributes, realm); List<UserModel> search = currentSession.users().searchForUserStream(attributes, realm)
.collect(Collectors.toList());
Assert.assertThat(search, hasSize(1)); Assert.assertThat(search, hasSize(1));
Assert.assertThat(search.get(0).getUsername(), equalTo("user")); Assert.assertThat(search.get(0).getUsername(), equalTo("user"));
attributes.clear(); attributes.clear();
attributes.put(UserModel.EMAIL, "email"); attributes.put(UserModel.EMAIL, "email");
search = currentSession.users().searchForUser(attributes, realm); search = currentSession.users().searchForUserStream(attributes, realm)
.collect(Collectors.toList());
Assert.assertThat(search, hasSize(1)); Assert.assertThat(search, hasSize(1));
Assert.assertThat(search.get(0).getUsername(), equalTo("user")); Assert.assertThat(search.get(0).getUsername(), equalTo("user"));
attributes.clear(); attributes.clear();
attributes.put(UserModel.LAST_NAME, "last-name"); attributes.put(UserModel.LAST_NAME, "last-name");
attributes.put(UserModel.EMAIL, "email"); attributes.put(UserModel.EMAIL, "email");
search = currentSession.users().searchForUser(attributes, realm); search = currentSession.users().searchForUserStream(attributes, realm).collect(Collectors.toList());
Assert.assertThat(search, hasSize(1)); Assert.assertThat(search, hasSize(1));
Assert.assertThat(search.get(0).getUsername(), equalTo("user")); Assert.assertThat(search.get(0).getUsername(), equalTo("user"));
}); });
@ -169,8 +172,8 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest {
RealmModel realm = currentSession.realms().getRealmByName("original"); RealmModel realm = currentSession.realms().getRealmByName("original");
UserModel user = currentSession.users().addUser(realm, "user"); UserModel user = currentSession.users().addUser(realm, "user");
List<String> requiredActions = user.getRequiredActionsStream().collect(Collectors.toList());
Assert.assertThat(user.getRequiredActions(), empty()); Assert.assertThat(requiredActions, empty());
user.addRequiredAction(RequiredAction.CONFIGURE_TOTP); user.addRequiredAction(RequiredAction.CONFIGURE_TOTP);
String id = realm.getId(); String id = realm.getId();
@ -178,20 +181,23 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest {
realm = currentSession.realms().getRealm(id); realm = currentSession.realms().getRealm(id);
user = currentSession.users().getUserByUsername("user", realm); user = currentSession.users().getUserByUsername("user", realm);
Assert.assertThat(user.getRequiredActions(), hasSize(1)); requiredActions = user.getRequiredActionsStream().collect(Collectors.toList());
Assert.assertThat(user.getRequiredActions(), contains(RequiredAction.CONFIGURE_TOTP.name())); Assert.assertThat(requiredActions, hasSize(1));
Assert.assertThat(requiredActions, contains(RequiredAction.CONFIGURE_TOTP.name()));
user.addRequiredAction(RequiredAction.CONFIGURE_TOTP); user.addRequiredAction(RequiredAction.CONFIGURE_TOTP);
user = currentSession.users().getUserByUsername("user", realm); user = currentSession.users().getUserByUsername("user", realm);
Assert.assertThat(user.getRequiredActions(), hasSize(1)); requiredActions = user.getRequiredActionsStream().collect(Collectors.toList());
Assert.assertThat(user.getRequiredActions(), contains(RequiredAction.CONFIGURE_TOTP.name())); Assert.assertThat(requiredActions, hasSize(1));
Assert.assertThat(requiredActions, contains(RequiredAction.CONFIGURE_TOTP.name()));
user.addRequiredAction(RequiredAction.VERIFY_EMAIL.name()); user.addRequiredAction(RequiredAction.VERIFY_EMAIL.name());
user = currentSession.users().getUserByUsername("user", realm); user = currentSession.users().getUserByUsername("user", realm);
Assert.assertThat(user.getRequiredActions(), hasSize(2)); requiredActions = user.getRequiredActionsStream().collect(Collectors.toList());
Assert.assertThat(user.getRequiredActions(), containsInAnyOrder( Assert.assertThat(requiredActions, hasSize(2));
Assert.assertThat(requiredActions, containsInAnyOrder(
RequiredAction.CONFIGURE_TOTP.name(), RequiredAction.CONFIGURE_TOTP.name(),
RequiredAction.VERIFY_EMAIL.name()) RequiredAction.VERIFY_EMAIL.name())
); );
@ -199,13 +205,15 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest {
user.removeRequiredAction(RequiredAction.CONFIGURE_TOTP.name()); user.removeRequiredAction(RequiredAction.CONFIGURE_TOTP.name());
user = currentSession.users().getUserByUsername("user", realm); user = currentSession.users().getUserByUsername("user", realm);
Assert.assertThat(user.getRequiredActions(), hasSize(1)); requiredActions = user.getRequiredActionsStream().collect(Collectors.toList());
Assert.assertThat(user.getRequiredActions(), contains(RequiredAction.VERIFY_EMAIL.name())); Assert.assertThat(requiredActions, hasSize(1));
Assert.assertThat(requiredActions, contains(RequiredAction.VERIFY_EMAIL.name()));
user.removeRequiredAction(RequiredAction.VERIFY_EMAIL.name()); user.removeRequiredAction(RequiredAction.VERIFY_EMAIL.name());
user = currentSession.users().getUserByUsername("user", realm); user = currentSession.users().getUserByUsername("user", realm);
Assert.assertThat(user.getRequiredActions(), empty()); requiredActions = user.getRequiredActionsStream().collect(Collectors.toList());
Assert.assertThat(requiredActions, empty());
}); });
} }
@ -236,24 +244,24 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest {
// Test read attributes // Test read attributes
UserModel user = currentSession.users().getUserByUsername("user", realm); UserModel user = currentSession.users().getUserByUsername("user", realm);
List<String> attrVals = user.getAttribute("key1"); List<String> attrVals = user.getAttributeStream("key1").collect(Collectors.toList());
Assert.assertThat(attrVals, hasSize(1)); Assert.assertThat(attrVals, hasSize(1));
Assert.assertThat(attrVals, contains("value1")); Assert.assertThat(attrVals, contains("value1"));
Assert.assertThat(user.getFirstAttribute("key1"), equalTo("value1")); Assert.assertThat(user.getFirstAttribute("key1"), equalTo("value1"));
attrVals = user.getAttribute("key2"); attrVals = user.getAttributeStream("key2").collect(Collectors.toList());
Assert.assertThat(attrVals, hasSize(2)); Assert.assertThat(attrVals, hasSize(2));
Assert.assertThat(attrVals, containsInAnyOrder("val21", "val22")); Assert.assertThat(attrVals, containsInAnyOrder("val21", "val22"));
attrVals = user.getAttribute("key3"); attrVals = user.getAttributeStream("key3").collect(Collectors.toList());
Assert.assertThat(attrVals, empty()); Assert.assertThat(attrVals, empty());
Assert.assertThat(user.getFirstAttribute("key3"), nullValue()); Assert.assertThat(user.getFirstAttribute("key3"), nullValue());
Map<String, List<String>> allAttrVals = user.getAttributes(); Map<String, List<String>> allAttrVals = user.getAttributes();
Assert.assertThat(allAttrVals.keySet(), hasSize(6)); Assert.assertThat(allAttrVals.keySet(), hasSize(6));
Assert.assertThat(allAttrVals.keySet(), containsInAnyOrder(UserModel.USERNAME, UserModel.FIRST_NAME, UserModel.LAST_NAME, UserModel.EMAIL, "key1", "key2")); Assert.assertThat(allAttrVals.keySet(), containsInAnyOrder(UserModel.USERNAME, UserModel.FIRST_NAME, UserModel.LAST_NAME, UserModel.EMAIL, "key1", "key2"));
Assert.assertThat(allAttrVals.get("key1"), equalTo(user.getAttribute("key1"))); Assert.assertThat(allAttrVals.get("key1"), equalTo(user.getAttributeStream("key1").collect(Collectors.toList())));
Assert.assertThat(allAttrVals.get("key2"), equalTo(user.getAttribute("key2"))); Assert.assertThat(allAttrVals.get("key2"), equalTo(user.getAttributeStream("key2").collect(Collectors.toList())));
// Test remove and rewrite attribute // Test remove and rewrite attribute
user.removeAttribute("key1"); user.removeAttribute("key1");
@ -267,7 +275,7 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest {
UserModel user = currentSession.users().getUserByUsername("user", realm); UserModel user = currentSession.users().getUserByUsername("user", realm);
Assert.assertThat(user.getFirstAttribute("key1"), nullValue()); Assert.assertThat(user.getFirstAttribute("key1"), nullValue());
List<String> attrVals = user.getAttribute("key2"); List<String> attrVals = user.getAttributeStream("key2").collect(Collectors.toList());
Assert.assertThat(attrVals, hasSize(1)); Assert.assertThat(attrVals, hasSize(1));
Assert.assertThat(attrVals.get(0), equalTo("val23")); Assert.assertThat(attrVals.get(0), equalTo("val23"));
@ -365,7 +373,8 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest {
UserModel user1 = currentSession.users().getUserByUsername("user1", realm); UserModel user1 = currentSession.users().getUserByUsername("user1", realm);
List<UserModel> users = currentSession.users().searchForUser("user", realm, 0, 7); List<UserModel> users = currentSession.users().searchForUserStream("user", realm, 0, 7)
.collect(Collectors.toList());
Assert.assertThat(users, hasSize(1)); Assert.assertThat(users, hasSize(1));
Assert.assertThat(users, contains(user1)); Assert.assertThat(users, contains(user1));
}); });
@ -404,19 +413,23 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest {
UserModel user2 = currentSession.users().getUserByUsername("user2", realm); UserModel user2 = currentSession.users().getUserByUsername("user2", realm);
UserModel user3 = currentSession.users().getUserByUsername("user3", realm); UserModel user3 = currentSession.users().getUserByUsername("user3", realm);
List<UserModel> users = currentSession.users().searchForUserByUserAttribute("key1", "value1", realm); List<UserModel> users = currentSession.users().searchForUserByUserAttributeStream("key1", "value1", realm)
.collect(Collectors.toList());
Assert.assertThat(users, hasSize(2)); Assert.assertThat(users, hasSize(2));
Assert.assertThat(users, containsInAnyOrder(user1, user2)); Assert.assertThat(users, containsInAnyOrder(user1, user2));
users = currentSession.users().searchForUserByUserAttribute("key2", "value21", realm); users = currentSession.users().searchForUserByUserAttributeStream("key2", "value21", realm)
.collect(Collectors.toList());
Assert.assertThat(users, hasSize(2)); Assert.assertThat(users, hasSize(2));
Assert.assertThat(users, containsInAnyOrder(user1, user3)); Assert.assertThat(users, containsInAnyOrder(user1, user3));
users = currentSession.users().searchForUserByUserAttribute("key2", "value22", realm); users = currentSession.users().searchForUserByUserAttributeStream("key2", "value22", realm)
.collect(Collectors.toList());
Assert.assertThat(users, hasSize(1)); Assert.assertThat(users, hasSize(1));
Assert.assertThat(users, contains(user2)); Assert.assertThat(users, contains(user2));
users = currentSession.users().searchForUserByUserAttribute("key3", "value3", realm); users = currentSession.users().searchForUserByUserAttributeStream("key3", "value3", realm)
.collect(Collectors.toList());
Assert.assertThat(users, empty()); Assert.assertThat(users, empty());
}); });
} }
@ -441,7 +454,8 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest {
// Search // Search
Assert.assertThat(currentSession.users().getServiceAccount(client), nullValue()); Assert.assertThat(currentSession.users().getServiceAccount(client), nullValue());
List<UserModel> users = currentSession.users().searchForUser("John Doe", realm); List<UserModel> users = currentSession.users().searchForUserStream("John Doe", realm)
.collect(Collectors.toList());
Assert.assertThat(users, hasSize(2)); Assert.assertThat(users, hasSize(2));
Assert.assertThat(users, containsInAnyOrder(user1, user2)); Assert.assertThat(users, containsInAnyOrder(user1, user2));
@ -460,15 +474,16 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest {
ClientModel client = realm.getClientByClientId("foo"); ClientModel client = realm.getClientByClientId("foo");
UserModel searched = currentSession.users().getServiceAccount(client); UserModel searched = currentSession.users().getServiceAccount(client);
Assert.assertThat(searched, equalTo(user1)); Assert.assertThat(searched, equalTo(user1));
List<UserModel> users = currentSession.users().searchForUser("John Doe", realm); List<UserModel> users = currentSession.users().searchForUserStream("John Doe", realm)
.collect(Collectors.toList());
Assert.assertThat(users, hasSize(1)); Assert.assertThat(users, hasSize(1));
Assert.assertThat(users, contains(user2)); Assert.assertThat(users, contains(user2));
users = currentSession.users().getUsers(realm, false); users = currentSession.users().getUsersStream(realm, false).collect(Collectors.toList());
Assert.assertThat(users, hasSize(1)); Assert.assertThat(users, hasSize(1));
Assert.assertThat(users, contains(user2)); Assert.assertThat(users, contains(user2));
users = currentSession.users().getUsers(realm, true); users = currentSession.users().getUsersStream(realm, true).collect(Collectors.toList());
Assert.assertThat(users, hasSize(2)); Assert.assertThat(users, hasSize(2));
Assert.assertThat(users, containsInAnyOrder(user1, user2)); Assert.assertThat(users, containsInAnyOrder(user1, user2));
@ -573,7 +588,8 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest {
Assert.assertThat(actual.getCreatedTimestamp(), equalTo(expected.getCreatedTimestamp())); Assert.assertThat(actual.getCreatedTimestamp(), equalTo(expected.getCreatedTimestamp()));
Assert.assertThat(actual.getFirstName(), equalTo(expected.getFirstName())); Assert.assertThat(actual.getFirstName(), equalTo(expected.getFirstName()));
Assert.assertThat(actual.getLastName(), equalTo(expected.getLastName())); Assert.assertThat(actual.getLastName(), equalTo(expected.getLastName()));
Assert.assertThat(actual.getRequiredActions(), containsInAnyOrder(expected.getRequiredActions().toArray())); Assert.assertThat(actual.getRequiredActionsStream().collect(Collectors.toSet()),
containsInAnyOrder(expected.getRequiredActionsStream().toArray()));
} }
@Override @Override

View file

@ -19,12 +19,10 @@ package org.keycloak.testsuite.util.cli;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientScopeModel; import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.FederatedIdentityModel;
import org.keycloak.models.GroupModel; import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel; import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.UserModel;
/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -47,19 +45,18 @@ public class TestCacheUtils {
realm.getClientScopesStream().map(ClientScopeModel::getId).forEach(realm::getClientScopeById); realm.getClientScopesStream().map(ClientScopeModel::getId).forEach(realm::getClientScopeById);
for (UserModel user : session.users().getUsers(realm)) { session.users().getUsersStream(realm).forEach(user -> {
session.users().getUserById(user.getId(), realm); session.users().getUserById(user.getId(), realm);
if (user.getEmail() != null) { if (user.getEmail() != null) {
session.users().getUserByEmail(user.getEmail(), realm); session.users().getUserByEmail(user.getEmail(), realm);
} }
session.users().getUserByUsername(user.getUsername(), realm); session.users().getUserByUsername(user.getUsername(), realm);
session.users().getConsents(realm, user.getId()); session.users().getConsentsStream(realm, user.getId());
for (FederatedIdentityModel fedIdentity : session.users().getFederatedIdentities(user, realm)) { session.users().getFederatedIdentitiesStream(user, realm)
session.users().getUserByFederatedIdentity(fedIdentity, realm); .forEach(identity -> session.users().getUserByFederatedIdentity(identity, realm));
} });
}
} }
private static void cacheRoles(KeycloakSession session, RealmModel realm, RoleContainerModel roleContainer) { private static void cacheRoles(KeycloakSession session, RealmModel realm, RoleContainerModel roleContainer) {