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.Stream;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
import static org.keycloak.utils.StreamsUtil.paginatedStream;
/** /**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a> * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
*/ */
@ -316,18 +318,18 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
} }
@Override @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); 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(); final String clientUuid = client.getId();
UserSessionPredicate predicate = UserSessionPredicate.create(realm.getId()).client(clientUuid); UserSessionPredicate predicate = UserSessionPredicate.create(realm.getId()).client(clientUuid);
return getUserSessionModels(realm, firstResult, maxResults, offline, predicate); 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<String, SessionEntityWrapper<UserSessionEntity>> cache = getCache(offline);
cache = CacheDecorators.skipCacheLoaders(cache); cache = CacheDecorators.skipCacheLoaders(cache);
@ -338,15 +340,7 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
.map(Mappers.userSessionEntity()) .map(Mappers.userSessionEntity())
.sorted(Comparators.userSessionLastSessionRefresh()); .sorted(Comparators.userSessionLastSessionRefresh());
if (firstResult > 0) { return paginatedStream(stream, firstResult, maxResults).map(entity -> this.wrap(realm, entity, offline));
stream = stream.skip(firstResult);
}
if (maxResults > 0) {
stream = stream.limit(maxResults);
}
return stream.map(entity -> this.wrap(realm, entity, offline));
} }
@Override @Override
@ -862,7 +856,7 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
} }
@Override @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); 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.io.Serializable;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -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()); log.tracef("Loading sessions for segment=%d createdOn=%d lastSessionId=%s", ctx.getSegment(), ctx.getLastCreatedOn(), ctx.getLastSessionId());
UserSessionPersisterProvider persister = session.getProvider(UserSessionPersisterProvider.class); 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()); 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.EntityManager;
import javax.persistence.FlushModeType; import javax.persistence.FlushModeType;
import javax.persistence.Query;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaQuery;
@ -43,6 +42,8 @@ import org.keycloak.authorization.store.ResourceStore;
import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.models.utils.KeycloakModelUtils;
import javax.persistence.LockModeType; import javax.persistence.LockModeType;
import static org.keycloak.models.jpa.PaginationUtils.paginateQuery;
/** /**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a> * @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"))); 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) { List<String> result = paginateQuery(query, firstResult, maxResult).getResultList();
query.setFirstResult(firstResult);
}
if (maxResult != -1) {
query.setMaxResults(maxResult);
}
List<String> result = query.getResultList();
List<PermissionTicket> list = new LinkedList<>(); List<PermissionTicket> list = new LinkedList<>();
PermissionTicketStore ticketStore = provider.getStoreFactory().getPermissionTicketStore(); PermissionTicketStore ticketStore = provider.getStoreFactory().getPermissionTicketStore();
@ -278,12 +271,7 @@ public class JPAPermissionTicketStore implements PermissionTicketStore {
query.setParameter("resourceName", "%" + name.toLowerCase() + "%"); query.setParameter("resourceName", "%" + name.toLowerCase() + "%");
} }
if (first > -1 && max > -1) { List<String> result = paginateQuery(query, first, max).getResultList();
query.setFirstResult(first);
query.setMaxResults(max);
}
List<String> result = query.getResultList();
List<Resource> list = new LinkedList<>(); List<Resource> list = new LinkedList<>();
ResourceStore resourceStore = provider.getStoreFactory().getResourceStore(); ResourceStore resourceStore = provider.getStoreFactory().getResourceStore();
@ -305,12 +293,7 @@ public class JPAPermissionTicketStore implements PermissionTicketStore {
query.setFlushMode(FlushModeType.COMMIT); query.setFlushMode(FlushModeType.COMMIT);
query.setParameter("owner", owner); query.setParameter("owner", owner);
if (first > -1 && max > -1) { List<String> result = paginateQuery(query, first, max).getResultList();
query.setFirstResult(first);
query.setMaxResults(max);
}
List<String> result = query.getResultList();
List<Resource> list = new LinkedList<>(); List<Resource> list = new LinkedList<>();
ResourceStore resourceStore = provider.getStoreFactory().getResourceStore(); ResourceStore resourceStore = provider.getStoreFactory().getResourceStore();

View file

@ -28,7 +28,6 @@ import java.util.function.Consumer;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.FlushModeType; import javax.persistence.FlushModeType;
import javax.persistence.NoResultException; import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaQuery;
@ -45,6 +44,9 @@ import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation; import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation;
import javax.persistence.LockModeType; 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> * @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"))); 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) { List<String> result = paginateQuery(query, firstResult, maxResult).getResultList();
query.setFirstResult(firstResult);
}
if (maxResult != -1) {
query.setMaxResults(maxResult);
}
List<String> result = query.getResultList();
List<Policy> list = new LinkedList<>(); List<Policy> list = new LinkedList<>();
for (String id : result) { for (String id : result) {
Policy policy = provider.getStoreFactory().getPolicyStore().findById(id, resourceServerId); Policy policy = provider.getStoreFactory().getPolicyStore().findById(id, resourceServerId);
@ -215,9 +210,9 @@ public class JPAPolicyStore implements PolicyStore {
PolicyStore storeFactory = provider.getStoreFactory().getPolicyStore(); PolicyStore storeFactory = provider.getStoreFactory().getPolicyStore();
query.getResultStream() closing(query.getResultStream()
.map(entity -> storeFactory.findById(entity.getId(), resourceServerId)) .map(entity -> storeFactory.findById(entity.getId(), resourceServerId))
.filter(Objects::nonNull) .filter(Objects::nonNull))
.forEach(consumer::accept); .forEach(consumer::accept);
} }
@ -238,9 +233,9 @@ public class JPAPolicyStore implements PolicyStore {
query.setParameter("type", resourceType); query.setParameter("type", resourceType);
query.setParameter("serverId", resourceServerId); query.setParameter("serverId", resourceServerId);
query.getResultStream() closing(query.getResultStream()
.map(id -> new PolicyAdapter(id, entityManager, provider.getStoreFactory())) .map(id -> new PolicyAdapter(id, entityManager, provider.getStoreFactory()))
.filter(Objects::nonNull) .filter(Objects::nonNull))
.forEach(consumer::accept); .forEach(consumer::accept);
} }
@ -294,9 +289,9 @@ public class JPAPolicyStore implements PolicyStore {
StoreFactory storeFactory = provider.getStoreFactory(); StoreFactory storeFactory = provider.getStoreFactory();
query.getResultStream() closing(query.getResultStream()
.map(id -> new PolicyAdapter(id, entityManager, storeFactory)) .map(id -> new PolicyAdapter(id, entityManager, storeFactory))
.filter(Objects::nonNull) .filter(Objects::nonNull))
.forEach(consumer::accept); .forEach(consumer::accept);
} }

View file

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

View file

@ -25,7 +25,6 @@ import java.util.Map;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.FlushModeType; import javax.persistence.FlushModeType;
import javax.persistence.NoResultException; import javax.persistence.NoResultException;
import javax.persistence.Query;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.CriteriaQuery;
@ -40,6 +39,8 @@ import org.keycloak.authorization.store.ScopeStore;
import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.models.utils.KeycloakModelUtils;
import javax.persistence.LockModeType; import javax.persistence.LockModeType;
import static org.keycloak.models.jpa.PaginationUtils.paginateQuery;
/** /**
* @author <a href="mailto:psilva@redhat.com">Pedro Igor</a> * @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"))); 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) { List result = paginateQuery(query, firstResult, maxResult).getResultList();
query.setFirstResult(firstResult);
}
if (maxResult != -1) {
query.setMaxResults(maxResult);
}
List result = query.getResultList();
List<Scope> list = new LinkedList<>(); List<Scope> list = new LinkedList<>();
for (Object id : result) { for (Object id : result) {
list.add(provider.getStoreFactory().getScopeStore().findById((String)id, resourceServerId)); 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.provider.ProviderFactory;
import org.keycloak.storage.UserStorageProvider; import org.keycloak.storage.UserStorageProvider;
import java.util.List; import java.util.function.Predicate;
/** /**
* @author <a href="mailto:bburke@redhat.com">Bill Burke</a> * @author <a href="mailto:bburke@redhat.com">Bill Burke</a>
@ -30,17 +30,23 @@ import java.util.List;
public class MigrateUserFedToComponent extends AbstractUserFedToComponent { public class MigrateUserFedToComponent extends AbstractUserFedToComponent {
@Override @Override
protected void generateStatementsImpl() throws CustomChangeException { protected void generateStatementsImpl() {
List<ProviderFactory> factories = kcSession.getKeycloakSessionFactory().getProviderFactories(UserStorageProvider.class); kcSession.getKeycloakSessionFactory().getProviderFactoriesStream(UserStorageProvider.class)
for (ProviderFactory factory : factories) { .map(ProviderFactory::getId)
if (!factory.getId().equals(LDAPConstants.LDAP_PROVIDER)) { .filter(Predicate.isEqual(LDAPConstants.LDAP_PROVIDER).negate())
convertFedProviderToComponent(factory.getId(), null); .forEach(this::convertFedProviderToComponent);
}
}
} }
@Override @Override
protected String getTaskId() { protected String getTaskId() {
return "Update 2.5.0.Final"; 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.List;
import java.util.stream.Stream; 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; import static org.keycloak.utils.StreamsUtil.closing;
/** /**
@ -153,18 +153,7 @@ public class JpaAdminEventQuery implements AdminEventQuery {
TypedQuery<AdminEventEntity> query = em.createQuery(cq); TypedQuery<AdminEventEntity> query = em.createQuery(cq);
if (firstResult != null) { return closing(paginateQuery(query, firstResult, maxResults).getResultStream().map(JpaEventStoreProvider::convertAdminEvent));
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));
} }
} }

View file

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

View file

@ -50,7 +50,11 @@ import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaDelete; import javax.persistence.criteria.CriteriaDelete;
import javax.persistence.criteria.Root; 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.Collectors;
import java.util.stream.Stream; 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) { protected Stream<RoleModel> searchForRoles(TypedQuery<RoleEntity> query, RealmModel realm, String search, Integer first, Integer max) {
query.setParameter("search", "%" + search.trim().toLowerCase() + "%"); query.setParameter("search", "%" + search.trim().toLowerCase() + "%");
if(Objects.nonNull(first) && Objects.nonNull(max) Stream<RoleEntity> results = paginateQuery(query, first, max).getResultStream();
&& first >= 0 && max >= 0) {
query= query.setFirstResult(first).setMaxResults(max);
}
Stream<RoleEntity> results = query.getResultStream();
return closing(results.map(role -> new RoleAdapter(session, realm, em, role))); 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.Query;
import javax.persistence.TypedQuery; import javax.persistence.TypedQuery;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -47,8 +45,12 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.persistence.LockModeType; 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> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/ */
@ -240,7 +242,8 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
} }
@Override @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); String offlineStr = offlineToString(offline);
TypedQuery<PersistentUserSessionEntity> query = em.createNamedQuery("findUserSessions", PersistentUserSessionEntity.class); TypedQuery<PersistentUserSessionEntity> query = em.createNamedQuery("findUserSessions", PersistentUserSessionEntity.class);
@ -248,15 +251,8 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
query.setParameter("lastCreatedOn", lastCreatedOn); query.setParameter("lastCreatedOn", lastCreatedOn);
query.setParameter("lastSessionId", lastUserSessionId); query.setParameter("lastSessionId", lastUserSessionId);
if (firstResult != -1) { List<PersistentUserSessionAdapter> result = closing(paginateQuery(query, firstResult, maxResults).getResultStream()
query.setFirstResult(firstResult); .map(this::toAdapter))
}
if (maxResults != -1) {
query.setMaxResults(maxResults);
}
List<PersistentUserSessionAdapter> result = query.getResultStream()
.map(this::toAdapter)
.collect(Collectors.toList()); .collect(Collectors.toList());
Map<String, PersistentUserSessionAdapter> sessionsById = result.stream() Map<String, PersistentUserSessionAdapter> sessionsById = result.stream()
@ -270,9 +266,7 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
TypedQuery<PersistentClientSessionEntity> query2 = em.createNamedQuery("findClientSessionsByUserSessions", PersistentClientSessionEntity.class); TypedQuery<PersistentClientSessionEntity> query2 = em.createNamedQuery("findClientSessionsByUserSessions", PersistentClientSessionEntity.class);
query2.setParameter("userSessionIds", userSessionIds); query2.setParameter("userSessionIds", userSessionIds);
query2.setParameter("offline", offlineStr); query2.setParameter("offline", offlineStr);
List<PersistentClientSessionEntity> clientSessions = query2.getResultList(); closing(query2.getResultStream()).forEach(clientSession -> {
for (PersistentClientSessionEntity clientSession : clientSessions) {
PersistentUserSessionAdapter userSession = sessionsById.get(clientSession.getUserSessionId()); PersistentUserSessionAdapter userSession = sessionsById.get(clientSession.getUserSessionId());
PersistentAuthenticatedClientSessionAdapter clientSessAdapter = toAdapter(userSession.getRealm(), userSession, clientSession); PersistentAuthenticatedClientSessionAdapter clientSessAdapter = toAdapter(userSession.getRealm(), userSession, clientSession);
@ -284,14 +278,14 @@ public class JpaUserSessionPersisterProvider implements UserSessionPersisterProv
} else { } else {
currentClientSessions.put(clientSession.getClientId(), clientSessAdapter); currentClientSessions.put(clientSession.getClientId(), clientSessAdapter);
} }
} });
} }
for (String clientUUID : removedClientUUIDs) { for (String clientUUID : removedClientUUIDs) {
onClientRemoved(clientUUID); onClientRemoved(clientUUID);
} }
return (List) result; return result.stream().map(UserSessionModel.class::cast);
} }
private PersistentUserSessionAdapter toAdapter(PersistentUserSessionEntity entity) { private PersistentUserSessionAdapter toAdapter(PersistentUserSessionEntity entity) {

View file

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

View file

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

View file

@ -55,7 +55,7 @@ public interface EventQuery {
/** /**
* Returns requested results that match given criteria as a stream. * 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(); Stream<Event> getResultStream();
} }

View file

@ -138,7 +138,7 @@ public interface AdminEventQuery {
/** /**
* Executes the query and returns the results as a stream. * 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(); Stream<AdminEvent> getResultStream();
} }

View file

@ -27,8 +27,7 @@ import org.keycloak.models.UserModel;
import org.keycloak.models.UserSessionModel; import org.keycloak.models.UserSessionModel;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.stream.Stream;
import java.util.List;
/** /**
* Persistence of userSessions is disabled . Useful just if you never need survive of userSessions/clientSessions * 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 @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,
return Collections.emptyList(); Integer lastCreatedOn, String lastUserSessionId) {
return Stream.empty();
} }
@Override @Override

View file

@ -26,6 +26,8 @@ import org.keycloak.provider.Provider;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a> * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@ -54,8 +56,27 @@ public interface UserSessionPersisterProvider extends Provider {
// Remove userSessions and clientSessions, which are expired // Remove userSessions and clientSessions, which are expired
void removeExpired(RealmModel realm); 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); int getUserSessionsCount(boolean offline);

View file

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

View file

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

View file

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

View file

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

View file

@ -66,10 +66,16 @@ public interface GroupModel extends RoleMapperModel {
/** /**
* @param name * @param name
* @return list of all attribute values or empty list if there are not any values. Never return null * @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 @Deprecated
List<String> getAttribute(String name); 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) { default Stream<String> getAttributeStream(String name) {
List<String> value = this.getAttribute(name); List<String> value = this.getAttribute(name);
return value != null ? value.stream() : Stream.empty(); return value != null ? value.stream() : Stream.empty();
@ -80,9 +86,16 @@ public interface GroupModel extends RoleMapperModel {
GroupModel getParent(); GroupModel getParent();
String getParentId(); String getParentId();
/**
* @deprecated Use {@link #getSubGroupsStream() getSubGroupsStream} instead.
*/
@Deprecated @Deprecated
Set<GroupModel> getSubGroups(); 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() { default Stream<GroupModel> getSubGroupsStream() {
Set<GroupModel> value = this.getSubGroups(); Set<GroupModel> value = this.getSubGroups();
return value != null ? value.stream() : Stream.empty(); return value != null ? value.stream() : Stream.empty();

View file

@ -65,12 +65,12 @@ public interface GroupProvider extends Provider, GroupLookupProvider {
Stream<GroupModel> getGroupsStream(RealmModel realm); 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)}. * Effectively the same as {@code getGroupsStream(realm, ids, null, null, null)}.
* *
* @param realm Realm. * @param realm Realm.
* @param ids List of ids. * @param ids Stream of ids.
* @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) { default Stream<GroupModel> getGroupsStream(RealmModel realm, Stream<String> ids) {
return getGroupsStream(realm, ids, null, null, null); 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. * Returns a paginated stream of groups with given ids and given search value in group names.
* *
* @param realm Realm. * @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 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 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}. * @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); 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)}. * Effectively the same as {@code getGroupsStream(realm, ids, null, first, max)}.
* *
* @param realm Realm. * @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 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}. * @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) { default Stream<GroupModel> getGroupsStream(RealmModel realm, Stream<String> ids, Integer first, Integer max) {
return getGroupsStream(realm, ids, null, first, max); return getGroupsStream(realm, ids, null, first, max);
@ -137,8 +137,8 @@ public interface GroupProvider extends Provider, GroupLookupProvider {
* *
* @param realm Realm. * @param realm Realm.
* @param role Role. * @param role Role.
* @param firstResult First result 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. * @param maxResults Maximum number of results to return. Ignored if negative or {@code null}.
* @return List of groups with the given role. * @return List of groups with the given role.
* @deprecated Use {@link #getGroupsByRoleStream(RealmModel, RoleModel, Integer, Integer) getGroupsByRoleStream} instead. * @deprecated Use {@link #getGroupsByRoleStream(RealmModel, RoleModel, Integer, Integer) getGroupsByRoleStream} instead.
*/ */
@ -154,7 +154,7 @@ public interface GroupProvider extends Provider, GroupLookupProvider {
* @param role Role. * @param role Role.
* @param firstResult First result to return. Ignored if negative or {@code null}. * @param firstResult First result to return. Ignored if negative or {@code null}.
* @param maxResults Maximum number of results to return. Ignored if negative or {@code null}. * @param maxResults Maximum number of results to return. Ignored if negative or {@code null}.
* @return 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); 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. * Returns all top level groups (i.e. groups without parent group) for the given realm.
* *
* @param realm 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); Stream<GroupModel> getTopLevelGroupsStream(RealmModel realm);
@ -198,7 +198,7 @@ public interface GroupProvider extends Provider, GroupLookupProvider {
* @param realm Realm. * @param realm Realm.
* @param firstResult First result to return. Ignored if negative or {@code null}. * @param firstResult First result to return. Ignored if negative or {@code null}.
* @param maxResults Maximum number of results to return. Ignored if negative or {@code null}. * @param maxResults Maximum number of results to return. Ignored if negative or {@code null}.
* @return 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); 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. * Returns all {@code KeyWrapper} for the given realm.
* @param realm {@code RealmModel}. * @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); Stream<KeyWrapper> getKeysStream(RealmModel realm);
@ -77,7 +77,7 @@ public interface KeyManager {
* @param realm {@code RealmModel}. * @param realm {@code RealmModel}.
* @param use {@code KeyUse}. * @param use {@code KeyUse}.
* @param algorithm {@code String}. * @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); 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.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @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); <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(); long getServerStartupTimestamp();

View file

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

View file

@ -49,25 +49,51 @@ public interface RoleContainerModel {
boolean removeRole(RoleModel role); boolean removeRole(RoleModel role);
/**
* @deprecated Use {@link #getRolesStream() getRolesStream} instead.
*/
@Deprecated @Deprecated
default Set<RoleModel> getRoles() { default Set<RoleModel> getRoles() {
return getRolesStream().collect(Collectors.toSet()); return getRolesStream().collect(Collectors.toSet());
} }
/**
* Returns available roles as a stream.
* @return Stream of {@link RoleModel}. Never returns {@code null}.
*/
Stream<RoleModel> getRolesStream(); Stream<RoleModel> getRolesStream();
/**
* @deprecated Use {@link #getRolesStream(Integer, Integer) getRolesStream} instead.
*/
@Deprecated @Deprecated
default Set<RoleModel> getRoles(Integer firstResult, Integer maxResults) { default Set<RoleModel> getRoles(Integer firstResult, Integer maxResults) {
return getRolesStream(firstResult, maxResults).collect(Collectors.toSet()); 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); Stream<RoleModel> getRolesStream(Integer firstResult, Integer maxResults);
/**
* @deprecated Use {@link #searchForRolesStream(String, Integer, Integer) searchForRolesStream} instead.
*/
@Deprecated @Deprecated
default Set<RoleModel> searchForRoles(String search, Integer first, Integer max) { default Set<RoleModel> searchForRoles(String search, Integer first, Integer max) {
return searchForRolesStream(search, first, max).collect(Collectors.toSet()); 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); 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. * Returns set of realm roles that are directly set to this object.
* @return see description * @return see description
* @deprecated Use {@link #getRealmRoleMappingsStream()} getRealmRoleMappingsStream} instead. * @deprecated Use {@link #getRealmRoleMappingsStream() getRealmRoleMappingsStream} instead.
*/ */
@Deprecated @Deprecated
Set<RoleModel> getRealmRoleMappings(); Set<RoleModel> getRealmRoleMappings();
/** /**
* Returns stream of realm roles that are directly set to this object. * 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() { default Stream<RoleModel> getRealmRoleMappingsStream() {
Set<RoleModel> value = this.getRealmRoleMappings(); 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. * Returns set of client roles that are directly set to this object for the given client.
* @param app Client to get the roles for * @param app Client to get the roles for
* @return see description * @return see description
* @deprecated Use {@link #getClientRoleMappingsStream(ClientModel)} getClientRoleMappingsStream} instead. * @deprecated Use {@link #getClientRoleMappingsStream(ClientModel) getClientRoleMappingsStream} instead.
*/ */
@Deprecated @Deprecated
Set<RoleModel> getClientRoleMappings(ClientModel app); Set<RoleModel> getClientRoleMappings(ClientModel app);
/** /**
* Returns stream of client roles that are directly set to this object for the given client. * Returns stream of client roles that are directly set to this object for the given client.
* @param app Client to get the roles for * @param app {@link ClientModel} Client to get the roles for.
* @return stream of {@link RoleModel} * @return Stream of {@link RoleModel}. Never returns {@code null}.
*/ */
default Stream<RoleModel> getClientRoleMappingsStream(ClientModel app) { default Stream<RoleModel> getClientRoleMappingsStream(ClientModel app) {
Set<RoleModel> value = this.getClientRoleMappings(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. * Returns set of all role (both realm all client) that are directly set to this object.
* @return * @return
* @deprecated Use {@link #getRoleMappingsStream()} getRoleMappingsStream} instead. * @deprecated Use {@link #getRoleMappingsStream() getRoleMappingsStream} instead.
*/ */
@Deprecated @Deprecated
Set<RoleModel> getRoleMappings(); Set<RoleModel> getRoleMappings();
/** /**
* Returns stream of all role (both realm all client) that are directly set to this object. * 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() { default Stream<RoleModel> getRoleMappingsStream() {
Set<RoleModel> value = this.getRoleMappings(); Set<RoleModel> value = this.getRoleMappings();

View file

@ -44,11 +44,18 @@ public interface RoleModel {
void removeCompositeRole(RoleModel role); void removeCompositeRole(RoleModel role);
/**
* @deprecated Use {@link #getCompositesStream() getCompositesStream} instead.
*/
@Deprecated @Deprecated
default Set<RoleModel> getComposites() { default Set<RoleModel> getComposites() {
return getCompositesStream().collect(Collectors.toSet()); return getCompositesStream().collect(Collectors.toSet());
} }
/**
* Returns all composite roles as a stream.
* @return Stream of {@link RoleModel}. Never returns {@code null}.
*/
Stream<RoleModel> getCompositesStream(); Stream<RoleModel> getCompositesStream();
boolean isClientRole(); boolean isClientRole();
@ -69,11 +76,19 @@ public interface RoleModel {
return getAttributeStream(name).findFirst().orElse(null); return getAttributeStream(name).findFirst().orElse(null);
} }
/**
* @deprecated Use {@link #getAttributeStream(String) getAttributeStream} instead.
*/
@Deprecated @Deprecated
default List<String> getAttribute(String name) { default List<String> getAttribute(String name) {
return getAttributeStream(name).collect(Collectors.toList()); 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); Stream<String> getAttributeStream(String name);
Map<String, List<String>> getAttributes(); 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. * Removes given realm role from the given realm.
* @param realm Realm.
* @param role Role to be removed. * @param role Role to be removed.
* @return {@code true} if the role existed and has been removed, {@code false} otherwise. * @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. * Returns all the client roles of the given client.
* Effectively the same as the call {@code getClientRoles(client, null, null)}. * Effectively the same as the call {@code getClientRoles(client, null, null)}.
* @param client Client. * @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) { default Stream<RoleModel> getClientRolesStream(ClientModel client) {
return getClientRolesStream(client, null, null); return getClientRolesStream(client, null, null);
@ -130,7 +129,7 @@ public interface RoleProvider extends Provider, RoleLookupProvider {
* @param client Client. * @param client Client.
* @param first First result to return. Ignored if negative or {@code null}. * @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}. * @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); Stream<RoleModel> getClientRolesStream(ClientModel client, Integer first, Integer max);

View file

@ -27,18 +27,25 @@ import java.util.stream.Stream;
*/ */
public interface ScopeContainerModel { public interface ScopeContainerModel {
/**
* @deprecated Use {@link #getScopeMappingsStream() getScopeMappingsStream} instead.
*/
@Deprecated @Deprecated
default Set<RoleModel> getScopeMappings() { default Set<RoleModel> getScopeMappings() {
return getScopeMappingsStream().collect(Collectors.toSet()); 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(); Stream<RoleModel> getScopeMappingsStream();
/** /**
* From the scope mappings returned by {@link #getScopeMappings()} returns only those * From the scope mappings returned by {@link #getScopeMappings()} returns only those
* that belong to the realm that owns this scope container. * that belong to the realm that owns this scope container.
* @return set of {@link RealmModel} * @return set of {@link RealmModel}
* @deprecated Use {@link #getRealmScopeMappingsStream()} getRealmScopeMappingsStream} instead. * @deprecated Use {@link #getRealmScopeMappingsStream() getRealmScopeMappingsStream} instead.
*/ */
@Deprecated @Deprecated
default Set<RoleModel> getRealmScopeMappings() { 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. * 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(); 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 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 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}. * @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) { default Stream<GroupModel> getGroupsStream(String search, Integer first, Integer max) {
if (search != null) search = search.toLowerCase(); if (search != null) search = search.toLowerCase();

View file

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

View file

@ -162,7 +162,7 @@ public class RoleUtils {
* @param role * @param role
* @param visited Track roles, which were already visited. Those will be ignored and won't be added to the stream. Besides that, * @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 * 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) { private static Stream<RoleModel> expandCompositeRolesStream(RoleModel role, Set<RoleModel> visited) {
Stream.Builder<RoleModel> sb = Stream.builder(); 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.) * identifier ({@code client_id} in OIDC or {@code entityID} in SAML.)
* @param firstResult First result to return. Ignored if negative or {@code null}. * @param firstResult First result to return. Ignored if negative or {@code null}.
* @param maxResults Maximum number of results to return. Ignored if negative or {@code null}. * @param maxResults Maximum number of results to return. Ignored if negative or {@code null}.
* @return 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); Stream<ClientModel> searchClientsByClientIdStream(RealmModel realm, String clientId, Integer firstResult, Integer maxResults);
} }

View file

@ -46,7 +46,7 @@ public interface UserFederatedStorageProvider extends Provider,
UserFederatedUserCredentialStore { UserFederatedUserCredentialStore {
/** /**
* @deprecated Use {@link #getStoredUsersStream(RealmModel, int, int) getStoredUsersStream} instead. * @deprecated Use {@link #getStoredUsersStream(RealmModel, Integer, Integer) getStoredUsersStream} instead.
*/ */
@Deprecated @Deprecated
List<String> getStoredUsers(RealmModel realm, int first, int max); 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. * Obtains the ids of all federated users in the realm.
* *
* @param realm a reference to the realm. * @param realm a reference to the realm.
* @param first first result 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. * @param max maximum number of results to return. Ignored if negative or {@code null}.
* @return a non-null {@link Stream} of federated user ids. * @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); List<String> value = this.getStoredUsers(realm, first, max);
return value != null ? value.stream() : Stream.empty(); return value != null ? value.stream() : Stream.empty();
} }
@ -105,6 +105,6 @@ public interface UserFederatedStorageProvider extends Provider,
} }
@Override @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); 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 @Deprecated
List<String> getMembership(RealmModel realm, GroupModel group, int firstResult, int max); 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 realm a reference to the realm.
* @param group a reference to the group whose federated members are being searched. * @param group a reference to the group whose federated members are being searched.
* @param firstResult first result 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. * @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. * @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); List<String> value = this.getMembership(realm, group, firstResult, max);
return value != null ? value.stream() : Stream.empty(); return value != null ? value.stream() : Stream.empty();
} }
@ -94,6 +94,6 @@ public interface UserGroupMembershipFederatedStorage {
} }
@Override @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 search Case sensitive searched string.
* @param firstResult First result to return. Ignored if negative or {@code null}. * @param firstResult First result to return. Ignored if negative or {@code null}.
* @param maxResults Maximum number of results to return. Ignored if negative or {@code null}. * @param maxResults Maximum number of results to return. Ignored if negative or {@code null}.
* @return 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); 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}. * 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 realm a reference to the realm.
* @param firstResult first result to return. Ignored if negative or zero. * @param firstResult first result to return. Ignored if negative or {@code null}.
* @param maxResults maximum number of results to return. Ignored if negative. * @param maxResults maximum number of results to return. Ignored if negative or {@code null}.
* @return a non-null {@link Stream} of users. * @return a non-null {@link Stream} of users.
*/ */
default Stream<UserModel> getUsersStream(RealmModel realm, Integer firstResult, Integer maxResults) { 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 realm a reference to the realm.
* @param role a reference to the role. * @param role a reference to the role.
* @param firstResult first result 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. * @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. * @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) { 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.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.POST; import javax.ws.rs.POST;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
@ -280,8 +280,8 @@ public class PolicyService {
} }
return Response.ok( return Response.ok(
authorization.getProviderFactories().stream() authorization.getProviderFactoriesStream()
.filter(factory -> !factory.isInternal()) .filter(((Predicate<PolicyProviderFactory>) PolicyProviderFactory::isInternal).negate())
.map(factory -> { .map(factory -> {
PolicyProviderRepresentation representation = new PolicyProviderRepresentation(); PolicyProviderRepresentation representation = new PolicyProviderRepresentation();

View file

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

View file

@ -62,20 +62,22 @@ public class DefaultKeyManager implements KeyManager {
return activeKey; 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)) { Optional<KeyProviderFactory> keyProviderFactory = session.getKeycloakSessionFactory()
KeyProviderFactory kf = (KeyProviderFactory) f; .getProviderFactoriesStream(KeyProvider.class)
if (kf.createFallbackKeys(session, use, algorithm)) { .map(KeyProviderFactory.class::cast)
providersMap.remove(realm.getId()); .filter(kf -> kf.createFallbackKeys(session, use, algorithm))
List<KeyProvider> providers = getProviders(realm); .findFirst();
activeKey = getActiveKey(providers, realm, use, algorithm); if (keyProviderFactory.isPresent()) {
if (activeKey != null) { providersMap.remove(realm.getId());
logger.infov("No keys found for realm={0} and algorithm={1} for use={2}. Generating keys.", realm.getName(), algorithm, use.name()); List<KeyProvider> providers = getProviders(realm);
return activeKey; activeKey = getActiveKey(providers, realm, use, algorithm);
} else { if (activeKey != null) {
break; 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.models.UserModel;
import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory; import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
import org.keycloak.provider.ProviderFactory;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Comparator; import java.util.Comparator;
@ -112,14 +111,13 @@ public class ProtocolMapperUtils {
* @return The builtin locale mapper. * @return The builtin locale mapper.
*/ */
public static ProtocolMapperModel findLocaleMapper(KeycloakSession session) { public static ProtocolMapperModel findLocaleMapper(KeycloakSession session) {
for (ProviderFactory p : session.getKeycloakSessionFactory().getProviderFactories(LoginProtocol.class)) { return session.getKeycloakSessionFactory().getProviderFactoriesStream(LoginProtocol.class)
LoginProtocolFactory factory = (LoginProtocolFactory) p; .map(LoginProtocolFactory.class::cast)
ProtocolMapperModel found = factory.getBuiltinMappers().get(OIDCLoginProtocolFactory.LOCALE); .map(factory -> factory.getBuiltinMappers().get(OIDCLoginProtocolFactory.LOCALE))
if (found != null && found.getProtocol().equals(OIDCLoginProtocol.LOGIN_PROTOCOL)) { .filter(Objects::nonNull)
return found; .filter(protocolMapper -> Objects.equals(protocolMapper.getProtocol(), OIDCLoginProtocol.LOGIN_PROTOCOL))
} .findFirst()
} .orElse(null);
return null;
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -23,12 +23,10 @@ import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.UriInfo;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.spi.HttpRequest; import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse; import org.jboss.resteasy.spi.HttpResponse;
import org.keycloak.common.util.CollectionUtil; import org.keycloak.common.util.CollectionUtil;
import org.keycloak.common.util.UriUtils;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.protocol.oidc.utils.WebOriginsUtils; 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.SamlService;
import org.keycloak.protocol.saml.SamlSessionUtils; import org.keycloak.protocol.saml.SamlSessionUtils;
import org.keycloak.protocol.saml.preprocessor.SamlAuthenticationPreprocessor; import org.keycloak.protocol.saml.preprocessor.SamlAuthenticationPreprocessor;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.representations.AccessToken; import org.keycloak.representations.AccessToken;
import org.keycloak.services.ErrorPage; import org.keycloak.services.ErrorPage;
import org.keycloak.services.ErrorPageException; import org.keycloak.services.ErrorPageException;
@ -111,10 +110,7 @@ import java.net.URI;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
@ -122,6 +118,7 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* <p></p> * <p></p>
@ -1290,17 +1287,12 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
} }
public static IdentityProviderFactory getIdentityProviderFactory(KeycloakSession session, IdentityProviderModel model) { public static IdentityProviderFactory getIdentityProviderFactory(KeycloakSession session, IdentityProviderModel model) {
Map<String, IdentityProviderFactory> availableProviders = new HashMap<String, IdentityProviderFactory>(); return Stream.concat(session.getKeycloakSessionFactory().getProviderFactoriesStream(IdentityProvider.class),
List<ProviderFactory> allProviders = new ArrayList<ProviderFactory>(); session.getKeycloakSessionFactory().getProviderFactoriesStream(SocialIdentityProvider.class))
.filter(providerFactory -> Objects.equals(providerFactory.getId(), model.getProviderId()))
allProviders.addAll(session.getKeycloakSessionFactory().getProviderFactories(IdentityProvider.class)); .map(IdentityProviderFactory.class::cast)
allProviders.addAll(session.getKeycloakSessionFactory().getProviderFactories(SocialIdentityProvider.class)); .findFirst()
.orElse(null);
for (ProviderFactory providerFactory : allProviders) {
availableProviders.put(providerFactory.getId(), (IdentityProviderFactory) providerFactory);
}
return availableProviders.get(model.getProviderId());
} }
private IdentityProviderModel getIdentityProviderConfig(String providerId) { 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.common.VerificationException;
import org.keycloak.events.Errors; import org.keycloak.events.Errors;
import org.keycloak.forms.login.LoginFormsProvider; 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.protocol.oidc.utils.RedirectUtils;
import org.keycloak.representations.JsonWebToken; import org.keycloak.representations.JsonWebToken;
import org.keycloak.services.managers.AuthenticationManager; import org.keycloak.services.managers.AuthenticationManager;

View file

@ -23,7 +23,6 @@ import org.keycloak.OAuthErrorException;
import org.keycloak.authorization.AuthorizationProvider; import org.keycloak.authorization.AuthorizationProvider;
import org.keycloak.authorization.AuthorizationService; import org.keycloak.authorization.AuthorizationService;
import org.keycloak.common.ClientConnection; import org.keycloak.common.ClientConnection;
import org.keycloak.common.Profile;
import org.keycloak.common.util.KeycloakUriBuilder; import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.events.EventBuilder; import org.keycloak.events.EventBuilder;
import org.keycloak.models.ClientModel; 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.resources.account.AccountLoader;
import org.keycloak.services.util.CacheControlUtil; import org.keycloak.services.util.CacheControlUtil;
import org.keycloak.services.util.ResolveRelative; import org.keycloak.services.util.ResolveRelative;
import org.keycloak.utils.MediaTypeMatcher;
import org.keycloak.utils.ProfileHelper;
import org.keycloak.wellknown.WellKnownProvider; import org.keycloak.wellknown.WellKnownProvider;
import javax.ws.rs.GET; import javax.ws.rs.GET;

View file

@ -18,11 +18,6 @@
package org.keycloak.services.resources; package org.keycloak.services.resources;
import java.net.URI; 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.Response;
import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;

View file

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

View file

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

View file

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

View file

@ -48,10 +48,8 @@ import javax.ws.rs.GET;
import javax.ws.rs.POST; import javax.ws.rs.POST;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; 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.Context;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Stream;
/** /**
* @resource Client Registration Policy * @resource Client Registration Policy
@ -67,23 +67,17 @@ public class ClientRegistrationPolicyResource {
@GET @GET
@NoCache @NoCache
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public List<ComponentTypeRepresentation> getProviders() { public Stream<ComponentTypeRepresentation> getProviders() {
List<ProviderFactory> providerFactories = session.getKeycloakSessionFactory().getProviderFactories(ClientRegistrationPolicy.class); 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) -> { ComponentTypeRepresentation rep = new ComponentTypeRepresentation();
rep.setId(clientRegFactory.getId());
ClientRegistrationPolicyFactory clientRegFactory = (ClientRegistrationPolicyFactory) factory; rep.setHelpText(clientRegFactory.getHelpText());
List<ProviderConfigProperty> configProps = clientRegFactory.getConfigProperties(session); rep.setProperties(ModelToRepresentation.toRepresentation(configProps));
return rep;
ComponentTypeRepresentation rep = new ComponentTypeRepresentation(); });
rep.setId(clientRegFactory.getId());
rep.setHelpText(clientRegFactory.getHelpText());
rep.setProperties(ModelToRepresentation.toRepresentation(configProps));
return rep;
}).collect(Collectors.toList());
} }
} }

View file

@ -77,8 +77,6 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -298,21 +296,14 @@ public class ClientResource {
@NoCache @NoCache
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Path("default-client-scopes") @Path("default-client-scopes")
public List<ClientScopeRepresentation> getDefaultClientScopes() { public Stream<ClientScopeRepresentation> getDefaultClientScopes() {
return getDefaultClientScopes(true); return getDefaultClientScopes(true);
} }
private List<ClientScopeRepresentation> getDefaultClientScopes(boolean defaultScope) { private Stream<ClientScopeRepresentation> getDefaultClientScopes(boolean defaultScope) {
auth.clients().requireView(client); auth.clients().requireView(client);
List<ClientScopeRepresentation> defaults = new LinkedList<>(); return client.getClientScopes(defaultScope, true).values().stream().map(ClientResource::toRepresentation);
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;
} }
@ -361,7 +352,7 @@ public class ClientResource {
@NoCache @NoCache
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@Path("optional-client-scopes") @Path("optional-client-scopes")
public List<ClientScopeRepresentation> getOptionalClientScopes() { public Stream<ClientScopeRepresentation> getOptionalClientScopes() {
return getDefaultClientScopes(false); return getDefaultClientScopes(false);
} }
@ -699,4 +690,11 @@ public class ClientResource {
} }
return rep; 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.PUT;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
/** /**
@ -145,7 +143,4 @@ public class ClientScopeResource {
return ErrorResponse.error(me.getMessage(), Response.Status.BAD_REQUEST); 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.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.Objects; import java.util.Objects;
import java.util.Properties;
import java.util.stream.Stream; 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 java.lang.Boolean.TRUE;
import static org.keycloak.utils.StreamsUtil.paginatedStream;
/** /**
* Base resource class for managing a realm's clients. * Base resource class for managing a realm's clients.
@ -141,12 +138,7 @@ public class ClientsResource {
.filter(Objects::nonNull); .filter(Objects::nonNull);
if (!canView) { if (!canView) {
if (firstResult != null && firstResult > 0) { s = paginatedStream(s, firstResult, maxResults);
s = s.skip(firstResult);
}
if (maxResults != null && maxResults > 0) {
s = s.limit(maxResults);
}
} }
return s; 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.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.text.MessageFormat; 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; import java.util.stream.Stream;
/** /**
@ -213,7 +217,7 @@ public class ComponentResource {
@Path("{id}/sub-component-types") @Path("{id}/sub-component-types")
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
@NoCache @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(); auth.realm().requireViewRealm();
ComponentModel parent = realm.getComponent(parentId); ComponentModel parent = realm.getComponent(parentId);
if (parent == null) { if (parent == null) {
@ -222,41 +226,39 @@ public class ComponentResource {
if (subtype == null) { if (subtype == null) {
throw new BadRequestException("must specify a subtype"); throw new BadRequestException("must specify a subtype");
} }
Class<? extends Provider> providerClass = null; Class<? extends Provider> providerClass;
try { try {
providerClass = (Class<? extends Provider>)Class.forName(subtype); providerClass = (Class<? extends Provider>)Class.forName(subtype);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
throw new RuntimeException(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()); return session.getKeycloakSessionFactory().getProviderFactoriesStream(providerClass)
List<ProviderConfigProperty> props = null; .filter(ComponentFactory.class::isInstance)
Map<String, Object> metadata = null; .map(factory -> toComponentTypeRepresentation(factory, parent));
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;
} }
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 static javax.ws.rs.core.Response.Status.BAD_REQUEST;
import com.google.common.collect.Streams;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.jboss.resteasy.annotations.cache.NoCache; import org.jboss.resteasy.annotations.cache.NoCache;
import javax.ws.rs.NotFoundException; 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.ModelToRepresentation;
import org.keycloak.models.utils.RepresentationToModel; import org.keycloak.models.utils.RepresentationToModel;
import org.keycloak.models.utils.StripSecretsUtils; 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.ComponentRepresentation;
import org.keycloak.representations.idm.ConfigPropertyRepresentation;
import org.keycloak.representations.idm.IdentityProviderMapperRepresentation; import org.keycloak.representations.idm.IdentityProviderMapperRepresentation;
import org.keycloak.representations.idm.IdentityProviderMapperTypeRepresentation; import org.keycloak.representations.idm.IdentityProviderMapperTypeRepresentation;
import org.keycloak.representations.idm.IdentityProviderRepresentation; import org.keycloak.representations.idm.IdentityProviderRepresentation;
@ -62,7 +60,10 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam; import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.util.*; 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.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -230,16 +231,12 @@ public class IdentityProviderResource {
private IdentityProviderFactory getIdentityProviderFactory() { private IdentityProviderFactory getIdentityProviderFactory() {
List<ProviderFactory> allProviders = new ArrayList<ProviderFactory>(); return Streams.concat(session.getKeycloakSessionFactory().getProviderFactoriesStream(IdentityProvider.class),
session.getKeycloakSessionFactory().getProviderFactoriesStream(SocialIdentityProvider.class))
allProviders.addAll(this.session.getKeycloakSessionFactory().getProviderFactories(IdentityProvider.class)); .filter(providerFactory -> Objects.equals(providerFactory.getId(), identityProviderModel.getProviderId()))
allProviders.addAll(this.session.getKeycloakSessionFactory().getProviderFactories(SocialIdentityProvider.class)); .map(IdentityProviderFactory.class::cast)
.findFirst()
for (ProviderFactory providerFactory : allProviders) { .orElse(null);
if (providerFactory.getId().equals(identityProviderModel.getProviderId())) return (IdentityProviderFactory)providerFactory;
}
return null;
} }
/** /**
@ -280,28 +277,26 @@ public class IdentityProviderResource {
} }
KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory(); KeycloakSessionFactory sessionFactory = session.getKeycloakSessionFactory();
Map<String, IdentityProviderMapperTypeRepresentation> types = new HashMap<>(); return sessionFactory.getProviderFactoriesStream(IdentityProviderMapper.class)
List<ProviderFactory> factories = sessionFactory.getProviderFactories(IdentityProviderMapper.class); .map(IdentityProviderMapper.class::cast)
for (ProviderFactory factory : factories) { .map(mapper -> Arrays.stream(mapper.getCompatibleProviders())
IdentityProviderMapper mapper = (IdentityProviderMapper)factory; .filter(type -> Objects.equals(IdentityProviderMapper.ANY_PROVIDER, type) ||
for (String type : mapper.getCompatibleProviders()) { Objects.equals(identityProviderModel.getProviderId(), type))
if (IdentityProviderMapper.ANY_PROVIDER.equals(type) || type.equals(identityProviderModel.getProviderId())) { .map(type -> {
IdentityProviderMapperTypeRepresentation rep = new IdentityProviderMapperTypeRepresentation(); IdentityProviderMapperTypeRepresentation rep = new IdentityProviderMapperTypeRepresentation();
rep.setId(mapper.getId()); rep.setId(mapper.getId());
rep.setCategory(mapper.getDisplayCategory()); rep.setCategory(mapper.getDisplayCategory());
rep.setName(mapper.getDisplayType()); rep.setName(mapper.getDisplayType());
rep.setHelpText(mapper.getHelpText()); rep.setHelpText(mapper.getHelpText());
List<ProviderConfigProperty> configProperties = mapper.getConfigProperties(); rep.setProperties(mapper.getConfigProperties().stream()
for (ProviderConfigProperty prop : configProperties) { .map(ModelToRepresentation::toRepresentation)
ConfigPropertyRepresentation propRep = ModelToRepresentation.toRepresentation(prop); .collect(Collectors.toList()));
rep.getProperties().add(propRep); return rep;
} })
types.put(rep.getId(), rep); .findFirst()
break; .orElse(null))
} .filter(Objects::nonNull)
} .collect(Collectors.toMap(IdentityProviderMapperTypeRepresentation::getId, Function.identity()));
}
return types;
} }
/** /**
@ -470,9 +465,4 @@ public class IdentityProviderResource {
return new ManagementPermissionReference(); return new ManagementPermissionReference();
} }
} }
} }

View file

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

View file

@ -22,12 +22,13 @@ import static org.keycloak.util.JsonSerialization.readValue;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import javax.ws.rs.BadRequestException; import javax.ws.rs.BadRequestException;
@ -90,7 +91,6 @@ import org.keycloak.models.utils.RepresentationToModel;
import org.keycloak.models.utils.StripSecretsUtils; import org.keycloak.models.utils.StripSecretsUtils;
import org.keycloak.partialimport.PartialImportManager; import org.keycloak.partialimport.PartialImportManager;
import org.keycloak.protocol.oidc.TokenManager; import org.keycloak.protocol.oidc.TokenManager;
import org.keycloak.provider.ProviderFactory;
import org.keycloak.representations.adapters.action.GlobalRequestResult; import org.keycloak.representations.adapters.action.GlobalRequestResult;
import org.keycloak.representations.idm.AdminEventRepresentation; import org.keycloak.representations.idm.AdminEventRepresentation;
import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.ClientRepresentation;
@ -164,13 +164,12 @@ public class RealmAdminResource {
throw new NotFoundException("Realm not found."); throw new NotFoundException("Realm not found.");
} }
for (ProviderFactory<ClientDescriptionConverter> factory : session.getKeycloakSessionFactory().getProviderFactories(ClientDescriptionConverter.class)) { return session.getKeycloakSessionFactory().getProviderFactoriesStream(ClientDescriptionConverter.class)
if (((ClientDescriptionConverterFactory) factory).isSupported(description)) { .map(ClientDescriptionConverterFactory.class::cast)
return factory.create(session).convertToInternal(description); .filter(factory -> factory.isSupported(description))
} .map(factory -> factory.create(session).convertToInternal(description))
} .findFirst()
.orElseThrow(() -> new BadRequestException("Unsupported format"));
throw new BadRequestException("Unsupported format");
} }
/** /**
@ -672,12 +671,11 @@ public class RealmAdminResource {
RealmEventsConfigRepresentation config = ModelToRepresentation.toEventsConfigReprensetation(realm); RealmEventsConfigRepresentation config = ModelToRepresentation.toEventsConfigReprensetation(realm);
if (config.getEnabledEventTypes() == null || config.getEnabledEventTypes().isEmpty()) { if (config.getEnabledEventTypes() == null || config.getEnabledEventTypes().isEmpty()) {
config.setEnabledEventTypes(new LinkedList<String>()); List<String> eventTypes = Arrays.stream(EventType.values())
for (EventType e : EventType.values()) { .filter(EventType::isSaveByDefault)
if (e.isSaveByDefault()) { .map(EventType::name)
config.getEnabledEventTypes().add(e.name()); .collect(Collectors.toList());
} config.setEnabledEventTypes(eventTypes);
}
} }
return config; return config;
} }
@ -1200,7 +1198,7 @@ public class RealmAdminResource {
public Stream<String> getCredentialRegistrators(){ public Stream<String> getCredentialRegistrators(){
auth.realm().requireViewRealm(); auth.realm().requireViewRealm();
return session.getContext().getRealm().getRequiredActionProvidersStream() return session.getContext().getRealm().getRequiredActionProvidersStream()
.filter(ra -> ra.isEnabled()) .filter(RequiredActionProviderModel::isEnabled)
.map(RequiredActionProviderModel::getProviderId) .map(RequiredActionProviderModel::getProviderId)
.filter(providerId -> session.getProvider(RequiredActionProvider.class, providerId) instanceof CredentialRegistrator); .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 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.InputPart;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput; import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
@ -35,6 +30,8 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.HashMap;
import java.util.stream.Stream;
import javax.ws.rs.BadRequestException; import javax.ws.rs.BadRequestException;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
@ -132,13 +129,10 @@ public class RealmLocalizationResource {
@GET @GET
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public List<String> getRealmLocalizationLocales() { public Stream<String> getRealmLocalizationLocales() {
this.auth.realm().requireViewRealm(); this.auth.realm().requireViewRealm();
List<String> realmLocalesList = new ArrayList<>(realm.getRealmLocalizationTexts().keySet()); return realm.getRealmLocalizationTexts().keySet().stream().sorted();
Collections.sort(realmLocalesList);
return realmLocalesList;
} }
@Path("{locale}") @Path("{locale}")

View file

@ -25,7 +25,6 @@ import org.keycloak.models.ClientModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.policy.PasswordPolicyNotMetException; import org.keycloak.policy.PasswordPolicyNotMetException;
import org.keycloak.protocol.oidc.TokenManager; 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.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.net.URI; import java.net.URI;
import java.util.*; import java.util.Arrays;
import java.util.Objects;
import java.util.stream.Stream; import java.util.stream.Stream;
import static org.keycloak.utils.StreamsUtil.throwIfEmpty; import static org.keycloak.utils.StreamsUtil.throwIfEmpty;
@ -150,12 +150,10 @@ public class RealmsAdminResource {
return; return;
} }
RealmModel adminRealm = new RealmManager(session).getKeycloakAdminstrationRealm();
ClientModel realmAdminApp = realm.getMasterAdminClient(); ClientModel realmAdminApp = realm.getMasterAdminClient();
for (String r : AdminRoles.ALL_REALM_ROLES) { Arrays.stream(AdminRoles.ALL_REALM_ROLES)
RoleModel role = realmAdminApp.getRole(r); .map(realmAdminApp::getRole)
auth.getUser().grantRole(role); .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.events.admin.ResourceType;
import org.keycloak.models.ClientModel; import org.keycloak.models.ClientModel;
import org.keycloak.models.Constants; import org.keycloak.models.Constants;
import org.keycloak.models.GroupModel;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleContainerModel; import org.keycloak.models.RoleContainerModel;
import org.keycloak.models.RoleModel; import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.representations.idm.GroupRepresentation; import org.keycloak.representations.idm.GroupRepresentation;
import org.keycloak.representations.idm.ManagementPermissionReference; import org.keycloak.representations.idm.ManagementPermissionReference;
@ -54,10 +52,8 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.UriInfo;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Stream; import java.util.stream.Stream;

View file

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

View file

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

View file

@ -27,7 +27,6 @@ import org.keycloak.events.EventType;
import org.keycloak.events.admin.OperationType; import org.keycloak.events.admin.OperationType;
import org.keycloak.events.admin.ResourceType; import org.keycloak.events.admin.ResourceType;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.utils.ModelToRepresentation; import org.keycloak.models.utils.ModelToRepresentation;
import org.keycloak.policy.PasswordPolicyProvider; import org.keycloak.policy.PasswordPolicyProvider;
import org.keycloak.policy.PasswordPolicyProviderFactory; import org.keycloak.policy.PasswordPolicyProviderFactory;
@ -41,7 +40,6 @@ import org.keycloak.provider.ProviderFactory;
import org.keycloak.provider.ServerInfoAwareProviderFactory; import org.keycloak.provider.ServerInfoAwareProviderFactory;
import org.keycloak.provider.Spi; import org.keycloak.provider.Spi;
import org.keycloak.representations.idm.ComponentTypeRepresentation; import org.keycloak.representations.idm.ComponentTypeRepresentation;
import org.keycloak.representations.idm.ConfigPropertyRepresentation;
import org.keycloak.representations.idm.PasswordPolicyTypeRepresentation; import org.keycloak.representations.idm.PasswordPolicyTypeRepresentation;
import org.keycloak.representations.idm.ProtocolMapperRepresentation; import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.ProtocolMapperTypeRepresentation; 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.Context;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
@ -68,6 +67,8 @@ import java.util.LinkedHashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/** /**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a> * @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
@ -163,7 +164,7 @@ public class ServerInfoAdminResource {
} }
private void setThemes(ServerInfoRepresentation info) { private void setThemes(ServerInfoRepresentation info) {
info.setThemes(new HashMap<String, List<ThemeInfoRepresentation>>()); info.setThemes(new HashMap<>());
for (Theme.Type type : Theme.Type.values()) { for (Theme.Type type : Theme.Type.values()) {
List<String> themeNames = new LinkedList<>(session.theme().nameSet(type)); List<String> themeNames = new LinkedList<>(session.theme().nameSet(type));
@ -197,99 +198,123 @@ public class ServerInfoAdminResource {
} }
private void setSocialProviders(ServerInfoRepresentation info) { private void setSocialProviders(ServerInfoRepresentation info) {
info.setSocialProviders(new LinkedList<Map<String, String>>()); info.setSocialProviders(new LinkedList<>());
List<ProviderFactory> providerFactories = session.getKeycloakSessionFactory().getProviderFactories(SocialIdentityProvider.class); Stream<ProviderFactory> providerFactories = session.getKeycloakSessionFactory().getProviderFactoriesStream(SocialIdentityProvider.class);
setIdentityProviders(providerFactories, info.getSocialProviders(), "Social"); setIdentityProviders(providerFactories, info.getSocialProviders(), "Social");
} }
private void setIdentityProviders(ServerInfoRepresentation info) { private void setIdentityProviders(ServerInfoRepresentation info) {
info.setIdentityProviders(new LinkedList<Map<String, String>>()); info.setIdentityProviders(new LinkedList<>());
List<ProviderFactory> providerFactories = session.getKeycloakSessionFactory().getProviderFactories(IdentityProvider.class); Stream<ProviderFactory> providerFactories = session.getKeycloakSessionFactory().getProviderFactoriesStream(IdentityProvider.class);
setIdentityProviders(providerFactories, info.getIdentityProviders(), "User-defined"); setIdentityProviders(providerFactories, info.getIdentityProviders(), "User-defined");
providerFactories = session.getKeycloakSessionFactory().getProviderFactories(SocialIdentityProvider.class); providerFactories = session.getKeycloakSessionFactory().getProviderFactoriesStream(SocialIdentityProvider.class);
setIdentityProviders(providerFactories, info.getIdentityProviders(), "Social"); setIdentityProviders(providerFactories, info.getIdentityProviders(), "Social");
} }
public void setIdentityProviders(List<ProviderFactory> factories, List<Map<String, String>> providers, String groupName) { public void setIdentityProviders(Stream<ProviderFactory> factories, List<Map<String, String>> providers, String groupName) {
for (ProviderFactory providerFactory : factories) { List<Map<String, String>> providerMaps = factories
IdentityProviderFactory factory = (IdentityProviderFactory) providerFactory; .map(IdentityProviderFactory.class::cast)
Map<String, String> data = new HashMap<>(); .map(factory -> {
data.put("groupName", groupName); Map<String, String> data = new HashMap<>();
data.put("name", factory.getName()); data.put("groupName", groupName);
data.put("id", factory.getId()); 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) { private void setClientInstallations(ServerInfoRepresentation info) {
info.setClientInstallations(new HashMap<String, List<ClientInstallationRepresentation>>()); HashMap<String, List<ClientInstallationRepresentation>> clientInstallations = session.getKeycloakSessionFactory()
for (ProviderFactory p : session.getKeycloakSessionFactory().getProviderFactories(ClientInstallationProvider.class)) { .getProviderFactoriesStream(ClientInstallationProvider.class)
ClientInstallationProvider provider = (ClientInstallationProvider)p; .map(ClientInstallationProvider.class::cast)
List<ClientInstallationRepresentation> types = info.getClientInstallations().get(provider.getProtocol()); .collect(
if (types == null) { Collectors.toMap(
types = new LinkedList<>(); ClientInstallationProvider::getProtocol,
info.getClientInstallations().put(provider.getProtocol(), types); this::toClientInstallationRepresentation,
} (l1, l2) -> listCombiner(l1, l2),
ClientInstallationRepresentation rep = new ClientInstallationRepresentation(); HashMap::new
rep.setId(p.getId()); )
rep.setHelpText(provider.getHelpText()); );
rep.setDisplayType( provider.getDisplayType()); info.setClientInstallations(clientInstallations);
rep.setProtocol( provider.getProtocol());
rep.setDownloadOnly( provider.isDownloadOnly());
rep.setFilename(provider.getFilename());
rep.setMediaType(provider.getMediaType());
types.add(rep);
}
} }
private void setProtocolMapperTypes(ServerInfoRepresentation info) { private void setProtocolMapperTypes(ServerInfoRepresentation info) {
info.setProtocolMapperTypes(new HashMap<String, List<ProtocolMapperTypeRepresentation>>()); HashMap<String, List<ProtocolMapperTypeRepresentation>> protocolMappers = session.getKeycloakSessionFactory()
for (ProviderFactory p : session.getKeycloakSessionFactory().getProviderFactories(ProtocolMapper.class)) { .getProviderFactoriesStream(ProtocolMapper.class)
ProtocolMapper mapper = (ProtocolMapper)p; .map(ProtocolMapper.class::cast)
List<ProtocolMapperTypeRepresentation> types = info.getProtocolMapperTypes().get(mapper.getProtocol()); .collect(
if (types == null) { Collectors.toMap(
types = new LinkedList<>(); ProtocolMapper::getProtocol,
info.getProtocolMapperTypes().put(mapper.getProtocol(), types); this::toProtocolMapperTypeRepresentation,
} (l1, l2) -> listCombiner(l1, l2),
ProtocolMapperTypeRepresentation rep = new ProtocolMapperTypeRepresentation(); HashMap::new
rep.setId(mapper.getId()); )
rep.setName(mapper.getDisplayType()); );
rep.setHelpText(mapper.getHelpText()); info.setProtocolMapperTypes(protocolMappers);
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);
}
} }
private void setBuiltinProtocolMappers(ServerInfoRepresentation info) { private void setBuiltinProtocolMappers(ServerInfoRepresentation info) {
info.setBuiltinProtocolMappers(new HashMap<String, List<ProtocolMapperRepresentation>>()); Map<String, List<ProtocolMapperRepresentation>> protocolMappers = session.getKeycloakSessionFactory()
for (ProviderFactory p : session.getKeycloakSessionFactory().getProviderFactories(LoginProtocol.class)) { .getProviderFactoriesStream(LoginProtocol.class)
LoginProtocolFactory factory = (LoginProtocolFactory)p; .collect(Collectors.toMap(
List<ProtocolMapperRepresentation> mappers = new LinkedList<>(); p -> p.getId(),
for (ProtocolMapperModel mapper : factory.getBuiltinMappers().values()) { p -> {
mappers.add(ModelToRepresentation.toRepresentation(mapper)); LoginProtocolFactory factory = (LoginProtocolFactory) p;
} return factory.getBuiltinMappers().values().stream()
info.getBuiltinProtocolMappers().put(p.getId(), mappers); .map(ModelToRepresentation::toRepresentation)
} .collect(Collectors.toList());
})
);
info.setBuiltinProtocolMappers(protocolMappers);
} }
private void setPasswordPolicies(ServerInfoRepresentation info) { private void setPasswordPolicies(ServerInfoRepresentation info) {
info.setPasswordPolicies(new LinkedList<>()); List<PasswordPolicyTypeRepresentation> passwordPolicyTypes= session.getKeycloakSessionFactory().getProviderFactoriesStream(PasswordPolicyProvider.class)
for (ProviderFactory f : session.getKeycloakSessionFactory().getProviderFactories(PasswordPolicyProvider.class)) { .map(PasswordPolicyProviderFactory.class::cast)
PasswordPolicyProviderFactory factory = (PasswordPolicyProviderFactory) f; .map(factory -> {
PasswordPolicyTypeRepresentation rep = new PasswordPolicyTypeRepresentation(); PasswordPolicyTypeRepresentation rep = new PasswordPolicyTypeRepresentation();
rep.setId(factory.getId()); rep.setId(factory.getId());
rep.setDisplayName(factory.getDisplayName()); rep.setDisplayName(factory.getDisplayName());
rep.setConfigType(factory.getConfigType()); rep.setConfigType(factory.getConfigType());
rep.setDefaultValue(factory.getDefaultConfigValue()); rep.setDefaultValue(factory.getDefaultConfigValue());
rep.setMultipleSupported(factory.isMultiplSupported()); rep.setMultipleSupported(factory.isMultiplSupported());
info.getPasswordPolicies().add(rep); 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) { 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.KeycloakSessionFactory;
import org.keycloak.models.KeycloakTransaction; import org.keycloak.models.KeycloakTransaction;
import org.keycloak.provider.ExceptionConverter; import org.keycloak.provider.ExceptionConverter;
import org.keycloak.provider.ProviderFactory;
import javax.transaction.RollbackException; import javax.transaction.RollbackException;
import javax.transaction.Status; import javax.transaction.Status;
import javax.transaction.Transaction; import javax.transaction.Transaction;
import javax.transaction.TransactionManager; import javax.transaction.TransactionManager;
import java.util.Objects;
/** /**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -59,26 +59,24 @@ public class JtaTransactionWrapper implements KeycloakTransaction {
if (e instanceof RollbackException) { if (e instanceof RollbackException) {
e = e.getCause() != null ? e.getCause() : e; e = e.getCause() != null ? e.getCause() : e;
} }
final Throwable finalE = e;
for (ProviderFactory factory : this.factory.getProviderFactories(ExceptionConverter.class)) { factory.getProviderFactoriesStream(ExceptionConverter.class)
ExceptionConverter converter = (ExceptionConverter)factory; .map(factory -> ((ExceptionConverter) factory).convert(finalE))
Throwable throwable = converter.convert(e); .filter(Objects::nonNull)
if (throwable == null) continue; .forEach(throwable -> {
if (throwable instanceof RuntimeException) { if (throwable instanceof RuntimeException) {
throw (RuntimeException)throwable; throw (RuntimeException)throwable;
} else { } else {
throw new RuntimeException(throwable); throw new RuntimeException(throwable);
} }
} });
if (e instanceof RuntimeException) { if (e instanceof RuntimeException) {
throw (RuntimeException)e; throw (RuntimeException)e;
} else { } else {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
@Override @Override

View file

@ -389,7 +389,7 @@ public class UserMapStorage implements UserLookupProvider.Streams, UserStoragePr
} }
@Override @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) Stream<String> userStream = paginatedStream(userGroups.entrySet().stream(), firstResult, max)
.filter(me -> me.getValue().contains(group.getId())) .filter(me -> me.getValue().contains(group.getId()))
.map(Map.Entry::getKey) .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.UserLookupProvider;
import org.keycloak.storage.user.UserQueryProvider; 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.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Properties; import java.util.Properties;

View file

@ -131,7 +131,7 @@ public class ApiUtil {
public static UserRepresentation findUserByUsername(RealmResource realm, String username) { public static UserRepresentation findUserByUsername(RealmResource realm, String username) {
UserRepresentation user = null; 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) { if (ur.size() == 1) {
user = ur.get(0); 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. // Workaround for KEYCLOAK-3104. For this realm, search() only works if username is null.
private static UserRepresentation findByUsername(RealmResource realmRsc, String username) { 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; if (user.getUsername().equalsIgnoreCase(username)) return user;
} }
return null; return null;

View file

@ -287,13 +287,13 @@ public abstract class AbstractKerberosTest extends AbstractAuthTest {
protected void removeAllUsers() { protected void removeAllUsers() {
RealmResource realm = testRealmResource(); 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) { for (UserRepresentation user : users) {
if (!user.getUsername().equals(AssertEvents.DEFAULT_USERNAME)) { if (!user.getUsername().equals(AssertEvents.DEFAULT_USERNAME)) {
realm.users().get(user.getId()).remove(); 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")); Assert.assertTrue(usernames.contains("danny"));
// test searchForUser // 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, hasSize(1));
assertThat(users.get(0).getUsername(), equalTo("tbrady")); assertThat(users.get(0).getUsername(), equalTo("tbrady"));

View file

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

View file

@ -221,7 +221,7 @@ public class ManyUsersTest extends AbstractUserTest {
realmTimer.reset("re-import realm with " + realm.getUsers().size() + " users"); realmTimer.reset("re-import realm with " + realm.getUsers().size() + " users");
realmsResouce().create(realm); realmsResouce().create(realm);
realmTimer.reset("load " + realm.getUsers().size() + " users"); 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.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.KeycloakSessionFactory;
@ -124,7 +125,9 @@ public class LoadPersistentSessionsCommand extends AbstractCommand {
int offset = workerId * limit; int offset = workerId * limit;
UserSessionPersisterProvider persister = keycloakSession.getProvider(UserSessionPersisterProvider.class); 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());
}); });
} }