KEYCLOAK-15695 Streamification cleanup

This commit is contained in:
Martin Kanis 2020-12-14 10:55:56 +01:00 committed by Hynek Mlnařík
parent 6315fe5d22
commit 9f580e3ed8
86 changed files with 798 additions and 737 deletions

View file

@ -80,6 +80,8 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
import static org.keycloak.utils.StreamsUtil.paginatedStream;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/
@ -316,18 +318,18 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
}
@Override
public Stream<UserSessionModel> getUserSessionsStream(RealmModel realm, ClientModel client, int firstResult, int maxResults) {
public Stream<UserSessionModel> getUserSessionsStream(RealmModel realm, ClientModel client, Integer firstResult, Integer maxResults) {
return getUserSessionsStream(realm, client, firstResult, maxResults, false);
}
protected Stream<UserSessionModel> getUserSessionsStream(final RealmModel realm, ClientModel client, int firstResult, int maxResults, final boolean offline) {
protected Stream<UserSessionModel> getUserSessionsStream(final RealmModel realm, ClientModel client, Integer firstResult, Integer maxResults, final boolean offline) {
final String clientUuid = client.getId();
UserSessionPredicate predicate = UserSessionPredicate.create(realm.getId()).client(clientUuid);
return getUserSessionModels(realm, firstResult, maxResults, offline, predicate);
}
protected Stream<UserSessionModel> getUserSessionModels(RealmModel realm, int firstResult, int maxResults, boolean offline, UserSessionPredicate predicate) {
protected Stream<UserSessionModel> getUserSessionModels(RealmModel realm, Integer firstResult, Integer maxResults, boolean offline, UserSessionPredicate predicate) {
Cache<String, SessionEntityWrapper<UserSessionEntity>> cache = getCache(offline);
cache = CacheDecorators.skipCacheLoaders(cache);
@ -338,15 +340,7 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
.map(Mappers.userSessionEntity())
.sorted(Comparators.userSessionLastSessionRefresh());
if (firstResult > 0) {
stream = stream.skip(firstResult);
}
if (maxResults > 0) {
stream = stream.limit(maxResults);
}
return stream.map(entity -> this.wrap(realm, entity, offline));
return paginatedStream(stream, firstResult, maxResults).map(entity -> this.wrap(realm, entity, offline));
}
@Override
@ -862,7 +856,7 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
}
@Override
public Stream<UserSessionModel> getOfflineUserSessionsStream(RealmModel realm, ClientModel client, int first, int max) {
public Stream<UserSessionModel> getOfflineUserSessionsStream(RealmModel realm, ClientModel client, Integer first, Integer max) {
return getUserSessionsStream(realm, client, first, max, true);
}

View file

@ -29,6 +29,7 @@ import org.keycloak.models.session.UserSessionPersisterProvider;
import java.io.Serializable;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -99,7 +100,9 @@ public class OfflinePersistentUserSessionLoader implements SessionLoader<Offline
log.tracef("Loading sessions for segment=%d createdOn=%d lastSessionId=%s", ctx.getSegment(), ctx.getLastCreatedOn(), ctx.getLastSessionId());
UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class);
List<UserSessionModel> sessions = persister.loadUserSessions(first, sessionsPerSegment, true, ctx.getLastCreatedOn(), ctx.getLastSessionId());
List<UserSessionModel> sessions = persister
.loadUserSessionsStream(first, sessionsPerSegment, true, ctx.getLastCreatedOn(), ctx.getLastSessionId())
.collect(Collectors.toList());
log.tracef("Sessions loaded from DB - segment=%d createdOn=%d lastSessionId=%s", ctx.getSegment(), ctx.getLastCreatedOn(), ctx.getLastSessionId());

View file

@ -26,7 +26,6 @@ import java.util.Objects;
import javax.persistence.EntityManager;
import javax.persistence.FlushModeType;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
@ -43,6 +42,8 @@ import org.keycloak.authorization.store.ResourceStore;
import org.keycloak.models.utils.KeycloakModelUtils;
import javax.persistence.LockModeType;
import static org.keycloak.models.jpa.PaginationUtils.paginateQuery;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
@ -220,17 +221,9 @@ public class JPAPermissionTicketStore implements PermissionTicketStore {
querybuilder.where(predicates.toArray(new Predicate[predicates.size()])).orderBy(builder.asc(root.get("id")));
Query query = entityManager.createQuery(querybuilder);
TypedQuery query = entityManager.createQuery(querybuilder);
if (firstResult != -1) {
query.setFirstResult(firstResult);
}
if (maxResult != -1) {
query.setMaxResults(maxResult);
}
List<String> result = query.getResultList();
List<String> result = paginateQuery(query, firstResult, maxResult).getResultList();
List<PermissionTicket> list = new LinkedList<>();
PermissionTicketStore ticketStore = provider.getStoreFactory().getPermissionTicketStore();
@ -278,12 +271,7 @@ public class JPAPermissionTicketStore implements PermissionTicketStore {
query.setParameter("resourceName", "%" + name.toLowerCase() + "%");
}
if (first > -1 && max > -1) {
query.setFirstResult(first);
query.setMaxResults(max);
}
List<String> result = query.getResultList();
List<String> result = paginateQuery(query, first, max).getResultList();
List<Resource> list = new LinkedList<>();
ResourceStore resourceStore = provider.getStoreFactory().getResourceStore();
@ -305,12 +293,7 @@ public class JPAPermissionTicketStore implements PermissionTicketStore {
query.setFlushMode(FlushModeType.COMMIT);
query.setParameter("owner", owner);
if (first > -1 && max > -1) {
query.setFirstResult(first);
query.setMaxResults(max);
}
List<String> result = query.getResultList();
List<String> result = paginateQuery(query, first, max).getResultList();
List<Resource> list = new LinkedList<>();
ResourceStore resourceStore = provider.getStoreFactory().getResourceStore();

View file

@ -28,7 +28,6 @@ import java.util.function.Consumer;
import javax.persistence.EntityManager;
import javax.persistence.FlushModeType;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
@ -45,6 +44,9 @@ import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
import javax.persistence.LockModeType;
import static org.keycloak.models.jpa.PaginationUtils.paginateQuery;
import static org.keycloak.utils.StreamsUtil.closing;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
@ -176,16 +178,9 @@ public class JPAPolicyStore implements PolicyStore {
querybuilder.where(predicates.toArray(new Predicate[predicates.size()])).orderBy(builder.asc(root.get("name")));
Query query = entityManager.createQuery(querybuilder);
TypedQuery query = entityManager.createQuery(querybuilder);
if (firstResult != -1) {
query.setFirstResult(firstResult);
}
if (maxResult != -1) {
query.setMaxResults(maxResult);
}
List<String> result = query.getResultList();
List<String> result = paginateQuery(query, firstResult, maxResult).getResultList();
List<Policy> list = new LinkedList<>();
for (String id : result) {
Policy policy = provider.getStoreFactory().getPolicyStore().findById(id, resourceServerId);
@ -215,9 +210,9 @@ public class JPAPolicyStore implements PolicyStore {
PolicyStore storeFactory = provider.getStoreFactory().getPolicyStore();
query.getResultStream()
closing(query.getResultStream()
.map(entity -> storeFactory.findById(entity.getId(), resourceServerId))
.filter(Objects::nonNull)
.filter(Objects::nonNull))
.forEach(consumer::accept);
}
@ -238,9 +233,9 @@ public class JPAPolicyStore implements PolicyStore {
query.setParameter("type", resourceType);
query.setParameter("serverId", resourceServerId);
query.getResultStream()
closing(query.getResultStream()
.map(id -> new PolicyAdapter(id, entityManager, provider.getStoreFactory()))
.filter(Objects::nonNull)
.filter(Objects::nonNull))
.forEach(consumer::accept);
}
@ -294,9 +289,9 @@ public class JPAPolicyStore implements PolicyStore {
StoreFactory storeFactory = provider.getStoreFactory();
query.getResultStream()
closing(query.getResultStream()
.map(id -> new PolicyAdapter(id, entityManager, storeFactory))
.filter(Objects::nonNull)
.filter(Objects::nonNull))
.forEach(consumer::accept);
}

View file

@ -28,7 +28,6 @@ import org.keycloak.models.utils.KeycloakModelUtils;
import javax.persistence.EntityManager;
import javax.persistence.FlushModeType;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
@ -41,6 +40,9 @@ import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import static org.keycloak.models.jpa.PaginationUtils.paginateQuery;
import static org.keycloak.utils.StreamsUtil.closing;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
@ -145,7 +147,7 @@ public class JPAResourceStore implements ResourceStore {
}
ResourceStore resourceStore = provider.getStoreFactory().getResourceStore();
query.getResultStream().map(id -> resourceStore.findById(id.getId(), resourceServerId)).forEach(consumer);
closing(query.getResultStream().map(id -> resourceStore.findById(id.getId(), resourceServerId))).forEach(consumer);
}
@Override
@ -232,16 +234,9 @@ public class JPAResourceStore implements ResourceStore {
querybuilder.where(predicates.toArray(new Predicate[predicates.size()])).orderBy(builder.asc(root.get("name")));
Query query = entityManager.createQuery(querybuilder);
TypedQuery query = entityManager.createQuery(querybuilder);
if (firstResult != -1) {
query.setFirstResult(firstResult);
}
if (maxResult != -1) {
query.setMaxResults(maxResult);
}
List<String> result = query.getResultList();
List<String> result = paginateQuery(query, firstResult, maxResult).getResultList();
List<Resource> list = new LinkedList<>();
ResourceStore resourceStore = provider.getStoreFactory().getResourceStore();

View file

@ -25,7 +25,6 @@ import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.FlushModeType;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
@ -40,6 +39,8 @@ import org.keycloak.authorization.store.ScopeStore;
import org.keycloak.models.utils.KeycloakModelUtils;
import javax.persistence.LockModeType;
import static org.keycloak.models.jpa.PaginationUtils.paginateQuery;
/**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a>
*/
@ -149,16 +150,9 @@ public class JPAScopeStore implements ScopeStore {
querybuilder.where(predicates.toArray(new Predicate[predicates.size()])).orderBy(builder.asc(root.get("name")));
Query query = entityManager.createQuery(querybuilder);
TypedQuery query = entityManager.createQuery(querybuilder);
if (firstResult != -1) {
query.setFirstResult(firstResult);
}
if (maxResult != -1) {
query.setMaxResults(maxResult);
}
List result = query.getResultList();
List result = paginateQuery(query, firstResult, maxResult).getResultList();
List<Scope> list = new LinkedList<>();
for (Object id : result) {
list.add(provider.getStoreFactory().getScopeStore().findById((String)id, resourceServerId));

View file

@ -22,7 +22,7 @@ import org.keycloak.models.LDAPConstants;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.storage.UserStorageProvider;
import java.util.List;
import java.util.function.Predicate;
/**
* @author <a href="mailto:bburke@redhat.com">Bill Burke</a>
@ -30,17 +30,23 @@ import java.util.List;
public class MigrateUserFedToComponent extends AbstractUserFedToComponent {
@Override
protected void generateStatementsImpl() throws CustomChangeException {
List<ProviderFactory> factories = kcSession.getKeycloakSessionFactory().getProviderFactories(UserStorageProvider.class);
for (ProviderFactory factory : factories) {
if (!factory.getId().equals(LDAPConstants.LDAP_PROVIDER)) {
convertFedProviderToComponent(factory.getId(), null);
}
}
protected void generateStatementsImpl() {
kcSession.getKeycloakSessionFactory().getProviderFactoriesStream(UserStorageProvider.class)
.map(ProviderFactory::getId)
.filter(Predicate.isEqual(LDAPConstants.LDAP_PROVIDER).negate())
.forEach(this::convertFedProviderToComponent);
}
@Override
protected String getTaskId() {
return "Update 2.5.0.Final";
}
private void convertFedProviderToComponent(String id) {
try {
convertFedProviderToComponent(id, null);
} catch (CustomChangeException ex) {
throw new RuntimeException(ex);
}
}
}

View file

@ -35,7 +35,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.stream.Stream;
import static org.keycloak.events.jpa.JpaEventQuery.DEFAULT_MAX_RESULTS;
import static org.keycloak.models.jpa.PaginationUtils.paginateQuery;
import static org.keycloak.utils.StreamsUtil.closing;
/**
@ -153,18 +153,7 @@ public class JpaAdminEventQuery implements AdminEventQuery {
TypedQuery<AdminEventEntity> query = em.createQuery(cq);
if (firstResult != null) {
query.setFirstResult(firstResult);
}
if (maxResults != null) {
query.setMaxResults(maxResults);
} else {
// to workaround https://hibernate.atlassian.net/browse/HHH-14295
query.setMaxResults(DEFAULT_MAX_RESULTS);
}
return closing(query.getResultStream().map(JpaEventStoreProvider::convertAdminEvent));
return closing(paginateQuery(query, firstResult, maxResults).getResultStream().map(JpaEventStoreProvider::convertAdminEvent));
}
}

View file

@ -33,6 +33,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.stream.Stream;
import static org.keycloak.models.jpa.PaginationUtils.paginateQuery;
import static org.keycloak.utils.StreamsUtil.closing;
/**
@ -48,8 +49,6 @@ public class JpaEventQuery implements EventQuery {
private Integer firstResult;
private Integer maxResults;
public static final int DEFAULT_MAX_RESULTS = Integer.MAX_VALUE >> 1;
public JpaEventQuery(EntityManager em) {
this.em = em;
@ -127,18 +126,7 @@ public class JpaEventQuery implements EventQuery {
TypedQuery<EventEntity> query = em.createQuery(cq);
if (firstResult != null) {
query.setFirstResult(firstResult);
}
if (maxResults != null) {
query.setMaxResults(maxResults);
} else {
// to workaround https://hibernate.atlassian.net/browse/HHH-14295
query.setMaxResults(DEFAULT_MAX_RESULTS);
}
return closing(query.getResultStream().map(JpaEventStoreProvider::convertEvent));
return closing(paginateQuery(query, firstResult, maxResults).getResultStream().map(JpaEventStoreProvider::convertEvent));
}
}

View file

@ -50,7 +50,11 @@ import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaDelete;
import javax.persistence.criteria.Root;
import java.util.*;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -310,14 +314,8 @@ public class JpaRealmProvider implements RealmProvider, ClientProvider, GroupPro
}
protected Stream<RoleModel> searchForRoles(TypedQuery<RoleEntity> query, RealmModel realm, String search, Integer first, Integer max) {
query.setParameter("search", "%" + search.trim().toLowerCase() + "%");
if(Objects.nonNull(first) && Objects.nonNull(max)
&& first >= 0 && max >= 0) {
query= query.setFirstResult(first).setMaxResults(max);
}
Stream<RoleEntity> results = query.getResultStream();
Stream<RoleEntity> results = paginateQuery(query, first, max).getResultStream();
return closing(results.map(role -> new RoleAdapter(session, realm, em, role)));
}

View file

@ -37,9 +37,7 @@ import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@ -47,8 +45,12 @@ import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.persistence.LockModeType;
import static org.keycloak.models.jpa.PaginationUtils.paginateQuery;
import static org.keycloak.utils.StreamsUtil.closing;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
@ -240,7 +242,8 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
}
@Override
public List<UserSessionModel> loadUserSessions(int firstResult, int maxResults, boolean offline, int lastCreatedOn, String lastUserSessionId) {
public Stream<UserSessionModel> loadUserSessionsStream(Integer firstResult, Integer maxResults, boolean offline,
Integer lastCreatedOn, String lastUserSessionId) {
String offlineStr = offlineToString(offline);
TypedQuery<PersistentUserSessionEntity> query = em.createNamedQuery("findUserSessions", PersistentUserSessionEntity.class);
@ -248,15 +251,8 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
query.setParameter("lastCreatedOn", lastCreatedOn);
query.setParameter("lastSessionId", lastUserSessionId);
if (firstResult != -1) {
query.setFirstResult(firstResult);
}
if (maxResults != -1) {
query.setMaxResults(maxResults);
}
List<PersistentUserSessionAdapter> result = query.getResultStream()
.map(this::toAdapter)
List<PersistentUserSessionAdapter> result = closing(paginateQuery(query, firstResult, maxResults).getResultStream()
.map(this::toAdapter))
.collect(Collectors.toList());
Map<String, PersistentUserSessionAdapter> sessionsById = result.stream()
@ -270,9 +266,7 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
TypedQuery<PersistentClientSessionEntity> query2 = em.createNamedQuery("findClientSessionsByUserSessions", PersistentClientSessionEntity.class);
query2.setParameter("userSessionIds", userSessionIds);
query2.setParameter("offline", offlineStr);
List<PersistentClientSessionEntity> clientSessions = query2.getResultList();
for (PersistentClientSessionEntity clientSession : clientSessions) {
closing(query2.getResultStream()).forEach(clientSession -> {
PersistentUserSessionAdapter userSession = sessionsById.get(clientSession.getUserSessionId());
PersistentAuthenticatedClientSessionAdapter clientSessAdapter = toAdapter(userSession.getRealm(), userSession, clientSession);
@ -284,14 +278,14 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
} else {
currentClientSessions.put(clientSession.getClientId(), clientSessAdapter);
}
}
});
}
for (String clientUUID : removedClientUUIDs) {
onClientRemoved(clientUUID);
}
return (List) result;
return result.stream().map(UserSessionModel.class::cast);
}
private PersistentUserSessionAdapter toAdapter(PersistentUserSessionEntity entity) {

View file

@ -63,6 +63,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.persistence.LockModeType;
import static org.keycloak.models.jpa.PaginationUtils.paginateQuery;
import static org.keycloak.utils.StreamsUtil.closing;
/**
@ -465,18 +466,12 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
public Stream<String> getMembershipStream(RealmModel realm, GroupModel group, int firstResult, int max) {
public Stream<String> getMembershipStream(RealmModel realm, GroupModel group, Integer firstResult, Integer max) {
TypedQuery<String> query = em.createNamedQuery("fedgroupMembership", String.class)
.setParameter("realmId", realm.getId())
.setParameter("groupId", group.getId());
if (firstResult != -1) {
query.setFirstResult(firstResult);
}
if (max != -1) {
query.setMaxResults(max);
}
return closing(query.getResultStream());
return closing(paginateQuery(query, firstResult, max).getResultStream());
}
@Override
@ -660,13 +655,10 @@ public class JpaUserFederatedStorageProvider implements
}
@Override
public Stream<String> getStoredUsersStream(RealmModel realm, int first, int max) {
public Stream<String> getStoredUsersStream(RealmModel realm, Integer first, Integer max) {
TypedQuery<String> query = em.createNamedQuery("getFederatedUserIds", String.class)
.setParameter("realmId", realm.getId());
if (first > 0)
query.setFirstResult(first);
if (max > 0) query.setMaxResults(max);
return closing(query.getResultStream());
return closing(paginateQuery(query, first, max).getResultStream());
}
@Override

View file

@ -18,12 +18,12 @@
package org.keycloak.authorization;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.keycloak.authorization.model.PermissionTicket;
import org.keycloak.authorization.model.Policy;
@ -126,11 +126,11 @@ public final class AuthorizationProvider implements Provider {
/**
* Returns the registered {@link PolicyProviderFactory}.
*
* @return a {@link List} containing all registered {@link PolicyProviderFactory}
* @return a {@link Stream} containing all registered {@link PolicyProviderFactory}
*/
public Collection<PolicyProviderFactory> getProviderFactories() {
return keycloakSession.getKeycloakSessionFactory().getProviderFactories(PolicyProvider.class).stream().map(
PolicyProviderFactory.class::cast).collect(Collectors.toList());
public Stream<PolicyProviderFactory> getProviderFactoriesStream() {
return keycloakSession.getKeycloakSessionFactory().getProviderFactoriesStream(PolicyProvider.class)
.map(PolicyProviderFactory.class::cast);
}
/**

View file

@ -55,7 +55,7 @@ public interface EventQuery {
/**
* Returns requested results that match given criteria as a stream.
* @return Stream of events
* @return Stream of events. Never returns {@code null}.
*/
Stream<Event> getResultStream();
}

View file

@ -138,7 +138,7 @@ public interface AdminEventQuery {
/**
* Executes the query and returns the results as a stream.
* @return Stream of admin events
* @return Stream of admin events. Never returns {@code null}.
*/
Stream<AdminEvent> getResultStream();
}

View file

@ -27,8 +27,7 @@ import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
/**
* Persistence of userSessions is disabled . Useful just if you never need survive of userSessions/clientSessions
@ -111,8 +110,9 @@ public class DisabledUserSessionPersisterProvider implements UserSessionPersiste
}
@Override
public List<UserSessionModel> loadUserSessions(int firstResult, int maxResults, boolean offline, int lastCreatedOn, String lastUserSessionId) {
return Collections.emptyList();
public Stream<UserSessionModel> loadUserSessionsStream(Integer firstResult, Integer maxResults, boolean offline,
Integer lastCreatedOn, String lastUserSessionId) {
return Stream.empty();
}
@Override

View file

@ -26,6 +26,8 @@ import org.keycloak.provider.Provider;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -54,8 +56,27 @@ public interface UserSessionPersisterProvider extends Provider {
// Remove userSessions and clientSessions, which are expired
void removeExpired(RealmModel realm);
// Called during startup. For each userSession, it loads also clientSessions
List<UserSessionModel> loadUserSessions(int firstResult, int maxResults, boolean offline, int lastCreatedOn, String lastUserSessionId);
/**
* Called during startup. For each userSession, it loads also clientSessions
* @deprecated Use {@link #loadUserSessionsStream(Integer, Integer, boolean, Integer, String) loadUserSessionsStream} instead.
*/
@Deprecated
default List<UserSessionModel> loadUserSessions(int firstResult, int maxResults, boolean offline, int lastCreatedOn, String lastUserSessionId) {
return loadUserSessionsStream(firstResult, maxResults, offline, lastCreatedOn, lastUserSessionId).collect(Collectors.toList());
}
/**
* Called during startup. For each userSession, it loads also clientSessions.
* @param firstResult {@code Integer} Index of the first desired user session. Ignored if negative or {@code null}.
* @param maxResults {@code Integer} Maximum number of returned user sessions. Ignored if negative or {@code null}.
* @param offline {@code boolean} Flag to include offline sessions.
* @param lastCreatedOn {@code Integer} Timestamp when the user session was created. It will return only user sessions created later.
* @param lastUserSessionId {@code String} Id of the user session. In case of equal {@code lastCreatedOn}
* it will compare the id in dictionary order and takes only those created later.
* @return Stream of {@link UserSessionModel}. Never returns {@code null}.
*/
Stream<UserSessionModel> loadUserSessionsStream(Integer firstResult, Integer maxResults, boolean offline,
Integer lastCreatedOn, String lastUserSessionId);
int getUserSessionsCount(boolean offline);

View file

@ -17,8 +17,6 @@
package org.keycloak.models.utils;
import java.util.List;
import org.keycloak.OAuth2Constants;
import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.Constants;
@ -27,7 +25,6 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.protocol.LoginProtocol;
import org.keycloak.protocol.LoginProtocolFactory;
import org.keycloak.provider.ProviderFactory;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -41,11 +38,9 @@ public class DefaultClientScopes {
* @param addScopesToExistingClients true when creating new realm. False when migrating from previous version
*/
public static void createDefaultClientScopes(KeycloakSession session, RealmModel realm, boolean addScopesToExistingClients) {
List<ProviderFactory> loginProtocolFactories = session.getKeycloakSessionFactory().getProviderFactories(LoginProtocol.class);
for (ProviderFactory factory : loginProtocolFactories) {
LoginProtocolFactory lpf = (LoginProtocolFactory) factory;
lpf.createDefaultClientScopes(realm, addScopesToExistingClients);
}
session.getKeycloakSessionFactory().getProviderFactoriesStream(LoginProtocol.class)
.map(LoginProtocolFactory.class::cast)
.forEach(lpf -> lpf.createDefaultClientScopes(realm, addScopesToExistingClients));
}

View file

@ -26,8 +26,6 @@ import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.credential.PasswordCredentialModel;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**

View file

@ -26,17 +26,14 @@ public interface ProviderLoader {
/**
* Load the SPI definitions themselves.
*
* @return a list of Spi definition objects
*/
List<Spi> loadSpis();
/**
* Load all provider factories of a specific SPI.
*
* @param spi the Spi definition
* @return a list of provider factories
*/
List<ProviderFactory> load(Spi spi);
}

View file

@ -43,11 +43,12 @@ public interface ClientSessionContext {
/**
* Returns client scopes as a stream.
* @return Stream of client scopes.
* @return Stream of client scopes. Never returns {@code null}.
*/
Stream<ClientScopeModel> getClientScopesStream();
/**
* @deprecated Use {@link #getRolesStream() getRolesStream} instead.
* @return expanded roles (composite roles already applied)
*/
@Deprecated
@ -55,6 +56,10 @@ public interface ClientSessionContext {
return getRolesStream().collect(Collectors.toSet());
}
/**
* Returns all roles including composite ones as a stream.
* @return Stream of {@link RoleModel}. Never returns {@code null}.
*/
Stream<RoleModel> getRolesStream();
/**
@ -68,7 +73,7 @@ public interface ClientSessionContext {
/**
* Returns protocol mappers as a stream.
* @return Stream of protocol mappers.
* @return Stream of protocol mappers. Never returns {@code null}.
*/
Stream<ProtocolMapperModel> getProtocolMappersStream();

View file

@ -66,10 +66,16 @@ public interface GroupModel extends RoleMapperModel {
/**
* @param name
* @return list of all attribute values or empty list if there are not any values. Never return null
* @deprecated Use {@link #getAttributeStream(String) getAttributeStream} instead.
*/
@Deprecated
List<String> getAttribute(String name);
/**
* Returns group attributes that match the given name as a stream.
* @param name {@code String} Name of the attribute to be used as a filter.
* @return Stream of all attribute values or empty stream if there are not any values. Never return {@code null}.
*/
default Stream<String> getAttributeStream(String name) {
List<String> value = this.getAttribute(name);
return value != null ? value.stream() : Stream.empty();
@ -80,9 +86,16 @@ public interface GroupModel extends RoleMapperModel {
GroupModel getParent();
String getParentId();
/**
* @deprecated Use {@link #getSubGroupsStream() getSubGroupsStream} instead.
*/
@Deprecated
Set<GroupModel> getSubGroups();
/**
* Returns all sub groups for the parent group as a stream.
* @return Stream of {@link GroupModel}. Never returns {@code null}.
*/
default Stream<GroupModel> getSubGroupsStream() {
Set<GroupModel> value = this.getSubGroups();
return value != null ? value.stream() : Stream.empty();

View file

@ -65,12 +65,12 @@ public interface GroupProvider extends Provider, GroupLookupProvider {
Stream<GroupModel> getGroupsStream(RealmModel realm);
/**
* Returns a list of groups with given ids.
* Returns a stream of groups with given ids.
* Effectively the same as {@code getGroupsStream(realm, ids, null, null, null)}.
*
* @param realm Realm.
* @param ids List of ids.
* @return List of GroupModels with the specified ids
* @param ids Stream of ids.
* @return Stream of GroupModels with the specified ids
*/
default Stream<GroupModel> getGroupsStream(RealmModel realm, Stream<String> ids) {
return getGroupsStream(realm, ids, null, null, null);
@ -80,23 +80,23 @@ public interface GroupProvider extends Provider, GroupLookupProvider {
* Returns a paginated stream of groups with given ids and given search value in group names.
*
* @param realm Realm.
* @param ids List of ids.
* @param ids Stream of ids.
* @param search Case insensitive string which will be searched for. Ignored if null.
* @param first Index of the first result to return. Ignored if negative or {@code null}.
* @param max Maximum number of results to return. Ignored if negative or {@code null}.
* @return List of desired groups.
* @return Stream of desired groups. Never returns {@code null}.
*/
Stream<GroupModel> getGroupsStream(RealmModel realm, Stream<String> ids, String search, Integer first, Integer max);
/**
* Returns a paginated list of groups with given ids.
* Returns a paginated stream of groups with given ids.
* Effectively the same as {@code getGroupsStream(realm, ids, null, first, max)}.
*
* @param realm Realm.
* @param ids List of ids.
* @param ids Stream of ids.
* @param first Index of the first result to return. Ignored if negative or {@code null}.
* @param max Maximum number of results to return. Ignored if negative or {@code null}.
* @return List of GroupModels with the specified ids
* @return Stream of GroupModels with the specified ids
*/
default Stream<GroupModel> getGroupsStream(RealmModel realm, Stream<String> ids, Integer first, Integer max) {
return getGroupsStream(realm, ids, null, first, max);
@ -137,8 +137,8 @@ public interface GroupProvider extends Provider, GroupLookupProvider {
*
* @param realm Realm.
* @param role Role.
* @param firstResult First result to return. Ignored if negative.
* @param maxResults Maximum number of results to return. Ignored if negative.
* @param firstResult First result to return. Ignored if negative or {@code null}.
* @param maxResults Maximum number of results to return. Ignored if negative or {@code null}.
* @return List of groups with the given role.
* @deprecated Use {@link #getGroupsByRoleStream(RealmModel, RoleModel, Integer, Integer) getGroupsByRoleStream} instead.
*/
@ -154,7 +154,7 @@ public interface GroupProvider extends Provider, GroupLookupProvider {
* @param role Role.
* @param firstResult First result to return. Ignored if negative or {@code null}.
* @param maxResults Maximum number of results to return. Ignored if negative or {@code null}.
* @return Stream of groups with the given role.
* @return Stream of groups with the given role. Never returns {@code null}.
*/
Stream<GroupModel> getGroupsByRoleStream(RealmModel realm, RoleModel role, Integer firstResult, Integer maxResults);
@ -174,7 +174,7 @@ public interface GroupProvider extends Provider, GroupLookupProvider {
* Returns all top level groups (i.e. groups without parent group) for the given realm.
*
* @param realm Realm.
* @return Stream of all top level groups in the realm.
* @return Stream of all top level groups in the realm. Never returns {@code null}.
*/
Stream<GroupModel> getTopLevelGroupsStream(RealmModel realm);
@ -198,7 +198,7 @@ public interface GroupProvider extends Provider, GroupLookupProvider {
* @param realm Realm.
* @param firstResult First result to return. Ignored if negative or {@code null}.
* @param maxResults Maximum number of results to return. Ignored if negative or {@code null}.
* @return Stream of top level groups in the realm.
* @return Stream of top level groups in the realm. Never returns {@code null}.
*/
Stream<GroupModel> getTopLevelGroupsStream(RealmModel realm, Integer firstResult, Integer maxResults);

View file

@ -55,7 +55,7 @@ public interface KeyManager {
/**
* Returns all {@code KeyWrapper} for the given realm.
* @param realm {@code RealmModel}.
* @return Stream of all {@code KeyWrapper} in the realm.
* @return Stream of all {@code KeyWrapper} in the realm. Never returns {@code null}.
*/
Stream<KeyWrapper> getKeysStream(RealmModel realm);
@ -77,7 +77,7 @@ public interface KeyManager {
* @param realm {@code RealmModel}.
* @param use {@code KeyUse}.
* @param algorithm {@code String}.
* @return Stream of all {@code KeyWrapper} in the realm.
* @return Stream of all {@code KeyWrapper} in the realm. Never returns {@code null}.
*/
Stream<KeyWrapper> getKeysStream(RealmModel realm, KeyUse use, String algorithm);

View file

@ -24,6 +24,8 @@ import org.keycloak.provider.Spi;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -40,7 +42,23 @@ public interface KeycloakSessionFactory extends ProviderEventManager {
<T extends Provider> ProviderFactory<T> getProviderFactory(Class<T> clazz, String id);
List<ProviderFactory> getProviderFactories(Class<? extends Provider> clazz);
/**
* Returns list of provider factories for the given provider.
* @param clazz {@code Class<? extends Provider>}
* @return {@code List<ProviderFactory>} List of provider factories
* @deprecated Use {@link #getProviderFactoriesStream(Class) getProviderFactoriesStream} instead.
*/
@Deprecated
default List<ProviderFactory> getProviderFactories(Class<? extends Provider> clazz) {
return getProviderFactoriesStream(clazz).collect(Collectors.toList());
}
/**
* Returns stream of provider factories for the given provider.
* @param clazz {@code Class<? extends Provider>}
* @return {@code Stream<ProviderFactory>} Stream of provider factories. Never returns {@code null}.
*/
Stream<ProviderFactory> getProviderFactoriesStream(Class<? extends Provider> clazz);
long getServerStartupTimestamp();

View file

@ -37,7 +37,7 @@ public interface ProtocolMapperContainerModel {
/**
* Returns protocol mappers as a stream.
* @return Stream of protocol mapper.
* @return Stream of protocol mapper. Never returns {@code null}.
*/
Stream<ProtocolMapperModel> getProtocolMappersStream();

View file

@ -28,7 +28,9 @@ import org.keycloak.storage.client.ClientStorageProviderModel;
import org.keycloak.storage.role.RoleStorageProvider;
import org.keycloak.storage.role.RoleStorageProviderModel;
import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -232,13 +234,17 @@ public interface RealmModel extends RoleContainerModel {
void setActionTokenGeneratedByUserLifespan(String actionTokenType, Integer seconds);
/**
* @deprecated Use {@link #getRequiredCredentialsStream() getRequiredCredentialsStream} instead.
* @deprecated Use {@link #getRequiredCredentialsStream() getRequiredCredentialsStream} instead.
*/
@Deprecated
default List<RequiredCredentialModel> getRequiredCredentials() {
return getRequiredCredentialsStream().collect(Collectors.toList());
}
/**
* Returns required credentials as a stream.
* @return Stream of {@link RequiredCredentialModel}. Never returns {@code null}.
*/
Stream<RequiredCredentialModel> getRequiredCredentialsStream();
void addRequiredCredential(String cred);
@ -276,38 +282,68 @@ public interface RealmModel extends RoleContainerModel {
RoleModel getRoleById(String id);
/**
* @deprecated Use {@link #getDefaultGroupsStream() getDefaultGroupsStream} instead.
*/
@Deprecated
default List<GroupModel> getDefaultGroups() {
return getDefaultGroupsStream().collect(Collectors.toList());
}
/**
* Returns default groups as a stream.
* @return Stream of {@link GroupModel}. Never returns {@code null}.
*/
Stream<GroupModel> getDefaultGroupsStream();
void addDefaultGroup(GroupModel group);
void removeDefaultGroup(GroupModel group);
/**
* @deprecated Use {@link #getClientsStream() getClientsStream} instead.
*/
@Deprecated
default List<ClientModel> getClients() {
return getClientsStream(null, null).collect(Collectors.toList());
}
/**
* Returns clients as a stream.
* @return Stream of {@link ClientModel}. Never returns {@code null}.
*/
Stream<ClientModel> getClientsStream();
/**
* @deprecated Use {@link #getClientsStream(Integer, Integer) getClientsStream} instead.
*/
@Deprecated
default List<ClientModel> getClients(Integer firstResult, Integer maxResults) {
return getClientsStream(firstResult, maxResults).collect(Collectors.toList());
}
/**
* Returns clients as a stream.
* @param firstResult {@code Integer} Index of the first desired client. Ignored if negative or {@code null}.
* @param maxResults {@code Integer} Maximum number of returned clients. Ignored if negative or {@code null}.
* @return Stream of {@link ClientModel}. Never returns {@code null}.
*/
Stream<ClientModel> getClientsStream(Integer firstResult, Integer maxResults);
Long getClientsCount();
/**
* @deprecated Use {@link #getAlwaysDisplayInConsoleClientsStream() getAlwaysDisplayInConsoleClientsStream} instead.
*/
@Deprecated
default List<ClientModel> getAlwaysDisplayInConsoleClients() {
return getAlwaysDisplayInConsoleClientsStream().collect(Collectors.toList());
}
/**
* Returns clients which are always displayed in the admin console as a stream.
* @return Stream of {@link ClientModel}. Never returns {@code null}.
*/
Stream<ClientModel> getAlwaysDisplayInConsoleClientsStream();
ClientModel addClient(String name);
@ -319,11 +355,21 @@ public interface RealmModel extends RoleContainerModel {
ClientModel getClientById(String id);
ClientModel getClientByClientId(String clientId);
/**
* @deprecated Use {@link #searchClientByClientIdStream(String, Integer, Integer) searchClientByClientId} instead.
*/
@Deprecated
default List<ClientModel> searchClientByClientId(String clientId, Integer firstResult, Integer maxResults) {
return searchClientByClientIdStream(clientId, firstResult, maxResults).collect(Collectors.toList());
}
/**
* Search for clients by provided client's id.
* @param clientId {@code String} Id of the client.
* @param firstResult Index of the first desired client. Ignored if negative or {@code null}.
* @param maxResults Maximum number of returned clients. Ignored if negative or {@code null}.
* @return Stream of {@link ClientModel}. Never returns {@code null}.
*/
Stream<ClientModel> searchClientByClientIdStream(String clientId, Integer firstResult, Integer maxResults);
void updateRequiredCredentials(Set<String> creds);
@ -354,13 +400,17 @@ public interface RealmModel extends RoleContainerModel {
void setDockerAuthenticationFlow(AuthenticationFlowModel flow);
/**
* @deprecated Use {@link #getAuthenticationFlowsStream() getAuthenticationFlowsStream} instead.
* @deprecated Use {@link #getAuthenticationFlowsStream() getAuthenticationFlowsStream} instead.
*/
@Deprecated
default List<AuthenticationFlowModel> getAuthenticationFlows() {
return getAuthenticationFlowsStream().collect(Collectors.toList());
}
/**
* Returns authentications flows as a stream.
* @return Stream of {@link AuthenticationFlowModel}. Never returns {@code null}.
*/
Stream<AuthenticationFlowModel> getAuthenticationFlowsStream();
AuthenticationFlowModel getFlowByAlias(String alias);
@ -380,7 +430,8 @@ public interface RealmModel extends RoleContainerModel {
/**
* Returns sorted {@link AuthenticationExecutionModel AuthenticationExecutionModel} as a stream.
* It should be used with forEachOrdered if the ordering is required.
* @return Sorted stream
* @param flowId {@code String} Id of the flow.
* @return Sorted stream of {@link AuthenticationExecutionModel}. Never returns {@code null}.
*/
Stream<AuthenticationExecutionModel> getAuthenticationExecutionsStream(String flowId);
@ -398,6 +449,10 @@ public interface RealmModel extends RoleContainerModel {
return getAuthenticatorConfigsStream().collect(Collectors.toList());
}
/**
* Returns authentication configs as a stream.
* @return Stream of {@link AuthenticatorConfigModel}. Never returns {@code null}.
*/
Stream<AuthenticatorConfigModel> getAuthenticatorConfigsStream();
AuthenticatorConfigModel addAuthenticatorConfig(AuthenticatorConfigModel model);
@ -417,7 +472,7 @@ public interface RealmModel extends RoleContainerModel {
/**
* Returns sorted {@link RequiredActionProviderModel RequiredActionProviderModel} as a stream.
* It should be used with forEachOrdered if the ordering is required.
* @return Sorted stream
* @return Sorted stream of {@link RequiredActionProviderModel}. Never returns {@code null}.
*/
Stream<RequiredActionProviderModel> getRequiredActionProvidersStream();
@ -435,6 +490,10 @@ public interface RealmModel extends RoleContainerModel {
return getIdentityProvidersStream().collect(Collectors.toList());
}
/**
* Returns identity providers as a stream.
* @return Stream of {@link IdentityProviderModel}. Never returns {@code null}.
*/
Stream<IdentityProviderModel> getIdentityProvidersStream();
IdentityProviderModel getIdentityProviderByAlias(String alias);
@ -450,6 +509,10 @@ public interface RealmModel extends RoleContainerModel {
return getIdentityProviderMappersStream().collect(Collectors.toSet());
}
/**
* Returns identity provider mappers as a stream.
* @return Stream of {@link IdentityProviderMapperModel}. Never returns {@code null}.
*/
Stream<IdentityProviderMapperModel> getIdentityProviderMappersStream();
/**
@ -460,6 +523,11 @@ public interface RealmModel extends RoleContainerModel {
return getIdentityProviderMappersByAliasStream(brokerAlias).collect(Collectors.toSet());
}
/**
* Returns identity provider mappers by the provided alias as a stream.
* @param brokerAlias {@code String} Broker's alias to filter results.
* @return Stream of {@link IdentityProviderMapperModel} Never returns {@code null}.
*/
Stream<IdentityProviderMapperModel> getIdentityProviderMappersByAliasStream(String brokerAlias);
IdentityProviderMapperModel addIdentityProviderMapper(IdentityProviderMapperModel model);
@ -500,12 +568,17 @@ public interface RealmModel extends RoleContainerModel {
/**
* Returns stream of ComponentModels for specific parentId and providerType.
* @param parentId id of parent
* @param providerType type of provider
* @return stream of ComponentModels
* @param parentId {@code String} id of parent
* @param providerType {@code String} type of provider
* @return Stream of {@link ComponentModel}. Never returns {@code null}.
*/
Stream<ComponentModel> getComponentsStream(String parentId, String providerType);
/**
* Returns stream of ComponentModels for specific parentId.
* @param parentId {@code String} id of parent
* @return Stream of {@link ComponentModel}. Never returns {@code null}.
*/
Stream<ComponentModel> getComponentsStream(String parentId);
/**
@ -524,6 +597,10 @@ public interface RealmModel extends RoleContainerModel {
return getComponentsStream().collect(Collectors.toList());
}
/**
* Returns stream of component models.
* @return Stream of {@link ComponentModel}. Never returns {@code null}.
*/
Stream<ComponentModel> getComponentsStream();
ComponentModel getComponent(String id);
@ -539,7 +616,7 @@ public interface RealmModel extends RoleContainerModel {
/**
* Returns sorted {@link UserStorageProviderModel UserStorageProviderModel} as a stream.
* It should be used with forEachOrdered if the ordering is required.
* @return Sorted stream
* @return Sorted stream of {@link UserStorageProviderModel}. Never returns {@code null}.
*/
default Stream<UserStorageProviderModel> getUserStorageProvidersStream() {
return getComponentsStream(getId(), UserStorageProvider.class.getName())
@ -558,7 +635,7 @@ public interface RealmModel extends RoleContainerModel {
/**
* Returns sorted {@link ClientStorageProviderModel ClientStorageProviderModel} as a stream.
* It should be used with forEachOrdered if the ordering is required.
* @return Sorted stream
* @return Sorted stream of {@link ClientStorageProviderModel}. Never returns {@code null}.
*/
default Stream<ClientStorageProviderModel> getClientStorageProvidersStream() {
return getComponentsStream(getId(), ClientStorageProvider.class.getName())
@ -577,7 +654,7 @@ public interface RealmModel extends RoleContainerModel {
/**
* Returns sorted {@link RoleStorageProviderModel RoleStorageProviderModel} as a stream.
* It should be used with forEachOrdered if the ordering is required.
* @return Sorted stream
* @return Sorted stream of {@link RoleStorageProviderModel}. Never returns {@code null}.
*/
default Stream<RoleStorageProviderModel> getRoleStorageProvidersStream() {
return getComponentsStream(getId(), RoleStorageProvider.class.getName())
@ -586,9 +663,9 @@ public interface RealmModel extends RoleContainerModel {
}
/**
* Returns stream of ComponentModels that represent StorageProviders for class storageProviderClass in this realm
* @param storageProviderClass class
* @return stream of StorageProviders
* Returns stream of ComponentModels that represent StorageProviders for class storageProviderClass in this realm.
* @param storageProviderClass {@code Class<? extends Provider>}
* @return Stream of {@link ComponentModel}. Never returns {@code null}.
*/
default Stream<ComponentModel> getStorageProviders(Class<? extends Provider> storageProviderClass) {
return getComponentsStream(getId(), storageProviderClass.getName());
@ -640,6 +717,10 @@ public interface RealmModel extends RoleContainerModel {
return getEventsListenersStream().collect(Collectors.toSet());
}
/**
* Returns events listeners as a stream.
* @return Stream of {@code String}. Never returns {@code null}.
*/
Stream<String> getEventsListenersStream();
void setEventsListeners(Set<String> listeners);
@ -652,6 +733,10 @@ public interface RealmModel extends RoleContainerModel {
return getEnabledEventTypesStream().collect(Collectors.toSet());
}
/**
* Returns enabled event types as a stream.
* @return Stream of {@code String}. Never returns {@code null}.
*/
Stream<String> getEnabledEventTypesStream();
void setEnabledEventTypes(Set<String> enabledEventTypes);
@ -693,6 +778,10 @@ public interface RealmModel extends RoleContainerModel {
return getSupportedLocalesStream().collect(Collectors.toSet());
}
/**
* Returns supported locales as a stream.
* @return Stream of {@code String}. Never returns {@code null}.
*/
Stream<String> getSupportedLocalesStream();
void setSupportedLocales(Set<String> locales);
@ -723,6 +812,10 @@ public interface RealmModel extends RoleContainerModel {
return getGroupsStream().collect(Collectors.toList());
}
/**
* Returns groups as a stream.
* @return Stream of {@link GroupModel}. Never returns {@code null}.
*/
Stream<GroupModel> getGroupsStream();
Long getGroupsCount(Boolean onlyTopGroups);
@ -736,6 +829,10 @@ public interface RealmModel extends RoleContainerModel {
return getTopLevelGroupsStream().collect(Collectors.toList());
}
/**
* Returns top level groups as a stream.
* @return Stream of {@link GroupModel}. Never returns {@code null}.
*/
Stream<GroupModel> getTopLevelGroupsStream();
/**
@ -746,6 +843,12 @@ public interface RealmModel extends RoleContainerModel {
return getTopLevelGroupsStream(first, max).collect(Collectors.toList());
}
/**
* Returns top level groups as a stream.
* @param first {@code Integer} Index of the first desired group. Ignored if negative or {@code null}.
* @param max {@code Integer} Maximum number of returned groups. Ignored if negative or {@code null}.
* @return Stream of {@link GroupModel}. Never returns {@code null}.
*/
Stream<GroupModel> getTopLevelGroupsStream(Integer first, Integer max);
/**
@ -756,6 +859,13 @@ public interface RealmModel extends RoleContainerModel {
return searchForGroupByNameStream(search, first, max).collect(Collectors.toList());
}
/**
* Searches for groups by provided name. Results that match the given filter are returned as a stream.
* @param search {@code String} Name of a group to be used as a filter.
* @param first {@code Integer} Index of the first desired group. Ignored if negative or {@code null}.
* @param max {@code Integer} Maximum number of returned groups. Ignored if negative or {@code null}.
* @return Stream of {@link GroupModel}. Never returns {@code null}.
*/
Stream<GroupModel> searchForGroupByNameStream(String search, Integer first, Integer max);
boolean removeGroup(GroupModel group);
@ -769,6 +879,10 @@ public interface RealmModel extends RoleContainerModel {
return getClientScopesStream().collect(Collectors.toList());
}
/**
* Returns client's scopes as a stream.
* @return Stream of {@link ClientScopeModel}. Never returns {@code null}.
*/
Stream<ClientScopeModel> getClientScopesStream();
ClientScopeModel addClientScope(String name);
@ -799,6 +913,11 @@ public interface RealmModel extends RoleContainerModel {
return getDefaultClientScopesStream(defaultScope).collect(Collectors.toList());
}
/**
* Returns client's scopes with ability to specify whether default client's scopes are desired.
* @param defaultScope {@code boolean} Flag to include default client's scopes.
* @return Stream of {@link ClientScopeModel}. Never returns {@code null}.
*/
Stream<ClientScopeModel> getDefaultClientScopesStream(boolean defaultScope);
/**

View file

@ -42,23 +42,32 @@ public interface RealmProvider extends Provider /* TODO: Remove in future versio
ClientScopeModel getClientScopeById(String id, RealmModel realm);
/**
* @deprecated Use {@link #getRealmsStream() getRealmsStream} instead.
* @deprecated Use {@link #getRealmsStream() getRealmsStream} instead.
*/
@Deprecated
default List<RealmModel> getRealms() {
return getRealmsStream().collect(Collectors.toList());
}
/**
* Returns realms as a stream.
* @return Stream of {@link RealmModel}. Never returns {@code null}.
*/
Stream<RealmModel> getRealmsStream();
/**
* @deprecated Use {@link #getRealmsWithProviderTypeStream(Class)} getRealmsWithProviderTypeStream} instead.
* @deprecated Use {@link #getRealmsWithProviderTypeStream(Class) getRealmsWithProviderTypeStream} instead.
*/
@Deprecated
default List<RealmModel> getRealmsWithProviderType(Class<?> type) {
return getRealmsWithProviderTypeStream(type).collect(Collectors.toList());
}
/**
* Returns realms with the given provider type as a stream.
* @param type {@code Class<?>} Type of the provider.
* @return Stream of {@link RealmModel}. Never returns {@code null}.
*/
Stream<RealmModel> getRealmsWithProviderTypeStream(Class<?> type);
@ -69,13 +78,18 @@ public interface RealmProvider extends Provider /* TODO: Remove in future versio
void removeClientInitialAccessModel(RealmModel realm, String id);
/**
* @deprecated Use {@link #listClientInitialAccessStream(RealmModel)} listClientInitialAccessStream} instead.
* @deprecated Use {@link #listClientInitialAccessStream(RealmModel) listClientInitialAccessStream} instead.
*/
@Deprecated
default List<ClientInitialAccessModel> listClientInitialAccess(RealmModel realm) {
return listClientInitialAccessStream(realm).collect(Collectors.toList());
}
/**
* Returns client's initial access as a stream.
* @param realm {@link RealmModel} The realm where to list client's initial access.
* @return Stream of {@link ClientInitialAccessModel}. Never returns {@code null}.
*/
Stream<ClientInitialAccessModel> listClientInitialAccessStream(RealmModel realm);
void removeExpiredClientInitialAccess();

View file

@ -49,25 +49,51 @@ public interface RoleContainerModel {
boolean removeRole(RoleModel role);
/**
* @deprecated Use {@link #getRolesStream() getRolesStream} instead.
*/
@Deprecated
default Set<RoleModel> getRoles() {
return getRolesStream().collect(Collectors.toSet());
}
/**
* Returns available roles as a stream.
* @return Stream of {@link RoleModel}. Never returns {@code null}.
*/
Stream<RoleModel> getRolesStream();
/**
* @deprecated Use {@link #getRolesStream(Integer, Integer) getRolesStream} instead.
*/
@Deprecated
default Set<RoleModel> getRoles(Integer firstResult, Integer maxResults) {
return getRolesStream(firstResult, maxResults).collect(Collectors.toSet());
}
/**
* Returns available roles as a stream.
* @param firstResult {@code Integer} Index of the first desired role. Ignored if negative or {@code null}.
* @param maxResults {@code Integer} Maximum number of returned roles. Ignored if negative or {@code null}.
* @return Stream of {@link RoleModel}. Never returns {@code null}.
*/
Stream<RoleModel> getRolesStream(Integer firstResult, Integer maxResults);
/**
* @deprecated Use {@link #searchForRolesStream(String, Integer, Integer) searchForRolesStream} instead.
*/
@Deprecated
default Set<RoleModel> searchForRoles(String search, Integer first, Integer max) {
return searchForRolesStream(search, first, max).collect(Collectors.toSet());
}
/**
* Searches roles by the given name. Returns all roles that match the given filter.
* @param search {@code String} Name of the role to be used as a filter.
* @param first {@code Integer} Index of the first desired role. Ignored if negative or {@code null}.
* @param max {@code Integer} Maximum number of returned roles. Ignored if negative or {@code null}.
* @return Stream of {@link RoleModel}. Never returns {@code null}.
*/
Stream<RoleModel> searchForRolesStream(String search, Integer first, Integer max);
/**

View file

@ -29,14 +29,14 @@ public interface RoleMapperModel {
/**
* Returns set of realm roles that are directly set to this object.
* @return see description
* @deprecated Use {@link #getRealmRoleMappingsStream()} getRealmRoleMappingsStream} instead.
* @deprecated Use {@link #getRealmRoleMappingsStream() getRealmRoleMappingsStream} instead.
*/
@Deprecated
Set<RoleModel> getRealmRoleMappings();
/**
* Returns stream of realm roles that are directly set to this object.
* @return stream of {@link RoleModel}
* @return Stream of {@link RoleModel}. Never returns {@code null}.
*/
default Stream<RoleModel> getRealmRoleMappingsStream() {
Set<RoleModel> value = this.getRealmRoleMappings();
@ -47,15 +47,15 @@ public interface RoleMapperModel {
* Returns set of client roles that are directly set to this object for the given client.
* @param app Client to get the roles for
* @return see description
* @deprecated Use {@link #getClientRoleMappingsStream(ClientModel)} getClientRoleMappingsStream} instead.
* @deprecated Use {@link #getClientRoleMappingsStream(ClientModel) getClientRoleMappingsStream} instead.
*/
@Deprecated
Set<RoleModel> getClientRoleMappings(ClientModel app);
/**
* Returns stream of client roles that are directly set to this object for the given client.
* @param app Client to get the roles for
* @return stream of {@link RoleModel}
* @param app {@link ClientModel} Client to get the roles for.
* @return Stream of {@link RoleModel}. Never returns {@code null}.
*/
default Stream<RoleModel> getClientRoleMappingsStream(ClientModel app) {
Set<RoleModel> value = this.getClientRoleMappings(app);
@ -85,14 +85,14 @@ public interface RoleMapperModel {
/**
* Returns set of all role (both realm all client) that are directly set to this object.
* @return
* @deprecated Use {@link #getRoleMappingsStream()} getRoleMappingsStream} instead.
* @deprecated Use {@link #getRoleMappingsStream() getRoleMappingsStream} instead.
*/
@Deprecated
Set<RoleModel> getRoleMappings();
/**
* Returns stream of all role (both realm all client) that are directly set to this object.
* @return stream of {@link RoleModel}
* @return Stream of {@link RoleModel}. Never returns {@code null}.
*/
default Stream<RoleModel> getRoleMappingsStream() {
Set<RoleModel> value = this.getRoleMappings();

View file

@ -44,11 +44,18 @@ public interface RoleModel {
void removeCompositeRole(RoleModel role);
/**
* @deprecated Use {@link #getCompositesStream() getCompositesStream} instead.
*/
@Deprecated
default Set<RoleModel> getComposites() {
return getCompositesStream().collect(Collectors.toSet());
}
/**
* Returns all composite roles as a stream.
* @return Stream of {@link RoleModel}. Never returns {@code null}.
*/
Stream<RoleModel> getCompositesStream();
boolean isClientRole();
@ -69,11 +76,19 @@ public interface RoleModel {
return getAttributeStream(name).findFirst().orElse(null);
}
/**
* @deprecated Use {@link #getAttributeStream(String) getAttributeStream} instead.
*/
@Deprecated
default List<String> getAttribute(String name) {
return getAttributeStream(name).collect(Collectors.toList());
}
/**
* Returns all role's attributes that match the given name as a stream.
* @param name {@code String} Name of an attribute to be used as a filter.
* @return Stream of {@code String}. Never returns {@code null}.
*/
Stream<String> getAttributeStream(String name);
Map<String, List<String>> getAttributes();

View file

@ -83,7 +83,6 @@ public interface RoleProvider extends Provider, RoleLookupProvider {
/**
* Removes given realm role from the given realm.
* @param realm Realm.
* @param role Role to be removed.
* @return {@code true} if the role existed and has been removed, {@code false} otherwise.
*/
@ -119,7 +118,7 @@ public interface RoleProvider extends Provider, RoleLookupProvider {
* Returns all the client roles of the given client.
* Effectively the same as the call {@code getClientRoles(client, null, null)}.
* @param client Client.
* @return List of the roles. Never returns {@code null}.
* @return Stream of the roles. Never returns {@code null}.
*/
default Stream<RoleModel> getClientRolesStream(ClientModel client) {
return getClientRolesStream(client, null, null);
@ -130,7 +129,7 @@ public interface RoleProvider extends Provider, RoleLookupProvider {
* @param client Client.
* @param first First result to return. Ignored if negative or {@code null}.
* @param max Maximum number of results to return. Ignored if negative or {@code null}.
* @return List of the roles. Never returns {@code null}.
* @return Stream of the roles. Never returns {@code null}.
*/
Stream<RoleModel> getClientRolesStream(ClientModel client, Integer first, Integer max);

View file

@ -27,18 +27,25 @@ import java.util.stream.Stream;
*/
public interface ScopeContainerModel {
/**
* @deprecated Use {@link #getScopeMappingsStream() getScopeMappingsStream} instead.
*/
@Deprecated
default Set<RoleModel> getScopeMappings() {
return getScopeMappingsStream().collect(Collectors.toSet());
}
/**
* Returns scope mappings for this scope container as a stream.
* @return Stream of {@link RoleModel}. Never returns {@code null}.
*/
Stream<RoleModel> getScopeMappingsStream();
/**
* From the scope mappings returned by {@link #getScopeMappings()} returns only those
* that belong to the realm that owns this scope container.
* @return set of {@link RealmModel}
* @deprecated Use {@link #getRealmScopeMappingsStream()} getRealmScopeMappingsStream} instead.
* @deprecated Use {@link #getRealmScopeMappingsStream() getRealmScopeMappingsStream} instead.
*/
@Deprecated
default Set<RoleModel> getRealmScopeMappings() {
@ -46,9 +53,9 @@ public interface ScopeContainerModel {
}
/**
* From the scope mappings returned by {@link #getScopeMappingsStream()} ()} returns only those
* From the scope mappings returned by {@link #getScopeMappingsStream()} returns only those
* that belong to the realm that owns this scope container.
* @return stream of {@link RoleModel}
* @return stream of {@link RoleModel}. Never returns {@code null}.
*/
Stream<RoleModel> getRealmScopeMappingsStream();

View file

@ -210,7 +210,7 @@ public interface UserModel extends RoleMapperModel {
* @param search Case insensitive string which will be searched for. Ignored if null.
* @param first Index of first group to return. Ignored if negative or {@code null}.
* @param max Maximum number of records to return. Ignored if negative or {@code null}.
* @return Stream of desired groups.
* @return Stream of desired groups. Never returns {@code null}.
*/
default Stream<GroupModel> getGroupsStream(String search, Integer first, Integer max) {
if (search != null) search = search.toLowerCase();

View file

@ -78,7 +78,7 @@ public interface UserSessionProvider extends Provider {
Stream<UserSessionModel> getUserSessionsStream(RealmModel realm, ClientModel client);
/**
* @deprecated Use {@link #getUserSessionsStream(RealmModel, ClientModel, int, int) getUserSessionsStream} instead.
* @deprecated Use {@link #getUserSessionsStream(RealmModel, ClientModel, Integer, Integer) getUserSessionsStream} instead.
*/
@Deprecated
default List<UserSessionModel> getUserSessions(RealmModel realm, ClientModel client, int firstResult, int maxResults) {
@ -91,11 +91,11 @@ public interface UserSessionProvider extends Provider {
*
* @param realm a reference tot he realm.
* @param client the client whose user sessions are being searched.
* @param firstResult first result to return. Ignored if negative.
* @param maxResults maximum number of results to return. Ignored if negative.
* @param firstResult first result to return. Ignored if negative or {@code null}.
* @param maxResults maximum number of results to return. Ignored if negative or {@code null}.
* @return a non-null {@link Stream} of user sessions.
*/
Stream<UserSessionModel> getUserSessionsStream(RealmModel realm, ClientModel client, int firstResult, int maxResults);
Stream<UserSessionModel> getUserSessionsStream(RealmModel realm, ClientModel client, Integer firstResult, Integer maxResults);
/**
* @deprecated Use {@link #getUserSessionByBrokerUserIdStream(RealmModel, String) getUserSessionByBrokerUserIdStream}
@ -200,7 +200,7 @@ public interface UserSessionProvider extends Provider {
long getOfflineSessionsCount(RealmModel realm, ClientModel client);
/**
* @deprecated use {@link #getOfflineUserSessionsStream(RealmModel, ClientModel, int, int) getOfflineUserSessionsStream}
* @deprecated use {@link #getOfflineUserSessionsStream(RealmModel, ClientModel, Integer, Integer) getOfflineUserSessionsStream}
* instead.
*/
@Deprecated
@ -214,11 +214,11 @@ public interface UserSessionProvider extends Provider {
*
* @param realm a reference tot he realm.
* @param client the client whose user sessions are being searched.
* @param firstResult first result to return. Ignored if negative.
* @param maxResults maximum number of results to return. Ignored if negative.
* @param firstResult first result to return. Ignored if negative or {@code null}.
* @param maxResults maximum number of results to return. Ignored if negative or {@code null}.
* @return a non-null {@link Stream} of offline user sessions.
*/
Stream<UserSessionModel> getOfflineUserSessionsStream(RealmModel realm, ClientModel client, int firstResult, int maxResults);
Stream<UserSessionModel> getOfflineUserSessionsStream(RealmModel realm, ClientModel client, Integer firstResult, Integer maxResults);
/** Triggered by persister during pre-load. It imports authenticatedClientSessions too **/
void importUserSessions(Collection<UserSessionModel> persistentUserSessions, boolean offline);

View file

@ -162,7 +162,7 @@ public class RoleUtils {
* @param role
* @param visited Track roles, which were already visited. Those will be ignored and won't be added to the stream. Besides that,
* the "visited" set itself will be updated as a result of this method call and all the tracked roles will be added to it
* @return Stream of containing all of the composite roles and their components.
* @return Stream of containing all of the composite roles and their components. Never returns {@code null}.
*/
private static Stream<RoleModel> expandCompositeRolesStream(RoleModel role, Set<RoleModel> visited) {
Stream.Builder<RoleModel> sb = Stream.builder();

View file

@ -89,7 +89,7 @@ public interface ClientLookupProvider {
* identifier ({@code client_id} in OIDC or {@code entityID} in SAML.)
* @param firstResult First result to return. Ignored if negative or {@code null}.
* @param maxResults Maximum number of results to return. Ignored if negative or {@code null}.
* @return Stream of ClientModel or an empty stream if no client is found.
* @return Stream of ClientModel or an empty stream if no client is found. Never returns {@code null}.
*/
Stream<ClientModel> searchClientsByClientIdStream(RealmModel realm, String clientId, Integer firstResult, Integer maxResults);
}

View file

@ -46,7 +46,7 @@ public interface UserFederatedStorageProvider extends Provider,
UserFederatedUserCredentialStore {
/**
* @deprecated Use {@link #getStoredUsersStream(RealmModel, int, int) getStoredUsersStream} instead.
* @deprecated Use {@link #getStoredUsersStream(RealmModel, Integer, Integer) getStoredUsersStream} instead.
*/
@Deprecated
List<String> getStoredUsers(RealmModel realm, int first, int max);
@ -55,11 +55,11 @@ public interface UserFederatedStorageProvider extends Provider,
* Obtains the ids of all federated users in the realm.
*
* @param realm a reference to the realm.
* @param first first result to return. Ignored if negative.
* @param max maximum number of results to return. Ignored if negative.
* @param first first result to return. Ignored if negative or {@code null}.
* @param max maximum number of results to return. Ignored if negative or {@code null}.
* @return a non-null {@link Stream} of federated user ids.
*/
default Stream<String> getStoredUsersStream(RealmModel realm, int first, int max) {
default Stream<String> getStoredUsersStream(RealmModel realm, Integer first, Integer max) {
List<String> value = this.getStoredUsers(realm, first, max);
return value != null ? value.stream() : Stream.empty();
}
@ -105,6 +105,6 @@ public interface UserFederatedStorageProvider extends Provider,
}
@Override
Stream<String> getStoredUsersStream(RealmModel realm, int first, int max);
Stream<String> getStoredUsersStream(RealmModel realm, Integer first, Integer max);
}
}

View file

@ -52,7 +52,7 @@ public interface UserGroupMembershipFederatedStorage {
void leaveGroup(RealmModel realm, String userId, GroupModel group);
/**
* @deprecated Use {@link #getMembershipStream(RealmModel, GroupModel, int, int) getMembershipStream} instead.
* @deprecated Use {@link #getMembershipStream(RealmModel, GroupModel, Integer, Integer) getMembershipStream} instead.
*/
@Deprecated
List<String> getMembership(RealmModel realm, GroupModel group, int firstResult, int max);
@ -62,11 +62,11 @@ public interface UserGroupMembershipFederatedStorage {
*
* @param realm a reference to the realm.
* @param group a reference to the group whose federated members are being searched.
* @param firstResult first result to return. Ignored if negative.
* @param max maximum number of results to return. Ignored if negative.
* @param firstResult first result to return. Ignored if negative or {@code null}.
* @param max maximum number of results to return. Ignored if negative or {@code null}.
* @return a non-null {@code Stream} of federated user ids that are members of the group in the realm.
*/
default Stream<String> getMembershipStream(RealmModel realm, GroupModel group, int firstResult, int max) {
default Stream<String> getMembershipStream(RealmModel realm, GroupModel group, Integer firstResult, Integer max) {
List<String> value = this.getMembership(realm, group, firstResult, max);
return value != null ? value.stream() : Stream.empty();
}
@ -94,6 +94,6 @@ public interface UserGroupMembershipFederatedStorage {
}
@Override
Stream<String> getMembershipStream(RealmModel realm, GroupModel group, int firstResult, int max);
Stream<String> getMembershipStream(RealmModel realm, GroupModel group, Integer firstResult, Integer max);
}
}

View file

@ -56,7 +56,7 @@ public interface GroupLookupProvider {
* @param search Case sensitive searched string.
* @param firstResult First result to return. Ignored if negative or {@code null}.
* @param maxResults Maximum number of results to return. Ignored if negative or {@code null}.
* @return Stream of groups with the given string in name.
* @return Stream of groups with the given string in name. Never returns {@code null}.
*/
Stream<GroupModel> searchForGroupByNameStream(RealmModel realm, String search, Integer firstResult, Integer maxResults);

View file

@ -201,8 +201,8 @@ public interface UserQueryProvider {
* Searches all users in the realm, starting from the {@code firstResult} and containing at most {@code maxResults}.
*
* @param realm a reference to the realm.
* @param firstResult first result to return. Ignored if negative or zero.
* @param maxResults maximum number of results to return. Ignored if negative.
* @param firstResult first result to return. Ignored if negative or {@code null}.
* @param maxResults maximum number of results to return. Ignored if negative or {@code null}.
* @return a non-null {@link Stream} of users.
*/
default Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) {
@ -500,8 +500,8 @@ public interface UserQueryProvider {
*
* @param realm a reference to the realm.
* @param role a reference to the role.
* @param firstResult first result to return. Ignored if negative.
* @param maxResults maximum number of results to return. Ignored if negative.
* @param firstResult first result to return. Ignored if negative or {@code null}.
* @param maxResults maximum number of results to return. Ignored if negative or {@code null}.
* @return a non-null {@link Stream} of users that have the specified role.
*/
default Stream<UserModel> getRoleMembersStream(RealmModel realm, RoleModel role, Integer firstResult, Integer maxResults) {

View file

@ -22,11 +22,11 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
@ -280,8 +280,8 @@ public class PolicyService {
}
return Response.ok(
authorization.getProviderFactories().stream()
.filter(factory -> !factory.isInternal())
authorization.getProviderFactoriesStream()
.filter(((Predicate<PolicyProviderFactory>) PolicyProviderFactory::isInternal).negate())
.map(factory -> {
PolicyProviderRepresentation representation = new PolicyProviderRepresentation();

View file

@ -34,7 +34,7 @@ import org.keycloak.storage.UserStorageProviderModel;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.Objects;
import java.util.stream.Stream;
/**
@ -113,16 +113,13 @@ public class UserCredentialStoreManager extends AbstractStorageManager<UserStora
@Override
public CredentialModel createCredentialThroughProvider(RealmModel realm, UserModel user, CredentialModel model){
throwExceptionIfInvalidUser(user);
List <CredentialProvider> credentialProviders = session.getKeycloakSessionFactory().getProviderFactories(CredentialProvider.class)
.stream()
return session.getKeycloakSessionFactory()
.getProviderFactoriesStream(CredentialProvider.class)
.map(f -> session.getProvider(CredentialProvider.class, f.getId()))
.filter(provider -> provider.getType().equals(model.getType()))
.collect(Collectors.toList());
if (credentialProviders.isEmpty()) {
return null;
} else {
return credentialProviders.get(0).createCredential(realm, user, credentialProviders.get(0).getCredentialFromModel(model));
}
.filter(provider -> Objects.equals(provider.getType(), model.getType()))
.map(cp -> cp.createCredential(realm, user, cp.getCredentialFromModel(model)))
.findFirst()
.orElse(null);
}
@Override
@ -168,8 +165,7 @@ public class UserCredentialStoreManager extends AbstractStorageManager<UserStora
}
public static <T> Stream<T> getCredentialProviders(KeycloakSession session, Class<T> type) {
return session.getKeycloakSessionFactory().getProviderFactories(CredentialProvider.class)
.stream()
return session.getKeycloakSessionFactory().getProviderFactoriesStream(CredentialProvider.class)
.filter(f -> Types.supports(type, f, CredentialProviderFactory.class))
.map(f -> (T) session.getProvider(CredentialProvider.class, f.getId()));
}

View file

@ -62,20 +62,22 @@ public class DefaultKeyManager implements KeyManager {
return activeKey;
}
logger.debugv("Failed to find active key for realm, trying fallback: realm={0} algorithm={1} use={2}", realm.getName(), algorithm, use.name());
logger.debugv("Failed to find active key for realm, trying fallback: realm={0} algorithm={1} use={2}",
realm.getName(), algorithm, use.name());
for (ProviderFactory f : session.getKeycloakSessionFactory().getProviderFactories(KeyProvider.class)) {
KeyProviderFactory kf = (KeyProviderFactory) f;
if (kf.createFallbackKeys(session, use, algorithm)) {
providersMap.remove(realm.getId());
List<KeyProvider> providers = getProviders(realm);
activeKey = getActiveKey(providers, realm, use, algorithm);
if (activeKey != null) {
logger.infov("No keys found for realm={0} and algorithm={1} for use={2}. Generating keys.", realm.getName(), algorithm, use.name());
return activeKey;
} else {
break;
}
Optional<KeyProviderFactory> keyProviderFactory = session.getKeycloakSessionFactory()
.getProviderFactoriesStream(KeyProvider.class)
.map(KeyProviderFactory.class::cast)
.filter(kf -> kf.createFallbackKeys(session, use, algorithm))
.findFirst();
if (keyProviderFactory.isPresent()) {
providersMap.remove(realm.getId());
List<KeyProvider> providers = getProviders(realm);
activeKey = getActiveKey(providers, realm, use, algorithm);
if (activeKey != null) {
logger.infov("No keys found for realm={0} and algorithm={1} for use={2}. Generating keys.",
realm.getName(), algorithm, use.name());
return activeKey;
}
}

View file

@ -24,7 +24,6 @@ import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.UserModel;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
import org.keycloak.provider.ProviderFactory;
import java.lang.reflect.Method;
import java.util.Comparator;
@ -112,14 +111,13 @@ public class ProtocolMapperUtils {
* @return The builtin locale mapper.
*/
public static ProtocolMapperModel findLocaleMapper(KeycloakSession session) {
for (ProviderFactory p : session.getKeycloakSessionFactory().getProviderFactories(LoginProtocol.class)) {
LoginProtocolFactory factory = (LoginProtocolFactory) p;
ProtocolMapperModel found = factory.getBuiltinMappers().get(OIDCLoginProtocolFactory.LOCALE);
if (found != null && found.getProtocol().equals(OIDCLoginProtocol.LOGIN_PROTOCOL)) {
return found;
}
}
return null;
return session.getKeycloakSessionFactory().getProviderFactoriesStream(LoginProtocol.class)
.map(LoginProtocolFactory.class::cast)
.map(factory -> factory.getBuiltinMappers().get(OIDCLoginProtocolFactory.LOCALE))
.filter(Objects::nonNull)
.filter(protocolMapper -> Objects.equals(protocolMapper.getProtocol(), OIDCLoginProtocol.LOGIN_PROTOCOL))
.findFirst()
.orElse(null);
}

View file

@ -17,6 +17,7 @@
package org.keycloak.protocol.oidc;
import com.google.common.collect.Streams;
import org.keycloak.OAuth2Constants;
import org.keycloak.authentication.ClientAuthenticator;
import org.keycloak.authentication.ClientAuthenticatorFactory;
@ -31,6 +32,7 @@ import org.keycloak.models.RealmModel;
import org.keycloak.protocol.oidc.endpoints.TokenEndpoint;
import org.keycloak.protocol.oidc.representations.OIDCConfigurationRepresentation;
import org.keycloak.protocol.oidc.utils.OIDCResponseType;
import org.keycloak.provider.Provider;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.representations.IDToken;
import org.keycloak.services.Urls;
@ -45,10 +47,11 @@ import javax.ws.rs.core.UriInfo;
import java.net.URI;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@ -167,58 +170,36 @@ public class OIDCWellKnownProvider implements WellKnownProvider {
}
private List<String> getClientAuthMethodsSupported() {
List<String> result = new LinkedList<>();
return session.getKeycloakSessionFactory().getProviderFactoriesStream(ClientAuthenticator.class)
.map(ClientAuthenticatorFactory.class::cast)
.map(caf -> caf.getProtocolAuthenticatorMethods(OIDCLoginProtocol.LOGIN_PROTOCOL))
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
List<ProviderFactory> providerFactories = session.getKeycloakSessionFactory().getProviderFactories(ClientAuthenticator.class);
for (ProviderFactory factory : providerFactories) {
ClientAuthenticatorFactory clientAuthFactory = (ClientAuthenticatorFactory) factory;
result.addAll(clientAuthFactory.getProtocolAuthenticatorMethods(OIDCLoginProtocol.LOGIN_PROTOCOL));
private List<String> getSupportedAlgorithms(Class<? extends Provider> clazz, boolean includeNone) {
Stream<String> supportedAlgorithms = session.getKeycloakSessionFactory().getProviderFactoriesStream(clazz)
.map(ProviderFactory::getId);
if (includeNone) {
supportedAlgorithms = Streams.concat(supportedAlgorithms, Stream.of("none"));
}
return result;
return supportedAlgorithms.collect(Collectors.toList());
}
private List<String> getSupportedSigningAlgorithms(boolean includeNone) {
List<String> result = new LinkedList<>();
for (ProviderFactory s : session.getKeycloakSessionFactory().getProviderFactories(SignatureProvider.class)) {
result.add(s.getId());
}
if (includeNone) {
result.add("none");
}
return result;
return getSupportedAlgorithms(SignatureProvider.class, includeNone);
}
private List<String> getSupportedClientSigningAlgorithms(boolean includeNone) {
List<String> result = new LinkedList<>();
for (ProviderFactory s : session.getKeycloakSessionFactory().getProviderFactories(ClientSignatureVerifierProvider.class)) {
result.add(s.getId());
}
if (includeNone) {
result.add("none");
}
return result;
return getSupportedAlgorithms(ClientSignatureVerifierProvider.class, includeNone);
}
private List<String> getSupportedIdTokenEncryptionAlg(boolean includeNone) {
List<String> result = new LinkedList<>();
for (ProviderFactory s : session.getKeycloakSessionFactory().getProviderFactories(CekManagementProvider.class)) {
result.add(s.getId());
}
if (includeNone) {
result.add("none");
}
return result;
return getSupportedAlgorithms(CekManagementProvider.class, includeNone);
}
private List<String> getSupportedIdTokenEncryptionEnc(boolean includeNone) {
List<String> result = new LinkedList<>();
for (ProviderFactory s : session.getKeycloakSessionFactory().getProviderFactories(ContentEncryptionProvider.class)) {
result.add(s.getId());
}
if (includeNone) {
result.add("none");
}
return result;
return getSupportedAlgorithms(ContentEncryptionProvider.class, includeNone);
}
}

View file

@ -29,12 +29,10 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.services.ErrorResponseException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import java.util.List;
import java.util.Map;
/**
@ -92,15 +90,11 @@ public class AuthorizeClientUtil {
}
public static ClientAuthenticatorFactory findClientAuthenticatorForOIDCAuthMethod(KeycloakSession session, String oidcAuthMethod) {
List<ProviderFactory> providerFactories = session.getKeycloakSessionFactory().getProviderFactories(ClientAuthenticator.class);
for (ProviderFactory factory : providerFactories) {
ClientAuthenticatorFactory clientAuthFactory = (ClientAuthenticatorFactory) factory;
if (clientAuthFactory.getProtocolAuthenticatorMethods(OIDCLoginProtocol.LOGIN_PROTOCOL).contains(oidcAuthMethod)) {
return clientAuthFactory;
}
}
return null;
return session.getKeycloakSessionFactory().getProviderFactoriesStream(ClientAuthenticator.class)
.map(ClientAuthenticatorFactory.class::cast)
.filter(caf -> caf.getProtocolAuthenticatorMethods(OIDCLoginProtocol.LOGIN_PROTOCOL).contains(oidcAuthMethod))
.findFirst()
.orElse(null);
}
public static class ClientAuthResult {

View file

@ -69,7 +69,7 @@ public class SamlSessionUtils {
}
public static Iterator<SamlAuthenticationPreprocessor> getSamlAuthenticationPreprocessorIterator(KeycloakSession session) {
return session.getKeycloakSessionFactory().getProviderFactories(SamlAuthenticationPreprocessor.class).stream()
return session.getKeycloakSessionFactory().getProviderFactoriesStream(SamlAuthenticationPreprocessor.class)
.filter(Objects::nonNull)
.map(SamlAuthenticationPreprocessor.class::cast)
.iterator();

View file

@ -22,7 +22,6 @@ import org.keycloak.common.util.MultivaluedHashMap;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

View file

@ -44,6 +44,7 @@ import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Stream;
public class DefaultKeycloakSessionFactory implements KeycloakSessionFactory, ProviderManagerDeployer {
@ -261,7 +262,6 @@ public class DefaultKeycloakSessionFactory implements KeycloakSessionFactory, Pr
if (spi.isInternal() && !isInternal(factory)) {
ServicesLogger.LOGGER.spiMayChange(factory.getId(), factory.getClass().getName(), spi.getName());
}
factories.put(factory.getId(), factory);
} else {
logger.debugv("SPI {0} provider {1} disabled", spi.getName(), factory.getId());
@ -315,13 +315,11 @@ public class DefaultKeycloakSessionFactory implements KeycloakSessionFactory, Pr
}
@Override
public List<ProviderFactory> getProviderFactories(Class<? extends Provider> clazz) {
if (factoriesMap == null) return Collections.emptyList();
List<ProviderFactory> list = new LinkedList<ProviderFactory>();
public Stream<ProviderFactory> getProviderFactoriesStream(Class<? extends Provider> clazz) {
if (factoriesMap == null) return Stream.empty();
Map<String, ProviderFactory> providerFactoryMap = factoriesMap.get(clazz);
if (providerFactoryMap == null) return list;
list.addAll(providerFactoryMap.values());
return list;
if (providerFactoryMap == null) return Stream.empty();
return providerFactoryMap.values().stream();
}
<T extends Provider> Set<String> getAllProviderIds(Class<T> clazz) {

View file

@ -61,12 +61,9 @@ public class ProtocolMappersClientRegistrationPolicyFactory extends AbstractClie
}
private List<String> getProtocolMapperFactoryIds() {
List<ProviderFactory> protocolMapperFactories = sessionFactory.getProviderFactories(ProtocolMapper.class);
return protocolMapperFactories.stream().map((ProviderFactory factory) -> {
return factory.getId();
}).collect(Collectors.toList());
return sessionFactory.getProviderFactoriesStream(ProtocolMapper.class)
.map(ProviderFactory::getId)
.collect(Collectors.toList());
}
@Override

View file

@ -23,12 +23,10 @@ import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.UriInfo;
import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse;
import org.keycloak.common.util.CollectionUtil;
import org.keycloak.common.util.UriUtils;
import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.protocol.oidc.utils.WebOriginsUtils;

View file

@ -70,7 +70,6 @@ import org.keycloak.protocol.saml.SamlProtocol;
import org.keycloak.protocol.saml.SamlService;
import org.keycloak.protocol.saml.SamlSessionUtils;
import org.keycloak.protocol.saml.preprocessor.SamlAuthenticationPreprocessor;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.representations.AccessToken;
import org.keycloak.services.ErrorPage;
import org.keycloak.services.ErrorPageException;
@ -111,10 +110,7 @@ import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
@ -122,6 +118,7 @@ import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* <p></p>
@ -1290,17 +1287,12 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
}
public static IdentityProviderFactory getIdentityProviderFactory(KeycloakSession session, IdentityProviderModel model) {
Map<String, IdentityProviderFactory> availableProviders = new HashMap<String, IdentityProviderFactory>();
List<ProviderFactory> allProviders = new ArrayList<ProviderFactory>();
allProviders.addAll(session.getKeycloakSessionFactory().getProviderFactories(IdentityProvider.class));
allProviders.addAll(session.getKeycloakSessionFactory().getProviderFactories(SocialIdentityProvider.class));
for (ProviderFactory providerFactory : allProviders) {
availableProviders.put(providerFactory.getId(), (IdentityProviderFactory) providerFactory);
}
return availableProviders.get(model.getProviderId());
return Stream.concat(session.getKeycloakSessionFactory().getProviderFactoriesStream(IdentityProvider.class),
session.getKeycloakSessionFactory().getProviderFactoriesStream(SocialIdentityProvider.class))
.filter(providerFactory -> Objects.equals(providerFactory.getId(), model.getProviderId()))
.map(IdentityProviderFactory.class::cast)
.findFirst()
.orElse(null);
}
private IdentityProviderModel getIdentityProviderConfig(String providerId) {

View file

@ -24,7 +24,14 @@ import org.keycloak.authentication.actiontoken.ExplainedTokenVerificationExcepti
import org.keycloak.common.VerificationException;
import org.keycloak.events.Errors;
import org.keycloak.forms.login.LoginFormsProvider;
import org.keycloak.models.*;
import org.keycloak.models.ActionTokenKeyModel;
import org.keycloak.models.ActionTokenStoreProvider;
import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel;
import org.keycloak.protocol.oidc.utils.RedirectUtils;
import org.keycloak.representations.JsonWebToken;
import org.keycloak.services.managers.AuthenticationManager;

View file

@ -23,7 +23,6 @@ import org.keycloak.OAuthErrorException;
import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.AuthorizationService;
import org.keycloak.common.ClientConnection;
import org.keycloak.common.Profile;
import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.events.EventBuilder;
import org.keycloak.models.ClientModel;
@ -38,8 +37,6 @@ import org.keycloak.services.resource.RealmResourceProvider;
import org.keycloak.services.resources.account.AccountLoader;
import org.keycloak.services.util.CacheControlUtil;
import org.keycloak.services.util.ResolveRelative;
import org.keycloak.utils.MediaTypeMatcher;
import org.keycloak.utils.ProfileHelper;
import org.keycloak.wellknown.WellKnownProvider;
import javax.ws.rs.GET;

View file

@ -18,11 +18,6 @@
package org.keycloak.services.resources;
import java.net.URI;
import java.util.AbstractMap.SimpleEntry;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;

View file

@ -16,7 +16,6 @@
*/
package org.keycloak.services.resources;
import org.jboss.logging.Logger;
import org.keycloak.common.Version;
import org.keycloak.common.util.MimeTypeUtil;
import org.keycloak.encoding.ResourceEncodingHelper;

View file

@ -19,8 +19,6 @@ package org.keycloak.services.resources.account;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.SortedSet;
@ -107,13 +105,9 @@ public class LinkedAccountsResource {
}
private Set<String> findSocialIds() {
Set<String> socialIds = new HashSet();
List<ProviderFactory> providerFactories = session.getKeycloakSessionFactory().getProviderFactories(SocialIdentityProvider.class);
for (ProviderFactory factory: providerFactories) {
socialIds.add(factory.getId());
}
return socialIds;
return session.getKeycloakSessionFactory().getProviderFactoriesStream(SocialIdentityProvider.class)
.map(ProviderFactory::getId)
.collect(Collectors.toSet());
}
public SortedSet<LinkedAccountRepresentation> getLinkedAccounts(KeycloakSession session, RealmModel realm, UserModel user) {

View file

@ -102,86 +102,79 @@ public class AuthenticationManagementResource {
/**
* Get form providers
*
* Returns a list of form providers.
* Returns a stream of form providers.
*/
@Path("/form-providers")
@GET
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public List<Map<String, Object>> getFormProviders() {
public Stream<Map<String, Object>> getFormProviders() {
auth.realm().requireViewRealm();
List<ProviderFactory> factories = session.getKeycloakSessionFactory().getProviderFactories(FormAuthenticator.class);
return buildProviderMetadata(factories);
return buildProviderMetadata(session.getKeycloakSessionFactory().getProviderFactoriesStream(FormAuthenticator.class));
}
/**
* Get authenticator providers
*
* Returns a list of authenticator providers.
* Returns a stream of authenticator providers.
*/
@Path("/authenticator-providers")
@GET
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public List<Map<String, Object>> getAuthenticatorProviders() {
public Stream<Map<String, Object>> getAuthenticatorProviders() {
auth.realm().requireViewRealm();
List<ProviderFactory> factories = session.getKeycloakSessionFactory().getProviderFactories(Authenticator.class);
return buildProviderMetadata(factories);
return buildProviderMetadata(session.getKeycloakSessionFactory().getProviderFactoriesStream(Authenticator.class));
}
/**
* Get client authenticator providers
*
* Returns a list of client authenticator providers.
* Returns a stream of client authenticator providers.
*/
@Path("/client-authenticator-providers")
@GET
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public List<Map<String, Object>> getClientAuthenticatorProviders() {
public Stream<Map<String, Object>> getClientAuthenticatorProviders() {
auth.realm().requireViewClientAuthenticatorProviders();
List<ProviderFactory> factories = session.getKeycloakSessionFactory().getProviderFactories(ClientAuthenticator.class);
return buildProviderMetadata(factories);
return buildProviderMetadata(session.getKeycloakSessionFactory().getProviderFactoriesStream(ClientAuthenticator.class));
}
public List<Map<String, Object>> buildProviderMetadata(List<ProviderFactory> factories) {
List<Map<String, Object>> providers = new LinkedList<>();
for (ProviderFactory factory : factories) {
public Stream<Map<String, Object>> buildProviderMetadata(Stream<ProviderFactory> factories) {
return factories.map(factory -> {
Map<String, Object> data = new HashMap<>();
data.put("id", factory.getId());
ConfigurableAuthenticatorFactory configured = (ConfigurableAuthenticatorFactory)factory;
data.put("description", configured.getHelpText());
data.put("displayName", configured.getDisplayType());
providers.add(data);
}
return providers;
return data;
});
}
/**
* Get form action providers
*
* Returns a list of form action providers.
* Returns a stream of form action providers.
*/
@Path("/form-action-providers")
@GET
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public List<Map<String, Object>> getFormActionProviders() {
public Stream<Map<String, Object>> getFormActionProviders() {
auth.realm().requireViewRealm();
List<ProviderFactory> factories = session.getKeycloakSessionFactory().getProviderFactories(FormAction.class);
return buildProviderMetadata(factories);
return buildProviderMetadata(session.getKeycloakSessionFactory().getProviderFactoriesStream(FormAction.class));
}
/**
* Get authentication flows
*
* Returns a list of authentication flows.
* Returns a stream of authentication flows.
*/
@Path("/flows")
@GET
@ -890,7 +883,7 @@ public class AuthenticationManagementResource {
/**
* Get unregistered required actions
*
* Returns a list of unregistered required actions.
* Returns a stream of unregistered required actions.
*/
@Path("unregistered-required-actions")
@GET
@ -902,8 +895,7 @@ public class AuthenticationManagementResource {
Set<String> providerIds = realm.getRequiredActionProvidersStream()
.map(RequiredActionProviderModel::getProviderId).collect(Collectors.toSet());
return session.getKeycloakSessionFactory().getProviderFactories(RequiredActionProvider.class)
.stream()
return session.getKeycloakSessionFactory().getProviderFactoriesStream(RequiredActionProvider.class)
.filter(factory -> !providerIds.contains(factory.getId()))
.map(factory -> {
RequiredActionFactory r = (RequiredActionFactory) factory;
@ -950,7 +942,7 @@ public class AuthenticationManagementResource {
/**
* Get required actions
*
* Returns a list of required actions.
* Returns a stream of required actions.
*/
@Path("required-actions")
@GET
@ -1149,24 +1141,15 @@ public class AuthenticationManagementResource {
public Map<String, List<ConfigPropertyRepresentation>> getPerClientConfigDescription() {
auth.realm().requireViewClientAuthenticatorProviders();
List<ProviderFactory> factories = session.getKeycloakSessionFactory().getProviderFactories(ClientAuthenticator.class);
Map<String, List<ConfigPropertyRepresentation>> toReturn = new HashMap<>();
for (ProviderFactory clientAuthenticatorFactory : factories) {
String providerId = clientAuthenticatorFactory.getId();
ConfigurableAuthenticatorFactory factory = CredentialHelper.getConfigurableAuthenticatorFactory(session, providerId);
ClientAuthenticatorFactory clientAuthFactory = (ClientAuthenticatorFactory) factory;
List<ProviderConfigProperty> perClientConfigProps = clientAuthFactory.getConfigPropertiesPerClient();
List<ConfigPropertyRepresentation> result = new LinkedList<>();
for (ProviderConfigProperty prop : perClientConfigProps) {
ConfigPropertyRepresentation propRep = getConfigPropertyRep(prop);
result.add(propRep);
}
toReturn.put(providerId, result);
}
return toReturn;
return session.getKeycloakSessionFactory().getProviderFactoriesStream(ClientAuthenticator.class)
.collect(Collectors.toMap(
ProviderFactory::getId,
factory -> {
ClientAuthenticatorFactory clientAuthFactory = (ClientAuthenticatorFactory)
CredentialHelper.getConfigurableAuthenticatorFactory(session, factory.getId());
return clientAuthFactory.getConfigPropertiesPerClient().stream()
.map(this::getConfigPropertyRep).collect(Collectors.toList());
}));
}
/**

View file

@ -48,10 +48,8 @@ import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

View file

@ -35,7 +35,7 @@ import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @resource Client Registration Policy
@ -67,23 +67,17 @@ public class ClientRegistrationPolicyResource {
@GET
@NoCache
@Produces(MediaType.APPLICATION_JSON)
public List<ComponentTypeRepresentation> getProviders() {
List<ProviderFactory> providerFactories = session.getKeycloakSessionFactory().getProviderFactories(ClientRegistrationPolicy.class);
public Stream<ComponentTypeRepresentation> getProviders() {
return session.getKeycloakSessionFactory().getProviderFactoriesStream(ClientRegistrationPolicy.class)
.map((ProviderFactory factory) -> {
ClientRegistrationPolicyFactory clientRegFactory = (ClientRegistrationPolicyFactory) factory;
List<ProviderConfigProperty> configProps = clientRegFactory.getConfigProperties(session);
return providerFactories.stream().map((ProviderFactory factory) -> {
ClientRegistrationPolicyFactory clientRegFactory = (ClientRegistrationPolicyFactory) factory;
List<ProviderConfigProperty> configProps = clientRegFactory.getConfigProperties(session);
ComponentTypeRepresentation rep = new ComponentTypeRepresentation();
rep.setId(clientRegFactory.getId());
rep.setHelpText(clientRegFactory.getHelpText());
rep.setProperties(ModelToRepresentation.toRepresentation(configProps));
return rep;
}).collect(Collectors.toList());
ComponentTypeRepresentation rep = new ComponentTypeRepresentation();
rep.setId(clientRegFactory.getId());
rep.setHelpText(clientRegFactory.getHelpText());
rep.setProperties(ModelToRepresentation.toRepresentation(configProps));
return rep;
});
}
}

View file

@ -77,8 +77,6 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Stream;
@ -298,21 +296,14 @@ public class ClientResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
@Path("default-client-scopes")
public List<ClientScopeRepresentation> getDefaultClientScopes() {
public Stream<ClientScopeRepresentation> getDefaultClientScopes() {
return getDefaultClientScopes(true);
}
private List<ClientScopeRepresentation> getDefaultClientScopes(boolean defaultScope) {
private Stream<ClientScopeRepresentation> getDefaultClientScopes(boolean defaultScope) {
auth.clients().requireView(client);
List<ClientScopeRepresentation> defaults = new LinkedList<>();
for (ClientScopeModel clientScope : client.getClientScopes(defaultScope, true).values()) {
ClientScopeRepresentation rep = new ClientScopeRepresentation();
rep.setId(clientScope.getId());
rep.setName(clientScope.getName());
defaults.add(rep);
}
return defaults;
return client.getClientScopes(defaultScope, true).values().stream().map(ClientResource::toRepresentation);
}
@ -361,7 +352,7 @@ public class ClientResource {
@NoCache
@Produces(MediaType.APPLICATION_JSON)
@Path("optional-client-scopes")
public List<ClientScopeRepresentation> getOptionalClientScopes() {
public Stream<ClientScopeRepresentation> getOptionalClientScopes() {
return getDefaultClientScopes(false);
}
@ -699,4 +690,11 @@ public class ClientResource {
}
return rep;
}
private static ClientScopeRepresentation toRepresentation(ClientScopeModel clientScopeModel) {
ClientScopeRepresentation rep = new ClientScopeRepresentation();
rep.setId(clientScopeModel.getId());
rep.setName(clientScopeModel.getName());
return rep;
}
}

View file

@ -38,10 +38,8 @@ import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
/**
@ -145,7 +143,4 @@ public class ClientScopeResource {
return ErrorResponse.error(me.getMessage(), Response.Status.BAD_REQUEST);
}
}
}

View file

@ -54,13 +54,10 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.Objects;
import java.util.Properties;
import java.util.stream.Stream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static java.lang.Boolean.TRUE;
import static org.keycloak.utils.StreamsUtil.paginatedStream;
/**
* Base resource class for managing a realm's clients.
@ -141,12 +138,7 @@ public class ClientsResource {
.filter(Objects::nonNull);
if (!canView) {
if (firstResult != null && firstResult > 0) {
s = s.skip(firstResult);
}
if (maxResults != null && maxResults > 0) {
s = s.limit(maxResults);
}
s = paginatedStream(s, firstResult, maxResults);
}
return s;

View file

@ -55,7 +55,11 @@ import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.text.MessageFormat;
import java.util.*;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.stream.Stream;
/**
@ -213,7 +217,7 @@ public class ComponentResource {
@Path("{id}/sub-component-types")
@Produces(MediaType.APPLICATION_JSON)
@NoCache
public List<ComponentTypeRepresentation> getSubcomponentConfig(@PathParam("id") String parentId, @QueryParam("type") String subtype) {
public Stream<ComponentTypeRepresentation> getSubcomponentConfig(@PathParam("id") String parentId, @QueryParam("type") String subtype) {
auth.realm().requireViewRealm();
ComponentModel parent = realm.getComponent(parentId);
if (parent == null) {
@ -222,41 +226,39 @@ public class ComponentResource {
if (subtype == null) {
throw new BadRequestException("must specify a subtype");
}
Class<? extends Provider> providerClass = null;
Class<? extends Provider> providerClass;
try {
providerClass = (Class<? extends Provider>)Class.forName(subtype);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
List<ComponentTypeRepresentation> subcomponents = new LinkedList<>();
for (ProviderFactory factory : session.getKeycloakSessionFactory().getProviderFactories(providerClass)) {
ComponentTypeRepresentation rep = new ComponentTypeRepresentation();
rep.setId(factory.getId());
if (!(factory instanceof ComponentFactory)) {
continue;
}
ComponentFactory componentFactory = (ComponentFactory)factory;
rep.setHelpText(componentFactory.getHelpText());
List<ProviderConfigProperty> props = null;
Map<String, Object> metadata = null;
if (factory instanceof SubComponentFactory) {
props = ((SubComponentFactory)factory).getConfigProperties(realm, parent);
metadata = ((SubComponentFactory)factory).getTypeMetadata(realm, parent);
} else {
props = componentFactory.getConfigProperties();
metadata = componentFactory.getTypeMetadata();
}
List<ConfigPropertyRepresentation> propReps = ModelToRepresentation.toRepresentation(props);
rep.setProperties(propReps);
rep.setMetadata(metadata);
subcomponents.add(rep);
}
return subcomponents;
return session.getKeycloakSessionFactory().getProviderFactoriesStream(providerClass)
.filter(ComponentFactory.class::isInstance)
.map(factory -> toComponentTypeRepresentation(factory, parent));
}
private ComponentTypeRepresentation toComponentTypeRepresentation(ProviderFactory factory, ComponentModel parent) {
ComponentTypeRepresentation rep = new ComponentTypeRepresentation();
rep.setId(factory.getId());
ComponentFactory componentFactory = (ComponentFactory)factory;
rep.setHelpText(componentFactory.getHelpText());
List<ProviderConfigProperty> props;
Map<String, Object> metadata;
if (factory instanceof SubComponentFactory) {
props = ((SubComponentFactory)factory).getConfigProperties(realm, parent);
metadata = ((SubComponentFactory)factory).getTypeMetadata(realm, parent);
} else {
props = componentFactory.getConfigProperties();
metadata = componentFactory.getTypeMetadata();
}
List<ConfigPropertyRepresentation> propReps = ModelToRepresentation.toRepresentation(props);
rep.setProperties(propReps);
rep.setMetadata(metadata);
return rep;
}
}

View file

@ -18,6 +18,7 @@ package org.keycloak.services.resources.admin;
import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
import com.google.common.collect.Streams;
import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache;
import javax.ws.rs.NotFoundException;
@ -38,10 +39,7 @@ import org.keycloak.models.UserModel;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.models.utils.RepresentationToModel;
import org.keycloak.models.utils.StripSecretsUtils;
import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.representations.idm.ComponentRepresentation;
import org.keycloak.representations.idm.ConfigPropertyRepresentation;
import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
import org.keycloak.representations.idm.IdentityProviderMapperTypeRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation;
@ -62,7 +60,10 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.*;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -230,16 +231,12 @@ public class IdentityProviderResource {
private IdentityProviderFactory getIdentityProviderFactory() {
List<ProviderFactory> allProviders = new ArrayList<ProviderFactory>();
allProviders.addAll(this.session.getKeycloakSessionFactory().getProviderFactories(IdentityProvider.class));
allProviders.addAll(this.session.getKeycloakSessionFactory().getProviderFactories(SocialIdentityProvider.class));
for (ProviderFactory providerFactory : allProviders) {
if (providerFactory.getId().equals(identityProviderModel.getProviderId())) return (IdentityProviderFactory)providerFactory;
}
return null;
return Streams.concat(session.getKeycloakSessionFactory().getProviderFactoriesStream(IdentityProvider.class),
session.getKeycloakSessionFactory().getProviderFactoriesStream(SocialIdentityProvider.class))
.filter(providerFactory -> Objects.equals(providerFactory.getId(), identityProviderModel.getProviderId()))
.map(IdentityProviderFactory.class::cast)
.findFirst()
.orElse(null);
}
/**
@ -280,28 +277,26 @@ public class IdentityProviderResource {
}
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
Map<String, IdentityProviderMapperTypeRepresentation> types = new HashMap<>();
List<ProviderFactory> factories = sessionFactory.getProviderFactories(IdentityProviderMapper.class);
for (ProviderFactory factory : factories) {
IdentityProviderMapper mapper = (IdentityProviderMapper)factory;
for (String type : mapper.getCompatibleProviders()) {
if (IdentityProviderMapper.ANY_PROVIDER.equals(type) || type.equals(identityProviderModel.getProviderId())) {
IdentityProviderMapperTypeRepresentation rep = new IdentityProviderMapperTypeRepresentation();
rep.setId(mapper.getId());
rep.setCategory(mapper.getDisplayCategory());
rep.setName(mapper.getDisplayType());
rep.setHelpText(mapper.getHelpText());
List<ProviderConfigProperty> configProperties = mapper.getConfigProperties();
for (ProviderConfigProperty prop : configProperties) {
ConfigPropertyRepresentation propRep = ModelToRepresentation.toRepresentation(prop);
rep.getProperties().add(propRep);
}
types.put(rep.getId(), rep);
break;
}
}
}
return types;
return sessionFactory.getProviderFactoriesStream(IdentityProviderMapper.class)
.map(IdentityProviderMapper.class::cast)
.map(mapper -> Arrays.stream(mapper.getCompatibleProviders())
.filter(type -> Objects.equals(IdentityProviderMapper.ANY_PROVIDER, type) ||
Objects.equals(identityProviderModel.getProviderId(), type))
.map(type -> {
IdentityProviderMapperTypeRepresentation rep = new IdentityProviderMapperTypeRepresentation();
rep.setId(mapper.getId());
rep.setCategory(mapper.getDisplayCategory());
rep.setName(mapper.getDisplayType());
rep.setHelpText(mapper.getHelpText());
rep.setProperties(mapper.getConfigProperties().stream()
.map(ModelToRepresentation::toRepresentation)
.collect(Collectors.toList()));
return rep;
})
.findFirst()
.orElse(null))
.filter(Objects::nonNull)
.collect(Collectors.toMap(IdentityProviderMapperTypeRepresentation::getId, Function.identity()));
}
/**
@ -470,9 +465,4 @@ public class IdentityProviderResource {
return new ManagementPermissionReference();
}
}
}

View file

@ -17,6 +17,7 @@
package org.keycloak.services.resources.admin;
import com.google.common.collect.Streams;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.plugins.providers.multipart.InputPart;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
@ -50,7 +51,6 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@ -222,23 +222,15 @@ public class IdentityProvidersResource {
}
private IdentityProviderFactory getProviderFactorytById(String providerId) {
List<ProviderFactory> allProviders = getProviderFactories();
for (ProviderFactory providerFactory : allProviders) {
if (providerFactory.getId().equals(providerId)) {
return (IdentityProviderFactory) providerFactory;
}
}
return null;
return getProviderFactories()
.filter(providerFactory -> Objects.equals(providerId, providerFactory.getId()))
.map(IdentityProviderFactory.class::cast)
.findFirst()
.orElse(null);
}
private List<ProviderFactory> getProviderFactories() {
List<ProviderFactory> allProviders = new ArrayList<ProviderFactory>();
allProviders.addAll(this.session.getKeycloakSessionFactory().getProviderFactories(IdentityProvider.class));
allProviders.addAll(this.session.getKeycloakSessionFactory().getProviderFactories(SocialIdentityProvider.class));
return allProviders;
private Stream<ProviderFactory> getProviderFactories() {
return Streams.concat(session.getKeycloakSessionFactory().getProviderFactoriesStream(IdentityProvider.class),
session.getKeycloakSessionFactory().getProviderFactoriesStream(SocialIdentityProvider.class));
}
}

View file

@ -22,12 +22,13 @@ import static org.keycloak.util.JsonSerialization.readValue;
import java.security.cert.X509Certificate;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.ws.rs.BadRequestException;
@ -90,7 +91,6 @@ import org.keycloak.models.utils.RepresentationToModel;
import org.keycloak.models.utils.StripSecretsUtils;
import org.keycloak.partialimport.PartialImportManager;
import org.keycloak.protocol.oidc.TokenManager;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.representations.adapters.action.GlobalRequestResult;
import org.keycloak.representations.idm.AdminEventRepresentation;
import org.keycloak.representations.idm.ClientRepresentation;
@ -164,13 +164,12 @@ public class RealmAdminResource {
throw new NotFoundException("Realm not found.");
}
for (ProviderFactory<ClientDescriptionConverter> factory : session.getKeycloakSessionFactory().getProviderFactories(ClientDescriptionConverter.class)) {
if (((ClientDescriptionConverterFactory) factory).isSupported(description)) {
return factory.create(session).convertToInternal(description);
}
}
throw new BadRequestException("Unsupported format");
return session.getKeycloakSessionFactory().getProviderFactoriesStream(ClientDescriptionConverter.class)
.map(ClientDescriptionConverterFactory.class::cast)
.filter(factory -> factory.isSupported(description))
.map(factory -> factory.create(session).convertToInternal(description))
.findFirst()
.orElseThrow(() -> new BadRequestException("Unsupported format"));
}
/**
@ -672,12 +671,11 @@ public class RealmAdminResource {
RealmEventsConfigRepresentation config = ModelToRepresentation.toEventsConfigReprensetation(realm);
if (config.getEnabledEventTypes() == null || config.getEnabledEventTypes().isEmpty()) {
config.setEnabledEventTypes(new LinkedList<String>());
for (EventType e : EventType.values()) {
if (e.isSaveByDefault()) {
config.getEnabledEventTypes().add(e.name());
}
}
List<String> eventTypes = Arrays.stream(EventType.values())
.filter(EventType::isSaveByDefault)
.map(EventType::name)
.collect(Collectors.toList());
config.setEnabledEventTypes(eventTypes);
}
return config;
}
@ -1200,7 +1198,7 @@ public class RealmAdminResource {
public Stream<String> getCredentialRegistrators(){
auth.realm().requireViewRealm();
return session.getContext().getRealm().getRequiredActionProvidersStream()
.filter(ra -> ra.isEnabled())
.filter(RequiredActionProviderModel::isEnabled)
.map(RequiredActionProviderModel::getProviderId)
.filter(providerId -> session.getProvider(RequiredActionProvider.class, providerId) instanceof CredentialRegistrator);
}

View file

@ -19,11 +19,6 @@ package org.keycloak.services.resources.admin;
import com.fasterxml.jackson.core.type.TypeReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Set;
import org.jboss.resteasy.plugins.providers.multipart.InputPart;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
import org.keycloak.models.KeycloakSession;
@ -35,6 +30,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.stream.Stream;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.Consumes;
@ -132,13 +129,10 @@ public class RealmLocalizationResource {
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<String> getRealmLocalizationLocales() {
public Stream<String> getRealmLocalizationLocales() {
this.auth.realm().requireViewRealm();
List<String> realmLocalesList = new ArrayList<>(realm.getRealmLocalizationTexts().keySet());
Collections.sort(realmLocalesList);
return realmLocalesList;
return realm.getRealmLocalizationTexts().keySet().stream().sorted();
}
@Path("{locale}")

View file

@ -25,7 +25,6 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.policy.PasswordPolicyNotMetException;
import org.keycloak.protocol.oidc.TokenManager;
@ -49,7 +48,8 @@ import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.util.*;
import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Stream;
import static org.keycloak.utils.StreamsUtil.throwIfEmpty;
@ -150,12 +150,10 @@ public class RealmsAdminResource {
return;
}
RealmModel adminRealm = new RealmManager(session).getKeycloakAdminstrationRealm();
ClientModel realmAdminApp = realm.getMasterAdminClient();
for (String r : AdminRoles.ALL_REALM_ROLES) {
RoleModel role = realmAdminApp.getRole(r);
auth.getUser().grantRole(role);
}
Arrays.stream(AdminRoles.ALL_REALM_ROLES)
.map(realmAdminApp::getRole)
.forEach(auth.getUser()::grantRole);
}
/**

View file

@ -23,13 +23,11 @@ import org.keycloak.events.admin.OperationType;
import org.keycloak.events.admin.ResourceType;
import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.ManagementPermissionReference;
@ -54,10 +52,8 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Stream;

View file

@ -55,6 +55,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@ -120,25 +121,25 @@ public class RoleMapperResource {
List<RoleRepresentation> realmRolesRepresentation = new ArrayList<>();
Map<String, ClientMappingsRepresentation> appMappings = new HashMap<>();
ClientModel clientModel;
ClientMappingsRepresentation mappings;
final AtomicReference<ClientMappingsRepresentation> mappings = new AtomicReference<>();
for (RoleModel roleMapping : roleMapper.getRoleMappingsStream().collect(Collectors.toSet())) {
roleMapper.getRoleMappingsStream().forEach(roleMapping -> {
RoleContainerModel container = roleMapping.getContainer();
if (container instanceof RealmModel) {
realmRolesRepresentation.add(ModelToRepresentation.toBriefRepresentation(roleMapping));
} else if (container instanceof ClientModel) {
clientModel = (ClientModel) container;
if ((mappings = appMappings.get(clientModel.getClientId())) == null) {
mappings = new ClientMappingsRepresentation();
mappings.setId(clientModel.getId());
mappings.setClient(clientModel.getClientId());
mappings.setMappings(new ArrayList<>());
appMappings.put(clientModel.getClientId(), mappings);
ClientModel clientModel = (ClientModel) container;
mappings.set(appMappings.get(clientModel.getClientId()));
if (mappings.get() == null) {
mappings.set(new ClientMappingsRepresentation());
mappings.get().setId(clientModel.getId());
mappings.get().setClient(clientModel.getClientId());
mappings.get().setMappings(new ArrayList<>());
appMappings.put(clientModel.getClientId(), mappings.get());
}
mappings.getMappings().add(ModelToRepresentation.toBriefRepresentation(roleMapping));
mappings.get().getMappings().add(ModelToRepresentation.toBriefRepresentation(roleMapping));
}
}
});
MappingsRepresentation all = new MappingsRepresentation();
if (!realmRolesRepresentation.isEmpty()) all.setRealmMappings(realmRolesRepresentation);

View file

@ -28,7 +28,11 @@ import org.keycloak.services.resources.admin.permissions.AdminPermissionEvaluato
import javax.ws.rs.NotFoundException;
import javax.ws.rs.core.UriInfo;
import java.util.*;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Stream;
/**

View file

@ -107,7 +107,6 @@ import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -231,17 +230,17 @@ public class UserResource {
List<String> reqActions = rep.getRequiredActions();
if (reqActions != null) {
Set<String> allActions = new HashSet<>();
for (ProviderFactory factory : session.getKeycloakSessionFactory().getProviderFactories(RequiredActionProvider.class)) {
allActions.add(factory.getId());
}
for (String action : allActions) {
if (reqActions.contains(action)) {
user.addRequiredAction(action);
} else if (removeMissingRequiredActions) {
user.removeRequiredAction(action);
}
}
session.getKeycloakSessionFactory()
.getProviderFactoriesStream(RequiredActionProvider.class)
.map(ProviderFactory::getId)
.distinct()
.forEach(action -> {
if (reqActions.contains(action)) {
user.addRequiredAction(action);
} else if (removeMissingRequiredActions) {
user.removeRequiredAction(action);
}
});
}
List<CredentialRepresentation> credentials = rep.getCredentials();

View file

@ -244,8 +244,4 @@ public class UserStorageProviderResource {
adminEvent.operation(OperationType.ACTION).resourcePath(session.getContext().getUri()).representation(eventRep).success();
return syncResult;
}
}

View file

@ -27,7 +27,6 @@ import org.keycloak.events.EventType;
import org.keycloak.events.admin.OperationType;
import org.keycloak.events.admin.ResourceType;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.policy.PasswordPolicyProvider;
import org.keycloak.policy.PasswordPolicyProviderFactory;
@ -41,7 +40,6 @@ import org.keycloak.provider.ProviderFactory;
import org.keycloak.provider.ServerInfoAwareProviderFactory;
import org.keycloak.provider.Spi;
import org.keycloak.representations.idm.ComponentTypeRepresentation;
import org.keycloak.representations.idm.ConfigPropertyRepresentation;
import org.keycloak.representations.idm.PasswordPolicyTypeRepresentation;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.ProtocolMapperTypeRepresentation;
@ -61,6 +59,7 @@ import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@ -68,6 +67,8 @@ import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@ -163,7 +164,7 @@ public class ServerInfoAdminResource {
}
private void setThemes(ServerInfoRepresentation info) {
info.setThemes(new HashMap<String, List<ThemeInfoRepresentation>>());
info.setThemes(new HashMap<>());
for (Theme.Type type : Theme.Type.values()) {
List<String> themeNames = new LinkedList<>(session.theme().nameSet(type));
@ -197,99 +198,123 @@ public class ServerInfoAdminResource {
}
private void setSocialProviders(ServerInfoRepresentation info) {
info.setSocialProviders(new LinkedList<Map<String, String>>());
List<ProviderFactory> providerFactories = session.getKeycloakSessionFactory().getProviderFactories(SocialIdentityProvider.class);
info.setSocialProviders(new LinkedList<>());
Stream<ProviderFactory> providerFactories = session.getKeycloakSessionFactory().getProviderFactoriesStream(SocialIdentityProvider.class);
setIdentityProviders(providerFactories, info.getSocialProviders(), "Social");
}
private void setIdentityProviders(ServerInfoRepresentation info) {
info.setIdentityProviders(new LinkedList<Map<String, String>>());
List<ProviderFactory> providerFactories = session.getKeycloakSessionFactory().getProviderFactories(IdentityProvider.class);
info.setIdentityProviders(new LinkedList<>());
Stream<ProviderFactory> providerFactories = session.getKeycloakSessionFactory().getProviderFactoriesStream(IdentityProvider.class);
setIdentityProviders(providerFactories, info.getIdentityProviders(), "User-defined");
providerFactories = session.getKeycloakSessionFactory().getProviderFactories(SocialIdentityProvider.class);
providerFactories = session.getKeycloakSessionFactory().getProviderFactoriesStream(SocialIdentityProvider.class);
setIdentityProviders(providerFactories, info.getIdentityProviders(), "Social");
}
public void setIdentityProviders(List<ProviderFactory> factories, List<Map<String, String>> providers, String groupName) {
for (ProviderFactory providerFactory : factories) {
IdentityProviderFactory factory = (IdentityProviderFactory) providerFactory;
Map<String, String> data = new HashMap<>();
data.put("groupName", groupName);
data.put("name", factory.getName());
data.put("id", factory.getId());
public void setIdentityProviders(Stream<ProviderFactory> factories, List<Map<String, String>> providers, String groupName) {
List<Map<String, String>> providerMaps = factories
.map(IdentityProviderFactory.class::cast)
.map(factory -> {
Map<String, String> data = new HashMap<>();
data.put("groupName", groupName);
data.put("name", factory.getName());
data.put("id", factory.getId());
return data;
})
.collect(Collectors.toList());
providers.add(data);
}
providers.addAll(providerMaps);
}
private void setClientInstallations(ServerInfoRepresentation info) {
info.setClientInstallations(new HashMap<String, List<ClientInstallationRepresentation>>());
for (ProviderFactory p : session.getKeycloakSessionFactory().getProviderFactories(ClientInstallationProvider.class)) {
ClientInstallationProvider provider = (ClientInstallationProvider)p;
List<ClientInstallationRepresentation> types = info.getClientInstallations().get(provider.getProtocol());
if (types == null) {
types = new LinkedList<>();
info.getClientInstallations().put(provider.getProtocol(), types);
}
ClientInstallationRepresentation rep = new ClientInstallationRepresentation();
rep.setId(p.getId());
rep.setHelpText(provider.getHelpText());
rep.setDisplayType( provider.getDisplayType());
rep.setProtocol( provider.getProtocol());
rep.setDownloadOnly( provider.isDownloadOnly());
rep.setFilename(provider.getFilename());
rep.setMediaType(provider.getMediaType());
types.add(rep);
}
HashMap<String, List<ClientInstallationRepresentation>> clientInstallations = session.getKeycloakSessionFactory()
.getProviderFactoriesStream(ClientInstallationProvider.class)
.map(ClientInstallationProvider.class::cast)
.collect(
Collectors.toMap(
ClientInstallationProvider::getProtocol,
this::toClientInstallationRepresentation,
(l1, l2) -> listCombiner(l1, l2),
HashMap::new
)
);
info.setClientInstallations(clientInstallations);
}
private void setProtocolMapperTypes(ServerInfoRepresentation info) {
info.setProtocolMapperTypes(new HashMap<String, List<ProtocolMapperTypeRepresentation>>());
for (ProviderFactory p : session.getKeycloakSessionFactory().getProviderFactories(ProtocolMapper.class)) {
ProtocolMapper mapper = (ProtocolMapper)p;
List<ProtocolMapperTypeRepresentation> types = info.getProtocolMapperTypes().get(mapper.getProtocol());
if (types == null) {
types = new LinkedList<>();
info.getProtocolMapperTypes().put(mapper.getProtocol(), types);
}
ProtocolMapperTypeRepresentation rep = new ProtocolMapperTypeRepresentation();
rep.setId(mapper.getId());
rep.setName(mapper.getDisplayType());
rep.setHelpText(mapper.getHelpText());
rep.setCategory(mapper.getDisplayCategory());
rep.setPriority(mapper.getPriority());
rep.setProperties(new LinkedList<ConfigPropertyRepresentation>());
List<ProviderConfigProperty> configProperties = mapper.getConfigProperties();
rep.setProperties(ModelToRepresentation.toRepresentation(configProperties));
types.add(rep);
}
HashMap<String, List<ProtocolMapperTypeRepresentation>> protocolMappers = session.getKeycloakSessionFactory()
.getProviderFactoriesStream(ProtocolMapper.class)
.map(ProtocolMapper.class::cast)
.collect(
Collectors.toMap(
ProtocolMapper::getProtocol,
this::toProtocolMapperTypeRepresentation,
(l1, l2) -> listCombiner(l1, l2),
HashMap::new
)
);
info.setProtocolMapperTypes(protocolMappers);
}
private void setBuiltinProtocolMappers(ServerInfoRepresentation info) {
info.setBuiltinProtocolMappers(new HashMap<String, List<ProtocolMapperRepresentation>>());
for (ProviderFactory p : session.getKeycloakSessionFactory().getProviderFactories(LoginProtocol.class)) {
LoginProtocolFactory factory = (LoginProtocolFactory)p;
List<ProtocolMapperRepresentation> mappers = new LinkedList<>();
for (ProtocolMapperModel mapper : factory.getBuiltinMappers().values()) {
mappers.add(ModelToRepresentation.toRepresentation(mapper));
}
info.getBuiltinProtocolMappers().put(p.getId(), mappers);
}
Map<String, List<ProtocolMapperRepresentation>> protocolMappers = session.getKeycloakSessionFactory()
.getProviderFactoriesStream(LoginProtocol.class)
.collect(Collectors.toMap(
p -> p.getId(),
p -> {
LoginProtocolFactory factory = (LoginProtocolFactory) p;
return factory.getBuiltinMappers().values().stream()
.map(ModelToRepresentation::toRepresentation)
.collect(Collectors.toList());
})
);
info.setBuiltinProtocolMappers(protocolMappers);
}
private void setPasswordPolicies(ServerInfoRepresentation info) {
info.setPasswordPolicies(new LinkedList<>());
for (ProviderFactory f : session.getKeycloakSessionFactory().getProviderFactories(PasswordPolicyProvider.class)) {
PasswordPolicyProviderFactory factory = (PasswordPolicyProviderFactory) f;
PasswordPolicyTypeRepresentation rep = new PasswordPolicyTypeRepresentation();
rep.setId(factory.getId());
rep.setDisplayName(factory.getDisplayName());
rep.setConfigType(factory.getConfigType());
rep.setDefaultValue(factory.getDefaultConfigValue());
rep.setMultipleSupported(factory.isMultiplSupported());
info.getPasswordPolicies().add(rep);
}
List<PasswordPolicyTypeRepresentation> passwordPolicyTypes= session.getKeycloakSessionFactory().getProviderFactoriesStream(PasswordPolicyProvider.class)
.map(PasswordPolicyProviderFactory.class::cast)
.map(factory -> {
PasswordPolicyTypeRepresentation rep = new PasswordPolicyTypeRepresentation();
rep.setId(factory.getId());
rep.setDisplayName(factory.getDisplayName());
rep.setConfigType(factory.getConfigType());
rep.setDefaultValue(factory.getDefaultConfigValue());
rep.setMultipleSupported(factory.isMultiplSupported());
return rep;
})
.collect(Collectors.toList());
info.setPasswordPolicies(passwordPolicyTypes);
}
private List<ClientInstallationRepresentation> toClientInstallationRepresentation(ClientInstallationProvider provider) {
ClientInstallationRepresentation rep = new ClientInstallationRepresentation();
rep.setId(provider.getId());
rep.setHelpText(provider.getHelpText());
rep.setDisplayType( provider.getDisplayType());
rep.setProtocol( provider.getProtocol());
rep.setDownloadOnly( provider.isDownloadOnly());
rep.setFilename(provider.getFilename());
rep.setMediaType(provider.getMediaType());
return Arrays.asList(rep);
}
private List<ProtocolMapperTypeRepresentation> toProtocolMapperTypeRepresentation(ProtocolMapper mapper) {
ProtocolMapperTypeRepresentation rep = new ProtocolMapperTypeRepresentation();
rep.setId(mapper.getId());
rep.setName(mapper.getDisplayType());
rep.setHelpText(mapper.getHelpText());
rep.setCategory(mapper.getDisplayCategory());
rep.setPriority(mapper.getPriority());
List<ProviderConfigProperty> configProperties = mapper.getConfigProperties();
rep.setProperties(ModelToRepresentation.toRepresentation(configProperties));
return Arrays.asList(rep);
}
private static <T> List<T> listCombiner(List<T> list1, List<T> list2) {
return Stream.concat(list1.stream(), list2.stream()).collect(Collectors.toList());
}
private static Map<String, List<String>> createEnumsMap(Class... enums) {

View file

@ -20,12 +20,12 @@ import org.jboss.logging.Logger;
import org.keycloak.models.KeycloakSessionFactory;
import org.keycloak.models.KeycloakTransaction;
import org.keycloak.provider.ExceptionConverter;
import org.keycloak.provider.ProviderFactory;
import javax.transaction.RollbackException;
import javax.transaction.Status;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import java.util.Objects;
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -59,26 +59,24 @@ public class JtaTransactionWrapper implements KeycloakTransaction {
if (e instanceof RollbackException) {
e = e.getCause() != null ? e.getCause() : e;
}
final Throwable finalE = e;
for (ProviderFactory factory : this.factory.getProviderFactories(ExceptionConverter.class)) {
ExceptionConverter converter = (ExceptionConverter)factory;
Throwable throwable = converter.convert(e);
if (throwable == null) continue;
if (throwable instanceof RuntimeException) {
throw (RuntimeException)throwable;
} else {
throw new RuntimeException(throwable);
}
}
factory.getProviderFactoriesStream(ExceptionConverter.class)
.map(factory -> ((ExceptionConverter) factory).convert(finalE))
.filter(Objects::nonNull)
.forEach(throwable -> {
if (throwable instanceof RuntimeException) {
throw (RuntimeException)throwable;
} else {
throw new RuntimeException(throwable);
}
});
if (e instanceof RuntimeException) {
throw (RuntimeException)e;
} else {
throw new RuntimeException(e);
}
}
@Override

View file

@ -389,7 +389,7 @@ public class UserMapStorage implements UserLookupProvider.Streams, UserStoragePr
}
@Override
public Stream<String> getMembershipStream(RealmModel realm, GroupModel group, int firstResult, int max) {
public Stream<String> getMembershipStream(RealmModel realm, GroupModel group, Integer firstResult, Integer max) {
Stream<String> userStream = paginatedStream(userGroups.entrySet().stream(), firstResult, max)
.filter(me -> me.getValue().contains(group.getId()))
.map(Map.Entry::getKey)

View file

@ -33,9 +33,6 @@ import org.keycloak.storage.adapter.AbstractUserAdapterFederatedStorage;
import org.keycloak.storage.user.UserLookupProvider;
import org.keycloak.storage.user.UserQueryProvider;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;

View file

@ -131,7 +131,7 @@ public class ApiUtil {
public static UserRepresentation findUserByUsername(RealmResource realm, String username) {
UserRepresentation user = null;
List<UserRepresentation> ur = realm.users().search(username, null, null, null, 0, Integer.MAX_VALUE);
List<UserRepresentation> ur = realm.users().search(username, null, null, null, 0, -1);
if (ur.size() == 1) {
user = ur.get(0);
}

View file

@ -474,7 +474,7 @@ public class ExportImportUtil {
// Workaround for KEYCLOAK-3104. For this realm, search() only works if username is null.
private static UserRepresentation findByUsername(RealmResource realmRsc, String username) {
for (UserRepresentation user : realmRsc.users().search(null, 0, Integer.MAX_VALUE)) {
for (UserRepresentation user : realmRsc.users().search(null, 0, -1)) {
if (user.getUsername().equalsIgnoreCase(username)) return user;
}
return null;

View file

@ -287,13 +287,13 @@ public abstract class AbstractKerberosTest extends AbstractAuthTest {
protected void removeAllUsers() {
RealmResource realm = testRealmResource();
List<UserRepresentation> users = realm.users().search("", 0, Integer.MAX_VALUE);
List<UserRepresentation> users = realm.users().search("", 0, -1);
for (UserRepresentation user : users) {
if (!user.getUsername().equals(AssertEvents.DEFAULT_USERNAME)) {
realm.users().get(user.getId()).remove();
}
}
Assert.assertEquals(1, realm.users().search("", 0, Integer.MAX_VALUE).size());
Assert.assertEquals(1, realm.users().search("", 0, -1).size());
}

View file

@ -425,7 +425,7 @@ public class UserStorageTest extends AbstractAuthTest {
Assert.assertTrue(usernames.contains("danny"));
// test searchForUser
List<UserRepresentation> users = testRealmResource().users().search("tbrady", 0, Integer.MAX_VALUE);
List<UserRepresentation> users = testRealmResource().users().search("tbrady", 0, -1);
assertThat(users, hasSize(1));
assertThat(users.get(0).getUsername(), equalTo("tbrady"));

View file

@ -45,6 +45,7 @@ import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@ -412,8 +413,8 @@ public class UserSessionPersisterProviderTest extends AbstractTestRealmKeycloakT
public void testNoSessions(KeycloakSession session) {
KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionNS) -> {
UserSessionPersisterProvider persister = sessionNS.getProvider(UserSessionPersisterProvider.class);
List<UserSessionModel> sessions = persister.loadUserSessions(0, 1, true, 0, "abc");
Assert.assertEquals(0, sessions.size());
Stream<UserSessionModel> sessions = persister.loadUserSessionsStream(0, 1, true, 0, "abc");
Assert.assertEquals(0, sessions.count());
});
}
@ -579,7 +580,9 @@ public class UserSessionPersisterProviderTest extends AbstractTestRealmKeycloakT
String lastSessionId = "abc";
while (next) {
List<UserSessionModel> sess = persister.loadUserSessions(0, sessionsPerPage, offline, lastCreatedOn, lastSessionId);
List<UserSessionModel> sess = persister
.loadUserSessionsStream(0, sessionsPerPage, offline, lastCreatedOn, lastSessionId)
.collect(Collectors.toList());
if (sess.size() < sessionsPerPage) {
next = false;

View file

@ -221,7 +221,7 @@ public class ManyUsersTest extends AbstractUserTest {
realmTimer.reset("re-import realm with " + realm.getUsers().size() + " users");
realmsResouce().create(realm);
realmTimer.reset("load " + realm.getUsers().size() + " users");
users = realmResource().users().search("", 0, Integer.MAX_VALUE);
users = realmResource().users().search("", 0, -1);
}

View file

@ -22,6 +22,7 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;
@ -124,7 +125,9 @@ public class LoadPersistentSessionsCommand extends AbstractCommand {
int offset = workerId * limit;
UserSessionPersisterProvider persister = keycloakSession.getProvider(UserSessionPersisterProvider.class);
loadedSessions = persister.loadUserSessions(offset, limit, true, lastCreatedOn, lastSessionId);
loadedSessions = persister
.loadUserSessionsStream(offset, limit, true, lastCreatedOn, lastSessionId)
.collect(Collectors.toList());
});
}