diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java index 3195d5f288e..ea1dd01d5e4 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/UserCacheSession.java @@ -65,6 +65,7 @@ import org.keycloak.storage.UserStorageProvider; import org.keycloak.storage.UserStorageProviderModel; import org.keycloak.storage.client.ClientStorageProvider; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -681,13 +682,35 @@ public class UserCacheSession implements UserCache, OnCreateComponent, OnUpdateC CachedUserConsents cached = cache.get(cacheKey, CachedUserConsents.class); if (cached == null) { + UserConsentModel consent = getDelegate().getConsentByClient(realm, userId, clientId); + List consents; + + if (consent == null) { + consents = Collections.singletonList(new CachedUserConsent(clientId)); + } else { + consents = Collections.singletonList(new CachedUserConsent(consent)); + } + Long loaded = cache.getCurrentRevision(cacheKey); - List consents = getDelegate().getConsentsStream(realm, userId).collect(Collectors.toList()); - cached = new CachedUserConsents(loaded, cacheKey, realm, consents); + cached = new CachedUserConsents(loaded, cacheKey, realm, consents, false); cache.addRevisioned(cached, startupRevision); } - CachedUserConsent cachedConsent = cached.getConsents().get(clientId); - if (cachedConsent == null) return null; + + Map consents = cached.getConsents(); + CachedUserConsent cachedConsent = consents.get(clientId); + + if (cachedConsent == null) { + UserConsentModel consent = getDelegate().getConsentByClient(realm, userId, clientId); + + if (consent == null) { + cachedConsent = new CachedUserConsent(clientId); + } else { + cachedConsent = new CachedUserConsent(consent); + } + + consents.put(cachedConsent.getClientDbId(), cachedConsent); + } + return toConsentModel(realm, cachedConsent); } @@ -702,10 +725,15 @@ public class UserCacheSession implements UserCache, OnCreateComponent, OnUpdateC CachedUserConsents cached = cache.get(cacheKey, CachedUserConsents.class); + if (cached != null && !cached.isAllConsents()) { + cached = null; + cache.invalidateObject(cacheKey); + } + if (cached == null) { Long loaded = cache.getCurrentRevision(cacheKey); List consents = getDelegate().getConsentsStream(realm, userId).collect(Collectors.toList()); - cached = new CachedUserConsents(loaded, cacheKey, realm, consents); + cached = new CachedUserConsents(loaded, cacheKey, realm, consents.stream().map(CachedUserConsent::new).collect(Collectors.toList())); cache.addRevisioned(cached, startupRevision); return consents.stream(); } else { @@ -715,6 +743,10 @@ public class UserCacheSession implements UserCache, OnCreateComponent, OnUpdateC } private UserConsentModel toConsentModel(RealmModel realm, CachedUserConsent cachedConsent) { + if (cachedConsent.isNotExistent()) { + return null; + } + ClientModel client = session.clients().getClientById(realm, cachedConsent.getClientDbId()); if (client == null) { return null; diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUserConsent.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUserConsent.java index fa418cb8ad1..669f35bb6db 100644 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUserConsent.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUserConsent.java @@ -32,6 +32,7 @@ public class CachedUserConsent { private final Set clientScopeIds = new HashSet<>(); private final Long createdDate; private final Long lastUpdatedDate; + private boolean notExistent; public CachedUserConsent(UserConsentModel consentModel) { this.clientDbId = consentModel.getClient().getId(); @@ -42,6 +43,13 @@ public class CachedUserConsent { this.lastUpdatedDate = consentModel.getLastUpdatedDate(); } + public CachedUserConsent(String clientDbId) { + this.clientDbId = clientDbId; + this.createdDate = null; + this.lastUpdatedDate = null; + this.notExistent = true; + } + public String getClientDbId() { return clientDbId; } @@ -57,4 +65,8 @@ public class CachedUserConsent { public Long getLastUpdatedDate() { return lastUpdatedDate; } + + public boolean isNotExistent() { + return notExistent; + } } diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUserConsents.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUserConsents.java index eaca957688b..c482abdad7a 100644 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUserConsents.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/entities/CachedUserConsents.java @@ -29,14 +29,21 @@ import java.util.List; public class CachedUserConsents extends AbstractRevisioned implements InRealm { private HashMap consents = new HashMap<>(); private final String realmId; + private boolean allConsents; public CachedUserConsents(Long revision, String id, RealmModel realm, - List consents) { + List consents) { + this(revision, id, realm, consents, true); + } + + public CachedUserConsents(Long revision, String id, RealmModel realm, + List consents, boolean allConsents) { super(revision, id); this.realmId = realm.getId(); + this.allConsents = allConsents; if (consents != null) { - for (UserConsentModel consent : consents) { - this.consents.put(consent.getClient().getId(), new CachedUserConsent(consent)); + for (CachedUserConsent consent : consents) { + this.consents.put(consent.getClientDbId(), consent); } } } @@ -50,4 +57,8 @@ public class CachedUserConsents extends AbstractRevisioned implements InRealm { public HashMap getConsents() { return consents; } + + public boolean isAllConsents() { + return allConsents; + } }