mirror of
https://github.com/keycloak/keycloak.git
synced 2026-05-07 23:50:03 -05:00
Do not cache partial results when FGAP is enabled
Closes #38705 Signed-off-by: Pedro Igor <pigor.craveiro@gmail.com>
This commit is contained in:
+10
-3
@@ -16,9 +16,13 @@
|
||||
*/
|
||||
package org.keycloak.models.cache.infinispan;
|
||||
|
||||
import static org.keycloak.authorization.AdminPermissionsSchema.runWithoutAuthorization;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link DefaultLazyLoader} that only fetches data once. This implementation is not thread-safe
|
||||
* and cached data is assumed to not be shared across different threads to sync state.
|
||||
@@ -37,10 +41,13 @@ public class DefaultLazyLoader<S, D> implements LazyLoader<S, D> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public D get(Supplier<S> sourceSupplier) {
|
||||
public D get(KeycloakSession session, Supplier<S> sourceSupplier) {
|
||||
if (data == null) {
|
||||
S source = sourceSupplier.get();
|
||||
data = source == null ? fallback.get() : this.loader.apply(source);
|
||||
runWithoutAuthorization(session, () -> {
|
||||
// make sure caching does not include partial results when FGAP is enabled
|
||||
S source = sourceSupplier.get();
|
||||
data = source == null ? fallback.get() : loader.apply(source);
|
||||
});
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
+8
-8
@@ -134,13 +134,13 @@ public class GroupAdapter implements GroupModel {
|
||||
@Override
|
||||
public String getFirstAttribute(String name) {
|
||||
if (isUpdated()) return updated.getFirstAttribute(name);
|
||||
return cached.getAttributes(modelSupplier).getFirst(name);
|
||||
return cached.getAttributes(keycloakSession, modelSupplier).getFirst(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getAttributeStream(String name) {
|
||||
if (isUpdated()) return updated.getAttributeStream(name);
|
||||
List<String> values = cached.getAttributes(modelSupplier).get(name);
|
||||
List<String> values = cached.getAttributes(keycloakSession, modelSupplier).get(name);
|
||||
if (values == null) return Stream.empty();
|
||||
return values.stream();
|
||||
}
|
||||
@@ -148,7 +148,7 @@ public class GroupAdapter implements GroupModel {
|
||||
@Override
|
||||
public Map<String, List<String>> getAttributes() {
|
||||
if (isUpdated()) return updated.getAttributes();
|
||||
return cached.getAttributes(modelSupplier);
|
||||
return cached.getAttributes(keycloakSession, modelSupplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -167,13 +167,13 @@ public class GroupAdapter implements GroupModel {
|
||||
public boolean hasDirectRole(RoleModel role) {
|
||||
if (isUpdated()) return updated.hasDirectRole(role);
|
||||
|
||||
return cached.getRoleMappings(modelSupplier).contains(role.getId());
|
||||
return cached.getRoleMappings(keycloakSession, modelSupplier).contains(role.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRole(RoleModel role) {
|
||||
if (isUpdated()) return updated.hasRole(role);
|
||||
if (cached.getRoleMappings(modelSupplier).contains(role.getId())) return true;
|
||||
if (cached.getRoleMappings(keycloakSession, modelSupplier).contains(role.getId())) return true;
|
||||
if (getRoleMappingsStream().anyMatch(r -> r.hasRole(role))) return true;
|
||||
GroupModel parent = getParent();
|
||||
return parent != null && parent.hasRole(role);
|
||||
@@ -189,7 +189,7 @@ public class GroupAdapter implements GroupModel {
|
||||
public Stream<RoleModel> getRoleMappingsStream() {
|
||||
if (isUpdated()) return updated.getRoleMappingsStream();
|
||||
Set<RoleModel> roles = new HashSet<>();
|
||||
for (String id : cached.getRoleMappings(modelSupplier)) {
|
||||
for (String id : cached.getRoleMappings(keycloakSession, modelSupplier)) {
|
||||
RoleModel roleById = keycloakSession.roles().getRoleById(realm, id);
|
||||
if (roleById == null) {
|
||||
// chance that role was removed, so just delegate to persistence and get user invalidated
|
||||
@@ -225,7 +225,7 @@ public class GroupAdapter implements GroupModel {
|
||||
public Stream<GroupModel> getSubGroupsStream() {
|
||||
if (isUpdated()) return updated.getSubGroupsStream();
|
||||
Set<GroupModel> subGroups = new HashSet<>();
|
||||
for (String id : cached.getSubGroups(modelSupplier)) {
|
||||
for (String id : cached.getSubGroups(keycloakSession, modelSupplier)) {
|
||||
GroupModel subGroup = keycloakSession.groups().getGroupById(realm, id);
|
||||
if (subGroup == null) {
|
||||
// chance that role was removed, so just delegate to persistence and get user invalidated
|
||||
@@ -259,7 +259,7 @@ public class GroupAdapter implements GroupModel {
|
||||
@Override
|
||||
public Long getSubGroupsCount() {
|
||||
if (isUpdated()) return updated.getSubGroupsCount();
|
||||
return cached.getSubGroupsCount(modelSupplier);
|
||||
return getGroupModel().getSubGroupsCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-1
@@ -18,6 +18,8 @@ package org.keycloak.models.cache.infinispan;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
|
||||
/**
|
||||
* <p>A functional interface that can be used to return data {@code D} from a source {@code S} where implementations are free to define how and when
|
||||
* data is fetched from source as well how it is internally cached.
|
||||
@@ -33,8 +35,9 @@ public interface LazyLoader<S, D> {
|
||||
* Returns data from the given {@code source}. Data is only fetched from {@code source} once and only if necessary, it is
|
||||
* up to implementations to decide the momentum to actually fetch data from source.
|
||||
*
|
||||
* @param session the session
|
||||
* @param source the source from where data will be fetched.
|
||||
* @return the data from source
|
||||
*/
|
||||
D get(Supplier<S> source);
|
||||
D get(KeycloakSession session, Supplier<S> source);
|
||||
}
|
||||
|
||||
+4
-4
@@ -721,19 +721,19 @@ public class RealmAdapter implements CachedRealmModel {
|
||||
public OAuth2DeviceConfig getOAuth2DeviceConfig() {
|
||||
if (isUpdated())
|
||||
return updated.getOAuth2DeviceConfig();
|
||||
return cached.getOAuth2DeviceConfig(modelSupplier);
|
||||
return cached.getOAuth2DeviceConfig(session, modelSupplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CibaConfig getCibaPolicy() {
|
||||
if (isUpdated()) return updated.getCibaPolicy();
|
||||
return cached.getCibaConfig(modelSupplier);
|
||||
return cached.getCibaConfig(session, modelSupplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParConfig getParPolicy() {
|
||||
if (isUpdated()) return updated.getParPolicy();
|
||||
return cached.getParConfig(modelSupplier);
|
||||
return cached.getParConfig(session, modelSupplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1610,7 +1610,7 @@ public class RealmAdapter implements CachedRealmModel {
|
||||
@Override
|
||||
public Stream<ClientScopeModel> getDefaultClientScopesStream(boolean defaultScope) {
|
||||
if (isUpdated()) return updated.getDefaultClientScopesStream(defaultScope);
|
||||
List<String> clientScopeIds = defaultScope ? cached.getDefaultDefaultClientScopes(modelSupplier) : cached.getOptionalDefaultClientScopes(modelSupplier);
|
||||
List<String> clientScopeIds = defaultScope ? cached.getDefaultDefaultClientScopes(session, modelSupplier) : cached.getOptionalDefaultClientScopes(session, modelSupplier);
|
||||
return clientScopeIds.stream()
|
||||
.map(scope -> cacheSession.getClientScopeById(this, scope))
|
||||
.filter(Objects::nonNull);
|
||||
|
||||
+8
-5
@@ -17,6 +17,7 @@
|
||||
|
||||
package org.keycloak.models.cache.infinispan;
|
||||
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleContainerModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
@@ -40,15 +41,17 @@ import java.util.stream.Stream;
|
||||
public class RoleAdapter implements RoleModel {
|
||||
|
||||
protected RoleModel updated;
|
||||
private final KeycloakSession session;
|
||||
protected CachedRole cached;
|
||||
protected RealmCacheSession cacheSession;
|
||||
protected RealmModel realm;
|
||||
protected Set<RoleModel> composites;
|
||||
private final Supplier<RoleModel> modelSupplier;
|
||||
|
||||
public RoleAdapter(CachedRole cached, RealmCacheSession session, RealmModel realm) {
|
||||
public RoleAdapter(CachedRole cached, RealmCacheSession cacheSession, RealmModel realm) {
|
||||
this.cached = cached;
|
||||
this.cacheSession = session;
|
||||
this.cacheSession = cacheSession;
|
||||
this.session = cacheSession.session;
|
||||
this.realm = realm;
|
||||
this.modelSupplier = this::getRoleModel;
|
||||
}
|
||||
@@ -215,7 +218,7 @@ public class RoleAdapter implements RoleModel {
|
||||
return updated.getFirstAttribute(name);
|
||||
}
|
||||
|
||||
return cached.getAttributes(modelSupplier).getFirst(name);
|
||||
return cached.getAttributes(session, modelSupplier).getFirst(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -224,7 +227,7 @@ public class RoleAdapter implements RoleModel {
|
||||
return updated.getAttributeStream(name);
|
||||
}
|
||||
|
||||
List<String> result = cached.getAttributes(modelSupplier).get(name);
|
||||
List<String> result = cached.getAttributes(session, modelSupplier).get(name);
|
||||
if (result == null) {
|
||||
return Stream.empty();
|
||||
}
|
||||
@@ -237,7 +240,7 @@ public class RoleAdapter implements RoleModel {
|
||||
return updated.getAttributes();
|
||||
}
|
||||
|
||||
return cached.getAttributes(modelSupplier);
|
||||
return cached.getAttributes(session, modelSupplier);
|
||||
}
|
||||
|
||||
private RoleModel getRoleModel() {
|
||||
|
||||
+13
-13
@@ -223,26 +223,26 @@ public class UserAdapter implements CachedUserModel {
|
||||
@Override
|
||||
public String getFirstAttribute(String name) {
|
||||
if (updated != null) return updated.getFirstAttribute(name);
|
||||
return cached.getFirstAttribute(name, modelSupplier);
|
||||
return cached.getFirstAttribute(keycloakSession, name, modelSupplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getAttributeStream(String name) {
|
||||
if (updated != null) return updated.getAttributeStream(name);
|
||||
List<String> result = cached.getAttributes(modelSupplier).get(name);
|
||||
List<String> result = cached.getAttributes(keycloakSession, modelSupplier).get(name);
|
||||
return (result == null) ? Stream.empty() : result.stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<String>> getAttributes() {
|
||||
if (updated != null) return updated.getAttributes();
|
||||
return cached.getAttributes(modelSupplier);
|
||||
return cached.getAttributes(keycloakSession, modelSupplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<String> getRequiredActionsStream() {
|
||||
if (updated != null) return updated.getRequiredActionsStream();
|
||||
return cached.getRequiredActions(modelSupplier).stream();
|
||||
return cached.getRequiredActions(keycloakSession, modelSupplier).stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -318,7 +318,7 @@ public class UserAdapter implements CachedUserModel {
|
||||
@Override
|
||||
public CredentialModel getStoredCredentialById(String id) {
|
||||
if (updated == null) {
|
||||
return cached.getStoredCredentials(modelSupplier).stream().filter(credential ->
|
||||
return cached.getStoredCredentials(keycloakSession, modelSupplier).stream().filter(credential ->
|
||||
Objects.equals(id, credential.getId()))
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
@@ -328,7 +328,7 @@ public class UserAdapter implements CachedUserModel {
|
||||
@Override
|
||||
public Stream<CredentialModel> getStoredCredentialsStream() {
|
||||
if (updated == null) {
|
||||
return cached.getStoredCredentials(modelSupplier).stream();
|
||||
return cached.getStoredCredentials(keycloakSession, modelSupplier).stream();
|
||||
}
|
||||
return super.getStoredCredentialsStream();
|
||||
}
|
||||
@@ -336,7 +336,7 @@ public class UserAdapter implements CachedUserModel {
|
||||
@Override
|
||||
public Stream<CredentialModel> getStoredCredentialsByTypeStream(String type) {
|
||||
if (updated == null) {
|
||||
return cached.getStoredCredentials(modelSupplier).stream().filter(credential -> Objects.equals(type, credential.getType()));
|
||||
return cached.getStoredCredentials(keycloakSession, modelSupplier).stream().filter(credential -> Objects.equals(type, credential.getType()));
|
||||
}
|
||||
return super.getStoredCredentialsByTypeStream(type);
|
||||
}
|
||||
@@ -344,7 +344,7 @@ public class UserAdapter implements CachedUserModel {
|
||||
@Override
|
||||
public CredentialModel getStoredCredentialByNameAndType(String name, String type) {
|
||||
if (updated == null) {
|
||||
return cached.getStoredCredentials(modelSupplier).stream().filter(credential ->
|
||||
return cached.getStoredCredentials(keycloakSession, modelSupplier).stream().filter(credential ->
|
||||
Objects.equals(type, credential.getType()) && Objects.equals(name, credential.getUserLabel()))
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
@@ -375,13 +375,13 @@ public class UserAdapter implements CachedUserModel {
|
||||
@Override
|
||||
public boolean hasDirectRole(RoleModel role) {
|
||||
if (updated != null) return updated.hasDirectRole(role);
|
||||
return cached.getRoleMappings(modelSupplier).contains(role.getId());
|
||||
return cached.getRoleMappings(keycloakSession, modelSupplier).contains(role.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasRole(RoleModel role) {
|
||||
if (updated != null) return updated.hasRole(role);
|
||||
return cached.getRoleMappings(modelSupplier).contains(role.getId()) ||
|
||||
return cached.getRoleMappings(keycloakSession, modelSupplier).contains(role.getId()) ||
|
||||
getRoleMappingsStream().anyMatch(r -> r.hasRole(role)) ||
|
||||
RoleUtils.hasRoleFromGroup(getGroupsStream(), role, true);
|
||||
}
|
||||
@@ -396,7 +396,7 @@ public class UserAdapter implements CachedUserModel {
|
||||
public Stream<RoleModel> getRoleMappingsStream() {
|
||||
if (updated != null) return updated.getRoleMappingsStream();
|
||||
Set<RoleModel> roles = new HashSet<>();
|
||||
for (String id : cached.getRoleMappings(modelSupplier)) {
|
||||
for (String id : cached.getRoleMappings(keycloakSession, modelSupplier)) {
|
||||
RoleModel roleById = keycloakSession.roles().getRoleById(realm, id);
|
||||
if (roleById == null) {
|
||||
// chance that role was removed, so just delete to persistence and get user invalidated
|
||||
@@ -423,7 +423,7 @@ public class UserAdapter implements CachedUserModel {
|
||||
result = updated.getGroupsStream();
|
||||
} else {
|
||||
Set<GroupModel> groups = null;
|
||||
for (String id : cached.getGroups(modelSupplier)) {
|
||||
for (String id : cached.getGroups(keycloakSession, modelSupplier)) {
|
||||
GroupModel groupModel = keycloakSession.groups().getGroupById(realm, id);
|
||||
if (groupModel == null) {
|
||||
// chance that role was removed, so just delegate to persistence and get user invalidated
|
||||
@@ -468,7 +468,7 @@ public class UserAdapter implements CachedUserModel {
|
||||
@Override
|
||||
public boolean isMemberOf(GroupModel group) {
|
||||
if (updated != null) return updated.isMemberOf(group);
|
||||
return cached.getGroups(modelSupplier).contains(group.getId()) || RoleUtils.isMember(getGroupsStream(), group);
|
||||
return cached.getGroups(keycloakSession, modelSupplier).contains(group.getId()) || RoleUtils.isMember(getGroupsStream(), group);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/PolicyAdapter.java
Vendored
+20
-17
@@ -24,6 +24,7 @@ import org.keycloak.authorization.model.Scope;
|
||||
import org.keycloak.authorization.store.PolicyStore;
|
||||
import org.keycloak.authorization.store.ResourceStore;
|
||||
import org.keycloak.authorization.store.ScopeStore;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.cache.infinispan.authorization.entities.CachedPolicy;
|
||||
import org.keycloak.representations.idm.authorization.DecisionStrategy;
|
||||
import org.keycloak.representations.idm.authorization.Logic;
|
||||
@@ -45,11 +46,13 @@ public class PolicyAdapter implements Policy, CachedModel<Policy> {
|
||||
private final Supplier<Policy> modelSupplier;
|
||||
protected final CachedPolicy cached;
|
||||
protected final StoreFactoryCacheSession cacheSession;
|
||||
private final KeycloakSession session;
|
||||
protected Policy updated;
|
||||
|
||||
public PolicyAdapter(CachedPolicy cached, StoreFactoryCacheSession cacheSession) {
|
||||
this.cached = cached;
|
||||
this.cacheSession = cacheSession;
|
||||
this.session = cacheSession.session;
|
||||
this.modelSupplier = this::getPolicyModel;
|
||||
}
|
||||
|
||||
@@ -58,7 +61,7 @@ public class PolicyAdapter implements Policy, CachedModel<Policy> {
|
||||
if (updated == null) {
|
||||
updated = modelSupplier.get();
|
||||
String defaultResourceType = updated.getConfig().get("defaultResourceType");
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), cached.getResourcesIds(modelSupplier), cached.getScopesIds(modelSupplier), defaultResourceType, cached.getResourceServerId());
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), cached.getResourcesIds(session, modelSupplier), cached.getScopesIds(session, modelSupplier), defaultResourceType, cached.getResourceServerId());
|
||||
if (updated == null) throw new IllegalStateException("Not found in database");
|
||||
}
|
||||
return updated;
|
||||
@@ -106,7 +109,7 @@ public class PolicyAdapter implements Policy, CachedModel<Policy> {
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
getDelegateForUpdate();
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), name, cached.getResourcesIds(modelSupplier), cached.getScopesIds(modelSupplier), cached.getConfig(modelSupplier).get("defaultResourceType"), cached.getResourceServerId());
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), name, cached.getResourcesIds(session, modelSupplier), cached.getScopesIds(session, modelSupplier), cached.getConfig(session, modelSupplier).get("defaultResourceType"), cached.getResourceServerId());
|
||||
updated.setName(name);
|
||||
}
|
||||
|
||||
@@ -150,15 +153,15 @@ public class PolicyAdapter implements Policy, CachedModel<Policy> {
|
||||
@Override
|
||||
public Map<String, String> getConfig() {
|
||||
if (isUpdated()) return updated.getConfig();
|
||||
return cached.getConfig(modelSupplier);
|
||||
return cached.getConfig(session, modelSupplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setConfig(Map<String, String> config) {
|
||||
getDelegateForUpdate();
|
||||
if (config.containsKey("defaultResourceType") || cached.getConfig(modelSupplier).containsKey("defaultResourceType")) {
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), cached.getResourcesIds(modelSupplier), cached.getScopesIds(modelSupplier), cached.getConfig(modelSupplier).get("defaultResourceType"), cached.getResourceServerId());
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), cached.getResourcesIds(modelSupplier), cached.getScopesIds(modelSupplier), config.get("defaultResourceType"), cached.getResourceServerId());
|
||||
if (config.containsKey("defaultResourceType") || cached.getConfig(session, modelSupplier).containsKey("defaultResourceType")) {
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), cached.getResourcesIds(session, modelSupplier), cached.getScopesIds(session, modelSupplier), cached.getConfig(session, modelSupplier).get("defaultResourceType"), cached.getResourceServerId());
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), cached.getResourcesIds(session, modelSupplier), cached.getScopesIds(session, modelSupplier), config.get("defaultResourceType"), cached.getResourceServerId());
|
||||
}
|
||||
updated.setConfig(config);
|
||||
|
||||
@@ -168,7 +171,7 @@ public class PolicyAdapter implements Policy, CachedModel<Policy> {
|
||||
public void removeConfig(String name) {
|
||||
getDelegateForUpdate();
|
||||
if (name.equals("defaultResourceType")) {
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), cached.getResourcesIds(modelSupplier), cached.getScopesIds(modelSupplier), cached.getConfig(modelSupplier).get("defaultResourceType"), cached.getResourceServerId());
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), cached.getResourcesIds(session, modelSupplier), cached.getScopesIds(session, modelSupplier), cached.getConfig(session, modelSupplier).get("defaultResourceType"), cached.getResourceServerId());
|
||||
}
|
||||
updated.removeConfig(name);
|
||||
|
||||
@@ -178,8 +181,8 @@ public class PolicyAdapter implements Policy, CachedModel<Policy> {
|
||||
public void putConfig(String name, String value) {
|
||||
getDelegateForUpdate();
|
||||
if (name.equals("defaultResourceType")) {
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), cached.getResourcesIds(modelSupplier), cached.getScopesIds(modelSupplier), cached.getConfig(modelSupplier).get("defaultResourceType"), cached.getResourceServerId());
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), cached.getResourcesIds(modelSupplier), cached.getScopesIds(modelSupplier), value, cached.getResourceServerId());
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), cached.getResourcesIds(session, modelSupplier), cached.getScopesIds(session, modelSupplier), cached.getConfig(session, modelSupplier).get("defaultResourceType"), cached.getResourceServerId());
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), cached.getResourcesIds(session, modelSupplier), cached.getScopesIds(session, modelSupplier), value, cached.getResourceServerId());
|
||||
}
|
||||
updated.putConfig(name, value);
|
||||
}
|
||||
@@ -207,7 +210,7 @@ public class PolicyAdapter implements Policy, CachedModel<Policy> {
|
||||
associatedPolicies = new HashSet<>();
|
||||
PolicyStore policyStore = cacheSession.getPolicyStore();
|
||||
String resourceServerId = cached.getResourceServerId();
|
||||
for (String id : cached.getAssociatedPoliciesIds(modelSupplier)) {
|
||||
for (String id : cached.getAssociatedPoliciesIds(session, modelSupplier)) {
|
||||
Policy policy = policyStore.findById(cacheSession.getResourceServerStore().findById(resourceServerId), id);
|
||||
if (policy == null) {
|
||||
// probably because the policy was removed
|
||||
@@ -228,7 +231,7 @@ public class PolicyAdapter implements Policy, CachedModel<Policy> {
|
||||
resources = new HashSet<>();
|
||||
ResourceStore resourceStore = cacheSession.getResourceStore();
|
||||
ResourceServer resourceServer = getResourceServer();
|
||||
for (String resourceId : cached.getResourcesIds(modelSupplier)) {
|
||||
for (String resourceId : cached.getResourcesIds(session, modelSupplier)) {
|
||||
Resource resource = resourceStore.findById(resourceServer, resourceId);
|
||||
cacheSession.cacheResource(resource);
|
||||
resources.add(resource);
|
||||
@@ -239,14 +242,14 @@ public class PolicyAdapter implements Policy, CachedModel<Policy> {
|
||||
@Override
|
||||
public void addScope(Scope scope) {
|
||||
getDelegateForUpdate();
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), cached.getResourcesIds(modelSupplier), new HashSet<>(Arrays.asList(scope.getId())), cached.getConfig(modelSupplier).get("defaultResourceType"), cached.getResourceServerId());
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), cached.getResourcesIds(session, modelSupplier), new HashSet<>(Arrays.asList(scope.getId())), cached.getConfig(session, modelSupplier).get("defaultResourceType"), cached.getResourceServerId());
|
||||
updated.addScope(scope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeScope(Scope scope) {
|
||||
getDelegateForUpdate();
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), cached.getResourcesIds(modelSupplier), new HashSet<>(Arrays.asList(scope.getId())), cached.getConfig(modelSupplier).get("defaultResourceType"), cached.getResourceServerId());
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), cached.getResourcesIds(session, modelSupplier), new HashSet<>(Arrays.asList(scope.getId())), cached.getConfig(session, modelSupplier).get("defaultResourceType"), cached.getResourceServerId());
|
||||
updated.removeScope(scope);
|
||||
}
|
||||
|
||||
@@ -269,7 +272,7 @@ public class PolicyAdapter implements Policy, CachedModel<Policy> {
|
||||
getDelegateForUpdate();
|
||||
HashSet<String> resources = new HashSet<>();
|
||||
resources.add(resource.getId());
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), resources, cached.getScopesIds(modelSupplier), cached.getConfig(modelSupplier).get("defaultResourceType"), cached.getResourceServerId());
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), resources, cached.getScopesIds(session, modelSupplier), cached.getConfig(session, modelSupplier).get("defaultResourceType"), cached.getResourceServerId());
|
||||
updated.addResource(resource);
|
||||
|
||||
}
|
||||
@@ -279,7 +282,7 @@ public class PolicyAdapter implements Policy, CachedModel<Policy> {
|
||||
getDelegateForUpdate();
|
||||
HashSet<String> resources = new HashSet<>();
|
||||
resources.add(resource.getId());
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), resources, cached.getScopesIds(modelSupplier), cached.getConfig(modelSupplier).get("defaultResourceType"), cached.getResourceServerId());
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), resources, cached.getScopesIds(session, modelSupplier), cached.getConfig(session, modelSupplier).get("defaultResourceType"), cached.getResourceServerId());
|
||||
updated.removeResource(resource);
|
||||
|
||||
}
|
||||
@@ -293,7 +296,7 @@ public class PolicyAdapter implements Policy, CachedModel<Policy> {
|
||||
scopes = new HashSet<>();
|
||||
ResourceServer resourceServer = getResourceServer();
|
||||
ScopeStore scopeStore = cacheSession.getScopeStore();
|
||||
for (String scopeId : cached.getScopesIds(modelSupplier)) {
|
||||
for (String scopeId : cached.getScopesIds(session, modelSupplier)) {
|
||||
Scope scope = scopeStore.findById(resourceServer, scopeId);
|
||||
cacheSession.cacheScope(scope);
|
||||
scopes.add(scope);
|
||||
@@ -310,7 +313,7 @@ public class PolicyAdapter implements Policy, CachedModel<Policy> {
|
||||
@Override
|
||||
public void setOwner(String owner) {
|
||||
getDelegateForUpdate();
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), cached.getResourcesIds(modelSupplier), cached.getScopesIds(modelSupplier), cached.getConfig(modelSupplier).get("defaultResourceType"), cached.getResourceServerId());
|
||||
cacheSession.registerPolicyInvalidation(cached.getId(), cached.getName(), cached.getResourcesIds(session, modelSupplier), cached.getScopesIds(session, modelSupplier), cached.getConfig(session, modelSupplier).get("defaultResourceType"), cached.getResourceServerId());
|
||||
updated.setOwner(owner);
|
||||
}
|
||||
|
||||
|
||||
+15
-12
@@ -23,6 +23,7 @@ import org.keycloak.authorization.model.ResourceServer;
|
||||
import org.keycloak.authorization.model.Scope;
|
||||
import org.keycloak.authorization.store.PermissionTicketStore;
|
||||
import org.keycloak.authorization.store.PolicyStore;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.cache.infinispan.authorization.entities.CachedResource;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -40,6 +41,7 @@ import java.util.stream.Collectors;
|
||||
public class ResourceAdapter implements Resource, CachedModel<Resource> {
|
||||
|
||||
private final Supplier<Resource> modelSupplier;
|
||||
private final KeycloakSession session;
|
||||
protected final CachedResource cached;
|
||||
protected final StoreFactoryCacheSession cacheSession;
|
||||
protected Resource updated;
|
||||
@@ -47,6 +49,7 @@ public class ResourceAdapter implements Resource, CachedModel<Resource> {
|
||||
public ResourceAdapter(CachedResource cached, StoreFactoryCacheSession cacheSession) {
|
||||
this.cached = cached;
|
||||
this.cacheSession = cacheSession;
|
||||
this.session = cacheSession.session;
|
||||
this.modelSupplier = this::getResourceModel;
|
||||
}
|
||||
|
||||
@@ -54,7 +57,7 @@ public class ResourceAdapter implements Resource, CachedModel<Resource> {
|
||||
public Resource getDelegateForUpdate() {
|
||||
if (updated == null) {
|
||||
updated = modelSupplier.get();
|
||||
cacheSession.registerResourceInvalidation(cached.getId(), cached.getName(), cached.getType(), cached.getUris(modelSupplier), cached.getScopesIds(modelSupplier), cached.getResourceServerId(), cached.getOwner());
|
||||
cacheSession.registerResourceInvalidation(cached.getId(), cached.getName(), cached.getType(), cached.getUris(session, modelSupplier), cached.getScopesIds(session, modelSupplier), cached.getResourceServerId(), cached.getOwner());
|
||||
if (updated == null) throw new IllegalStateException("Not found in database");
|
||||
}
|
||||
return updated;
|
||||
@@ -102,7 +105,7 @@ public class ResourceAdapter implements Resource, CachedModel<Resource> {
|
||||
@Override
|
||||
public void setName(String name) {
|
||||
getDelegateForUpdate();
|
||||
cacheSession.registerResourceInvalidation(cached.getId(), name, cached.getType(), cached.getUris(modelSupplier), cached.getScopesIds(modelSupplier), cached.getResourceServerId(), cached.getOwner());
|
||||
cacheSession.registerResourceInvalidation(cached.getId(), name, cached.getType(), cached.getUris(session, modelSupplier), cached.getScopesIds(session, modelSupplier), cached.getResourceServerId(), cached.getOwner());
|
||||
updated.setName(name);
|
||||
}
|
||||
|
||||
@@ -115,7 +118,7 @@ public class ResourceAdapter implements Resource, CachedModel<Resource> {
|
||||
@Override
|
||||
public void setDisplayName(String name) {
|
||||
getDelegateForUpdate();
|
||||
cacheSession.registerResourceInvalidation(cached.getId(), cached.getName(), cached.getType(), cached.getUris(modelSupplier), cached.getScopesIds(modelSupplier), cached.getResourceServerId(), cached.getOwner());
|
||||
cacheSession.registerResourceInvalidation(cached.getId(), cached.getName(), cached.getType(), cached.getUris(session, modelSupplier), cached.getScopesIds(session, modelSupplier), cached.getResourceServerId(), cached.getOwner());
|
||||
updated.setDisplayName(name);
|
||||
}
|
||||
|
||||
@@ -140,13 +143,13 @@ public class ResourceAdapter implements Resource, CachedModel<Resource> {
|
||||
@Override
|
||||
public Set<String> getUris() {
|
||||
if (isUpdated()) return updated.getUris();
|
||||
return cached.getUris(modelSupplier);
|
||||
return cached.getUris(session, modelSupplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateUris(Set<String> uris) {
|
||||
getDelegateForUpdate();
|
||||
cacheSession.registerResourceInvalidation(cached.getId(), cached.getName(), cached.getType(), uris, cached.getScopesIds(modelSupplier), cached.getResourceServerId(), cached.getOwner());
|
||||
cacheSession.registerResourceInvalidation(cached.getId(), cached.getName(), cached.getType(), uris, cached.getScopesIds(session, modelSupplier), cached.getResourceServerId(), cached.getOwner());
|
||||
updated.updateUris(uris);
|
||||
}
|
||||
|
||||
@@ -159,7 +162,7 @@ public class ResourceAdapter implements Resource, CachedModel<Resource> {
|
||||
@Override
|
||||
public void setType(String type) {
|
||||
getDelegateForUpdate();
|
||||
cacheSession.registerResourceInvalidation(cached.getId(), cached.getName(), type, cached.getUris(modelSupplier), cached.getScopesIds(modelSupplier), cached.getResourceServerId(), cached.getOwner());
|
||||
cacheSession.registerResourceInvalidation(cached.getId(), cached.getName(), type, cached.getUris(session, modelSupplier), cached.getScopesIds(session, modelSupplier), cached.getResourceServerId(), cached.getOwner());
|
||||
updated.setType(type);
|
||||
|
||||
}
|
||||
@@ -171,7 +174,7 @@ public class ResourceAdapter implements Resource, CachedModel<Resource> {
|
||||
if (isUpdated()) return updated.getScopes();
|
||||
if (scopes != null) return scopes;
|
||||
scopes = new LinkedList<>();
|
||||
for (String scopeId : cached.getScopesIds(modelSupplier)) {
|
||||
for (String scopeId : cached.getScopesIds(session, modelSupplier)) {
|
||||
scopes.add(cacheSession.getScopeStore().findById(getResourceServer(), scopeId));
|
||||
}
|
||||
return scopes = Collections.unmodifiableList(scopes);
|
||||
@@ -192,7 +195,7 @@ public class ResourceAdapter implements Resource, CachedModel<Resource> {
|
||||
@Override
|
||||
public void setOwnerManagedAccess(boolean ownerManagedAccess) {
|
||||
getDelegateForUpdate();
|
||||
cacheSession.registerResourceInvalidation(cached.getId(), cached.getName(), cached.getType(), cached.getUris(modelSupplier), cached.getScopesIds(modelSupplier), cached.getResourceServerId(), cached.getOwner());
|
||||
cacheSession.registerResourceInvalidation(cached.getId(), cached.getName(), cached.getType(), cached.getUris(session, modelSupplier), cached.getScopesIds(session, modelSupplier), cached.getResourceServerId(), cached.getOwner());
|
||||
updated.setOwnerManagedAccess(ownerManagedAccess);
|
||||
}
|
||||
|
||||
@@ -219,21 +222,21 @@ public class ResourceAdapter implements Resource, CachedModel<Resource> {
|
||||
}
|
||||
}
|
||||
|
||||
cacheSession.registerResourceInvalidation(cached.getId(), cached.getName(), cached.getType(), cached.getUris(modelSupplier), scopes.stream().map(scope1 -> scope1.getId()).collect(Collectors.toSet()), cached.getResourceServerId(), cached.getOwner());
|
||||
cacheSession.registerResourceInvalidation(cached.getId(), cached.getName(), cached.getType(), cached.getUris(session, modelSupplier), scopes.stream().map(scope1 -> scope1.getId()).collect(Collectors.toSet()), cached.getResourceServerId(), cached.getOwner());
|
||||
updated.updateScopes(scopes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<String>> getAttributes() {
|
||||
if (updated != null) return updated.getAttributes();
|
||||
return cached.getAttributes(modelSupplier);
|
||||
return cached.getAttributes(session, modelSupplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSingleAttribute(String name) {
|
||||
if (updated != null) return updated.getSingleAttribute(name);
|
||||
|
||||
List<String> values = cached.getAttributes(modelSupplier).getOrDefault(name, Collections.emptyList());
|
||||
List<String> values = cached.getAttributes(session, modelSupplier).getOrDefault(name, Collections.emptyList());
|
||||
|
||||
if (values.isEmpty()) {
|
||||
return null;
|
||||
@@ -246,7 +249,7 @@ public class ResourceAdapter implements Resource, CachedModel<Resource> {
|
||||
public List<String> getAttribute(String name) {
|
||||
if (updated != null) return updated.getAttribute(name);
|
||||
|
||||
List<String> values = cached.getAttributes(modelSupplier).getOrDefault(name, Collections.emptyList());
|
||||
List<String> values = cached.getAttributes(session, modelSupplier).getOrDefault(name, Collections.emptyList());
|
||||
|
||||
if (values.isEmpty()) {
|
||||
return null;
|
||||
|
||||
+9
-8
@@ -21,6 +21,7 @@ package org.keycloak.models.cache.infinispan.authorization.entities;
|
||||
import org.keycloak.authorization.model.Policy;
|
||||
import org.keycloak.authorization.model.Resource;
|
||||
import org.keycloak.authorization.model.Scope;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.cache.infinispan.DefaultLazyLoader;
|
||||
import org.keycloak.models.cache.infinispan.LazyLoader;
|
||||
import org.keycloak.models.cache.infinispan.entities.AbstractRevisioned;
|
||||
@@ -83,8 +84,8 @@ public class CachedPolicy extends AbstractRevisioned implements InResourceServer
|
||||
return this.logic;
|
||||
}
|
||||
|
||||
public Map<String, String> getConfig(Supplier<Policy> policy) {
|
||||
return this.config.get(policy);
|
||||
public Map<String, String> getConfig(KeycloakSession session, Supplier<Policy> policy) {
|
||||
return this.config.get(session, policy);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@@ -95,16 +96,16 @@ public class CachedPolicy extends AbstractRevisioned implements InResourceServer
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public Set<String> getAssociatedPoliciesIds(Supplier<Policy> policy) {
|
||||
return this.associatedPoliciesIds.get(policy);
|
||||
public Set<String> getAssociatedPoliciesIds(KeycloakSession session, Supplier<Policy> policy) {
|
||||
return this.associatedPoliciesIds.get(session, policy);
|
||||
}
|
||||
|
||||
public Set<String> getResourcesIds(Supplier<Policy> policy) {
|
||||
return this.resourcesIds.get(policy);
|
||||
public Set<String> getResourcesIds(KeycloakSession session, Supplier<Policy> policy) {
|
||||
return this.resourcesIds.get(session, policy);
|
||||
}
|
||||
|
||||
public Set<String> getScopesIds(Supplier<Policy> policy) {
|
||||
return this.scopesIds.get(policy);
|
||||
public Set<String> getScopesIds(KeycloakSession session, Supplier<Policy> policy) {
|
||||
return this.scopesIds.get(session, policy);
|
||||
}
|
||||
|
||||
public String getResourceServerId() {
|
||||
|
||||
+7
-6
@@ -21,6 +21,7 @@ package org.keycloak.models.cache.infinispan.authorization.entities;
|
||||
import org.keycloak.authorization.model.Resource;
|
||||
import org.keycloak.authorization.model.Scope;
|
||||
import org.keycloak.common.util.MultivaluedHashMap;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.cache.infinispan.DefaultLazyLoader;
|
||||
import org.keycloak.models.cache.infinispan.LazyLoader;
|
||||
import org.keycloak.models.cache.infinispan.entities.AbstractRevisioned;
|
||||
@@ -75,8 +76,8 @@ public class CachedResource extends AbstractRevisioned implements InResourceServ
|
||||
return this.displayName;
|
||||
}
|
||||
|
||||
public Set<String> getUris(Supplier<Resource> source) {
|
||||
return this.uris.get(source);
|
||||
public Set<String> getUris(KeycloakSession session, Supplier<Resource> source) {
|
||||
return this.uris.get(session, source);
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
@@ -99,11 +100,11 @@ public class CachedResource extends AbstractRevisioned implements InResourceServ
|
||||
return this.resourceServerId;
|
||||
}
|
||||
|
||||
public Set<String> getScopesIds(Supplier<Resource> source) {
|
||||
return this.scopesIds.get(source);
|
||||
public Set<String> getScopesIds(KeycloakSession session, Supplier<Resource> source) {
|
||||
return this.scopesIds.get(session, source);
|
||||
}
|
||||
|
||||
public Map<String, List<String>> getAttributes(Supplier<Resource> source) {
|
||||
return attributes.get(source);
|
||||
public Map<String, List<String>> getAttributes(KeycloakSession session, Supplier<Resource> source) {
|
||||
return attributes.get(session, source);
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+7
-12
@@ -20,6 +20,7 @@ package org.keycloak.models.cache.infinispan.entities;
|
||||
import org.keycloak.common.util.MultivaluedHashMap;
|
||||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.GroupModel.Type;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.cache.infinispan.DefaultLazyLoader;
|
||||
@@ -42,7 +43,6 @@ public class CachedGroup extends AbstractRevisioned implements InRealm {
|
||||
private final LazyLoader<GroupModel, MultivaluedHashMap<String, String>> attributes;
|
||||
private final LazyLoader<GroupModel, Set<String>> roleMappings;
|
||||
private final LazyLoader<GroupModel, Set<String>> subGroups;
|
||||
private final LazyLoader<GroupModel, Long> subGroupsCount;
|
||||
private final Type type;
|
||||
|
||||
public CachedGroup(Long revision, RealmModel realm, GroupModel group) {
|
||||
@@ -53,7 +53,6 @@ public class CachedGroup extends AbstractRevisioned implements InRealm {
|
||||
this.attributes = new DefaultLazyLoader<>(source -> new MultivaluedHashMap<>(source.getAttributes()), MultivaluedHashMap::new);
|
||||
this.roleMappings = new DefaultLazyLoader<>(source -> source.getRoleMappingsStream().map(RoleModel::getId).collect(Collectors.toSet()), Collections::emptySet);
|
||||
this.subGroups = new DefaultLazyLoader<>(source -> source.getSubGroupsStream().map(GroupModel::getId).collect(Collectors.toSet()), Collections::emptySet);
|
||||
this.subGroupsCount = new DefaultLazyLoader<>(GroupModel::getSubGroupsCount, () -> 0L);
|
||||
this.type = group.getType();
|
||||
}
|
||||
|
||||
@@ -61,16 +60,16 @@ public class CachedGroup extends AbstractRevisioned implements InRealm {
|
||||
return realm;
|
||||
}
|
||||
|
||||
public MultivaluedHashMap<String, String> getAttributes(Supplier<GroupModel> group) {
|
||||
return attributes.get(group);
|
||||
public MultivaluedHashMap<String, String> getAttributes(KeycloakSession session, Supplier<GroupModel> group) {
|
||||
return attributes.get(session, group);
|
||||
}
|
||||
|
||||
public Set<String> getRoleMappings(Supplier<GroupModel> group) {
|
||||
public Set<String> getRoleMappings(KeycloakSession session, Supplier<GroupModel> group) {
|
||||
// it may happen that groups were not loaded before so we don't actually need to invalidate entries in the cache
|
||||
if (group == null) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
return roleMappings.get(group);
|
||||
return roleMappings.get(session, group);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
@@ -81,12 +80,8 @@ public class CachedGroup extends AbstractRevisioned implements InRealm {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
public Set<String> getSubGroups(Supplier<GroupModel> group) {
|
||||
return subGroups.get(group);
|
||||
}
|
||||
|
||||
public Long getSubGroupsCount(Supplier<GroupModel> group) {
|
||||
return subGroupsCount.get(group);
|
||||
public Set<String> getSubGroups(KeycloakSession session, Supplier<GroupModel> group) {
|
||||
return subGroups.get(session, group);
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
|
||||
Vendored
+11
-10
@@ -40,6 +40,7 @@ import org.keycloak.models.CibaConfig;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.ModelException;
|
||||
import org.keycloak.models.OAuth2DeviceConfig;
|
||||
import org.keycloak.models.OTPPolicy;
|
||||
@@ -526,16 +527,16 @@ public class CachedRealm extends AbstractExtendableRevisioned {
|
||||
return accessCodeLifespanLogin;
|
||||
}
|
||||
|
||||
public OAuth2DeviceConfig getOAuth2DeviceConfig(Supplier<RealmModel> modelSupplier) {
|
||||
return deviceConfig.get(modelSupplier);
|
||||
public OAuth2DeviceConfig getOAuth2DeviceConfig(KeycloakSession session, Supplier<RealmModel> modelSupplier) {
|
||||
return deviceConfig.get(session, modelSupplier);
|
||||
}
|
||||
|
||||
public CibaConfig getCibaConfig(Supplier<RealmModel> modelSupplier) {
|
||||
return cibaConfig.get(modelSupplier);
|
||||
public CibaConfig getCibaConfig(KeycloakSession session, Supplier<RealmModel> modelSupplier) {
|
||||
return cibaConfig.get(session, modelSupplier);
|
||||
}
|
||||
|
||||
public ParConfig getParConfig(Supplier<RealmModel> modelSupplier) {
|
||||
return parConfig.get(modelSupplier);
|
||||
public ParConfig getParConfig(KeycloakSession session, Supplier<RealmModel> modelSupplier) {
|
||||
return parConfig.get(session, modelSupplier);
|
||||
}
|
||||
|
||||
public int getActionTokenGeneratedByAdminLifespan() {
|
||||
@@ -702,12 +703,12 @@ public class CachedRealm extends AbstractExtendableRevisioned {
|
||||
return defaultGroups;
|
||||
}
|
||||
|
||||
public List<String> getDefaultDefaultClientScopes(Supplier<RealmModel> modelSupplier) {
|
||||
return defaultDefaultClientScopes.get(modelSupplier);
|
||||
public List<String> getDefaultDefaultClientScopes(KeycloakSession session, Supplier<RealmModel> modelSupplier) {
|
||||
return defaultDefaultClientScopes.get(session, modelSupplier);
|
||||
}
|
||||
|
||||
public List<String> getOptionalDefaultClientScopes(Supplier<RealmModel> modelSupplier) {
|
||||
return optionalDefaultClientScopes.get(modelSupplier);
|
||||
public List<String> getOptionalDefaultClientScopes(KeycloakSession session, Supplier<RealmModel> modelSupplier) {
|
||||
return optionalDefaultClientScopes.get(session, modelSupplier);
|
||||
}
|
||||
|
||||
public List<AuthenticationFlowModel> getAuthenticationFlowList() {
|
||||
|
||||
Vendored
+3
-2
@@ -18,6 +18,7 @@
|
||||
package org.keycloak.models.cache.infinispan.entities;
|
||||
|
||||
import org.keycloak.common.util.MultivaluedHashMap;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.cache.infinispan.DefaultLazyLoader;
|
||||
@@ -73,7 +74,7 @@ public class CachedRole extends AbstractRevisioned implements InRealm {
|
||||
return composites;
|
||||
}
|
||||
|
||||
public MultivaluedHashMap<String, String> getAttributes(Supplier<RoleModel> roleModel) {
|
||||
return attributes.get(roleModel);
|
||||
public MultivaluedHashMap<String, String> getAttributes(KeycloakSession session, Supplier<RoleModel> roleModel) {
|
||||
return attributes.get(session, roleModel);
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+13
-12
@@ -20,6 +20,7 @@ package org.keycloak.models.cache.infinispan.entities;
|
||||
import org.keycloak.common.util.MultivaluedHashMap;
|
||||
import org.keycloak.credential.CredentialModel;
|
||||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
@@ -83,11 +84,11 @@ public class CachedUser extends AbstractExtendableRevisioned implements InRealm
|
||||
return eagerLoadedAttributes.getFirst(UserModel.USERNAME);
|
||||
}
|
||||
|
||||
public String getFirstAttribute(String name, Supplier<UserModel> userModel) {
|
||||
public String getFirstAttribute(KeycloakSession session, String name, Supplier<UserModel> userModel) {
|
||||
if(eagerLoadedAttributes.containsKey(name))
|
||||
return eagerLoadedAttributes.getFirst(name);
|
||||
else
|
||||
return this.lazyLoadedAttributes.get(userModel).getFirst(name);
|
||||
return this.lazyLoadedAttributes.get(session, userModel).getFirst(name);
|
||||
}
|
||||
|
||||
public Long getCreatedTimestamp() {
|
||||
@@ -106,16 +107,16 @@ public class CachedUser extends AbstractExtendableRevisioned implements InRealm
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public MultivaluedHashMap<String, String> getAttributes(Supplier<UserModel> userModel) {
|
||||
return lazyLoadedAttributes.get(userModel);
|
||||
public MultivaluedHashMap<String, String> getAttributes(KeycloakSession session, Supplier<UserModel> userModel) {
|
||||
return lazyLoadedAttributes.get(session, userModel);
|
||||
}
|
||||
|
||||
public Set<String> getRequiredActions(Supplier<UserModel> userModel) {
|
||||
return this.requiredActions.get(userModel);
|
||||
public Set<String> getRequiredActions(KeycloakSession session, Supplier<UserModel> userModel) {
|
||||
return this.requiredActions.get(session, userModel);
|
||||
}
|
||||
|
||||
public Set<String> getRoleMappings(Supplier<UserModel> userModel) {
|
||||
return roleMappings.get(userModel);
|
||||
public Set<String> getRoleMappings(KeycloakSession session, Supplier<UserModel> userModel) {
|
||||
return roleMappings.get(session, userModel);
|
||||
}
|
||||
|
||||
public String getFederationLink() {
|
||||
@@ -126,17 +127,17 @@ public class CachedUser extends AbstractExtendableRevisioned implements InRealm
|
||||
return serviceAccountClientLink;
|
||||
}
|
||||
|
||||
public Set<String> getGroups(Supplier<UserModel> userModel) {
|
||||
return groups.get(userModel);
|
||||
public Set<String> getGroups(KeycloakSession session, Supplier<UserModel> userModel) {
|
||||
return groups.get(session, userModel);
|
||||
}
|
||||
|
||||
public int getNotBefore() {
|
||||
return notBefore;
|
||||
}
|
||||
|
||||
public List<CredentialModel> getStoredCredentials(Supplier<UserModel> userModel) {
|
||||
public List<CredentialModel> getStoredCredentials(KeycloakSession session, Supplier<UserModel> userModel) {
|
||||
// clone the credential model before returning it, so that modifications don't pollute the cache
|
||||
return storedCredentials.get(userModel).stream().map(CredentialModel::shallowClone).collect(Collectors.toList());
|
||||
return storedCredentials.get(session, userModel).stream().map(CredentialModel::shallowClone).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-2
@@ -22,6 +22,7 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import org.keycloak.common.util.MultivaluedHashMap;
|
||||
import org.keycloak.models.IdentityProviderModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.OrganizationDomainModel;
|
||||
import org.keycloak.models.OrganizationModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
@@ -80,8 +81,8 @@ public class CachedOrganization extends AbstractRevisioned implements InRealm {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public MultivaluedHashMap<String, String> getAttributes(Supplier<OrganizationModel> organizationModel) {
|
||||
return attributes.get(organizationModel);
|
||||
public MultivaluedHashMap<String, String> getAttributes(KeycloakSession session, Supplier<OrganizationModel> organizationModel) {
|
||||
return attributes.get(session, organizationModel);
|
||||
}
|
||||
|
||||
public Stream<OrganizationDomainModel> getDomains() {
|
||||
|
||||
+1
-1
@@ -107,7 +107,7 @@ public class InfinispanOrganizationProvider implements OrganizationProvider {
|
||||
} else if (managedOrganizations.containsKey(id)) {
|
||||
return managedOrganizations.get(id);
|
||||
}
|
||||
OrganizationAdapter adapter = new OrganizationAdapter(cached, () -> getDelegate(), this);
|
||||
OrganizationAdapter adapter = new OrganizationAdapter(session, cached, this::getDelegate, this);
|
||||
managedOrganizations.put(id, adapter);
|
||||
return adapter;
|
||||
}
|
||||
|
||||
+5
-2
@@ -22,6 +22,7 @@ import java.util.Set;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
import org.keycloak.models.IdentityProviderModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.OrganizationDomainModel;
|
||||
import org.keycloak.models.OrganizationModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
@@ -32,11 +33,13 @@ public class OrganizationAdapter implements OrganizationModel {
|
||||
private volatile boolean invalidated;
|
||||
private volatile OrganizationModel updated;
|
||||
private final Supplier<OrganizationModel> modelSupplier;
|
||||
private final KeycloakSession session;
|
||||
private final CachedOrganization cached;
|
||||
private final Supplier<OrganizationProvider> delegate;
|
||||
private final InfinispanOrganizationProvider organizationCache;
|
||||
|
||||
public OrganizationAdapter(CachedOrganization cached, Supplier<OrganizationProvider> delegate, InfinispanOrganizationProvider organizationCache) {
|
||||
public OrganizationAdapter(KeycloakSession session, CachedOrganization cached, Supplier<OrganizationProvider> delegate, InfinispanOrganizationProvider organizationCache) {
|
||||
this.session = session;
|
||||
this.cached = cached;
|
||||
this.delegate = delegate;
|
||||
this.organizationCache = organizationCache;
|
||||
@@ -136,7 +139,7 @@ public class OrganizationAdapter implements OrganizationModel {
|
||||
@Override
|
||||
public Map<String, List<String>> getAttributes() {
|
||||
if (isUpdated()) return updated.getAttributes();
|
||||
return cached.getAttributes(modelSupplier);
|
||||
return cached.getAttributes(session, modelSupplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Vendored
+1
-1
@@ -44,7 +44,7 @@ public class HasRolePredicate implements Predicate<Map.Entry<String, Revisioned>
|
||||
public boolean test(Map.Entry<String, Revisioned> entry) {
|
||||
Object value = entry.getValue();
|
||||
return (value instanceof CachedRole cachedRole && cachedRole.getComposites().contains(role)) ||
|
||||
(value instanceof CachedGroup cachedGroup && cachedGroup.getRoleMappings(null).contains(role)) ||
|
||||
(value instanceof CachedGroup cachedGroup && cachedGroup.getRoleMappings(null, null).contains(role)) ||
|
||||
(value instanceof RoleQuery roleQuery && roleQuery.getRoles().contains(role)) ||
|
||||
(value instanceof CachedClient cachedClient && cachedClient.getScope().contains(role)) ||
|
||||
(value instanceof CachedClientScope cachedClientScope && cachedClientScope.getScope().contains(role));
|
||||
|
||||
@@ -22,6 +22,7 @@ import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Predicate;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import org.keycloak.authorization.AdminPermissionsSchema;
|
||||
import org.keycloak.authorization.policy.provider.PartialEvaluationStorageProvider;
|
||||
import org.keycloak.common.util.MultivaluedHashMap;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.GroupModel;
|
||||
@@ -43,6 +44,7 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
import jakarta.persistence.LockModeType;
|
||||
import org.keycloak.storage.UserStoragePrivateUtil;
|
||||
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static org.keycloak.common.util.CollectionUtil.collectionEquals;
|
||||
@@ -161,7 +163,7 @@ public class GroupAdapter implements GroupModel , JpaModel<GroupEntity> {
|
||||
predicates.add(builder.like(builder.lower(root.get("name")), builder.lower(builder.literal("%" + search + "%"))));
|
||||
}
|
||||
|
||||
predicates.addAll(AdminPermissionsSchema.SCHEMA.applyAuthorizationFilters(session, AdminPermissionsSchema.GROUPS, realm, builder, queryBuilder, root));
|
||||
predicates.addAll(AdminPermissionsSchema.SCHEMA.applyAuthorizationFilters(session, AdminPermissionsSchema.GROUPS, (PartialEvaluationStorageProvider) UserStoragePrivateUtil.userLocalStorage(session), realm, builder, queryBuilder, root));
|
||||
|
||||
queryBuilder.where(predicates.toArray(new Predicate[0]));
|
||||
queryBuilder.orderBy(builder.asc(root.get("name")));
|
||||
@@ -186,7 +188,7 @@ public class GroupAdapter implements GroupModel , JpaModel<GroupEntity> {
|
||||
predicates.add(builder.equal(root.get("realm"), realm.getId()));
|
||||
predicates.add(builder.equal(root.get("type"), Type.REALM.intValue()));
|
||||
predicates.add(builder.equal(root.get("parentId"), group.getId()));
|
||||
predicates.addAll(AdminPermissionsSchema.SCHEMA.applyAuthorizationFilters(session, AdminPermissionsSchema.GROUPS, realm, builder, queryBuilder, root));
|
||||
predicates.addAll(AdminPermissionsSchema.SCHEMA.applyAuthorizationFilters(session, AdminPermissionsSchema.GROUPS, (PartialEvaluationStorageProvider) UserStoragePrivateUtil.userLocalStorage(session), realm, builder, queryBuilder, root));
|
||||
|
||||
queryBuilder.where(predicates.toArray(new Predicate[0]));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user