Reuse already fixed code to fetch offline user (#22429)
The problem is again the wrap(...) function. In case the user is not found, then null is returned. This can happen when a federated user is deleted on the federation side but Keycloak is not informed about it. In that case, the session is still present but no UserModel can be created. Without this patch the stream contains null values. Some downstream users can not cope well with that. The adjustment of the function getUserSessionsCount(...) is slightly more expensive in execution, but returns the correct number. Closes #22428 Co-authored-by: Martin Krüger <mkrueger@mkru.de>
This commit is contained in:
parent
47d9ae71c4
commit
498be3d928
1 changed files with 26 additions and 39 deletions
|
@ -65,6 +65,7 @@ import org.keycloak.models.sessions.infinispan.util.SessionTimeouts;
|
|||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
@ -331,9 +332,13 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
|
|||
private UserSessionEntity getUserSessionEntity(RealmModel realm, String id, boolean offline) {
|
||||
InfinispanChangelogBasedTransaction<String, UserSessionEntity> tx = getTransaction(offline);
|
||||
SessionEntityWrapper<UserSessionEntity> entityWrapper = tx.get(id);
|
||||
if (entityWrapper==null) return null;
|
||||
if (entityWrapper == null) {
|
||||
return null;
|
||||
}
|
||||
UserSessionEntity entity = entityWrapper.getEntity();
|
||||
if (!entity.getRealmId().equals(realm.getId())) return null;
|
||||
if (!entity.getRealmId().equals(realm.getId())) {
|
||||
return null;
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
@ -472,23 +477,10 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
|
|||
return persister.loadUserSessionsStream(realm, client, true, firstResult, maxResults);
|
||||
}
|
||||
|
||||
final String clientUuid = client.getId();
|
||||
UserSessionPredicate predicate = UserSessionPredicate.create(realm.getId()).client(clientUuid);
|
||||
UserSessionPredicate predicate = UserSessionPredicate.create(realm.getId()).client(client.getId());
|
||||
|
||||
return getUserSessionModels(realm, firstResult, maxResults, offline, predicate);
|
||||
}
|
||||
|
||||
protected Stream<UserSessionModel> getUserSessionModels(RealmModel realm, Integer firstResult, Integer maxResults, boolean offline, UserSessionPredicate predicate) {
|
||||
Cache<String, SessionEntityWrapper<UserSessionEntity>> cache = getCache(offline);
|
||||
cache = CacheDecorators.skipCacheLoaders(cache);
|
||||
|
||||
// return a stream that 'wraps' the infinispan cache stream so that the cache stream's elements are read one by one
|
||||
// and then filtered/mapped locally to avoid serialization issues when trying to manipulate the cache stream directly.
|
||||
Stream<UserSessionEntity> stream = StreamSupport.stream(cache.entrySet().stream().filter(predicate).spliterator(), false)
|
||||
.map(Mappers.userSessionEntity())
|
||||
.sorted(Comparators.userSessionLastSessionRefresh());
|
||||
|
||||
return paginatedStream(stream, firstResult, maxResults).map(entity -> this.wrap(realm, entity, offline));
|
||||
return paginatedStream(getUserSessionsStream(realm, predicate, offline)
|
||||
.sorted(Comparator.comparing(UserSessionModel::getLastSessionRefresh)), firstResult, maxResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -587,14 +579,7 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
|
|||
return persister.getUserSessionsCount(realm, client, true);
|
||||
}
|
||||
|
||||
Cache<String, SessionEntityWrapper<UserSessionEntity>> cache = getCache(offline);
|
||||
cache = CacheDecorators.skipCacheLoaders(cache);
|
||||
|
||||
final String clientUuid = client.getId();
|
||||
|
||||
return cache.entrySet().stream()
|
||||
.filter(UserSessionPredicate.create(realm.getId()).client(clientUuid))
|
||||
.count();
|
||||
return getUserSessionsStream(realm, UserSessionPredicate.create(realm.getId()).client(client.getId()), offline).count();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -775,7 +760,9 @@ public class InfinispanUserSessionProvider implements UserSessionProvider {
|
|||
|
||||
UserSessionEntity getUserSessionEntity(RealmModel realm, UserSessionModel userSession, boolean offline) {
|
||||
if (userSession instanceof UserSessionAdapter) {
|
||||
if (!userSession.getRealm().equals(realm)) return null;
|
||||
if (!userSession.getRealm().equals(realm)) {
|
||||
return null;
|
||||
}
|
||||
return ((UserSessionAdapter) userSession).getEntity();
|
||||
} else {
|
||||
return getUserSessionEntity(realm, userSession.getId(), offline);
|
||||
|
|
Loading…
Reference in a new issue