From 8beff63dc0ab8880fecc2ef761a29f5f4f84b9b5 Mon Sep 17 00:00:00 2001 From: Bill Burke Date: Mon, 4 Apr 2016 21:12:55 -0400 Subject: [PATCH] KEYCLOAK-2669 --- .../cache/infinispan/ClientAdapter.java | 98 +++++---- .../infinispan/ClientTemplateAdapter.java | 58 +++-- .../models/cache/infinispan/GroupAdapter.java | 42 ++-- .../models/cache/infinispan/RealmAdapter.java | 198 ++++++++++-------- .../cache/infinispan/RealmCacheSession.java | 91 ++++++-- .../models/cache/infinispan/RoleAdapter.java | 35 +++- .../infinispan/stream/HasRolePredicate.java | 6 + .../testsuite/model/ClientModelTest.java | 72 +++++++ 8 files changed, 402 insertions(+), 198 deletions(-) diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientAdapter.java index 2094fa2329..85fd17aba5 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientAdapter.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientAdapter.java @@ -28,14 +28,14 @@ import java.util.*; * @version $Revision: 1 $ */ public class ClientAdapter implements ClientModel { - protected CacheRealmProvider cacheSession; + protected RealmCacheSession cacheSession; protected RealmModel cachedRealm; protected RealmCache cache; protected ClientModel updated; protected CachedClient cached; - public ClientAdapter(RealmModel cachedRealm, CachedClient cached, CacheRealmProvider cacheSession, RealmCache cache) { + public ClientAdapter(RealmModel cachedRealm, CachedClient cached, RealmCacheSession cacheSession, RealmCache cache) { this.cachedRealm = cachedRealm; this.cache = cache; this.cacheSession = cacheSession; @@ -44,11 +44,23 @@ public class ClientAdapter implements ClientModel { private void getDelegateForUpdate() { if (updated == null) { - cacheSession.registerClientInvalidation(getId()); - updated = cacheSession.getDelegate().getClientById(getId(), cachedRealm); + cacheSession.registerClientInvalidation(cached.getId()); + updated = cacheSession.getDelegate().getClientById(cached.getId(), cachedRealm); if (updated == null) throw new IllegalStateException("Not found in database"); } } + protected boolean invalidated; + public void invalidate() { + invalidated = true; + } + + protected boolean isUpdated() { + if (updated != null) return true; + if (!invalidated) return false; + updated = cacheSession.getDelegate().getClientById(cached.getId(), cachedRealm); + if (updated == null) throw new IllegalStateException("Not found in database"); + return true; + } @Override public void updateClient() { @@ -57,12 +69,12 @@ public class ClientAdapter implements ClientModel { @Override public String getId() { - if (updated != null) return updated.getId(); + if (isUpdated()) return updated.getId(); return cached.getId(); } public Set getWebOrigins() { - if (updated != null) return updated.getWebOrigins(); + if (isUpdated()) return updated.getWebOrigins(); return cached.getWebOrigins(); } @@ -73,7 +85,7 @@ public class ClientAdapter implements ClientModel { @Override public ClientTemplateModel getClientTemplate() { - if (updated != null) return updated.getClientTemplate(); + if (isUpdated()) return updated.getClientTemplate(); if (cached.getClientTemplate() == null) return null; return cacheSession.getClientTemplateById(cached.getClientTemplate(), cachedRealm); } @@ -87,7 +99,7 @@ public class ClientAdapter implements ClientModel { @Override public boolean useTemplateScope() { - if (updated != null) return updated.useTemplateScope(); + if (isUpdated()) return updated.useTemplateScope(); return cached.isUseTemplateScope(); } @@ -100,7 +112,7 @@ public class ClientAdapter implements ClientModel { @Override public boolean useTemplateConfig() { - if (updated != null) return updated.useTemplateConfig(); + if (isUpdated()) return updated.useTemplateConfig(); return cached.isUseTemplateConfig(); } @@ -113,7 +125,7 @@ public class ClientAdapter implements ClientModel { @Override public boolean useTemplateMappers() { - if (updated != null) return updated.useTemplateMappers(); + if (isUpdated()) return updated.useTemplateMappers(); return cached.isUseTemplateMappers(); } @@ -137,7 +149,7 @@ public class ClientAdapter implements ClientModel { } public Set getRedirectUris() { - if (updated != null) return updated.getRedirectUris(); + if (isUpdated()) return updated.getRedirectUris(); return cached.getRedirectUris(); } @@ -157,7 +169,7 @@ public class ClientAdapter implements ClientModel { } public boolean isEnabled() { - if (updated != null) return updated.isEnabled(); + if (isUpdated()) return updated.isEnabled(); return cached.isEnabled(); } @@ -168,7 +180,7 @@ public class ClientAdapter implements ClientModel { @Override public String getClientAuthenticatorType() { - if (updated != null) return updated.getClientAuthenticatorType(); + if (isUpdated()) return updated.getClientAuthenticatorType(); return cached.getClientAuthenticatorType(); } @@ -183,7 +195,7 @@ public class ClientAdapter implements ClientModel { } public String getSecret() { - if (updated != null) return updated.getSecret(); + if (isUpdated()) return updated.getSecret(); return cached.getSecret(); } @@ -192,7 +204,7 @@ public class ClientAdapter implements ClientModel { updated.setSecret(secret); } public String getRegistrationToken() { - if (updated != null) return updated.getRegistrationToken(); + if (isUpdated()) return updated.getRegistrationToken(); return cached.getRegistrationToken(); } @@ -202,7 +214,7 @@ public class ClientAdapter implements ClientModel { } public boolean isPublicClient() { - if (updated != null) return updated.isPublicClient(); + if (isUpdated()) return updated.isPublicClient(); return cached.isPublicClient(); } @@ -212,7 +224,7 @@ public class ClientAdapter implements ClientModel { } public boolean isFrontchannelLogout() { - if (updated != null) return updated.isPublicClient(); + if (isUpdated()) return updated.isPublicClient(); return cached.isFrontchannelLogout(); } @@ -223,7 +235,7 @@ public class ClientAdapter implements ClientModel { @Override public boolean isFullScopeAllowed() { - if (updated != null) return updated.isFullScopeAllowed(); + if (isUpdated()) return updated.isFullScopeAllowed(); return cached.isFullScopeAllowed(); } @@ -235,7 +247,7 @@ public class ClientAdapter implements ClientModel { } public Set getScopeMappings() { - if (updated != null) return updated.getScopeMappings(); + if (isUpdated()) return updated.getScopeMappings(); Set roles = new HashSet(); for (String id : cached.getScope()) { roles.add(cacheSession.getRoleById(id, getRealm())); @@ -275,7 +287,7 @@ public class ClientAdapter implements ClientModel { } public int getNotBefore() { - if (updated != null) return updated.getNotBefore(); + if (isUpdated()) return updated.getNotBefore(); return cached.getNotBefore(); } @@ -286,7 +298,7 @@ public class ClientAdapter implements ClientModel { @Override public String getProtocol() { - if (updated != null) return updated.getProtocol(); + if (isUpdated()) return updated.getProtocol(); return cached.getProtocol(); } @@ -312,13 +324,13 @@ public class ClientAdapter implements ClientModel { @Override public String getAttribute(String name) { - if (updated != null) return updated.getAttribute(name); + if (isUpdated()) return updated.getAttribute(name); return cached.getAttributes().get(name); } @Override public Map getAttributes() { - if (updated != null) return updated.getAttributes(); + if (isUpdated()) return updated.getAttributes(); Map copy = new HashMap(); copy.putAll(cached.getAttributes()); return copy; @@ -326,7 +338,7 @@ public class ClientAdapter implements ClientModel { @Override public Set getProtocolMappers() { - if (updated != null) return updated.getProtocolMappers(); + if (isUpdated()) return updated.getProtocolMappers(); return cached.getProtocolMappers(); } @@ -368,7 +380,7 @@ public class ClientAdapter implements ClientModel { @Override public String getClientId() { - if (updated != null) return updated.getClientId(); + if (isUpdated()) return updated.getClientId(); return cached.getClientId(); } @@ -380,7 +392,7 @@ public class ClientAdapter implements ClientModel { @Override public String getName() { - if (updated != null) return updated.getName(); + if (isUpdated()) return updated.getName(); return cached.getName(); } @@ -392,7 +404,7 @@ public class ClientAdapter implements ClientModel { @Override public String getDescription() { - if (updated != null) return updated.getDescription(); + if (isUpdated()) return updated.getDescription(); return cached.getDescription(); } @@ -404,7 +416,7 @@ public class ClientAdapter implements ClientModel { @Override public boolean isSurrogateAuthRequired() { - if (updated != null) return updated.isSurrogateAuthRequired(); + if (isUpdated()) return updated.isSurrogateAuthRequired(); return cached.isSurrogateAuthRequired(); } @@ -416,7 +428,7 @@ public class ClientAdapter implements ClientModel { @Override public String getManagementUrl() { - if (updated != null) return updated.getManagementUrl(); + if (isUpdated()) return updated.getManagementUrl(); return cached.getManagementUrl(); } @@ -428,7 +440,7 @@ public class ClientAdapter implements ClientModel { @Override public String getRootUrl() { - if (updated != null) return updated.getRootUrl(); + if (isUpdated()) return updated.getRootUrl(); return cached.getRootUrl(); } @@ -440,7 +452,7 @@ public class ClientAdapter implements ClientModel { @Override public String getBaseUrl() { - if (updated != null) return updated.getBaseUrl(); + if (isUpdated()) return updated.getBaseUrl(); return cached.getBaseUrl(); } @@ -452,7 +464,7 @@ public class ClientAdapter implements ClientModel { @Override public List getDefaultRoles() { - if (updated != null) return updated.getDefaultRoles(); + if (isUpdated()) return updated.getDefaultRoles(); return cached.getDefaultRoles(); } @@ -477,7 +489,7 @@ public class ClientAdapter implements ClientModel { @Override public boolean isBearerOnly() { - if (updated != null) return updated.isBearerOnly(); + if (isUpdated()) return updated.isBearerOnly(); return cached.isBearerOnly(); } @@ -489,7 +501,7 @@ public class ClientAdapter implements ClientModel { @Override public boolean isConsentRequired() { - if (updated != null) return updated.isConsentRequired(); + if (isUpdated()) return updated.isConsentRequired(); return cached.isConsentRequired(); } @@ -501,7 +513,7 @@ public class ClientAdapter implements ClientModel { @Override public boolean isStandardFlowEnabled() { - if (updated != null) return updated.isStandardFlowEnabled(); + if (isUpdated()) return updated.isStandardFlowEnabled(); return cached.isStandardFlowEnabled(); } @@ -513,7 +525,7 @@ public class ClientAdapter implements ClientModel { @Override public boolean isImplicitFlowEnabled() { - if (updated != null) return updated.isImplicitFlowEnabled(); + if (isUpdated()) return updated.isImplicitFlowEnabled(); return cached.isImplicitFlowEnabled(); } @@ -525,7 +537,7 @@ public class ClientAdapter implements ClientModel { @Override public boolean isDirectAccessGrantsEnabled() { - if (updated != null) return updated.isDirectAccessGrantsEnabled(); + if (isUpdated()) return updated.isDirectAccessGrantsEnabled(); return cached.isDirectAccessGrantsEnabled(); } @@ -537,7 +549,7 @@ public class ClientAdapter implements ClientModel { @Override public boolean isServiceAccountsEnabled() { - if (updated != null) return updated.isServiceAccountsEnabled(); + if (isUpdated()) return updated.isServiceAccountsEnabled(); return cached.isServiceAccountsEnabled(); } @@ -573,9 +585,7 @@ public class ClientAdapter implements ClientModel { @Override public boolean removeRole(RoleModel role) { - cacheSession.registerRoleInvalidation(role.getId()); - getDelegateForUpdate(); - return updated.removeRole(role); + return cacheSession.removeRole(cachedRealm, role); } @Override @@ -585,7 +595,7 @@ public class ClientAdapter implements ClientModel { @Override public int getNodeReRegistrationTimeout() { - if (updated != null) return updated.getNodeReRegistrationTimeout(); + if (isUpdated()) return updated.getNodeReRegistrationTimeout(); return cached.getNodeReRegistrationTimeout(); } @@ -597,7 +607,7 @@ public class ClientAdapter implements ClientModel { @Override public Map getRegisteredNodes() { - if (updated != null) return updated.getRegisteredNodes(); + if (isUpdated()) return updated.getRegisteredNodes(); return cached.getRegisteredNodes(); } @@ -615,7 +625,7 @@ public class ClientAdapter implements ClientModel { @Override public boolean hasScope(RoleModel role) { - if (updated != null) return updated.hasScope(role); + if (isUpdated()) return updated.hasScope(role); if (cached.isFullScopeAllowed() || cached.getScope().contains(role.getId())) return true; Set roles = getScopeMappings(); diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientTemplateAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientTemplateAdapter.java index b54738ad9f..92d178e88b 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientTemplateAdapter.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/ClientTemplateAdapter.java @@ -36,13 +36,13 @@ import java.util.Set; * @version $Revision: 1 $ */ public class ClientTemplateAdapter implements ClientTemplateModel { - protected CacheRealmProvider cacheSession; + protected RealmCacheSession cacheSession; protected RealmModel cachedRealm; protected ClientTemplateModel updated; protected CachedClientTemplate cached; - public ClientTemplateAdapter(RealmModel cachedRealm, CachedClientTemplate cached, CacheRealmProvider cacheSession) { + public ClientTemplateAdapter(RealmModel cachedRealm, CachedClientTemplate cached, RealmCacheSession cacheSession) { this.cachedRealm = cachedRealm; this.cacheSession = cacheSession; this.cached = cached; @@ -50,15 +50,29 @@ public class ClientTemplateAdapter implements ClientTemplateModel { private void getDelegateForUpdate() { if (updated == null) { - cacheSession.registerClientTemplateInvalidation(getId()); - updated = cacheSession.getDelegate().getClientTemplateById(getId(), cachedRealm); + cacheSession.registerClientTemplateInvalidation(cached.getId()); + updated = cacheSession.getDelegate().getClientTemplateById(cached.getId(), cachedRealm); if (updated == null) throw new IllegalStateException("Not found in database"); } } + protected boolean invalidated; + public void invalidate() { + invalidated = true; + } + + protected boolean isUpdated() { + if (updated != null) return true; + if (!invalidated) return false; + updated = cacheSession.getDelegate().getClientTemplateById(cached.getId(), cachedRealm); + if (updated == null) throw new IllegalStateException("Not found in database"); + return true; + } + + @Override public String getId() { - if (updated != null) return updated.getId(); + if (isUpdated()) return updated.getId(); return cached.getId(); } @@ -68,7 +82,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel { @Override public Set getProtocolMappers() { - if (updated != null) return updated.getProtocolMappers(); + if (isUpdated()) return updated.getProtocolMappers(); return cached.getProtocolMappers(); } @@ -110,7 +124,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel { @Override public String getName() { - if (updated != null) return updated.getName(); + if (isUpdated()) return updated.getName(); return cached.getName(); } @@ -122,7 +136,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel { @Override public String getDescription() { - if (updated != null) return updated.getDescription(); + if (isUpdated()) return updated.getDescription(); return cached.getDescription(); } @@ -134,7 +148,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel { @Override public String getProtocol() { - if (updated != null) return updated.getProtocol(); + if (isUpdated()) return updated.getProtocol(); return cached.getProtocol(); } @@ -146,7 +160,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel { @Override public boolean isFullScopeAllowed() { - if (updated != null) return updated.isFullScopeAllowed(); + if (isUpdated()) return updated.isFullScopeAllowed(); return cached.isFullScopeAllowed(); } @@ -158,7 +172,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel { } public Set getScopeMappings() { - if (updated != null) return updated.getScopeMappings(); + if (isUpdated()) return updated.getScopeMappings(); Set roles = new HashSet(); for (String id : cached.getScope()) { roles.add(cacheSession.getRoleById(id, getRealm())); @@ -195,7 +209,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel { @Override public boolean hasScope(RoleModel role) { - if (updated != null) return updated.hasScope(role); + if (isUpdated()) return updated.hasScope(role); if (cached.isFullScopeAllowed() || cached.getScope().contains(role.getId())) return true; Set roles = getScopeMappings(); @@ -207,7 +221,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel { } public boolean isPublicClient() { - if (updated != null) return updated.isPublicClient(); + if (isUpdated()) return updated.isPublicClient(); return cached.isPublicClient(); } @@ -217,7 +231,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel { } public boolean isFrontchannelLogout() { - if (updated != null) return updated.isPublicClient(); + if (isUpdated()) return updated.isPublicClient(); return cached.isFrontchannelLogout(); } @@ -242,13 +256,13 @@ public class ClientTemplateAdapter implements ClientTemplateModel { @Override public String getAttribute(String name) { - if (updated != null) return updated.getAttribute(name); + if (isUpdated()) return updated.getAttribute(name); return cached.getAttributes().get(name); } @Override public Map getAttributes() { - if (updated != null) return updated.getAttributes(); + if (isUpdated()) return updated.getAttributes(); Map copy = new HashMap(); copy.putAll(cached.getAttributes()); return copy; @@ -256,7 +270,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel { @Override public boolean isBearerOnly() { - if (updated != null) return updated.isBearerOnly(); + if (isUpdated()) return updated.isBearerOnly(); return cached.isBearerOnly(); } @@ -268,7 +282,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel { @Override public boolean isConsentRequired() { - if (updated != null) return updated.isConsentRequired(); + if (isUpdated()) return updated.isConsentRequired(); return cached.isConsentRequired(); } @@ -280,7 +294,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel { @Override public boolean isStandardFlowEnabled() { - if (updated != null) return updated.isStandardFlowEnabled(); + if (isUpdated()) return updated.isStandardFlowEnabled(); return cached.isStandardFlowEnabled(); } @@ -292,7 +306,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel { @Override public boolean isImplicitFlowEnabled() { - if (updated != null) return updated.isImplicitFlowEnabled(); + if (isUpdated()) return updated.isImplicitFlowEnabled(); return cached.isImplicitFlowEnabled(); } @@ -304,7 +318,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel { @Override public boolean isDirectAccessGrantsEnabled() { - if (updated != null) return updated.isDirectAccessGrantsEnabled(); + if (isUpdated()) return updated.isDirectAccessGrantsEnabled(); return cached.isDirectAccessGrantsEnabled(); } @@ -316,7 +330,7 @@ public class ClientTemplateAdapter implements ClientTemplateModel { @Override public boolean isServiceAccountsEnabled() { - if (updated != null) return updated.isServiceAccountsEnabled(); + if (isUpdated()) return updated.isServiceAccountsEnabled(); return cached.isServiceAccountsEnabled(); } diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/GroupAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/GroupAdapter.java index 1810a34990..9b44eb3dbc 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/GroupAdapter.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/GroupAdapter.java @@ -38,11 +38,11 @@ import java.util.Set; public class GroupAdapter implements GroupModel { protected GroupModel updated; protected CachedGroup cached; - protected CacheRealmProvider cacheSession; + protected RealmCacheSession cacheSession; protected KeycloakSession keycloakSession; protected RealmModel realm; - public GroupAdapter(CachedGroup cached, CacheRealmProvider cacheSession, KeycloakSession keycloakSession, RealmModel realm) { + public GroupAdapter(CachedGroup cached, RealmCacheSession cacheSession, KeycloakSession keycloakSession, RealmModel realm) { this.cached = cached; this.cacheSession = cacheSession; this.keycloakSession = keycloakSession; @@ -51,12 +51,26 @@ public class GroupAdapter implements GroupModel { protected void getDelegateForUpdate() { if (updated == null) { - cacheSession.registerGroupInvalidation(getId()); - updated = cacheSession.getDelegate().getGroupById(getId(), realm); + cacheSession.registerGroupInvalidation(cached.getId()); + updated = cacheSession.getDelegate().getGroupById(cached.getId(), realm); if (updated == null) throw new IllegalStateException("Not found in database"); } } + protected boolean invalidated; + public void invalidate() { + invalidated = true; + } + + protected boolean isUpdated() { + if (updated != null) return true; + if (!invalidated) return false; + updated = cacheSession.getDelegate().getGroupById(cached.getId(), realm); + if (updated == null) throw new IllegalStateException("Not found in database"); + return true; + } + + @Override public boolean equals(Object o) { if (this == o) return true; @@ -76,13 +90,13 @@ public class GroupAdapter implements GroupModel { @Override public String getId() { - if (updated != null) return updated.getId(); + if (isUpdated()) return updated.getId(); return cached.getId(); } @Override public String getName() { - if (updated != null) return updated.getName(); + if (isUpdated()) return updated.getName(); return cached.getName(); } @@ -114,7 +128,7 @@ public class GroupAdapter implements GroupModel { @Override public String getFirstAttribute(String name) { - if (updated != null) return updated.getFirstAttribute(name); + if (isUpdated()) return updated.getFirstAttribute(name); return cached.getAttributes().getFirst(name); } @@ -132,7 +146,7 @@ public class GroupAdapter implements GroupModel { @Override public Set getRealmRoleMappings() { - if (updated != null) return updated.getRealmRoleMappings(); + if (isUpdated()) return updated.getRealmRoleMappings(); Set roleMappings = getRoleMappings(); Set realmMappings = new HashSet(); for (RoleModel role : roleMappings) { @@ -148,7 +162,7 @@ public class GroupAdapter implements GroupModel { @Override public Set getClientRoleMappings(ClientModel app) { - if (updated != null) return updated.getClientRoleMappings(app); + if (isUpdated()) return updated.getClientRoleMappings(app); Set roleMappings = getRoleMappings(); Set appMappings = new HashSet(); for (RoleModel role : roleMappings) { @@ -164,7 +178,7 @@ public class GroupAdapter implements GroupModel { @Override public boolean hasRole(RoleModel role) { - if (updated != null) return updated.hasRole(role); + if (isUpdated()) return updated.hasRole(role); if (cached.getRoleMappings().contains(role.getId())) return true; Set mappings = getRoleMappings(); @@ -182,7 +196,7 @@ public class GroupAdapter implements GroupModel { @Override public Set getRoleMappings() { - if (updated != null) return updated.getRoleMappings(); + if (isUpdated()) return updated.getRoleMappings(); Set roles = new HashSet(); for (String id : cached.getRoleMappings()) { RoleModel roleById = keycloakSession.realms().getRoleById(id, realm); @@ -205,20 +219,20 @@ public class GroupAdapter implements GroupModel { @Override public GroupModel getParent() { - if (updated != null) return updated.getParent(); + if (isUpdated()) return updated.getParent(); if (cached.getParentId() == null) return null; return keycloakSession.realms().getGroupById(cached.getParentId(), realm); } @Override public String getParentId() { - if (updated != null) return updated.getParentId(); + if (isUpdated()) return updated.getParentId(); return cached.getParentId(); } @Override public Set getSubGroups() { - if (updated != null) return updated.getSubGroups(); + if (isUpdated()) return updated.getSubGroups(); Set subGroups = new HashSet<>(); for (String id : cached.getSubGroups()) { GroupModel subGroup = keycloakSession.realms().getGroupById(id, realm); diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java index 837010c357..be67c49ad7 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmAdapter.java @@ -36,7 +36,7 @@ import java.util.*; */ public class RealmAdapter implements RealmModel { protected CachedRealm cached; - protected CacheRealmProvider cacheSession; + protected RealmCacheSession cacheSession; protected RealmModel updated; protected RealmCache cache; protected volatile transient PublicKey publicKey; @@ -44,28 +44,42 @@ public class RealmAdapter implements RealmModel { protected volatile transient Key codeSecretKey; protected volatile transient X509Certificate certificate; - public RealmAdapter(CachedRealm cached, CacheRealmProvider cacheSession) { + public RealmAdapter(CachedRealm cached, RealmCacheSession cacheSession) { this.cached = cached; this.cacheSession = cacheSession; } protected void getDelegateForUpdate() { if (updated == null) { - cacheSession.registerRealmInvalidation(getId()); - updated = cacheSession.getDelegate().getRealm(getId()); + cacheSession.registerRealmInvalidation(cached.getId()); + updated = cacheSession.getDelegate().getRealm(cached.getId()); if (updated == null) throw new IllegalStateException("Not found in database"); } } + protected boolean invalidated; + public void invalidate() { + invalidated = true; + } + + protected boolean isUpdated() { + if (updated != null) return true; + if (!invalidated) return false; + updated = cacheSession.getDelegate().getRealm(cached.getId()); + if (updated == null) throw new IllegalStateException("Not found in database"); + return true; + } + + @Override public String getId() { - if (updated != null) return updated.getId(); + if (isUpdated()) return updated.getId(); return cached.getId(); } @Override public String getName() { - if (updated != null) return updated.getName(); + if (isUpdated()) return updated.getName(); return cached.getName(); } @@ -77,7 +91,7 @@ public class RealmAdapter implements RealmModel { @Override public String getDisplayName() { - if (updated != null) return updated.getDisplayName(); + if (isUpdated()) return updated.getDisplayName(); return cached.getDisplayName(); } @@ -89,7 +103,7 @@ public class RealmAdapter implements RealmModel { @Override public String getDisplayNameHtml() { - if (updated != null) return updated.getDisplayNameHtml(); + if (isUpdated()) return updated.getDisplayNameHtml(); return cached.getDisplayNameHtml(); } @@ -101,7 +115,7 @@ public class RealmAdapter implements RealmModel { @Override public boolean isEnabled() { - if (updated != null) return updated.isEnabled(); + if (isUpdated()) return updated.isEnabled(); return cached.isEnabled(); } @@ -113,7 +127,7 @@ public class RealmAdapter implements RealmModel { @Override public SslRequired getSslRequired() { - if (updated != null) return updated.getSslRequired(); + if (isUpdated()) return updated.getSslRequired(); return cached.getSslRequired(); } @@ -125,7 +139,7 @@ public class RealmAdapter implements RealmModel { @Override public boolean isRegistrationAllowed() { - if (updated != null) return updated.isRegistrationAllowed(); + if (isUpdated()) return updated.isRegistrationAllowed(); return cached.isRegistrationAllowed(); } @@ -137,7 +151,7 @@ public class RealmAdapter implements RealmModel { @Override public boolean isRegistrationEmailAsUsername() { - if (updated != null) return updated.isRegistrationEmailAsUsername(); + if (isUpdated()) return updated.isRegistrationEmailAsUsername(); return cached.isRegistrationEmailAsUsername(); } @@ -149,7 +163,7 @@ public class RealmAdapter implements RealmModel { @Override public boolean isRememberMe() { - if (updated != null) return updated.isRememberMe(); + if (isUpdated()) return updated.isRememberMe(); return cached.isRememberMe(); } @@ -161,7 +175,7 @@ public class RealmAdapter implements RealmModel { @Override public boolean isBruteForceProtected() { - if (updated != null) return updated.isBruteForceProtected(); + if (isUpdated()) return updated.isBruteForceProtected(); return cached.isBruteForceProtected(); } @@ -173,7 +187,7 @@ public class RealmAdapter implements RealmModel { @Override public int getMaxFailureWaitSeconds() { - if (updated != null) return updated.getMaxFailureWaitSeconds(); + if (isUpdated()) return updated.getMaxFailureWaitSeconds(); return cached.getMaxFailureWaitSeconds(); } @@ -185,7 +199,7 @@ public class RealmAdapter implements RealmModel { @Override public int getWaitIncrementSeconds() { - if (updated != null) return updated.getWaitIncrementSeconds(); + if (isUpdated()) return updated.getWaitIncrementSeconds(); return cached.getWaitIncrementSeconds(); } @@ -197,7 +211,7 @@ public class RealmAdapter implements RealmModel { @Override public int getMinimumQuickLoginWaitSeconds() { - if (updated != null) return updated.getMinimumQuickLoginWaitSeconds(); + if (isUpdated()) return updated.getMinimumQuickLoginWaitSeconds(); return cached.getMinimumQuickLoginWaitSeconds(); } @@ -209,7 +223,7 @@ public class RealmAdapter implements RealmModel { @Override public long getQuickLoginCheckMilliSeconds() { - if (updated != null) return updated.getQuickLoginCheckMilliSeconds(); + if (isUpdated()) return updated.getQuickLoginCheckMilliSeconds(); return cached.getQuickLoginCheckMilliSeconds(); } @@ -221,7 +235,7 @@ public class RealmAdapter implements RealmModel { @Override public int getMaxDeltaTimeSeconds() { - if (updated != null) return updated.getMaxDeltaTimeSeconds(); + if (isUpdated()) return updated.getMaxDeltaTimeSeconds(); return cached.getMaxDeltaTimeSeconds(); } @@ -233,7 +247,7 @@ public class RealmAdapter implements RealmModel { @Override public int getFailureFactor() { - if (updated != null) return updated.getFailureFactor(); + if (isUpdated()) return updated.getFailureFactor(); return cached.getFailureFactor(); } @@ -245,7 +259,7 @@ public class RealmAdapter implements RealmModel { @Override public boolean isVerifyEmail() { - if (updated != null) return updated.isVerifyEmail(); + if (isUpdated()) return updated.isVerifyEmail(); return cached.isVerifyEmail(); } @@ -257,7 +271,7 @@ public class RealmAdapter implements RealmModel { @Override public boolean isResetPasswordAllowed() { - if (updated != null) return updated.isResetPasswordAllowed(); + if (isUpdated()) return updated.isResetPasswordAllowed(); return cached.isResetPasswordAllowed(); } @@ -269,7 +283,7 @@ public class RealmAdapter implements RealmModel { @Override public boolean isEditUsernameAllowed() { - if (updated != null) return updated.isEditUsernameAllowed(); + if (isUpdated()) return updated.isEditUsernameAllowed(); return cached.isEditUsernameAllowed(); } @@ -281,7 +295,7 @@ public class RealmAdapter implements RealmModel { @Override public boolean isRevokeRefreshToken() { - if (updated != null) return updated.isRevokeRefreshToken(); + if (isUpdated()) return updated.isRevokeRefreshToken(); return cached.isRevokeRefreshToken(); } @@ -293,7 +307,7 @@ public class RealmAdapter implements RealmModel { @Override public int getSsoSessionIdleTimeout() { - if (updated != null) return updated.getSsoSessionIdleTimeout(); + if (isUpdated()) return updated.getSsoSessionIdleTimeout(); return cached.getSsoSessionIdleTimeout(); } @@ -305,7 +319,7 @@ public class RealmAdapter implements RealmModel { @Override public int getSsoSessionMaxLifespan() { - if (updated != null) return updated.getSsoSessionMaxLifespan(); + if (isUpdated()) return updated.getSsoSessionMaxLifespan(); return cached.getSsoSessionMaxLifespan(); } @@ -317,7 +331,7 @@ public class RealmAdapter implements RealmModel { @Override public int getOfflineSessionIdleTimeout() { - if (updated != null) return updated.getOfflineSessionIdleTimeout(); + if (isUpdated()) return updated.getOfflineSessionIdleTimeout(); return cached.getOfflineSessionIdleTimeout(); } @@ -330,7 +344,7 @@ public class RealmAdapter implements RealmModel { @Override public int getAccessTokenLifespan() { - if (updated != null) return updated.getAccessTokenLifespan(); + if (isUpdated()) return updated.getAccessTokenLifespan(); return cached.getAccessTokenLifespan(); } @@ -342,7 +356,7 @@ public class RealmAdapter implements RealmModel { @Override public int getAccessTokenLifespanForImplicitFlow() { - if (updated != null) return updated.getAccessTokenLifespanForImplicitFlow(); + if (isUpdated()) return updated.getAccessTokenLifespanForImplicitFlow(); return cached.getAccessTokenLifespanForImplicitFlow(); } @@ -354,7 +368,7 @@ public class RealmAdapter implements RealmModel { @Override public int getAccessCodeLifespan() { - if (updated != null) return updated.getAccessCodeLifespan(); + if (isUpdated()) return updated.getAccessCodeLifespan(); return cached.getAccessCodeLifespan(); } @@ -366,7 +380,7 @@ public class RealmAdapter implements RealmModel { @Override public int getAccessCodeLifespanUserAction() { - if (updated != null) return updated.getAccessCodeLifespanUserAction(); + if (isUpdated()) return updated.getAccessCodeLifespanUserAction(); return cached.getAccessCodeLifespanUserAction(); } @@ -378,7 +392,7 @@ public class RealmAdapter implements RealmModel { @Override public int getAccessCodeLifespanLogin() { - if (updated != null) return updated.getAccessCodeLifespanLogin(); + if (isUpdated()) return updated.getAccessCodeLifespanLogin(); return cached.getAccessCodeLifespanLogin(); } @@ -390,7 +404,7 @@ public class RealmAdapter implements RealmModel { @Override public String getPublicKeyPem() { - if (updated != null) return updated.getPublicKeyPem(); + if (isUpdated()) return updated.getPublicKeyPem(); return cached.getPublicKeyPem(); } @@ -402,7 +416,7 @@ public class RealmAdapter implements RealmModel { @Override public String getPrivateKeyPem() { - if (updated != null) return updated.getPrivateKeyPem(); + if (isUpdated()) return updated.getPrivateKeyPem(); return cached.getPrivateKeyPem(); } @@ -414,7 +428,7 @@ public class RealmAdapter implements RealmModel { @Override public PublicKey getPublicKey() { - if (updated != null) return updated.getPublicKey(); + if (isUpdated()) return updated.getPublicKey(); if (publicKey != null) return publicKey; publicKey = cached.getPublicKey(); if (publicKey != null) return publicKey; @@ -431,7 +445,7 @@ public class RealmAdapter implements RealmModel { @Override public X509Certificate getCertificate() { - if (updated != null) return updated.getCertificate(); + if (isUpdated()) return updated.getCertificate(); if (certificate != null) return certificate; certificate = cached.getCertificate(); if (certificate != null) return certificate; @@ -448,7 +462,7 @@ public class RealmAdapter implements RealmModel { @Override public String getCertificatePem() { - if (updated != null) return updated.getCertificatePem(); + if (isUpdated()) return updated.getCertificatePem(); return cached.getCertificatePem(); } @@ -461,7 +475,7 @@ public class RealmAdapter implements RealmModel { @Override public PrivateKey getPrivateKey() { - if (updated != null) return updated.getPrivateKey(); + if (isUpdated()) return updated.getPrivateKey(); if (privateKey != null) { return privateKey; } @@ -482,7 +496,7 @@ public class RealmAdapter implements RealmModel { @Override public String getCodeSecret() { - return updated != null ? updated.getCodeSecret() : cached.getCodeSecret(); + return isUpdated() ? updated.getCodeSecret() : cached.getCodeSecret(); } @Override @@ -501,7 +515,7 @@ public class RealmAdapter implements RealmModel { @Override public List getRequiredCredentials() { - if (updated != null) return updated.getRequiredCredentials(); + if (isUpdated()) return updated.getRequiredCredentials(); return cached.getRequiredCredentials(); } @@ -513,7 +527,7 @@ public class RealmAdapter implements RealmModel { @Override public PasswordPolicy getPasswordPolicy() { - if (updated != null) return updated.getPasswordPolicy(); + if (isUpdated()) return updated.getPasswordPolicy(); return cached.getPasswordPolicy(); } @@ -525,7 +539,7 @@ public class RealmAdapter implements RealmModel { @Override public OTPPolicy getOTPPolicy() { - if (updated != null) return updated.getOTPPolicy(); + if (isUpdated()) return updated.getOTPPolicy(); return cached.getOtpPolicy(); } @@ -538,13 +552,13 @@ public class RealmAdapter implements RealmModel { @Override public RoleModel getRoleById(String id) { - if (updated != null) return updated.getRoleById(id); + if (isUpdated()) return updated.getRoleById(id); return cacheSession.getRoleById(id, this); } @Override public List getDefaultGroups() { - if (updated != null) return updated.getDefaultGroups(); + if (isUpdated()) return updated.getDefaultGroups(); List defaultGroups = new LinkedList<>(); for (String id : cached.getDefaultGroups()) { @@ -570,7 +584,7 @@ public class RealmAdapter implements RealmModel { @Override public List getDefaultRoles() { - if (updated != null) return updated.getDefaultRoles(); + if (isUpdated()) return updated.getDefaultRoles(); return cached.getDefaultRoles(); } @@ -616,7 +630,7 @@ public class RealmAdapter implements RealmModel { @Override public ClientModel getClientById(String id) { - if (updated != null) return updated.getClientById(id); + if (isUpdated()) return updated.getClientById(id); return cacheSession.getClientById(id, this); } @@ -633,7 +647,7 @@ public class RealmAdapter implements RealmModel { @Override public Map getBrowserSecurityHeaders() { - if (updated != null) return updated.getBrowserSecurityHeaders(); + if (isUpdated()) return updated.getBrowserSecurityHeaders(); return cached.getBrowserSecurityHeaders(); } @@ -646,7 +660,7 @@ public class RealmAdapter implements RealmModel { @Override public Map getSmtpConfig() { - if (updated != null) return updated.getSmtpConfig(); + if (isUpdated()) return updated.getSmtpConfig(); return cached.getSmtpConfig(); } @@ -659,13 +673,13 @@ public class RealmAdapter implements RealmModel { @Override public List getIdentityProviders() { - if (updated != null) return updated.getIdentityProviders(); + if (isUpdated()) return updated.getIdentityProviders(); return cached.getIdentityProviders(); } @Override public IdentityProviderModel getIdentityProviderByAlias(String alias) { - if (updated != null) return updated.getIdentityProviderByAlias(alias); + if (isUpdated()) return updated.getIdentityProviderByAlias(alias); for (IdentityProviderModel identityProviderModel : getIdentityProviders()) { if (identityProviderModel.getAlias().equals(alias)) { return identityProviderModel; @@ -695,7 +709,7 @@ public class RealmAdapter implements RealmModel { @Override public List getUserFederationProviders() { - if (updated != null) return updated.getUserFederationProviders(); + if (isUpdated()) return updated.getUserFederationProviders(); return cached.getUserFederationProviders(); } @@ -727,7 +741,7 @@ public class RealmAdapter implements RealmModel { @Override public String getLoginTheme() { - if (updated != null) return updated.getLoginTheme(); + if (isUpdated()) return updated.getLoginTheme(); return cached.getLoginTheme(); } @@ -739,7 +753,7 @@ public class RealmAdapter implements RealmModel { @Override public String getAccountTheme() { - if (updated != null) return updated.getAccountTheme(); + if (isUpdated()) return updated.getAccountTheme(); return cached.getAccountTheme(); } @@ -751,7 +765,7 @@ public class RealmAdapter implements RealmModel { @Override public String getAdminTheme() { - if (updated != null) return updated.getAdminTheme(); + if (isUpdated()) return updated.getAdminTheme(); return cached.getAdminTheme(); } @@ -763,7 +777,7 @@ public class RealmAdapter implements RealmModel { @Override public String getEmailTheme() { - if (updated != null) return updated.getEmailTheme(); + if (isUpdated()) return updated.getEmailTheme(); return cached.getEmailTheme(); } @@ -775,7 +789,7 @@ public class RealmAdapter implements RealmModel { @Override public int getNotBefore() { - if (updated != null) return updated.getNotBefore(); + if (isUpdated()) return updated.getNotBefore(); return cached.getNotBefore(); } @@ -794,7 +808,7 @@ public class RealmAdapter implements RealmModel { @Override public boolean isEventsEnabled() { - if (updated != null) return updated.isEventsEnabled(); + if (isUpdated()) return updated.isEventsEnabled(); return cached.isEventsEnabled(); } @@ -806,7 +820,7 @@ public class RealmAdapter implements RealmModel { @Override public long getEventsExpiration() { - if (updated != null) return updated.getEventsExpiration(); + if (isUpdated()) return updated.getEventsExpiration(); return cached.getEventsExpiration(); } @@ -818,7 +832,7 @@ public class RealmAdapter implements RealmModel { @Override public Set getEventsListeners() { - if (updated != null) return updated.getEventsListeners(); + if (isUpdated()) return updated.getEventsListeners(); return cached.getEventsListeners(); } @@ -830,7 +844,7 @@ public class RealmAdapter implements RealmModel { @Override public Set getEnabledEventTypes() { - if (updated != null) return updated.getEnabledEventTypes(); + if (isUpdated()) return updated.getEnabledEventTypes(); return cached.getEnabledEventTypes(); } @@ -842,7 +856,7 @@ public class RealmAdapter implements RealmModel { @Override public boolean isAdminEventsEnabled() { - if (updated != null) return updated.isAdminEventsEnabled(); + if (isUpdated()) return updated.isAdminEventsEnabled(); return cached.isAdminEventsEnabled(); } @@ -854,7 +868,7 @@ public class RealmAdapter implements RealmModel { @Override public boolean isAdminEventsDetailsEnabled() { - if (updated != null) return updated.isAdminEventsDetailsEnabled(); + if (isUpdated()) return updated.isAdminEventsDetailsEnabled(); return cached.isAdminEventsDetailsEnabled(); } @@ -907,15 +921,13 @@ public class RealmAdapter implements RealmModel { @Override public boolean removeRole(RoleModel role) { - cacheSession.registerRoleInvalidation(role.getId()); - getDelegateForUpdate(); - return updated.removeRole(role); + return cacheSession.removeRole(this, role); } @Override public boolean isIdentityFederationEnabled() { - if (updated != null) return updated.isIdentityFederationEnabled(); + if (isUpdated()) return updated.isIdentityFederationEnabled(); return cached.isIdentityFederationEnabled(); } @@ -936,7 +948,7 @@ public class RealmAdapter implements RealmModel { @Override public boolean isInternationalizationEnabled() { - if (updated != null) return updated.isInternationalizationEnabled(); + if (isUpdated()) return updated.isInternationalizationEnabled(); return cached.isInternationalizationEnabled(); } @@ -948,7 +960,7 @@ public class RealmAdapter implements RealmModel { @Override public Set getSupportedLocales() { - if (updated != null) return updated.getSupportedLocales(); + if (isUpdated()) return updated.getSupportedLocales(); return cached.getSupportedLocales(); } @@ -960,7 +972,7 @@ public class RealmAdapter implements RealmModel { @Override public String getDefaultLocale() { - if (updated != null) return updated.getDefaultLocale(); + if (isUpdated()) return updated.getDefaultLocale(); return cached.getDefaultLocale(); } @@ -971,13 +983,13 @@ public class RealmAdapter implements RealmModel { @Override public Set getIdentityProviderMappers() { - if (updated != null) return updated.getIdentityProviderMappers(); + if (isUpdated()) return updated.getIdentityProviderMappers(); return cached.getIdentityProviderMapperSet(); } @Override public Set getIdentityProviderMappersByAlias(String brokerAlias) { - if (updated != null) return updated.getIdentityProviderMappersByAlias(brokerAlias); + if (isUpdated()) return updated.getIdentityProviderMappersByAlias(brokerAlias); Set mappings = new HashSet<>(); List list = cached.getIdentityProviderMappers().getList(brokerAlias); for (IdentityProviderMapperModel entity : list) { @@ -1006,7 +1018,7 @@ public class RealmAdapter implements RealmModel { @Override public IdentityProviderMapperModel getIdentityProviderMapperById(String id) { - if (updated != null) return updated.getIdentityProviderMapperById(id); + if (isUpdated()) return updated.getIdentityProviderMapperById(id); for (List models : cached.getIdentityProviderMappers().values()) { for (IdentityProviderMapperModel model : models) { if (model.getId().equals(id)) return model; @@ -1017,7 +1029,7 @@ public class RealmAdapter implements RealmModel { @Override public IdentityProviderMapperModel getIdentityProviderMapperByName(String alias, String name) { - if (updated != null) return updated.getIdentityProviderMapperByName(alias, name); + if (isUpdated()) return updated.getIdentityProviderMapperByName(alias, name); List models = cached.getIdentityProviderMappers().getList(alias); if (models == null) return null; for (IdentityProviderMapperModel model : models) { @@ -1028,13 +1040,13 @@ public class RealmAdapter implements RealmModel { @Override public Set getUserFederationMappers() { - if (updated != null) return updated.getUserFederationMappers(); + if (isUpdated()) return updated.getUserFederationMappers(); return cached.getUserFederationMapperSet(); } @Override public Set getUserFederationMappersByFederationProvider(String federationProviderId) { - if (updated != null) return updated.getUserFederationMappersByFederationProvider(federationProviderId); + if (isUpdated()) return updated.getUserFederationMappersByFederationProvider(federationProviderId); Set mappers = new HashSet<>(); List list = cached.getUserFederationMappers().getList(federationProviderId); for (UserFederationMapperModel entity : list) { @@ -1063,7 +1075,7 @@ public class RealmAdapter implements RealmModel { @Override public UserFederationMapperModel getUserFederationMapperById(String id) { - if (updated != null) return updated.getUserFederationMapperById(id); + if (isUpdated()) return updated.getUserFederationMapperById(id); for (List models : cached.getUserFederationMappers().values()) { for (UserFederationMapperModel model : models) { if (model.getId().equals(id)) return model; @@ -1074,7 +1086,7 @@ public class RealmAdapter implements RealmModel { @Override public UserFederationMapperModel getUserFederationMapperByName(String federationProviderId, String name) { - if (updated != null) return updated.getUserFederationMapperByName(federationProviderId, name); + if (isUpdated()) return updated.getUserFederationMapperByName(federationProviderId, name); List models = cached.getUserFederationMappers().getList(federationProviderId); if (models == null) return null; for (UserFederationMapperModel model : models) { @@ -1085,7 +1097,7 @@ public class RealmAdapter implements RealmModel { @Override public AuthenticationFlowModel getBrowserFlow() { - if (updated != null) return updated.getBrowserFlow(); + if (isUpdated()) return updated.getBrowserFlow(); return cached.getBrowserFlow(); } @@ -1098,7 +1110,7 @@ public class RealmAdapter implements RealmModel { @Override public AuthenticationFlowModel getRegistrationFlow() { - if (updated != null) return updated.getRegistrationFlow(); + if (isUpdated()) return updated.getRegistrationFlow(); return cached.getRegistrationFlow(); } @@ -1111,7 +1123,7 @@ public class RealmAdapter implements RealmModel { @Override public AuthenticationFlowModel getDirectGrantFlow() { - if (updated != null) return updated.getDirectGrantFlow(); + if (isUpdated()) return updated.getDirectGrantFlow(); return cached.getDirectGrantFlow(); } @@ -1123,7 +1135,7 @@ public class RealmAdapter implements RealmModel { } @Override public AuthenticationFlowModel getResetCredentialsFlow() { - if (updated != null) return updated.getResetCredentialsFlow(); + if (isUpdated()) return updated.getResetCredentialsFlow(); return cached.getResetCredentialsFlow(); } @@ -1136,7 +1148,7 @@ public class RealmAdapter implements RealmModel { @Override public AuthenticationFlowModel getClientAuthenticationFlow() { - if (updated != null) return updated.getClientAuthenticationFlow(); + if (isUpdated()) return updated.getClientAuthenticationFlow(); return cached.getClientAuthenticationFlow(); } @@ -1148,7 +1160,7 @@ public class RealmAdapter implements RealmModel { @Override public List getAuthenticationFlows() { - if (updated != null) return updated.getAuthenticationFlows(); + if (isUpdated()) return updated.getAuthenticationFlows(); return cached.getAuthenticationFlowList(); } @@ -1181,7 +1193,7 @@ public class RealmAdapter implements RealmModel { @Override public AuthenticationFlowModel getAuthenticationFlowById(String id) { - if (updated != null) return updated.getAuthenticationFlowById(id); + if (isUpdated()) return updated.getAuthenticationFlowById(id); return cached.getAuthenticationFlows().get(id); } @@ -1201,13 +1213,13 @@ public class RealmAdapter implements RealmModel { @Override public List getAuthenticationExecutions(String flowId) { - if (updated != null) return updated.getAuthenticationExecutions(flowId); + if (isUpdated()) return updated.getAuthenticationExecutions(flowId); return cached.getAuthenticationExecutions().get(flowId); } @Override public AuthenticationExecutionModel getAuthenticationExecutionById(String id) { - if (updated != null) return updated.getAuthenticationExecutionById(id); + if (isUpdated()) return updated.getAuthenticationExecutionById(id); return cached.getExecutionsById().get(id); } @@ -1233,7 +1245,7 @@ public class RealmAdapter implements RealmModel { @Override public List getAuthenticatorConfigs() { - if (updated != null) return updated.getAuthenticatorConfigs(); + if (isUpdated()) return updated.getAuthenticatorConfigs(); List models = new ArrayList<>(); models.addAll(cached.getAuthenticatorConfigs().values()); return Collections.unmodifiableList(models); @@ -1261,13 +1273,13 @@ public class RealmAdapter implements RealmModel { @Override public AuthenticatorConfigModel getAuthenticatorConfigById(String id) { - if (updated != null) return updated.getAuthenticatorConfigById(id); + if (isUpdated()) return updated.getAuthenticatorConfigById(id); return cached.getAuthenticatorConfigs().get(id); } @Override public List getRequiredActionProviders() { - if (updated != null) return updated.getRequiredActionProviders(); + if (isUpdated()) return updated.getRequiredActionProviders(); return cached.getRequiredActionProviderList(); } @@ -1293,13 +1305,13 @@ public class RealmAdapter implements RealmModel { @Override public RequiredActionProviderModel getRequiredActionProviderById(String id) { - if (updated != null) return updated.getRequiredActionProviderById(id); + if (isUpdated()) return updated.getRequiredActionProviderById(id); return cached.getRequiredActionProviders().get(id); } @Override public RequiredActionProviderModel getRequiredActionProviderByAlias(String alias) { - if (updated != null) return updated.getRequiredActionProviderByAlias(alias); + if (isUpdated()) return updated.getRequiredActionProviderByAlias(alias); return cached.getRequiredActionProvidersByAlias().get(alias); } @@ -1346,7 +1358,7 @@ public class RealmAdapter implements RealmModel { @Override public List getClientTemplates() { - if (updated != null) return updated.getClientTemplates(); + if (isUpdated()) return updated.getClientTemplates(); List clientTemplates = cached.getClientTemplates(); if (clientTemplates.isEmpty()) return Collections.EMPTY_LIST; List apps = new LinkedList(); @@ -1386,7 +1398,7 @@ public class RealmAdapter implements RealmModel { @Override public ClientTemplateModel getClientTemplateById(String id) { - if (updated != null) return updated.getClientTemplateById(id); + if (isUpdated()) return updated.getClientTemplateById(id); return cacheSession.getClientTemplateById(id, this); } diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheSession.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheSession.java index 4a149ba65e..2a78a413a1 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheSession.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RealmCacheSession.java @@ -117,11 +117,11 @@ public class RealmCacheSession implements CacheRealmProvider { protected boolean transactionActive; protected boolean setRollbackOnly; - protected Map managedRealms = new HashMap<>(); - protected Map managedApplications = new HashMap<>(); - protected Map managedClientTemplates = new HashMap<>(); - protected Map managedRoles = new HashMap<>(); - protected Map managedGroups = new HashMap<>(); + protected Map managedRealms = new HashMap<>(); + protected Map managedApplications = new HashMap<>(); + protected Map managedClientTemplates = new HashMap<>(); + protected Map managedRoles = new HashMap<>(); + protected Map managedGroups = new HashMap<>(); protected Set listInvalidations = new HashSet<>(); protected Set invalidations = new HashSet<>(); @@ -140,6 +140,10 @@ public class RealmCacheSession implements CacheRealmProvider { return startupRevision; } + public boolean isInvalid(String id) { + return invalidations.contains(id); + } + @Override public void clear() { cache.clear(); @@ -160,33 +164,88 @@ public class RealmCacheSession implements CacheRealmProvider { @Override public void registerRealmInvalidation(String id) { - invalidations.add(id); + invalidateRealm(id); cache.realmInvalidation(id, invalidations); } + private void invalidateRealm(String id) { + invalidations.add(id); + RealmAdapter adapter = managedRealms.get(id); + if (adapter != null) adapter.invalidate(); + } + @Override public void registerClientInvalidation(String id) { - invalidations.add(id); + invalidateClient(id); cache.clientInvalidation(id, invalidations); } + + private void invalidateClient(String id) { + invalidations.add(id); + ClientAdapter adapter = managedApplications.get(id); + if (adapter != null) adapter.invalidate(); + } + @Override public void registerClientTemplateInvalidation(String id) { - invalidations.add(id); + invalidateClientTemplate(id); cache.clientTemplateInvalidation(id, invalidations); } + private void invalidateClientTemplate(String id) { + invalidations.add(id); + ClientTemplateAdapter adapter = managedClientTemplates.get(id); + if (adapter != null) adapter.invalidate(); + } + @Override public void registerRoleInvalidation(String id) { + invalidateRole(id); + roleInvalidations(id); + } + + private void roleInvalidations(String roleId) { + Set newInvalidations = new HashSet<>(); + cache.roleInvalidation(roleId, newInvalidations); + invalidations.addAll(newInvalidations); + // need to make sure that scope and group mapping clients and groups are invalidated + for (String id : newInvalidations) { + ClientAdapter adapter = managedApplications.get(id); + if (adapter != null) { + adapter.invalidate(); + continue; + } + GroupAdapter group = managedGroups.get(id); + if (group != null) { + group.invalidate(); + continue; + } + + + } + } + + + + + private void invalidateRole(String id) { invalidations.add(id); - cache.roleInvalidation(id, invalidations); + RoleAdapter adapter = managedRoles.get(id); + if (adapter != null) adapter.invalidate(); } @Override public void registerGroupInvalidation(String id) { - invalidations.add(id); + invalidateGroup(id); cache.groupInvalidation(id, invalidations); } + private void invalidateGroup(String id) { + invalidations.add(id); + GroupAdapter adapter = managedGroups.get(id); + if (adapter != null) adapter.invalidate(); + } + protected void runInvalidations() { for (String id : invalidations) { cache.invalidateObject(id); @@ -381,7 +440,7 @@ public class RealmCacheSession implements CacheRealmProvider { } protected void invalidateClient(RealmModel realm, ClientModel client) { - invalidations.add(client.getId()); + invalidateClient(client.getId()); invalidations.add(getRealmClientsQueryCacheKey(realm.getId())); invalidations.add(getClientByClientIdCacheKey(client.getClientId(), realm)); listInvalidations.add(realm.getId()); @@ -474,11 +533,13 @@ public class RealmCacheSession implements CacheRealmProvider { invalidateClient(realm, client); cache.clientRemoval(realm.getId(), id, invalidations); for (RoleModel role : client.getRoles()) { - cache.roleInvalidation(role.getId(), invalidations); + String roleId = role.getId(); + roleInvalidations(roleId); } return getDelegate().removeClient(id, realm); } + @Override public void close() { if (delegate != null) delegate.close(); @@ -582,7 +643,7 @@ public class RealmCacheSession implements CacheRealmProvider { // this is needed so that a new role that hasn't been committed isn't cached in a query listInvalidations.add(client.getId()); RoleModel role = getDelegate().addClientRole(realm, client, id, name); - invalidations.add(role.getId()); + invalidateRole(role.getId()); return role; } @@ -651,7 +712,7 @@ public class RealmCacheSession implements CacheRealmProvider { invalidations.add(getRolesCacheKey(role.getContainer().getId())); invalidations.add(getRoleByNameCacheKey(role.getContainer().getId(), role.getName())); listInvalidations.add(role.getContainer().getId()); - invalidations.add(role.getId()); + registerRoleInvalidation(role.getId()); return getDelegate().removeRole(realm, role); } @@ -913,7 +974,7 @@ public class RealmCacheSession implements CacheRealmProvider { } else if (managedClientTemplates.containsKey(id)) { return managedClientTemplates.get(id); } - ClientTemplateModel adapter = new ClientTemplateAdapter(realm, cached, this); + ClientTemplateAdapter adapter = new ClientTemplateAdapter(realm, cached, this); managedClientTemplates.put(id, adapter); return adapter; } diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RoleAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RoleAdapter.java index 0b0c3a6cfe..99fbcaaf31 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RoleAdapter.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/RoleAdapter.java @@ -37,10 +37,10 @@ public class RoleAdapter implements RoleModel { protected RoleModel updated; protected CachedRole cached; - protected CacheRealmProvider cacheSession; + protected RealmCacheSession cacheSession; protected RealmModel realm; - public RoleAdapter(CachedRole cached, CacheRealmProvider session, RealmModel realm) { + public RoleAdapter(CachedRole cached, RealmCacheSession session, RealmModel realm) { this.cached = cached; this.cacheSession = session; this.realm = realm; @@ -48,22 +48,37 @@ public class RoleAdapter implements RoleModel { protected void getDelegateForUpdate() { if (updated == null) { - cacheSession.registerRoleInvalidation(getId()); - updated = cacheSession.getDelegate().getRoleById(getId(), realm); + cacheSession.registerRoleInvalidation(cached.getId()); + updated = cacheSession.getDelegate().getRoleById(cached.getId(), realm); if (updated == null) throw new IllegalStateException("Not found in database"); } } + protected boolean invalidated; + public void invalidate() { + invalidated = true; + } + + protected boolean isUpdated() { + if (updated != null) return true; + if (!invalidated) return false; + updated = cacheSession.getDelegate().getRoleById(cached.getId(), realm); + if (updated == null) throw new IllegalStateException("Not found in database"); + return true; + } + + + @Override public String getName() { - if (updated != null) return updated.getName(); + if (isUpdated()) return updated.getName(); return cached.getName(); } @Override public String getDescription() { - if (updated != null) return updated.getDescription(); + if (isUpdated()) return updated.getDescription(); return cached.getDescription(); } @@ -75,7 +90,7 @@ public class RoleAdapter implements RoleModel { @Override public boolean isScopeParamRequired() { - if (updated != null) return updated.isScopeParamRequired(); + if (isUpdated()) return updated.isScopeParamRequired(); return cached.isScopeParamRequired(); } @@ -87,7 +102,7 @@ public class RoleAdapter implements RoleModel { @Override public String getId() { - if (updated != null) return updated.getId(); + if (isUpdated()) return updated.getId(); return cached.getId(); } @@ -99,7 +114,7 @@ public class RoleAdapter implements RoleModel { @Override public boolean isComposite() { - if (updated != null) return updated.isComposite(); + if (isUpdated()) return updated.isComposite(); return cached.isComposite(); } @@ -117,7 +132,7 @@ public class RoleAdapter implements RoleModel { @Override public Set getComposites() { - if (updated != null) return updated.getComposites(); + if (isUpdated()) return updated.getComposites(); Set set = new HashSet(); for (String id : cached.getComposites()) { RoleModel role = realm.getRoleById(id); diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/stream/HasRolePredicate.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/stream/HasRolePredicate.java index 7d32462de2..13f11658dc 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/stream/HasRolePredicate.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/stream/HasRolePredicate.java @@ -1,5 +1,6 @@ package org.keycloak.models.cache.infinispan.stream; +import org.keycloak.models.cache.infinispan.entities.CachedClient; import org.keycloak.models.cache.infinispan.entities.CachedGroup; import org.keycloak.models.cache.infinispan.entities.CachedRole; import org.keycloak.models.cache.infinispan.entities.Revisioned; @@ -41,6 +42,11 @@ public class HasRolePredicate implements Predicate RoleQuery roleQuery = (RoleQuery)value; if (roleQuery.getRoles().contains(role)) return true; } + if (value instanceof CachedClient) { + CachedClient cachedClient = (CachedClient)value; + if (cachedClient.getScope().contains(role)) return true; + + } return false; } } diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java index 595dccd777..4edb420571 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ClientModelTest.java @@ -33,6 +33,7 @@ import org.keycloak.services.managers.ClientManager; import java.util.Iterator; import java.util.List; +import java.util.Set; /** * @author Stian Thorgersen @@ -73,6 +74,77 @@ public class ClientModelTest extends AbstractModelTest { client.updateClient(); } + @Test + public void testClientRoleRemovalAndClientScope() throws Exception { + // Client "from" has a role. Assign this role to a scope to client "scoped". Delete the role and make sure + // cache gets cleared + ClientModel from = realm.addClient("from"); + RoleModel role = from.addRole("clientRole"); + String roleId = role.getId(); + ClientModel scoped = realm.addClient("scoped"); + String idOfClient = scoped.getId(); + scoped.setFullScopeAllowed(false); + scoped.addScopeMapping(role); + commit(); + realm = session.realms().getRealmByName("original"); + scoped = realm.getClientByClientId("scoped"); + from = realm.getClientByClientId("from"); + role = session.realms().getRoleById(roleId, realm); + from.removeRole(role); + commit(); + realm = session.realms().getRealmByName("original"); + scoped = realm.getClientByClientId("scoped"); + Set scopeMappings = scoped.getScopeMappings(); + Assert.assertEquals(0, scopeMappings.size()); // used to throw an NPE + + } + + @Test + public void testClientRoleRemovalAndClientScopeSameTx() throws Exception { + // Client "from" has a role. Assign this role to a scope to client "scoped". Delete the role and make sure + // cache gets cleared + ClientModel from = realm.addClient("from"); + RoleModel role = from.addRole("clientRole"); + String roleId = role.getId(); + ClientModel scoped = realm.addClient("scoped"); + String idOfClient = scoped.getId(); + scoped.setFullScopeAllowed(false); + scoped.addScopeMapping(role); + commit(); + realm = session.realms().getRealmByName("original"); + scoped = realm.getClientByClientId("scoped"); + from = realm.getClientByClientId("from"); + role = session.realms().getRoleById(roleId, realm); + from.removeRole(role); + Set scopeMappings = scoped.getScopeMappings(); + Assert.assertEquals(0, scopeMappings.size()); // used to throw an NPE + + } + + @Test + public void testRealmRoleRemovalAndClientScope() throws Exception { + // Client "from" has a role. Assign this role to a scope to client "scoped". Delete the role and make sure + // cache gets cleared + RoleModel role = realm.addRole("clientRole"); + String roleId = role.getId(); + ClientModel scoped = realm.addClient("scoped"); + String idOfClient = scoped.getId(); + scoped.setFullScopeAllowed(false); + scoped.addScopeMapping(role); + commit(); + realm = session.realms().getRealmByName("original"); + scoped = realm.getClientByClientId("scoped"); + role = session.realms().getRoleById(roleId, realm); + realm.removeRole(role); + commit(); + realm = session.realms().getRealmByName("original"); + scoped = realm.getClientByClientId("scoped"); + Set scopeMappings = scoped.getScopeMappings(); + Assert.assertEquals(0, scopeMappings.size()); // used to throw an NPE + + } + + @Test public void persist() { RealmModel persisted = realmManager.getRealm(realm.getId());