diff --git a/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/client/ClientPolicyProviderFactory.java b/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/client/ClientPolicyProviderFactory.java index b8fe006f4b..ca16751c3b 100644 --- a/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/client/ClientPolicyProviderFactory.java +++ b/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/client/ClientPolicyProviderFactory.java @@ -1,3 +1,20 @@ +/* + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.keycloak.authorization.policy.provider.client; import java.io.IOException; @@ -123,7 +140,7 @@ public class ClientPolicyProviderFactory implements PolicyProviderFactory filters = new HashMap<>(); filters.put(Policy.FilterOption.TYPE, new String[] { getId() }); - policyStore.findByResourceServer(null, filters, null, null).forEach(new Consumer() { + policyStore.find(realm, null, filters, null, null).forEach(new Consumer() { @Override public void accept(Policy policy) { @@ -93,7 +93,7 @@ public class ClientScopePolicyProviderFactory implements PolicyProviderFactory associatedPolicies = policy.getAssociatedPolicies(); + RealmModel realm = policy.getResourceServer().getRealm(); for (Policy associatedPolicy : associatedPolicies) { AbstractPolicyRepresentation associatedRep = ModelToRepresentation.toRepresentation(associatedPolicy, authorization, false, false); @@ -143,7 +144,7 @@ public class UMAPolicyProviderFactory implements PolicyProviderFactory roles) { - KeycloakSession session = authorization.getKeycloakSession(); - RealmModel realm = authorization.getRealm(); Set updatedRoles = new HashSet<>(); if (roles != null) { + RealmModel realm = authorization.getRealm(); for (RolePolicyRepresentation.RoleDefinition definition : roles) { String roleName = definition.getId(); String clientId = null; @@ -240,7 +238,7 @@ public class RolePolicyProviderFactory implements PolicyProviderFactory { protected boolean isUpdated() { if (updated != null) return true; if (!invalidated) return false; - updated = cacheSession.getPolicyStoreDelegate().findById(cacheSession.getResourceServerStore().findById(null, cached.getResourceServerId()), cached.getId()); + updated = cacheSession.getPolicyStoreDelegate().findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, cacheSession.getResourceServerStore().findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, cached.getResourceServerId()), cached.getId()); if (updated == null) throw new IllegalStateException("Not found in database"); return true; } @@ -112,7 +113,7 @@ public class PolicyAdapter implements Policy, CachedModel { @Override public ResourceServer getResourceServer() { - return cacheSession.getResourceServerStore().findById(null, cached.getResourceServerId()); + return cacheSession.getResourceServerStore().findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, cached.getResourceServerId()); } @Override @@ -208,7 +209,7 @@ public class PolicyAdapter implements Policy, CachedModel { PolicyStore policyStore = cacheSession.getPolicyStore(); String resourceServerId = cached.getResourceServerId(); for (String id : cached.getAssociatedPoliciesIds(modelSupplier)) { - Policy policy = policyStore.findById(cacheSession.getResourceServerStore().findById(null, resourceServerId), id); + Policy policy = policyStore.findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, cacheSession.getResourceServerStore().findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, resourceServerId), id); cacheSession.cachePolicy(policy); associatedPolicies.add(policy); } @@ -225,7 +226,7 @@ public class PolicyAdapter implements Policy, CachedModel { ResourceStore resourceStore = cacheSession.getResourceStore(); ResourceServer resourceServer = getResourceServer(); for (String resourceId : cached.getResourcesIds(modelSupplier)) { - Resource resource = resourceStore.findById(resourceServer, resourceId); + Resource resource = resourceStore.findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, resourceServer, resourceId); cacheSession.cacheResource(resource); resources.add(resource); } @@ -290,7 +291,7 @@ public class PolicyAdapter implements Policy, CachedModel { ResourceServer resourceServer = getResourceServer(); ScopeStore scopeStore = cacheSession.getScopeStore(); for (String scopeId : cached.getScopesIds(modelSupplier)) { - Scope scope = scopeStore.findById(resourceServer, scopeId); + Scope scope = scopeStore.findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, resourceServer, scopeId); cacheSession.cacheScope(scope); scopes.add(scope); } @@ -325,6 +326,6 @@ public class PolicyAdapter implements Policy, CachedModel { } private Policy getPolicyModel() { - return cacheSession.getPolicyStoreDelegate().findById(cacheSession.getResourceServerStore().findById(null, cached.getResourceServerId()), cached.getId()); + return cacheSession.getPolicyStoreDelegate().findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, cacheSession.getResourceServerStore().findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, cached.getResourceServerId()), cached.getId()); } } diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/ResourceAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/ResourceAdapter.java index 8286eea8fb..ad041dd033 100644 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/ResourceAdapter.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/ResourceAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -81,7 +81,7 @@ public class ResourceAdapter implements Resource, CachedModel { protected boolean isUpdated() { if (updated != null) return true; if (!invalidated) return false; - updated = cacheSession.getResourceStoreDelegate().findById(getResourceServer(), cached.getId()); + updated = cacheSession.getResourceStoreDelegate().findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, getResourceServer(), cached.getId()); if (updated == null) throw new IllegalStateException("Not found in database"); return true; } @@ -134,7 +134,7 @@ public class ResourceAdapter implements Resource, CachedModel { @Override public ResourceServer getResourceServer() { - return cacheSession.getResourceServerStoreDelegate().findById(null, cached.getResourceServerId()); + return cacheSession.getResourceServerStoreDelegate().findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, cached.getResourceServerId()); } @Override @@ -172,7 +172,7 @@ public class ResourceAdapter implements Resource, CachedModel { if (scopes != null) return scopes; scopes = new LinkedList<>(); for (String scopeId : cached.getScopesIds(modelSupplier)) { - scopes.add(cacheSession.getScopeStore().findById(getResourceServer(), scopeId)); + scopes.add(cacheSession.getScopeStore().findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, getResourceServer(), scopeId)); } return scopes = Collections.unmodifiableList(scopes); } @@ -206,7 +206,7 @@ public class ResourceAdapter implements Resource, CachedModel { List permissions = permissionStore.findByScope(getResourceServer(), scope); for (PermissionTicket permission : permissions) { - permissionStore.delete(permission.getId()); + permissionStore.delete(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, permission.getId()); } } } @@ -282,6 +282,6 @@ public class ResourceAdapter implements Resource, CachedModel { } private Resource getResourceModel() { - return cacheSession.getResourceStoreDelegate().findById(getResourceServer(), cached.getId()); + return cacheSession.getResourceStoreDelegate().findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, getResourceServer(), cached.getId()); } } diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/ResourceServerAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/ResourceServerAdapter.java index 2453b6d485..f54040400b 100644 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/ResourceServerAdapter.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/ResourceServerAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,6 +18,7 @@ package org.keycloak.models.cache.infinispan.authorization; import org.keycloak.authorization.model.CachedModel; import org.keycloak.authorization.model.ResourceServer; +import org.keycloak.authorization.store.PermissionTicketStore; import org.keycloak.models.ClientModel; import org.keycloak.models.RealmModel; import org.keycloak.models.cache.infinispan.authorization.entities.CachedResourceServer; @@ -42,7 +43,7 @@ public class ResourceServerAdapter implements ResourceServer, CachedModel { public Scope getDelegateForUpdate() { if (updated == null) { cacheSession.registerScopeInvalidation(cached.getId(), cached.getName(), cached.getResourceServerId()); - updated = cacheSession.getScopeStoreDelegate().findById(getResourceServer(), cached.getId()); + updated = cacheSession.getScopeStoreDelegate().findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, getResourceServer(), cached.getId()); if (updated == null) throw new IllegalStateException("Not found in database"); } return updated; @@ -66,7 +67,7 @@ public class ScopeAdapter implements Scope, CachedModel { protected boolean isUpdated() { if (updated != null) return true; if (!invalidated) return false; - updated = cacheSession.getScopeStoreDelegate().findById(getResourceServer(), cached.getId()); + updated = cacheSession.getScopeStoreDelegate().findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, getResourceServer(), cached.getId()); if (updated == null) throw new IllegalStateException("Not found in database"); return true; } @@ -118,7 +119,7 @@ public class ScopeAdapter implements Scope, CachedModel { @Override public ResourceServer getResourceServer() { - return cacheSession.getResourceServerStore().findById(null, cached.getResourceServerId()); + return cacheSession.getResourceServerStore().findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, cached.getResourceServerId()); } @Override diff --git a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/StoreFactoryCacheSession.java b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/StoreFactoryCacheSession.java index 258f1c81e2..c0325090d9 100644 --- a/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/StoreFactoryCacheSession.java +++ b/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/authorization/StoreFactoryCacheSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -310,9 +310,9 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { return Collections.emptySet(); } - ResourceServer resourceServer = getResourceServerStore().findById(null, serverId); + ResourceServer resourceServer = getResourceServerStore().findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, serverId); return resources.stream().map(resourceId -> { - Resource resource = getResourceStore().findById(resourceServer, resourceId); + Resource resource = getResourceStore().findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, resourceServer, resourceId); String type = resource.getType(); if (type != null) { @@ -451,7 +451,7 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { public void delete(ClientModel client) { String id = client.getId(); if (id == null) return; - ResourceServer server = findById(null, id); + ResourceServer server = findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, id); if (server == null) return; cache.invalidateObject(id); @@ -492,7 +492,7 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { @Override public ResourceServer findByClient(ClientModel client) { - return findById(null, client.getId()); + return findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, client.getId()); } } @@ -510,19 +510,19 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { } @Override - public void delete(String id) { + public void delete(RealmModel realm, String id) { if (id == null) return; - Scope scope = findById(null, id); + Scope scope = findById(realm, null, id); if (scope == null) return; cache.invalidateObject(id); invalidationEvents.add(ScopeRemovedEvent.create(id, scope.getName(), scope.getResourceServer().getId())); cache.scopeRemoval(id, scope.getName(), scope.getResourceServer().getId(), invalidations); - getScopeStoreDelegate().delete(id); + getScopeStoreDelegate().delete(realm, id); } @Override - public Scope findById(ResourceServer resourceServer, String id) { + public Scope findById(RealmModel realm, ResourceServer resourceServer, String id) { if (id == null) return null; CachedScope cached = cache.get(id, CachedScope.class); if (cached != null) { @@ -531,7 +531,7 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { if (cached == null) { Long loaded = cache.getCurrentRevision(id); if (! modelMightExist(id)) return null; - Scope model = getScopeStoreDelegate().findById(resourceServer, id); + Scope model = getScopeStoreDelegate().findById(realm, resourceServer, id); if (model == null) { setModelDoesNotExists(id, loaded); return null; @@ -540,7 +540,7 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { cached = new CachedScope(loaded, model); cache.addRevisioned(cached, startupRevision); } else if (invalidations.contains(id)) { - return getScopeStoreDelegate().findById(resourceServer, id); + return getScopeStoreDelegate().findById(realm, resourceServer, id); } else if (managedScopes.containsKey(id)) { return managedScopes.get(id); } @@ -573,7 +573,7 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { if (invalidations.contains(id)) { return getScopeStoreDelegate().findByName(resourceServer, name); } - return findById(resourceServer, id); + return findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, resourceServer, id); } } @@ -593,29 +593,29 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { @Override public Resource create(ResourceServer resourceServer, String id, String name, String owner) { Resource resource = getResourceStoreDelegate().create(resourceServer, id, name, owner); - Resource cached = findById(resourceServer, resource.getId()); + Resource cached = findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, resourceServer, resource.getId()); registerResourceInvalidation(resource.getId(), resource.getName(), resource.getType(), resource.getUris(), resource.getScopes().stream().map(Scope::getId).collect(Collectors.toSet()), resourceServer.getId(), resource.getOwner()); if (cached == null) { - cached = findById(resourceServer, resource.getId()); + cached = findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, resourceServer, resource.getId()); } return cached; } @Override - public void delete(String id) { + public void delete(RealmModel realm, String id) { if (id == null) return; - Resource resource = findById(null, id); + Resource resource = findById(realm, null, id); if (resource == null) return; cache.invalidateObject(id); invalidationEvents.add(ResourceRemovedEvent.create(id, resource.getName(), resource.getType(), resource.getUris(), resource.getOwner(), resource.getScopes().stream().map(Scope::getId).collect(Collectors.toSet()), resource.getResourceServer().getId())); cache.resourceRemoval(id, resource.getName(), resource.getType(), resource.getUris(), resource.getOwner(), resource.getScopes().stream().map(Scope::getId).collect(Collectors.toSet()), resource.getResourceServer().getId(), invalidations); - getResourceStoreDelegate().delete(id); + getResourceStoreDelegate().delete(realm, id); } @Override - public Resource findById(ResourceServer resourceServer, String id) { + public Resource findById(RealmModel realm, ResourceServer resourceServer, String id) { if (id == null) return null; CachedResource cached = cache.get(id, CachedResource.class); if (cached != null) { @@ -624,7 +624,7 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { if (cached == null) { Long loaded = cache.getCurrentRevision(id); if (! modelMightExist(id)) return null; - Resource model = getResourceStoreDelegate().findById(resourceServer, id); + Resource model = getResourceStoreDelegate().findById(realm, resourceServer, id); if (model == null) { setModelDoesNotExists(id, loaded); return null; @@ -633,7 +633,7 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { cached = new CachedResource(loaded, model); cache.addRevisioned(cached, startupRevision); } else if (invalidations.contains(id)) { - return getResourceStoreDelegate().findById(resourceServer, id); + return getResourceStoreDelegate().findById(realm, resourceServer, id); } else if (managedResources.containsKey(id)) { return managedResources.get(id); } @@ -666,20 +666,20 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { } @Override - public List findByOwner(ResourceServer resourceServer, String ownerId) { + public List findByOwner(RealmModel realm, ResourceServer resourceServer, String ownerId) { String resourceServerId = resourceServer == null ? null : resourceServer.getId(); String cacheKey = getResourceByOwnerCacheKey(ownerId, resourceServerId); - return cacheQuery(cacheKey, ResourceListQuery.class, () -> getResourceStoreDelegate().findByOwner(resourceServer, ownerId), + return cacheQuery(cacheKey, ResourceListQuery.class, () -> getResourceStoreDelegate().findByOwner(realm, resourceServer, ownerId), (revision, resources) -> new ResourceListQuery(revision, cacheKey, resources.stream().map(Resource::getId).collect(Collectors.toSet()), resourceServerId), resourceServer); } @Override - public void findByOwner(ResourceServer resourceServer, String ownerId, Consumer consumer) { + public void findByOwner(RealmModel realm, ResourceServer resourceServer, String ownerId, Consumer consumer) { String resourceServerId = resourceServer == null ? null : resourceServer.getId(); String cacheKey = getResourceByOwnerCacheKey(ownerId, resourceServerId); cacheQuery(cacheKey, ResourceListQuery.class, () -> { List resources = new ArrayList<>(); - getResourceStoreDelegate().findByOwner(resourceServer, ownerId, new Consumer() { + getResourceStoreDelegate().findByOwner(realm, resourceServer, ownerId, new Consumer() { @Override public void accept(Resource resource) { consumer.andThen(resources::add) @@ -692,28 +692,14 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { (revision, resources) -> new ResourceListQuery(revision, cacheKey, resources.stream().map(Resource::getId).collect(Collectors.toSet()), resourceServerId), resourceServer, consumer); } - @Override - public List findByOwner(ResourceServer resourceServer, String ownerId, Integer firstResult, Integer maxResults) { - return getResourceStoreDelegate().findByOwner(resourceServer, ownerId, firstResult, maxResults); - } - - @Override - public List findByUri(ResourceServer resourceServer, String uri) { - if (uri == null) return null; - String resourceServerId = resourceServer == null ? null : resourceServer.getId(); - String cacheKey = getResourceByUriCacheKey(uri, resourceServerId); - return cacheQuery(cacheKey, ResourceListQuery.class, () -> getResourceStoreDelegate().findByUri(resourceServer, uri), - (revision, resources) -> new ResourceListQuery(revision, cacheKey, resources.stream().map(Resource::getId).collect(Collectors.toSet()), resourceServerId), resourceServer); - } - @Override public List findByResourceServer(ResourceServer resourceServer) { return getResourceStoreDelegate().findByResourceServer(resourceServer); } @Override - public List findByResourceServer(ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults) { - return getResourceStoreDelegate().findByResourceServer(resourceServer, attributes, firstResult, maxResults); + public List find(RealmModel realm, ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults) { + return getResourceStoreDelegate().find(realm, resourceServer, attributes, firstResult, maxResults); } @Override @@ -782,19 +768,6 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { (revision, resources) -> new ResourceListQuery(revision, cacheKey, resources.stream().map(Resource::getId).collect(Collectors.toSet()), resourceServerId), resourceServer, consumer); } - @Override - public List findByType(ResourceServer resourceServer, String type, String owner) { - if (resourceServer != null && resourceServer.getId().equals(owner)) { - return findByType(resourceServer, type); - } else { - if (type == null) return Collections.emptyList(); - String resourceServerId = resourceServer == null ? null : resourceServer.getId(); - String cacheKey = getResourceByTypeCacheKey(type, owner, resourceServerId); - return cacheQuery(cacheKey, ResourceListQuery.class, () -> getResourceStoreDelegate().findByType(resourceServer, type, owner), - (revision, resources) -> new ResourceListQuery(revision, cacheKey, resources.stream().map(Resource::getId).collect(Collectors.toSet()), resourceServerId), resourceServer); - } - } - @Override public void findByType(ResourceServer resourceServer, String type, String owner, Consumer consumer) { if (type == null) return; @@ -815,15 +788,6 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { (revision, resources) -> new ResourceListQuery(revision, cacheKey, resources.stream().map(Resource::getId).collect(Collectors.toSet()), resourceServerId), resourceServer, consumer); } - @Override - public List findByTypeInstance(ResourceServer resourceServer, String type) { - if (type == null) return Collections.emptyList(); - String resourceServerId = resourceServer == null ? null : resourceServer.getId(); - String cacheKey = getResourceByTypeInstanceCacheKey(type, resourceServerId); - return cacheQuery(cacheKey, ResourceListQuery.class, () -> getResourceStoreDelegate().findByTypeInstance(resourceServer, type), - (revision, resources) -> new ResourceListQuery(revision, cacheKey, resources.stream().map(Resource::getId).collect(Collectors.toSet()), resourceServerId), resourceServer); - } - @Override public void findByTypeInstance(ResourceServer resourceServer, String type, Consumer consumer) { if (type == null) return; @@ -873,9 +837,9 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { Set resources = query.getResources(); if (consumer != null) { - resources.stream().map(resourceId -> (R) findById(resourceServer, resourceId)).forEach(consumer); + resources.stream().map(resourceId -> (R) findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, resourceServer, resourceId)).forEach(consumer); } else { - model = resources.stream().map(resourceId -> (R) findById(resourceServer, resourceId)).collect(Collectors.toList()); + model = resources.stream().map(resourceId -> (R) findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, resourceServer, resourceId)).collect(Collectors.toList()); } } @@ -891,18 +855,18 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { @Override public Policy create(ResourceServer resourceServer, AbstractPolicyRepresentation representation) { Policy policy = getPolicyStoreDelegate().create(resourceServer, representation); - Policy cached = findById(resourceServer, policy.getId()); + Policy cached = findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, resourceServer, policy.getId()); registerPolicyInvalidation(policy.getId(), representation.getName(), representation.getResources(), representation.getScopes(), null, resourceServer.getId()); if (cached == null) { - cached = findById(resourceServer, policy.getId()); + cached = findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, resourceServer, policy.getId()); } return cached; } @Override - public void delete(String id) { + public void delete(RealmModel realm, String id) { if (id == null) return; - Policy policy = findById(null, id); + Policy policy = findById(realm, null, id); if (policy == null) return; cache.invalidateObject(id); @@ -916,12 +880,12 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { Set scopes = policy.getScopes().stream().map(Scope::getId).collect(Collectors.toSet()); invalidationEvents.add(PolicyRemovedEvent.create(id, policy.getName(), resources, resourceTypes, scopes, resourceServer.getId())); cache.policyRemoval(id, policy.getName(), resources, resourceTypes, scopes, resourceServer.getId(), invalidations); - getPolicyStoreDelegate().delete(id); + getPolicyStoreDelegate().delete(realm, id); } @Override - public Policy findById(ResourceServer resourceServer, String id) { + public Policy findById(RealmModel realm, ResourceServer resourceServer, String id) { if (id == null) return null; CachedPolicy cached = cache.get(id, CachedPolicy.class); @@ -930,7 +894,7 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { } if (cached == null) { if (! modelMightExist(id)) return null; - Policy model = getPolicyStoreDelegate().findById(resourceServer, id); + Policy model = getPolicyStoreDelegate().findById(realm, resourceServer, id); Long loaded = cache.getCurrentRevision(id); if (model == null) { setModelDoesNotExists(id, loaded); @@ -940,7 +904,7 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { cached = new CachedPolicy(loaded, model); cache.addRevisioned(cached, startupRevision); } else if (invalidations.contains(id)) { - return getPolicyStoreDelegate().findById(resourceServer, id); + return getPolicyStoreDelegate().findById(realm, resourceServer, id); } else if (managedPolicies.containsKey(id)) { return managedPolicies.get(id); } @@ -977,8 +941,8 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { } @Override - public List findByResourceServer(ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults) { - return getPolicyStoreDelegate().findByResourceServer(resourceServer, attributes, firstResult, maxResults); + public List find(RealmModel realm, ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults) { + return getPolicyStoreDelegate().find(realm, resourceServer, attributes, firstResult, maxResults); } @Override @@ -1122,10 +1086,10 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { if (consumer != null) { for (String id : policies) { - consumer.accept((R) findById(resourceServer, id)); + consumer.accept((R) findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, resourceServer, id)); } } else { - model = policies.stream().map(resourceId -> (R) findById(resourceServer, resourceId)) + model = policies.stream().map(resourceId -> (R) findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, resourceServer, resourceId)) .filter(Objects::nonNull).collect(Collectors.toList()); } } @@ -1150,9 +1114,9 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { } @Override - public void delete(String id) { + public void delete(RealmModel realm, String id) { if (id == null) return; - PermissionTicket permission = findById(null, id); + PermissionTicket permission = findById(realm, null, id); if (permission == null) return; cache.invalidateObject(id); @@ -1162,13 +1126,13 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { } invalidationEvents.add(PermissionTicketRemovedEvent.create(id, permission.getOwner(), permission.getRequester(), permission.getResource().getId(), permission.getResource().getName(), scopeId, permission.getResourceServer().getId())); cache.permissionTicketRemoval(id, permission.getOwner(), permission.getRequester(), permission.getResource().getId(), permission.getResource().getName(),scopeId, permission.getResourceServer().getId(), invalidations); - getPermissionTicketStoreDelegate().delete(id); + getPermissionTicketStoreDelegate().delete(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, id); UserManagedPermissionUtil.removePolicy(permission, StoreFactoryCacheSession.this); } @Override - public PermissionTicket findById(ResourceServer resourceServer, String id) { + public PermissionTicket findById(RealmModel realm, ResourceServer resourceServer, String id) { if (id == null) return null; CachedPermissionTicket cached = cache.get(id, CachedPermissionTicket.class); @@ -1178,7 +1142,7 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { if (cached == null) { Long loaded = cache.getCurrentRevision(id); if (! modelMightExist(id)) return null; - PermissionTicket model = getPermissionTicketStoreDelegate().findById(resourceServer, id); + PermissionTicket model = getPermissionTicketStoreDelegate().findById(realm, resourceServer, id); if (model == null) { setModelDoesNotExists(id, loaded); return null; @@ -1187,7 +1151,7 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { cached = new CachedPermissionTicket(loaded, model); cache.addRevisioned(cached, startupRevision); } else if (invalidations.contains(id)) { - return getPermissionTicketStoreDelegate().findById(resourceServer, id); + return getPermissionTicketStoreDelegate().findById(realm, resourceServer, id); } else if (managedPermissionTickets.containsKey(id)) { return managedPermissionTickets.get(id); } @@ -1196,11 +1160,6 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { return adapter; } - @Override - public List findByResourceServer(ResourceServer resourceServer) { - return getPermissionTicketStoreDelegate().findByResourceServer(resourceServer); - } - @Override public List findByResource(ResourceServer resourceServer, Resource resource) { String resourceServerId = resourceServer == null ? null : resourceServer.getId(); @@ -1218,8 +1177,8 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { } @Override - public List find(ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResult) { - return getPermissionTicketStoreDelegate().find(resourceServer, attributes, firstResult, maxResult); + public List find(RealmModel realm, ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResult) { + return getPermissionTicketStoreDelegate().find(realm, resourceServer, attributes, firstResult, maxResult); } @Override @@ -1248,14 +1207,6 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { return getPermissionTicketStoreDelegate().findGrantedOwnerResources(realm, owner, firstResult, maxResults); } - @Override - public List findByOwner(ResourceServer resourceServer, String owner) { - String resourceServerId = resourceServer == null ? null : resourceServer.getId(); - String cacheKey = getPermissionTicketByOwner(owner, resourceServerId); - return cacheQuery(cacheKey, PermissionTicketListQuery.class, () -> getPermissionTicketStoreDelegate().findByOwner(resourceServer, owner), - (revision, permissions) -> new PermissionTicketListQuery(revision, cacheKey, permissions.stream().map(PermissionTicket::getId).collect(Collectors.toSet()), resourceServerId), resourceServer); - } - private List cacheQuery(String cacheKey, Class queryType, Supplier> resultSupplier, BiFunction, Q> querySupplier, ResourceServer resourceServer) { Q query = cache.get(cacheKey, queryType); if (query != null) { @@ -1272,7 +1223,7 @@ public class StoreFactoryCacheSession implements CachedStoreFactoryProvider { } else if (query.isInvalid(invalidations)) { return resultSupplier.get(); } else { - return query.getPermissions().stream().map(resourceId -> (R) findById(resourceServer, resourceId)).collect(Collectors.toList()); + return query.getPermissions().stream().map(resourceId -> (R) findById(InfinispanCacheStoreFactoryProviderFactory.NULL_REALM, resourceServer, resourceId)).collect(Collectors.toList()); } } } diff --git a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAAuthorizationStoreFactory.java b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAAuthorizationStoreFactory.java index 24d0a2963e..84a4351390 100644 --- a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAAuthorizationStoreFactory.java +++ b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAAuthorizationStoreFactory.java @@ -26,12 +26,24 @@ import org.keycloak.authorization.store.AuthorizationStoreFactory; import org.keycloak.authorization.store.StoreFactory; import org.keycloak.connections.jpa.JpaConnectionProvider; import org.keycloak.models.KeycloakSession; +import org.keycloak.models.RealmModel; + import static org.keycloak.models.jpa.JpaRealmProviderFactory.PROVIDER_PRIORITY; /** * @author Pedro Igor */ public class JPAAuthorizationStoreFactory implements AuthorizationStoreFactory { + + /** + * Legacy store doesn't store realm id for any entity and no method there is using new introduced RealmModel parameter. + * The parameter was introduced for usage only in the new storage. Therefore, in some cases we may break our rule specified in JavaDoc + * and use {@code null} value as parameter that otherwise cannot be {@code null}. We need to be careful and place such value only to a method call + * that cannot end up in the new store because it would end with {@link NullPointerException}. To mark all places where we do this, + * we use this variable so it is easily searchable. + */ + public static final RealmModel NULL_REALM = null; + @Override public StoreFactory create(KeycloakSession session) { AuthorizationProvider provider = session.getProvider(AuthorizationProvider.class); diff --git a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAPermissionTicketStore.java b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAPermissionTicketStore.java index b56d70144b..9a49eecce8 100644 --- a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAPermissionTicketStore.java +++ b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAPermissionTicketStore.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -152,7 +152,7 @@ public class JPAPermissionTicketStore implements PermissionTicketStore { } @Override - public void delete(String id) { + public void delete(RealmModel realm, String id) { PermissionTicketEntity policy = entityManager.find(PermissionTicketEntity.class, id, LockModeType.PESSIMISTIC_WRITE); if (policy != null) { this.entityManager.remove(policy); @@ -161,7 +161,7 @@ public class JPAPermissionTicketStore implements PermissionTicketStore { @Override - public PermissionTicket findById(ResourceServer resourceServer, String id) { + public PermissionTicket findById(RealmModel realm, ResourceServer resourceServer, String id) { if (id == null) { return null; } @@ -172,26 +172,6 @@ public class JPAPermissionTicketStore implements PermissionTicketStore { return new PermissionTicketAdapter(entity, entityManager, provider.getStoreFactory()); } - @Override - public List findByResourceServer(final ResourceServer resourceServer) { - TypedQuery query = entityManager.createNamedQuery("findPolicyIdByServerId", String.class); - - query.setParameter("serverId", resourceServer == null ? null : resourceServer.getId()); - - List result = query.getResultList(); - List list = new LinkedList<>(); - PermissionTicketStore ticketStore = provider.getStoreFactory().getPermissionTicketStore(); - - for (String id : result) { - PermissionTicket ticket = ticketStore.findById(resourceServer, id); - if (Objects.nonNull(ticket)) { - list.add(ticket); - } - } - - return list; - } - @Override public List findByResource(ResourceServer resourceServer, final Resource resource) { TypedQuery query = entityManager.createNamedQuery("findPermissionIdByResource", String.class); @@ -205,7 +185,7 @@ public class JPAPermissionTicketStore implements PermissionTicketStore { PermissionTicketStore ticketStore = provider.getStoreFactory().getPermissionTicketStore(); for (String id : result) { - PermissionTicket ticket = ticketStore.findById(resourceServer, id); + PermissionTicket ticket = ticketStore.findById(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, id); if (Objects.nonNull(ticket)) { list.add(ticket); } @@ -232,7 +212,7 @@ public class JPAPermissionTicketStore implements PermissionTicketStore { PermissionTicketStore ticketStore = provider.getStoreFactory().getPermissionTicketStore(); for (String id : result) { - PermissionTicket ticket = ticketStore.findById(resourceServer, id); + PermissionTicket ticket = ticketStore.findById(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, id); if (Objects.nonNull(ticket)) { list.add(ticket); } @@ -242,7 +222,7 @@ public class JPAPermissionTicketStore implements PermissionTicketStore { } @Override - public List find(ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResult) { + public List find(RealmModel realm, ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResult) { CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery querybuilder = builder.createQuery(PermissionTicketEntity.class); Root root = querybuilder.from(PermissionTicketEntity.class); @@ -260,7 +240,7 @@ public class JPAPermissionTicketStore implements PermissionTicketStore { PermissionTicketStore ticketStore = provider.getStoreFactory().getPermissionTicketStore(); for (String id : result) { - PermissionTicket ticket = ticketStore.findById(resourceServer, id); + PermissionTicket ticket = ticketStore.findById(realm, resourceServer, id); if (Objects.nonNull(ticket)) { list.add(ticket); } @@ -276,7 +256,7 @@ public class JPAPermissionTicketStore implements PermissionTicketStore { filters.put(PermissionTicket.FilterOption.GRANTED, Boolean.TRUE.toString()); filters.put(PermissionTicket.FilterOption.REQUESTER, userId); - return find(resourceServer, filters, null, null); + return find(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, filters, null, null); } @Override @@ -287,7 +267,7 @@ public class JPAPermissionTicketStore implements PermissionTicketStore { filters.put(PermissionTicket.FilterOption.GRANTED, Boolean.TRUE.toString()); filters.put(PermissionTicket.FilterOption.REQUESTER, userId); - return find(resourceServer, filters, null, null); + return find(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, filters, null, null); } @Override @@ -308,7 +288,7 @@ public class JPAPermissionTicketStore implements PermissionTicketStore { ResourceStore resourceStore = provider.getStoreFactory().getResourceStore(); for (String id : result) { - Resource resource = resourceStore.findById(null, id); + Resource resource = resourceStore.findById(realm, null, id); if (Objects.nonNull(resource)) { list.add(resource); @@ -330,7 +310,7 @@ public class JPAPermissionTicketStore implements PermissionTicketStore { ResourceStore resourceStore = provider.getStoreFactory().getResourceStore(); for (String id : result) { - Resource resource = resourceStore.findById(null, id); + Resource resource = resourceStore.findById(realm, null, id); if (Objects.nonNull(resource)) { list.add(resource); @@ -340,25 +320,4 @@ public class JPAPermissionTicketStore implements PermissionTicketStore { return list; } - @Override - public List findByOwner(ResourceServer resourceServer, String owner) { - TypedQuery query = entityManager.createNamedQuery("findPolicyIdByType", String.class); - - query.setFlushMode(FlushModeType.COMMIT); - query.setParameter("serverId", resourceServer == null ? null : resourceServer.getId()); - query.setParameter("owner", owner); - - List result = query.getResultList(); - List list = new LinkedList<>(); - PermissionTicketStore ticketStore = provider.getStoreFactory().getPermissionTicketStore(); - - for (String id : result) { - PermissionTicket ticket = ticketStore.findById(resourceServer, id); - if (Objects.nonNull(ticket)) { - list.add(ticket); - } - } - - return list; - } } diff --git a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAPolicyStore.java b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAPolicyStore.java index f5678ad1b8..a03f70b035 100644 --- a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAPolicyStore.java +++ b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAPolicyStore.java @@ -1,13 +1,12 @@ /* - * JBoss, Home of Professional Open Source. - * Copyright 2016 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -41,8 +40,10 @@ import org.keycloak.authorization.model.Policy; import org.keycloak.authorization.model.Resource; 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.authorization.store.StoreFactory; +import org.keycloak.models.RealmModel; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation; import javax.persistence.LockModeType; @@ -83,7 +84,7 @@ public class JPAPolicyStore implements PolicyStore { } @Override - public void delete(String id) { + public void delete(RealmModel realm, String id) { PolicyEntity policy = entityManager.find(PolicyEntity.class, id, LockModeType.PESSIMISTIC_WRITE); if (policy != null) { this.entityManager.remove(policy); @@ -92,7 +93,7 @@ public class JPAPolicyStore implements PolicyStore { @Override - public Policy findById(ResourceServer resourceServer, String id) { + public Policy findById(RealmModel realm, ResourceServer resourceServer, String id) { if (id == null) { return null; } @@ -130,7 +131,7 @@ public class JPAPolicyStore implements PolicyStore { List result = query.getResultList(); List list = new LinkedList<>(); for (String id : result) { - Policy policy = provider.getStoreFactory().getPolicyStore().findById(resourceServer, id); + Policy policy = provider.getStoreFactory().getPolicyStore().findById(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, id); if (Objects.nonNull(policy)) { list.add(policy); } @@ -139,7 +140,7 @@ public class JPAPolicyStore implements PolicyStore { } @Override - public List findByResourceServer(ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults) { + public List find(RealmModel realm, ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults) { CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery querybuilder = builder.createQuery(PolicyEntity.class); Root root = querybuilder.from(PolicyEntity.class); @@ -199,7 +200,7 @@ public class JPAPolicyStore implements PolicyStore { List result = paginateQuery(query, firstResult, maxResults).getResultList(); List list = new LinkedList<>(); for (String id : result) { - Policy policy = provider.getStoreFactory().getPolicyStore().findById(resourceServer, id); + Policy policy = provider.getStoreFactory().getPolicyStore().findById(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, id); if (Objects.nonNull(policy)) { list.add(policy); } @@ -218,7 +219,7 @@ public class JPAPolicyStore implements PolicyStore { PolicyStore storeFactory = provider.getStoreFactory().getPolicyStore(); closing(query.getResultStream() - .map(entity -> storeFactory.findById(resourceServer, entity.getId())) + .map(entity -> storeFactory.findById(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, entity.getId())) .filter(Objects::nonNull)) .forEach(consumer::accept); } @@ -254,7 +255,7 @@ public class JPAPolicyStore implements PolicyStore { PolicyStore storeFactory = provider.getStoreFactory().getPolicyStore(); for (PolicyEntity entity : query.getResultList()) { - list.add(storeFactory.findById(resourceServer, entity.getId())); + list.add(storeFactory.findById(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, entity.getId())); } return list; @@ -295,7 +296,7 @@ public class JPAPolicyStore implements PolicyStore { List result = query.getResultList(); List list = new LinkedList<>(); for (String id : result) { - Policy policy = provider.getStoreFactory().getPolicyStore().findById(resourceServer, id); + Policy policy = provider.getStoreFactory().getPolicyStore().findById(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, id); if (Objects.nonNull(policy)) { list.add(policy); } @@ -315,7 +316,7 @@ public class JPAPolicyStore implements PolicyStore { List result = query.getResultList(); List list = new LinkedList<>(); for (String id : result) { - Policy policy = provider.getStoreFactory().getPolicyStore().findById(resourceServer, id); + Policy policy = provider.getStoreFactory().getPolicyStore().findById(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, id); if (Objects.nonNull(policy)) { list.add(policy); } diff --git a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAResourceServerStore.java b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAResourceServerStore.java index 3f1b2cafbf..e484c6d12f 100644 --- a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAResourceServerStore.java +++ b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAResourceServerStore.java @@ -1,13 +1,12 @@ /* - * JBoss, Home of Professional Open Source. - * Copyright 2016 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -24,6 +23,7 @@ import org.keycloak.authorization.jpa.entities.ResourceEntity; import org.keycloak.authorization.jpa.entities.ResourceServerEntity; import org.keycloak.authorization.jpa.entities.ScopeEntity; import org.keycloak.authorization.model.ResourceServer; +import org.keycloak.authorization.store.PermissionTicketStore; import org.keycloak.authorization.store.ResourceServerStore; import org.keycloak.models.ModelException; import org.keycloak.models.RealmModel; @@ -131,6 +131,6 @@ public class JPAResourceServerStore implements ResourceServerStore { @Override public ResourceServer findByClient(ClientModel client) { - return findById(null, client.getId()); + return findById(JPAAuthorizationStoreFactory.NULL_REALM, client.getId()); } } diff --git a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAResourceStore.java b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAResourceStore.java index a327d7ef17..3fc03c9837 100644 --- a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAResourceStore.java +++ b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAResourceStore.java @@ -1,13 +1,12 @@ /* - * JBoss, Home of Professional Open Source. - * Copyright 2016 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -22,8 +21,10 @@ import org.keycloak.authorization.jpa.entities.ResourceEntity; import org.keycloak.authorization.model.Resource; import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.Scope; +import org.keycloak.authorization.store.PermissionTicketStore; import org.keycloak.authorization.store.ResourceStore; import org.keycloak.authorization.store.StoreFactory; +import org.keycloak.models.RealmModel; import org.keycloak.models.utils.KeycloakModelUtils; import javax.persistence.EntityManager; @@ -80,7 +81,7 @@ public class JPAResourceStore implements ResourceStore { } @Override - public void delete(String id) { + public void delete(RealmModel realm, String id) { ResourceEntity resource = entityManager.getReference(ResourceEntity.class, id); if (resource == null) return; @@ -89,7 +90,7 @@ public class JPAResourceStore implements ResourceStore { } @Override - public Resource findById(ResourceServer resourceServer, String id) { + public Resource findById(RealmModel realm, ResourceServer resourceServer, String id) { if (id == null) { return null; } @@ -100,19 +101,10 @@ public class JPAResourceStore implements ResourceStore { } @Override - public void findByOwner(ResourceServer resourceServer, String ownerId, Consumer consumer) { + public void findByOwner(RealmModel realm, ResourceServer resourceServer, String ownerId, Consumer consumer) { findByOwnerFilter(ownerId, resourceServer, consumer, -1, -1); } - @Override - public List findByOwner(ResourceServer resourceServer, String ownerId, Integer firstResult, Integer maxResults) { - List list = new LinkedList<>(); - - findByOwnerFilter(ownerId, resourceServer, list::add, firstResult, maxResults); - - return list; - } - private void findByOwnerFilter(String ownerId, ResourceServer resourceServer, Consumer consumer, int firstResult, int maxResult) { boolean pagination = firstResult > -1 && maxResult > -1; String queryName = pagination ? "findResourceIdByOwnerOrdered" : "findResourceIdByOwner"; @@ -136,30 +128,7 @@ public class JPAResourceStore implements ResourceStore { } ResourceStore resourceStore = provider.getStoreFactory().getResourceStore(); - closing(query.getResultStream().map(id -> resourceStore.findById(resourceServer, id.getId()))).forEach(consumer); - } - - @Override - public List findByUri(ResourceServer resourceServer, String uri) { - TypedQuery query = entityManager.createNamedQuery("findResourceIdByUri", String.class); - - query.setFlushMode(FlushModeType.COMMIT); - query.setParameter("uri", uri); - query.setParameter("serverId", resourceServer == null ? null : resourceServer.getId()); - - List result = query.getResultList(); - List list = new LinkedList<>(); - ResourceStore resourceStore = provider.getStoreFactory().getResourceStore(); - - for (String id : result) { - Resource resource = resourceStore.findById(resourceServer, id); - - if (resource != null) { - list.add(resource); - } - } - - return list; + closing(query.getResultStream().map(id -> resourceStore.findById(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, id.getId()))).forEach(consumer); } @Override @@ -173,7 +142,7 @@ public class JPAResourceStore implements ResourceStore { ResourceStore resourceStore = provider.getStoreFactory().getResourceStore(); for (String id : result) { - Resource resource = resourceStore.findById(resourceServer, id); + Resource resource = resourceStore.findById(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, id); if (resource != null) { list.add(resource); @@ -184,7 +153,7 @@ public class JPAResourceStore implements ResourceStore { } @Override - public List findByResourceServer(ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults) { + public List find(RealmModel realm, ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults) { CriteriaBuilder builder = entityManager.getCriteriaBuilder(); CriteriaQuery querybuilder = builder.createQuery(ResourceEntity.class); Root root = querybuilder.from(ResourceEntity.class); @@ -237,7 +206,7 @@ public class JPAResourceStore implements ResourceStore { ResourceStore resourceStore = provider.getStoreFactory().getResourceStore(); for (String id : result) { - Resource resource = resourceStore.findById(resourceServer, id); + Resource resource = resourceStore.findById(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, id); if (resource != null) { list.add(resource); diff --git a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAScopeStore.java b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAScopeStore.java index 0f6dd02d3b..b0114fb761 100644 --- a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAScopeStore.java +++ b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/JPAScopeStore.java @@ -1,13 +1,12 @@ /* - * JBoss, Home of Professional Open Source. - * Copyright 2016 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -35,7 +34,9 @@ import org.keycloak.authorization.AuthorizationProvider; import org.keycloak.authorization.jpa.entities.ScopeEntity; import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.Scope; +import org.keycloak.authorization.store.PermissionTicketStore; import org.keycloak.authorization.store.ScopeStore; +import org.keycloak.models.RealmModel; import org.keycloak.models.utils.KeycloakModelUtils; import javax.persistence.LockModeType; @@ -79,7 +80,7 @@ public class JPAScopeStore implements ScopeStore { } @Override - public void delete(String id) { + public void delete(RealmModel realm, String id) { ScopeEntity scope = entityManager.find(ScopeEntity.class, id, LockModeType.PESSIMISTIC_WRITE); if (scope != null) { @@ -88,7 +89,7 @@ public class JPAScopeStore implements ScopeStore { } @Override - public Scope findById(ResourceServer resourceServer, String id) { + public Scope findById(RealmModel realm, ResourceServer resourceServer, String id) { if (id == null) { return null; } @@ -109,7 +110,7 @@ public class JPAScopeStore implements ScopeStore { query.setParameter("name", name); String id = query.getSingleResult(); - return provider.getStoreFactory().getScopeStore().findById(resourceServer, id); + return provider.getStoreFactory().getScopeStore().findById(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, id); } catch (NoResultException nre) { return null; } @@ -125,7 +126,7 @@ public class JPAScopeStore implements ScopeStore { List result = query.getResultList(); List list = new LinkedList<>(); for (String id : result) { - list.add(provider.getStoreFactory().getScopeStore().findById(resourceServer, id)); + list.add(provider.getStoreFactory().getScopeStore().findById(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, id)); } return list; } @@ -160,7 +161,7 @@ public class JPAScopeStore implements ScopeStore { List result = paginateQuery(query, firstResult, maxResults).getResultList(); List list = new LinkedList<>(); for (Object id : result) { - list.add(provider.getStoreFactory().getScopeStore().findById(resourceServer, (String)id)); + list.add(provider.getStoreFactory().getScopeStore().findById(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, (String)id)); } return list; diff --git a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/PermissionTicketAdapter.java b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/PermissionTicketAdapter.java index 3e549ad48b..dcbf0e77a9 100644 --- a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/PermissionTicketAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/PermissionTicketAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,6 +28,7 @@ import org.keycloak.authorization.model.Policy; import org.keycloak.authorization.model.Resource; import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.Scope; +import org.keycloak.authorization.store.PermissionTicketStore; import org.keycloak.authorization.store.StoreFactory; import org.keycloak.models.jpa.JpaModel; @@ -90,7 +91,7 @@ public class PermissionTicketAdapter implements PermissionTicket, JpaModel set = new HashSet<>(); ResourceServer resourceServer = getResourceServer(); for (ResourceEntity res : entity.getResources()) { - set.add(storeFactory.getResourceStore().findById(resourceServer, res.getId())); + set.add(storeFactory.getResourceStore().findById(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, res.getId())); } return Collections.unmodifiableSet(set); } @@ -180,7 +181,7 @@ public class PolicyAdapter extends AbstractAuthorizationModel implements Policy, Set set = new HashSet<>(); ResourceServer resourceServer = getResourceServer(); for (ScopeEntity res : entity.getScopes()) { - set.add(storeFactory.getScopeStore().findById(resourceServer, res.getId())); + set.add(storeFactory.getScopeStore().findById(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, res.getId())); } return Collections.unmodifiableSet(set); } diff --git a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ResourceAdapter.java b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ResourceAdapter.java index d0809b43e5..6ca025c27b 100644 --- a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ResourceAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ResourceAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,6 +23,7 @@ import org.keycloak.authorization.model.AbstractAuthorizationModel; import org.keycloak.authorization.model.Resource; import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.Scope; +import org.keycloak.authorization.store.PermissionTicketStore; import org.keycloak.authorization.store.StoreFactory; import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.models.jpa.JpaModel; @@ -118,7 +119,7 @@ public class ResourceAdapter extends AbstractAuthorizationModel implements Resou List scopes = new LinkedList<>(); ResourceServer resourceServer = getResourceServer(); for (ScopeEntity scope : entity.getScopes()) { - scopes.add(storeFactory.getScopeStore().findById(resourceServer, scope.getId())); + scopes.add(storeFactory.getScopeStore().findById(JPAAuthorizationStoreFactory.NULL_REALM, resourceServer, scope.getId())); } return Collections.unmodifiableList(scopes); @@ -138,7 +139,7 @@ public class ResourceAdapter extends AbstractAuthorizationModel implements Resou @Override public ResourceServer getResourceServer() { - return storeFactory.getResourceServerStore().findById(null, entity.getResourceServer()); + return storeFactory.getResourceServerStore().findById(JPAAuthorizationStoreFactory.NULL_REALM, entity.getResourceServer()); } @Override diff --git a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ScopeAdapter.java b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ScopeAdapter.java index 735fab7deb..1e7391d04b 100644 --- a/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ScopeAdapter.java +++ b/model/jpa/src/main/java/org/keycloak/authorization/jpa/store/ScopeAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,6 +20,7 @@ import org.keycloak.authorization.jpa.entities.ScopeEntity; import org.keycloak.authorization.model.AbstractAuthorizationModel; import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.Scope; +import org.keycloak.authorization.store.PermissionTicketStore; import org.keycloak.authorization.store.StoreFactory; import org.keycloak.models.jpa.JpaModel; @@ -88,7 +89,7 @@ public class ScopeAdapter extends AbstractAuthorizationModel implements Scope, J @Override public ResourceServer getResourceServer() { - return storeFactory.getResourceServerStore().findById(null, entity.getResourceServer().getId()); + return storeFactory.getResourceServerStore().findById(JPAAuthorizationStoreFactory.NULL_REALM, entity.getResourceServer().getId()); } public static ScopeEntity toEntity(EntityManager em, Scope scope) { diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/MapPermissionTicketStore.java b/model/map/src/main/java/org/keycloak/models/map/authorization/MapPermissionTicketStore.java index b079937346..b2faafa3d0 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/MapPermissionTicketStore.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/MapPermissionTicketStore.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -60,26 +60,20 @@ public class MapPermissionTicketStore implements PermissionTicketStore { private static final Logger LOG = Logger.getLogger(MapPermissionTicketStore.class); private final AuthorizationProvider authorizationProvider; final MapKeycloakTransaction tx; - private final KeycloakSession session; public MapPermissionTicketStore(KeycloakSession session, MapStorage permissionTicketStore, AuthorizationProvider provider) { this.authorizationProvider = provider; this.tx = permissionTicketStore.createTransaction(session); session.getTransactionManager().enlist(tx); - this.session = session; } - private Function entityToAdapterFunc(ResourceServer resourceServer) { - return origEntity -> new MapPermissionTicketAdapter(resourceServer == null ? findResourceServer(origEntity) : resourceServer, origEntity, authorizationProvider.getStoreFactory()); + private Function entityToAdapterFunc(RealmModel realm, ResourceServer resourceServer) { + return origEntity -> new MapPermissionTicketAdapter(realm, resourceServer, origEntity, authorizationProvider.getStoreFactory()); } - private ResourceServer findResourceServer(MapPermissionTicketEntity entity) { - RealmModel realm = session.realms().getRealm(entity.getRealmId()); - return authorizationProvider.getStoreFactory().getResourceServerStore().findById(realm, entity.getResourceServerId()); - } - - private DefaultModelCriteria forResourceServer(ResourceServer resourceServer) { - DefaultModelCriteria mcb = criteria(); + private DefaultModelCriteria forRealmAndResourceServer(RealmModel realm, ResourceServer resourceServer) { + final DefaultModelCriteria mcb = DefaultModelCriteria.criteria() + .compare(PermissionTicket.SearchableFields.REALM_ID, Operator.EQ, realm.getId()); return resourceServer == null ? mcb @@ -89,7 +83,7 @@ public class MapPermissionTicketStore implements PermissionTicketStore { @Override public long count(ResourceServer resourceServer, Map attributes) { - DefaultModelCriteria mcb = forResourceServer(resourceServer).and( + DefaultModelCriteria mcb = forRealmAndResourceServer(resourceServer.getRealm(), resourceServer).and( attributes.entrySet().stream() .map(this::filterEntryToDefaultModelCriteria) .toArray(DefaultModelCriteria[]::new) @@ -101,11 +95,13 @@ public class MapPermissionTicketStore implements PermissionTicketStore { @Override public PermissionTicket create(ResourceServer resourceServer, Resource resource, Scope scope, String requester) { LOG.tracef("create(%s, %s, %s, %s)%s", resource, scope, requester, resourceServer, getShortStackTrace()); + RealmModel realm = resourceServer.getRealm(); + + String owner = authorizationProvider.getStoreFactory().getResourceStore().findById(realm, resourceServer, resource.getId()).getOwner(); - String owner = authorizationProvider.getStoreFactory().getResourceStore().findById(resourceServer, resource.getId()).getOwner(); // @UniqueConstraint(columnNames = {"OWNER", "REQUESTER", "RESOURCE_SERVER_ID", "RESOURCE_ID", "SCOPE_ID"}) - DefaultModelCriteria mcb = forResourceServer(resourceServer) + DefaultModelCriteria mcb = forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.OWNER, Operator.EQ, owner) .compare(SearchableFields.RESOURCE_ID, Operator.EQ, resource.getId()) .compare(SearchableFields.REQUESTER, Operator.EQ, requester); @@ -130,18 +126,18 @@ public class MapPermissionTicketStore implements PermissionTicketStore { entity.setOwner(owner); entity.setResourceServerId(resourceServer.getId()); - entity.setRealmId(resourceServer.getRealm().getId()); + entity.setRealmId(realm.getId()); entity = tx.create(entity); - return entity == null ? null : entityToAdapterFunc(resourceServer).apply(entity); + return entity == null ? null : entityToAdapterFunc(realm, resourceServer).apply(entity); } @Override - public void delete(String id) { + public void delete(RealmModel realm, String id) { LOG.tracef("delete(%s)%s", id, getShortStackTrace()); - PermissionTicket permissionTicket = findById((ResourceServer) null, id); + PermissionTicket permissionTicket = findById(realm, null, id); if (permissionTicket == null) return; tx.delete(id); @@ -149,42 +145,25 @@ public class MapPermissionTicketStore implements PermissionTicketStore { } @Override - public PermissionTicket findById(ResourceServer resourceServer, String id) { + public PermissionTicket findById(RealmModel realm, ResourceServer resourceServer, String id) { LOG.tracef("findById(%s, %s)%s", id, resourceServer, getShortStackTrace()); - return tx.read(withCriteria(forResourceServer(resourceServer) + return tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.ID, Operator.EQ, id))) .findFirst() - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .orElse(null); } - @Override - public List findByResourceServer(ResourceServer resourceServer) { - LOG.tracef("findByResourceServer(%s)%s", resourceServer, getShortStackTrace()); - - return tx.read(withCriteria(forResourceServer(resourceServer))) - .map(entityToAdapterFunc(resourceServer)) - .collect(Collectors.toList()); - } - - @Override - public List findByOwner(ResourceServer resourceServer, String owner) { - LOG.tracef("findByOwner(%s, %s)%s", owner, resourceServer, getShortStackTrace()); - - return tx.read(withCriteria(forResourceServer(resourceServer) - .compare(SearchableFields.OWNER, Operator.EQ, owner))) - .map(entityToAdapterFunc(resourceServer)) - .collect(Collectors.toList()); - } - @Override public List findByResource(ResourceServer resourceServer, Resource resource) { LOG.tracef("findByResource(%s, %s)%s", resource, resourceServer, getShortStackTrace()); - return tx.read(withCriteria(forResourceServer(resourceServer) + RealmModel realm = resourceServer.getRealm(); + + return tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.RESOURCE_ID, Operator.EQ, resource.getId()))) - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .collect(Collectors.toList()); } @@ -192,15 +171,17 @@ public class MapPermissionTicketStore implements PermissionTicketStore { public List findByScope(ResourceServer resourceServer, Scope scope) { LOG.tracef("findByScope(%s, %s)%s", scope, resourceServer, getShortStackTrace()); - return tx.read(withCriteria(forResourceServer(resourceServer) + RealmModel realm = resourceServer.getRealm(); + + return tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.SCOPE_ID, Operator.EQ, scope.getId()))) - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .collect(Collectors.toList()); } @Override - public List find(ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResult) { - DefaultModelCriteria mcb = forResourceServer(resourceServer); + public List find(RealmModel realm, ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResult) { + DefaultModelCriteria mcb = forRealmAndResourceServer(realm, resourceServer); if (attributes.containsKey(PermissionTicket.FilterOption.RESOURCE_NAME)) { String expectedResourceName = attributes.remove(PermissionTicket.FilterOption.RESOURCE_NAME); @@ -209,7 +190,7 @@ public class MapPermissionTicketStore implements PermissionTicketStore { filterOptionStringMap.put(Resource.FilterOption.EXACT_NAME, new String[]{expectedResourceName}); - List r = authorizationProvider.getStoreFactory().getResourceStore().findByResourceServer(resourceServer, filterOptionStringMap, null, null); + List r = authorizationProvider.getStoreFactory().getResourceStore().find(realm, resourceServer, filterOptionStringMap, null, null); if (r == null || r.isEmpty()) { return Collections.emptyList(); } @@ -223,7 +204,7 @@ public class MapPermissionTicketStore implements PermissionTicketStore { ); return tx.read(withCriteria(mcb).pagination(firstResult, maxResult, SearchableFields.ID)) - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .collect(Collectors.toList()); } @@ -264,7 +245,7 @@ public class MapPermissionTicketStore implements PermissionTicketStore { filters.put(PermissionTicket.FilterOption.GRANTED, Boolean.TRUE.toString()); filters.put(PermissionTicket.FilterOption.REQUESTER, userId); - return find(resourceServer, filters, null, null); + return find(resourceServer.getRealm(), resourceServer, filters, null, null); } @Override @@ -275,7 +256,7 @@ public class MapPermissionTicketStore implements PermissionTicketStore { filters.put(PermissionTicket.FilterOption.GRANTED, Boolean.TRUE.toString()); filters.put(PermissionTicket.FilterOption.REQUESTER, userId); - return find(resourceServer, filters, null, null); + return find(resourceServer.getRealm(), resourceServer, filters, null, null); } @Override @@ -296,13 +277,13 @@ public class MapPermissionTicketStore implements PermissionTicketStore { filterOptionMap.put(Resource.FilterOption.ID, new String[] {ticket.getResourceId()}); filterOptionMap.put(Resource.FilterOption.NAME, new String[] {name}); - List resource = resourceStore.findByResourceServer(resourceServerStore.findById(realm, ticket.getResourceServerId()), filterOptionMap, -1, 1); + List resource = resourceStore.find(realm, resourceServerStore.findById(realm, ticket.getResourceServerId()), filterOptionMap, -1, 1); return resource.isEmpty() ? null : resource.get(0); }; } else { ticketResourceMapper = ticket -> resourceStore - .findById(resourceServerStore.findById(realm, ticket.getResourceServerId()), ticket.getResourceId()); + .findById(realm, resourceServerStore.findById(realm, ticket.getResourceServerId()), ticket.getResourceId()); } return paginatedStream(tx.read(withCriteria(mcb).orderBy(SearchableFields.RESOURCE_ID, ASCENDING)) @@ -323,7 +304,7 @@ public class MapPermissionTicketStore implements PermissionTicketStore { return paginatedStream(tx.read(withCriteria(mcb).orderBy(SearchableFields.RESOURCE_ID, ASCENDING)) .filter(distinctByKey(MapPermissionTicketEntity::getResourceId)), firstResult, maxResults) - .map(ticket -> resourceStore.findById(resourceServerStore.findById(realm, ticket.getResourceServerId()), ticket.getResourceId())) + .map(ticket -> resourceStore.findById(realm, resourceServerStore.findById(realm, ticket.getResourceServerId()), ticket.getResourceId())) .collect(Collectors.toList()); } @@ -339,6 +320,6 @@ public class MapPermissionTicketStore implements PermissionTicketStore { public void preRemove(ResourceServer resourceServer) { LOG.tracef("preRemove(%s)%s", resourceServer, getShortStackTrace()); - tx.delete(withCriteria(forResourceServer(resourceServer))); + tx.delete(withCriteria(forRealmAndResourceServer(resourceServer.getRealm(), resourceServer))); } } diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/MapPolicyStore.java b/model/map/src/main/java/org/keycloak/models/map/authorization/MapPolicyStore.java index caebc233e9..41b695e969 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/MapPolicyStore.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/MapPolicyStore.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -54,26 +54,20 @@ public class MapPolicyStore implements PolicyStore { private static final Logger LOG = Logger.getLogger(MapPolicyStore.class); private final AuthorizationProvider authorizationProvider; final MapKeycloakTransaction tx; - private final KeycloakSession session; public MapPolicyStore(KeycloakSession session, MapStorage policyStore, AuthorizationProvider provider) { this.authorizationProvider = provider; this.tx = policyStore.createTransaction(session); session.getTransactionManager().enlist(tx); - this.session = session; } - private Function entityToAdapterFunc(ResourceServer resourceServer) { - return origEntity -> new MapPolicyAdapter(resourceServer == null ? findResourceServer(origEntity) : resourceServer, origEntity, authorizationProvider.getStoreFactory()); + private Function entityToAdapterFunc(RealmModel realm, ResourceServer resourceServer) { + return origEntity -> new MapPolicyAdapter(realm, resourceServer, origEntity, authorizationProvider.getStoreFactory()); } - private ResourceServer findResourceServer(MapPolicyEntity entity) { - RealmModel realm = session.realms().getRealm(entity.getRealmId()); - return authorizationProvider.getStoreFactory().getResourceServerStore().findById(realm, entity.getResourceServerId()); - } - - private DefaultModelCriteria forResourceServer(ResourceServer resourceServer) { - DefaultModelCriteria mcb = criteria(); + private DefaultModelCriteria forRealmAndResourceServer(RealmModel realm, ResourceServer resourceServer) { + DefaultModelCriteria mcb = DefaultModelCriteria.criteria() + .compare(Policy.SearchableFields.REALM_ID, Operator.EQ, realm.getId()); return resourceServer == null ? mcb @@ -84,9 +78,10 @@ public class MapPolicyStore implements PolicyStore { @Override public Policy create(ResourceServer resourceServer, AbstractPolicyRepresentation representation) { LOG.tracef("create(%s, %s, %s)%s", representation.getId(), resourceServer.getId(), resourceServer, getShortStackTrace()); + RealmModel realm = resourceServer.getRealm(); // @UniqueConstraint(columnNames = {"NAME", "RESOURCE_SERVER_ID"}) - DefaultModelCriteria mcb = forResourceServer(resourceServer) + DefaultModelCriteria mcb = forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.NAME, Operator.EQ, representation.getName()); if (tx.getCount(withCriteria(mcb)) > 0) { @@ -103,51 +98,57 @@ public class MapPolicyStore implements PolicyStore { entity = tx.create(entity); - return entity == null ? null : entityToAdapterFunc(resourceServer).apply(entity); + return entity == null ? null : entityToAdapterFunc(realm, resourceServer).apply(entity); } @Override - public void delete(String id) { + public void delete(RealmModel realm, String id) { LOG.tracef("delete(%s)%s", id, getShortStackTrace()); + + Policy policyEntity = findById(realm, null, id); + if (policyEntity == null) return; + tx.delete(id); } @Override - public Policy findById(ResourceServer resourceServer, String id) { + public Policy findById(RealmModel realm, ResourceServer resourceServer, String id) { LOG.tracef("findById(%s, %s)%s", id, resourceServer, getShortStackTrace()); - return tx.read(withCriteria(forResourceServer(resourceServer) + return tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.ID, Operator.EQ, id))) .findFirst() - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .orElse(null); } @Override public Policy findByName(ResourceServer resourceServer, String name) { LOG.tracef("findByName(%s, %s)%s", name, resourceServer, getShortStackTrace()); + RealmModel realm = resourceServer.getRealm(); - return tx.read(withCriteria(forResourceServer(resourceServer) + return tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.NAME, Operator.EQ, name))) .findFirst() - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .orElse(null); } @Override public List findByResourceServer(ResourceServer resourceServer) { LOG.tracef("findByResourceServer(%s)%s", resourceServer, getShortStackTrace()); + RealmModel realm = resourceServer.getRealm(); - return tx.read(withCriteria(forResourceServer(resourceServer))) - .map(entityToAdapterFunc(resourceServer)) + return tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer))) + .map(entityToAdapterFunc(realm, resourceServer)) .collect(Collectors.toList()); } @Override - public List findByResourceServer(ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults) { + public List find(RealmModel realm, ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults) { LOG.tracef("findByResourceServer(%s, %s, %d, %d)%s", attributes, resourceServer, firstResult, maxResults, getShortStackTrace()); - DefaultModelCriteria mcb = forResourceServer(resourceServer).and( + DefaultModelCriteria mcb = forRealmAndResourceServer(realm, resourceServer).and( attributes.entrySet().stream() .map(this::filterEntryToDefaultModelCriteria) .filter(Objects::nonNull) @@ -161,7 +162,7 @@ public class MapPolicyStore implements PolicyStore { return tx.read(withCriteria(mcb).pagination(firstResult, maxResults, SearchableFields.NAME)) .map(MapPolicyEntity::getId) // We need to go through cache - .map(id -> authorizationProvider.getStoreFactory().getPolicyStore().findById(resourceServer, id)) + .map(id -> authorizationProvider.getStoreFactory().getPolicyStore().findById(realm, resourceServer, id)) .collect(Collectors.toList()); } @@ -206,32 +207,40 @@ public class MapPolicyStore implements PolicyStore { @Override public void findByResource(ResourceServer resourceServer, Resource resource, Consumer consumer) { LOG.tracef("findByResource(%s, %s, %s)%s", resourceServer, resource, consumer, getShortStackTrace()); - - tx.read(withCriteria(forResourceServer(resourceServer) + RealmModel realm = resourceServer.getRealm(); + tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.RESOURCE_ID, Operator.EQ, resource.getId()))) - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .forEach(consumer); } @Override public void findByResourceType(ResourceServer resourceServer, String type, Consumer policyConsumer) { - tx.read(withCriteria(forResourceServer(resourceServer) + LOG.tracef("findByResourceType(%s, %s)%s", resourceServer, type, getShortStackTrace()); + RealmModel realm = resourceServer.getRealm(); + + tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.CONFIG, Operator.LIKE, (Object[]) new String[]{"defaultResourceType", type}))) - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .forEach(policyConsumer); } @Override public List findByScopes(ResourceServer resourceServer, List scopes) { - return tx.read(withCriteria(forResourceServer(resourceServer) + LOG.tracef("findByScopes(%s, %s)%s", resourceServer, scopes, getShortStackTrace()); + RealmModel realm = resourceServer.getRealm(); + + return tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.SCOPE_ID, Operator.IN, scopes.stream().map(Scope::getId)))) - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .collect(Collectors.toList()); } @Override public void findByScopes(ResourceServer resourceServer, Resource resource, List scopes, Consumer consumer) { - DefaultModelCriteria mcb = forResourceServer(resourceServer) + LOG.tracef("findByResourceType(%s, %s, %s)%s", resourceServer, resource, scopes, getShortStackTrace()); + RealmModel realm = resourceServer.getRealm(); + DefaultModelCriteria mcb = forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.TYPE, Operator.EQ, "scope") .compare(SearchableFields.SCOPE_ID, Operator.IN, scopes.stream().map(Scope::getId)); @@ -243,22 +252,26 @@ public class MapPolicyStore implements PolicyStore { .compare(SearchableFields.CONFIG, Operator.NOT_EXISTS, (Object[]) new String[] {"defaultResourceType"}); } - tx.read(withCriteria(mcb)).map(entityToAdapterFunc(resourceServer)).forEach(consumer); + tx.read(withCriteria(mcb)).map(entityToAdapterFunc(realm, resourceServer)).forEach(consumer); } @Override public List findByType(ResourceServer resourceServer, String type) { - return tx.read(withCriteria(forResourceServer(resourceServer) + LOG.tracef("findByType(%s, %s)%s", resourceServer, type, getShortStackTrace()); + RealmModel realm = resourceServer.getRealm(); + + return tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.TYPE, Operator.EQ, type))) - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .collect(Collectors.toList()); } @Override public List findDependentPolicies(ResourceServer resourceServer, String id) { - return tx.read(withCriteria(forResourceServer(resourceServer) + RealmModel realm = resourceServer.getRealm(); + return tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.ASSOCIATED_POLICY_ID, Operator.EQ, id))) - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .collect(Collectors.toList()); } @@ -274,6 +287,6 @@ public class MapPolicyStore implements PolicyStore { public void preRemove(ResourceServer resourceServer) { LOG.tracef("preRemove(%s)%s", resourceServer, getShortStackTrace()); - tx.delete(withCriteria(forResourceServer(resourceServer))); + tx.delete(withCriteria(forRealmAndResourceServer(resourceServer.getRealm(), resourceServer))); } } diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/MapResourceStore.java b/model/map/src/main/java/org/keycloak/models/map/authorization/MapResourceStore.java index c1c6b42748..6ee8d24272 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/MapResourceStore.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/MapResourceStore.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -36,7 +36,6 @@ import org.keycloak.models.map.storage.ModelCriteriaBuilder.Operator; import org.keycloak.models.map.storage.criteria.DefaultModelCriteria; import java.util.Arrays; -import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; @@ -62,17 +61,13 @@ public class MapResourceStore implements ResourceStore { this.session = session; } - private Function entityToAdapterFunc(final ResourceServer resourceServer) { - return origEntity -> new MapResourceAdapter(resourceServer == null ? findResourceServer(origEntity) : resourceServer, origEntity, authorizationProvider.getStoreFactory()); - } - - private ResourceServer findResourceServer(MapResourceEntity entity) { - RealmModel realm = session.realms().getRealm(entity.getRealmId()); - return authorizationProvider.getStoreFactory().getResourceServerStore().findById(realm, entity.getResourceServerId()); + private Function entityToAdapterFunc(RealmModel realm, final ResourceServer resourceServer) { + return origEntity -> new MapResourceAdapter(realm, resourceServer, origEntity, authorizationProvider.getStoreFactory()); } - private DefaultModelCriteria forResourceServer(ResourceServer resourceServer) { - DefaultModelCriteria mcb = criteria(); + private DefaultModelCriteria forRealmAndResourceServer(RealmModel realm, ResourceServer resourceServer) { + DefaultModelCriteria mcb = DefaultModelCriteria.criteria() + .compare(Resource.SearchableFields.REALM_ID, Operator.EQ, realm.getId()); return resourceServer == null ? mcb @@ -84,7 +79,9 @@ public class MapResourceStore implements ResourceStore { public Resource create(ResourceServer resourceServer, String id, String name, String owner) { LOG.tracef("create(%s, %s, %s, %s)%s", id, name, resourceServer, owner, getShortStackTrace()); // @UniqueConstraint(columnNames = {"NAME", "RESOURCE_SERVER_ID", "OWNER"}) - DefaultModelCriteria mcb = forResourceServer(resourceServer) + RealmModel realm = resourceServer.getRealm(); + + DefaultModelCriteria mcb = forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.NAME, Operator.EQ, name) .compare(SearchableFields.OWNER, Operator.EQ, owner); @@ -97,84 +94,64 @@ public class MapResourceStore implements ResourceStore { entity.setName(name); entity.setResourceServerId(resourceServer.getId()); entity.setOwner(owner); - entity.setRealmId(resourceServer.getRealm().getId()); + entity.setRealmId(realm.getId()); entity = tx.create(entity); - return entity == null ? null : entityToAdapterFunc(resourceServer).apply(entity); + return entity == null ? null : entityToAdapterFunc(realm, resourceServer).apply(entity); } @Override - public void delete(String id) { + public void delete(RealmModel realm, String id) { LOG.tracef("delete(%s)%s", id, getShortStackTrace()); + Resource resource = findById(realm, null, id); + if (resource == null) return; tx.delete(id); } @Override - public Resource findById(ResourceServer resourceServer, String id) { + public Resource findById(RealmModel realm, ResourceServer resourceServer, String id) { LOG.tracef("findById(%s, %s)%s", id, resourceServer, getShortStackTrace()); - return tx.read(withCriteria(forResourceServer(resourceServer) + return tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.ID, Operator.EQ, id))) .findFirst() - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .orElse(null); } @Override - public void findByOwner(ResourceServer resourceServer, String ownerId, Consumer consumer) { - findByOwnerFilter(ownerId, resourceServer, consumer, -1, -1); - } + public void findByOwner(RealmModel realm, ResourceServer resourceServer, String ownerId, Consumer consumer) { + LOG.tracef("findByOwner(%s, %s, %s)%s", realm, resourceServer, resourceServer, ownerId, getShortStackTrace()); - private void findByOwnerFilter(String ownerId, ResourceServer resourceServer, Consumer consumer, int firstResult, int maxResult) { - LOG.tracef("findByOwnerFilter(%s, %s, %s, %d, %d)%s", ownerId, resourceServer, consumer, firstResult, maxResult, getShortStackTrace()); - - tx.read(withCriteria(forResourceServer(resourceServer).compare(SearchableFields.OWNER, Operator.EQ, ownerId)) - .pagination(firstResult, maxResult, SearchableFields.ID) - ).map(entityToAdapterFunc(resourceServer)) - .forEach(consumer); - } - - @Override - public List findByOwner(ResourceServer resourceServer, String ownerId, Integer firstResult, Integer maxResults) { - List resourceList = new LinkedList<>(); - - findByOwnerFilter(ownerId, resourceServer, resourceList::add, firstResult, maxResults); - - return resourceList; - } - - @Override - public List findByUri(ResourceServer resourceServer, String uri) { - LOG.tracef("findByUri(%s, %s)%s", uri, resourceServer, getShortStackTrace()); - - return tx.read(withCriteria(forResourceServer(resourceServer) - .compare(SearchableFields.URI, Operator.EQ, uri))) - .map(entityToAdapterFunc(resourceServer)) - .collect(Collectors.toList()); + tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer) + .compare(SearchableFields.OWNER, Operator.EQ, ownerId))) + .map(entityToAdapterFunc(realm, resourceServer)) + .forEach(consumer); } @Override public List findByResourceServer(ResourceServer resourceServer) { LOG.tracef("findByResourceServer(%s)%s", resourceServer, getShortStackTrace()); + RealmModel realm = resourceServer.getRealm(); - return tx.read(withCriteria(forResourceServer(resourceServer))) - .map(entityToAdapterFunc(resourceServer)) + return tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer))) + .map(entityToAdapterFunc(realm, resourceServer)) .collect(Collectors.toList()); } @Override - public List findByResourceServer(ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults) { - LOG.tracef("findByResourceServer(%s, %s, %d, %d)%s", attributes, resourceServer, firstResult, maxResults, getShortStackTrace()); - DefaultModelCriteria mcb = forResourceServer(resourceServer).and( + public List find(RealmModel realm, ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults) { + LOG.tracef("findByResourceServer(%s, %s, %s, %d, %d)%s", realm, resourceServer, attributes, firstResult, maxResults, getShortStackTrace()); + DefaultModelCriteria mcb = forRealmAndResourceServer(realm, resourceServer).and( attributes.entrySet().stream() .map(this::filterEntryToDefaultModelCriteria) .toArray(DefaultModelCriteria[]::new) ); return tx.read(withCriteria(mcb).pagination(firstResult, maxResults, SearchableFields.NAME)) - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .collect(Collectors.toList()); } @@ -208,38 +185,44 @@ public class MapResourceStore implements ResourceStore { @Override public void findByScopes(ResourceServer resourceServer, Set scopes, Consumer consumer) { LOG.tracef("findByScope(%s, %s, %s)%s", scopes, resourceServer, consumer, getShortStackTrace()); + RealmModel realm = resourceServer.getRealm(); - tx.read(withCriteria(forResourceServer(resourceServer) + tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.SCOPE_ID, Operator.IN, scopes.stream().map(Scope::getId)))) - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .forEach(consumer); } @Override public Resource findByName(ResourceServer resourceServer, String name, String ownerId) { LOG.tracef("findByName(%s, %s, %s)%s", name, ownerId, resourceServer, getShortStackTrace()); - return tx.read(withCriteria(forResourceServer(resourceServer) + RealmModel realm = resourceServer.getRealm(); + + return tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.OWNER, Operator.EQ, ownerId) .compare(SearchableFields.NAME, Operator.EQ, name))) .findFirst() - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .orElse(null); } @Override public void findByType(ResourceServer resourceServer, String type, Consumer consumer) { LOG.tracef("findByType(%s, %s, %s)%s", type, resourceServer, consumer, getShortStackTrace()); - tx.read(withCriteria(forResourceServer(resourceServer) + RealmModel realm = authorizationProvider.getRealm(); + + tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.TYPE, Operator.EQ, type))) - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .forEach(consumer); } @Override public void findByType(ResourceServer resourceServer, String type, String owner, Consumer consumer) { LOG.tracef("findByType(%s, %s, %s, %s)%s", type, owner, resourceServer, consumer, getShortStackTrace()); + RealmModel realm = resourceServer.getRealm(); - DefaultModelCriteria mcb = forResourceServer(resourceServer) + DefaultModelCriteria mcb = forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.TYPE, Operator.EQ, type); if (owner != null) { @@ -247,17 +230,18 @@ public class MapResourceStore implements ResourceStore { } tx.read(withCriteria(mcb)) - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .forEach(consumer); } @Override public void findByTypeInstance(ResourceServer resourceServer, String type, Consumer consumer) { LOG.tracef("findByTypeInstance(%s, %s, %s)%s", type, resourceServer, consumer, getShortStackTrace()); - tx.read(withCriteria(forResourceServer(resourceServer) + RealmModel realm = resourceServer.getRealm(); + tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.OWNER, Operator.NE, resourceServer.getClientId()) .compare(SearchableFields.TYPE, Operator.EQ, type))) - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .forEach(consumer); } @@ -273,6 +257,6 @@ public class MapResourceStore implements ResourceStore { public void preRemove(ResourceServer resourceServer) { LOG.tracef("preRemove(%s)%s", resourceServer, getShortStackTrace()); - tx.delete(withCriteria(forResourceServer(resourceServer))); + tx.delete(withCriteria(forRealmAndResourceServer(resourceServer.getRealm(), resourceServer))); } } diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/MapScopeStore.java b/model/map/src/main/java/org/keycloak/models/map/authorization/MapScopeStore.java index b27ed6990e..31f91a26ab 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/MapScopeStore.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/MapScopeStore.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -58,17 +58,13 @@ public class MapScopeStore implements ScopeStore { this.session = session; } - private Function entityToAdapterFunc(ResourceServer resourceServer) { - return origEntity -> new MapScopeAdapter(resourceServer == null ? findResourceServer(origEntity) : resourceServer, origEntity, authorizationProvider.getStoreFactory()); + private Function entityToAdapterFunc(RealmModel realm, ResourceServer resourceServer) { + return origEntity -> new MapScopeAdapter(realm, resourceServer, origEntity, authorizationProvider.getStoreFactory()); } - private ResourceServer findResourceServer(MapScopeEntity entity) { - RealmModel realm = session.realms().getRealm(entity.getRealmId()); - return authorizationProvider.getStoreFactory().getResourceServerStore().findById(realm, entity.getResourceServerId()); - } - - private DefaultModelCriteria forResourceServer(ResourceServer resourceServer) { - DefaultModelCriteria mcb = criteria(); + private DefaultModelCriteria forRealmAndResourceServer(RealmModel realm, ResourceServer resourceServer) { + DefaultModelCriteria mcb = DefaultModelCriteria.criteria() + .compare(Scope.SearchableFields.REALM_ID, Operator.EQ, realm.getId()); return resourceServer == null ? mcb @@ -80,9 +76,9 @@ public class MapScopeStore implements ScopeStore { public Scope create(ResourceServer resourceServer, String id, String name) { LOG.tracef("create(%s, %s, %s)%s", id, name, resourceServer, getShortStackTrace()); - + RealmModel realm = resourceServer.getRealm(); // @UniqueConstraint(columnNames = {"NAME", "RESOURCE_SERVER_ID"}) - DefaultModelCriteria mcb = forResourceServer(resourceServer) + DefaultModelCriteria mcb = forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.NAME, Operator.EQ, name); if (tx.getCount(withCriteria(mcb)) > 0) { @@ -97,49 +93,54 @@ public class MapScopeStore implements ScopeStore { entity = tx.create(entity); - return entity == null ? null : entityToAdapterFunc(resourceServer).apply(entity); + return entity == null ? null : entityToAdapterFunc(realm, resourceServer).apply(entity); } @Override - public void delete(String id) { + public void delete(RealmModel realm, String id) { LOG.tracef("delete(%s)%s", id, getShortStackTrace()); + Scope scope = findById(realm, null, id); + if (scope == null) return; + tx.delete(id); } @Override - public Scope findById(ResourceServer resourceServer, String id) { + public Scope findById(RealmModel realm, ResourceServer resourceServer, String id) { LOG.tracef("findById(%s, %s)%s", id, resourceServer, getShortStackTrace()); - return tx.read(withCriteria(forResourceServer(resourceServer) + return tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer) .compare(SearchableFields.ID, Operator.EQ, id))) .findFirst() - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .orElse(null); } @Override public Scope findByName(ResourceServer resourceServer, String name) { LOG.tracef("findByName(%s, %s)%s", name, resourceServer, getShortStackTrace()); + RealmModel realm = resourceServer.getRealm(); - return tx.read(withCriteria(forResourceServer(resourceServer).compare(SearchableFields.NAME, + return tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer).compare(SearchableFields.NAME, Operator.EQ, name))) .findFirst() - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .orElse(null); } @Override public List findByResourceServer(ResourceServer resourceServer) { LOG.tracef("findByResourceServer(%s)%s", resourceServer, getShortStackTrace()); - - return tx.read(withCriteria(forResourceServer(resourceServer))) - .map(entityToAdapterFunc(resourceServer)) + RealmModel realm = resourceServer.getRealm(); + return tx.read(withCriteria(forRealmAndResourceServer(realm, resourceServer))) + .map(entityToAdapterFunc(realm, resourceServer)) .collect(Collectors.toList()); } @Override public List findByResourceServer(ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults) { - DefaultModelCriteria mcb = forResourceServer(resourceServer); + RealmModel realm = resourceServer.getRealm(); + DefaultModelCriteria mcb = forRealmAndResourceServer(realm, resourceServer); for (Scope.FilterOption filterOption : attributes.keySet()) { String[] value = attributes.get(filterOption); @@ -157,7 +158,7 @@ public class MapScopeStore implements ScopeStore { } return tx.read(withCriteria(mcb).pagination(firstResult, maxResults, SearchableFields.NAME)) - .map(entityToAdapterFunc(resourceServer)) + .map(entityToAdapterFunc(realm, resourceServer)) .collect(Collectors.toList()); } @@ -173,6 +174,6 @@ public class MapScopeStore implements ScopeStore { public void preRemove(ResourceServer resourceServer) { LOG.tracef("preRemove(%s)%s", resourceServer, getShortStackTrace()); - tx.delete(withCriteria(forResourceServer(resourceServer))); + tx.delete(withCriteria(forRealmAndResourceServer(resourceServer.getRealm(), resourceServer))); } } diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapPermissionTicketAdapter.java b/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapPermissionTicketAdapter.java index 23570d426c..68835d0842 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapPermissionTicketAdapter.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapPermissionTicketAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -26,16 +26,21 @@ import org.keycloak.authorization.model.Scope; import org.keycloak.authorization.store.StoreFactory; +import org.keycloak.models.RealmModel; import org.keycloak.models.map.authorization.entity.MapPermissionTicketEntity; import static org.keycloak.authorization.UserManagedPermissionUtil.updatePolicy; public class MapPermissionTicketAdapter extends AbstractPermissionTicketModel { - private final ResourceServer resourceServer; + private final RealmModel realm; + private ResourceServer resourceServer; - public MapPermissionTicketAdapter(ResourceServer resourceServer, MapPermissionTicketEntity entity, StoreFactory storeFactory) { + public MapPermissionTicketAdapter(RealmModel realm, ResourceServer resourceServer, MapPermissionTicketEntity entity, StoreFactory storeFactory) { super(entity, storeFactory); - Objects.requireNonNull(resourceServer); + + Objects.requireNonNull(realm, "realm"); + + this.realm = realm; this.resourceServer = resourceServer; } @@ -56,13 +61,13 @@ public class MapPermissionTicketAdapter extends AbstractPermissionTicketModel { - private final ResourceServer resourceServer; + private final RealmModel realm; + private ResourceServer resourceServer; - public MapPolicyAdapter(ResourceServer resourceServer, MapPolicyEntity entity, StoreFactory storeFactory) { + public MapPolicyAdapter(RealmModel realm, ResourceServer resourceServer, MapPolicyEntity entity, StoreFactory storeFactory) { super(entity, storeFactory); - Objects.requireNonNull(resourceServer); + Objects.requireNonNull(realm); + this.realm = realm; this.resourceServer = resourceServer; } @@ -124,14 +127,18 @@ public class MapPolicyAdapter extends AbstractPolicyModel { @Override public ResourceServer getResourceServer() { + if (resourceServer == null) { + resourceServer = storeFactory.getResourceServerStore().findById(realm, entity.getResourceServerId()); + } return resourceServer; } @Override public Set getAssociatedPolicies() { Set ids = entity.getAssociatedPolicyIds(); + ResourceServer resourceServer = getResourceServer(); return ids == null ? Collections.emptySet() : ids.stream() - .map(policyId -> storeFactory.getPolicyStore().findById(resourceServer, policyId)) + .map(policyId -> storeFactory.getPolicyStore().findById(realm, resourceServer, policyId)) .collect(Collectors.toSet()); } @@ -139,7 +146,7 @@ public class MapPolicyAdapter extends AbstractPolicyModel { public Set getResources() { Set ids = entity.getResourceIds(); return ids == null ? Collections.emptySet() : ids.stream() - .map(resourceId -> storeFactory.getResourceStore().findById(resourceServer, resourceId)) + .map(resourceId -> storeFactory.getResourceStore().findById(realm, getResourceServer(), resourceId)) .collect(Collectors.toSet()); } @@ -147,7 +154,7 @@ public class MapPolicyAdapter extends AbstractPolicyModel { public Set getScopes() { Set ids = entity.getScopeIds(); return ids == null ? Collections.emptySet() : ids.stream() - .map(scopeId -> storeFactory.getScopeStore().findById(resourceServer, scopeId)) + .map(scopeId -> storeFactory.getScopeStore().findById(realm, getResourceServer(), scopeId)) .collect(Collectors.toSet()); } diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapResourceAdapter.java b/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapResourceAdapter.java index 7ccd3f95a4..1c3ec259fd 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapResourceAdapter.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapResourceAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,6 +24,7 @@ import org.keycloak.authorization.store.PermissionTicketStore; import org.keycloak.authorization.store.PolicyStore; import org.keycloak.authorization.store.StoreFactory; +import org.keycloak.models.RealmModel; import org.keycloak.models.map.authorization.entity.MapResourceEntity; import java.util.Collections; import java.util.HashMap; @@ -35,11 +36,13 @@ import java.util.stream.Collectors; public class MapResourceAdapter extends AbstractResourceModel { - private final ResourceServer resourceServer; + private final RealmModel realm; + private ResourceServer resourceServer; - public MapResourceAdapter(ResourceServer resourceServer, MapResourceEntity entity, StoreFactory storeFactory) { + public MapResourceAdapter(RealmModel realm, ResourceServer resourceServer, MapResourceEntity entity, StoreFactory storeFactory) { super(entity, storeFactory); - Objects.requireNonNull(resourceServer); + Objects.requireNonNull(realm); + this.realm = realm; this.resourceServer = resourceServer; } @@ -99,7 +102,7 @@ public class MapResourceAdapter extends AbstractResourceModel ResourceServer resourceServer = getResourceServer(); return ids == null ? Collections.emptyList() : ids.stream() .map(id -> storeFactory - .getScopeStore().findById(resourceServer, id)) + .getScopeStore().findById(realm, resourceServer, id)) .collect(Collectors.toList()); } @@ -116,6 +119,9 @@ public class MapResourceAdapter extends AbstractResourceModel @Override public ResourceServer getResourceServer() { + if (resourceServer == null) { + resourceServer = storeFactory.getResourceServerStore().findById(realm, entity.getResourceServerId()); + } return resourceServer; } @@ -148,13 +154,13 @@ public class MapResourceAdapter extends AbstractResourceModel // The scope^ was removed from the Resource // Remove permission tickets based on the scope - List permissions = permissionStore.findByScope(resourceServer, scope); + List permissions = permissionStore.findByScope(getResourceServer(), scope); for (PermissionTicket permission : permissions) { - permissionStore.delete(permission.getId()); + permissionStore.delete(realm, permission.getId()); } // Remove the scope from each Policy for this Resource - policyStore.findByResource(resourceServer, this, policy -> policy.removeScope(scope)); + policyStore.findByResource(getResourceServer(), this, policy -> policy.removeScope(scope)); } } diff --git a/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapScopeAdapter.java b/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapScopeAdapter.java index 7908e411d6..3dc20c2f64 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapScopeAdapter.java +++ b/model/map/src/main/java/org/keycloak/models/map/authorization/adapter/MapScopeAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,15 +21,18 @@ package org.keycloak.models.map.authorization.adapter; import java.util.Objects; import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.store.StoreFactory; +import org.keycloak.models.RealmModel; import org.keycloak.models.map.authorization.entity.MapScopeEntity; public class MapScopeAdapter extends AbstractScopeModel { - private final ResourceServer resourceServer; + private final RealmModel realm; + private ResourceServer resourceServer; - public MapScopeAdapter(ResourceServer resourceServer, MapScopeEntity entity, StoreFactory storeFactory) { + public MapScopeAdapter(RealmModel realm, ResourceServer resourceServer, MapScopeEntity entity, StoreFactory storeFactory) { super(entity, storeFactory); - Objects.requireNonNull(resourceServer); + Objects.requireNonNull(realm); + this.realm = realm; this.resourceServer = resourceServer; } @@ -73,6 +76,9 @@ public class MapScopeAdapter extends AbstractScopeModel { @Override public ResourceServer getResourceServer() { + if (resourceServer == null) { + resourceServer = storeFactory.getResourceServerStore().findById(realm, entity.getResourceServerId()); + } return resourceServer; } diff --git a/model/map/src/main/java/org/keycloak/models/map/user/MapUserProvider.java b/model/map/src/main/java/org/keycloak/models/map/user/MapUserProvider.java index 4ebb1ce20a..04f304a02f 100644 --- a/model/map/src/main/java/org/keycloak/models/map/user/MapUserProvider.java +++ b/model/map/src/main/java/org/keycloak/models/map/user/MapUserProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -686,7 +686,7 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor authorizedGroups.removeIf(id -> { Map values = new EnumMap<>(Resource.FilterOption.class); values.put(Resource.FilterOption.EXACT_NAME, new String[] {"group.resource." + id}); - return resourceStore.findByResourceServer(null, values, 0, 1).isEmpty(); + return resourceStore.find(realm, null, values, 0, 1).isEmpty(); }); criteria = criteria.compare(SearchableFields.ASSIGNED_GROUP, Operator.IN, authorizedGroups); diff --git a/server-spi-private/src/main/java/org/keycloak/authorization/AuthorizationProvider.java b/server-spi-private/src/main/java/org/keycloak/authorization/AuthorizationProvider.java index 1dd9cf5e66..e7d3f75613 100644 --- a/server-spi-private/src/main/java/org/keycloak/authorization/AuthorizationProvider.java +++ b/server-spi-private/src/main/java/org/keycloak/authorization/AuthorizationProvider.java @@ -1,13 +1,12 @@ /* - * JBoss, Home of Professional Open Source. - * Copyright 2016 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -251,21 +250,21 @@ public final class AuthorizationProvider implements Provider { } @Override - public void delete(String id) { - Scope scope = findById(null, id); + public void delete(RealmModel realm, String id) { + Scope scope = findById(realm, null, id); PermissionTicketStore ticketStore = AuthorizationProvider.this.getStoreFactory().getPermissionTicketStore(); List permissions = ticketStore.findByScope(scope.getResourceServer(), scope); for (PermissionTicket permission : permissions) { - ticketStore.delete(permission.getId()); + ticketStore.delete(realm, permission.getId()); } - delegate.delete(id); + delegate.delete(realm, id); } @Override - public Scope findById(ResourceServer resourceServer, String id) { - return delegate.findById(resourceServer, id); + public Scope findById(RealmModel realm, ResourceServer resourceServer, String id) { + return delegate.findById(realm, resourceServer, id); } @Override @@ -293,10 +292,11 @@ public final class AuthorizationProvider implements Provider { @Override public Policy create(ResourceServer resourceServer, AbstractPolicyRepresentation representation) { Set resources = representation.getResources(); + RealmModel realm = resourceServer.getRealm(); if (resources != null) { representation.setResources(resources.stream().map(id -> { - Resource resource = storeFactory.getResourceStore().findById(resourceServer, id); + Resource resource = storeFactory.getResourceStore().findById(realm, resourceServer, id); if (resource == null) { resource = storeFactory.getResourceStore().findByName(resourceServer, id); @@ -314,7 +314,7 @@ public final class AuthorizationProvider implements Provider { if (scopes != null) { representation.setScopes(scopes.stream().map(id -> { - Scope scope = storeFactory.getScopeStore().findById(resourceServer, id); + Scope scope = storeFactory.getScopeStore().findById(realm, resourceServer, id); if (scope == null) { scope = storeFactory.getScopeStore().findByName(resourceServer, id); @@ -333,7 +333,7 @@ public final class AuthorizationProvider implements Provider { if (policies != null) { representation.setPolicies(policies.stream().map(id -> { - Policy policy = storeFactory.getPolicyStore().findById(resourceServer, id); + Policy policy = storeFactory.getPolicyStore().findById(realm, resourceServer, id); if (policy == null) { policy = storeFactory.getPolicyStore().findByName(resourceServer, id); @@ -351,8 +351,8 @@ public final class AuthorizationProvider implements Provider { } @Override - public void delete(String id) { - Policy policy = findById(null, id); + public void delete(RealmModel realm, String id) { + Policy policy = findById(realm, null, id); if (policy != null) { ResourceServer resourceServer = policy.getResourceServer(); @@ -363,7 +363,7 @@ public final class AuthorizationProvider implements Provider { // only remove associated policies created from the policy being deleted if (associatedPolicy.getOwner() != null) { policy.removeAssociatedPolicy(associatedPolicy); - policyStore.delete(associatedPolicy.getId()); + policyStore.delete(realm, associatedPolicy.getId()); } } } @@ -371,17 +371,17 @@ public final class AuthorizationProvider implements Provider { findDependentPolicies(resourceServer, policy.getId()).forEach(dependentPolicy -> { dependentPolicy.removeAssociatedPolicy(policy); if (dependentPolicy.getAssociatedPolicies().isEmpty()) { - delete(dependentPolicy.getId()); + delete(realm, dependentPolicy.getId()); } }); - policyStore.delete(id); + policyStore.delete(realm, id); } } @Override - public Policy findById(ResourceServer resourceServer, String id) { - return policyStore.findById(resourceServer, id); + public Policy findById(RealmModel realm, ResourceServer resourceServer, String id) { + return policyStore.findById(realm, resourceServer, id); } @Override @@ -395,8 +395,8 @@ public final class AuthorizationProvider implements Provider { } @Override - public List findByResourceServer(ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults) { - return policyStore.findByResourceServer(resourceServer, attributes, firstResult, maxResults); + public List find(RealmModel realm, ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults) { + return policyStore.find(realm, resourceServer, attributes, firstResult, maxResults); } @Override @@ -461,14 +461,14 @@ public final class AuthorizationProvider implements Provider { } @Override - public void delete(String id) { - Resource resource = findById(null, id); + public void delete(RealmModel realm, String id) { + Resource resource = findById(realm, null, id); StoreFactory storeFactory = AuthorizationProvider.this.getStoreFactory(); PermissionTicketStore ticketStore = storeFactory.getPermissionTicketStore(); List permissions = ticketStore.findByResource(resource.getResourceServer(), resource); for (PermissionTicket permission : permissions) { - ticketStore.delete(permission.getId()); + ticketStore.delete(realm, permission.getId()); } PolicyStore policyStore = storeFactory.getPolicyStore(); @@ -476,38 +476,28 @@ public final class AuthorizationProvider implements Provider { for (Policy policyModel : policies) { if (policyModel.getResources().size() == 1) { - policyStore.delete(policyModel.getId()); + policyStore.delete(realm, policyModel.getId()); } else { policyModel.removeResource(resource); } } - delegate.delete(id); + delegate.delete(realm, id); } @Override - public Resource findById(ResourceServer resourceServer, String id) { - return delegate.findById(resourceServer, id); + public Resource findById(RealmModel realm, ResourceServer resourceServer, String id) { + return delegate.findById(realm, resourceServer, id); } @Override - public List findByOwner(ResourceServer resourceServer, String ownerId) { - return delegate.findByOwner(resourceServer, ownerId); + public List findByOwner(RealmModel realm, ResourceServer resourceServer, String ownerId) { + return delegate.findByOwner(realm, resourceServer, ownerId); } @Override - public void findByOwner(ResourceServer resourceServer, String ownerId, Consumer consumer) { - delegate.findByOwner(resourceServer, ownerId, consumer); - } - - @Override - public List findByOwner(ResourceServer resourceServer, String ownerId, Integer firstResult, Integer maxResults) { - return delegate.findByOwner(resourceServer, ownerId, firstResult, maxResults); - } - - @Override - public List findByUri(ResourceServer resourceServer, String uri) { - return delegate.findByUri(resourceServer, uri); + public void findByOwner(RealmModel realm, ResourceServer resourceServer, String ownerId, Consumer consumer) { + delegate.findByOwner(realm, resourceServer, ownerId, consumer); } @Override @@ -516,8 +506,8 @@ public final class AuthorizationProvider implements Provider { } @Override - public List findByResourceServer(ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults) { - return delegate.findByResourceServer(resourceServer, attributes, firstResult, maxResults); + public List find(RealmModel realm, ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults) { + return delegate.find(realm, resourceServer, attributes, firstResult, maxResults); } @Override @@ -550,16 +540,6 @@ public final class AuthorizationProvider implements Provider { delegate.findByType(resourceServer, type, owner, consumer); } - @Override - public List findByType(ResourceServer resourceServer, String type, String owner) { - return delegate.findByType(resourceServer, type); - } - - @Override - public List findByTypeInstance(ResourceServer resourceServer, String type) { - return delegate.findByTypeInstance(resourceServer, type); - } - @Override public void findByTypeInstance(ResourceServer resourceServer, String type, Consumer consumer) { delegate.findByTypeInstance(resourceServer, type, consumer); diff --git a/server-spi-private/src/main/java/org/keycloak/authorization/UserManagedPermissionUtil.java b/server-spi-private/src/main/java/org/keycloak/authorization/UserManagedPermissionUtil.java index 556a35475e..555adbdb15 100644 --- a/server-spi-private/src/main/java/org/keycloak/authorization/UserManagedPermissionUtil.java +++ b/server-spi-private/src/main/java/org/keycloak/authorization/UserManagedPermissionUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,9 +22,11 @@ import java.util.Map; import org.keycloak.authorization.model.PermissionTicket; import org.keycloak.authorization.model.Policy; +import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.Scope; import org.keycloak.authorization.store.PolicyStore; import org.keycloak.authorization.store.StoreFactory; +import org.keycloak.models.RealmModel; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.representations.idm.authorization.PolicyRepresentation; import org.keycloak.representations.idm.authorization.UserPolicyRepresentation; @@ -37,6 +39,7 @@ public class UserManagedPermissionUtil { public static void updatePolicy(PermissionTicket ticket, StoreFactory storeFactory) { Scope scope = ticket.getScope(); Policy policy = ticket.getPolicy(); + ResourceServer resourceServer = ticket.getResourceServer(); if (policy == null) { Map filter = new EnumMap<>(PermissionTicket.FilterOption.class); @@ -46,7 +49,7 @@ public class UserManagedPermissionUtil { filter.put(PermissionTicket.FilterOption.RESOURCE_ID, ticket.getResource().getId()); filter.put(PermissionTicket.FilterOption.POLICY_IS_NOT_NULL, Boolean.TRUE.toString()); - List tickets = storeFactory.getPermissionTicketStore().find(ticket.getResourceServer(), filter, null, null); + List tickets = storeFactory.getPermissionTicketStore().find(resourceServer.getRealm(), resourceServer, filter, null, null); if (!tickets.isEmpty()) { policy = tickets.iterator().next().getPolicy(); @@ -71,6 +74,7 @@ public class UserManagedPermissionUtil { public static void removePolicy(PermissionTicket ticket, StoreFactory storeFactory) { Policy policy = ticket.getPolicy(); + RealmModel realm = ticket.getResourceServer().getRealm(); if (policy != null) { Map filter = new EnumMap<>(PermissionTicket.FilterOption.class); @@ -80,16 +84,16 @@ public class UserManagedPermissionUtil { filter.put(PermissionTicket.FilterOption.RESOURCE_ID, ticket.getResource().getId()); filter.put(PermissionTicket.FilterOption.GRANTED, Boolean.TRUE.toString()); - List tickets = storeFactory.getPermissionTicketStore().find(ticket.getResourceServer(), filter, null, null); + List tickets = storeFactory.getPermissionTicketStore().find(realm, ticket.getResourceServer(), filter, null, null); if (tickets.isEmpty()) { PolicyStore policyStore = storeFactory.getPolicyStore(); for (Policy associatedPolicy : policy.getAssociatedPolicies()) { - policyStore.delete(associatedPolicy.getId()); + policyStore.delete(realm, associatedPolicy.getId()); } - policyStore.delete(policy.getId()); + policyStore.delete(realm, policy.getId()); } else if (ticket.getScope() != null) { policy.removeScope(ticket.getScope()); } diff --git a/server-spi-private/src/main/java/org/keycloak/authorization/permission/Permissions.java b/server-spi-private/src/main/java/org/keycloak/authorization/permission/Permissions.java index 0ff27edc68..f2e1e73d6e 100644 --- a/server-spi-private/src/main/java/org/keycloak/authorization/permission/Permissions.java +++ b/server-spi-private/src/main/java/org/keycloak/authorization/permission/Permissions.java @@ -1,13 +1,12 @@ /* - * JBoss, Home of Professional Open Source. - * Copyright 2016 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -74,7 +73,7 @@ public final class Permissions { } // obtain all resources where owner is the resource server - resourceStore.findByOwner(resourceServer, resourceServer.getClientId(), resource -> { + resourceStore.findByOwner(resourceServer.getRealm(), resourceServer, resourceServer.getClientId(), resource -> { if (limit.decrementAndGet() >= 0) { evaluator.accept(createResourcePermissions(resource, resourceServer, resource.getScopes(), authorization, request)); } @@ -83,7 +82,7 @@ public final class Permissions { // resource server isn't current user if (!Objects.equals(resourceServer.getClientId(), identity.getId())) { // obtain all resources where owner is the current user - resourceStore.findByOwner(resourceServer, identity.getId(), resource -> { + resourceStore.findByOwner(resourceServer.getRealm(), resourceServer, identity.getId(), resource -> { if (limit.decrementAndGet() >= 0) { evaluator.accept(createResourcePermissions(resource, resourceServer, resource.getScopes(), authorization, request)); } diff --git a/server-spi-private/src/main/java/org/keycloak/authorization/policy/evaluation/PermissionTicketAwareDecisionResultCollector.java b/server-spi-private/src/main/java/org/keycloak/authorization/policy/evaluation/PermissionTicketAwareDecisionResultCollector.java index 08f7e38abb..452176c6f6 100644 --- a/server-spi-private/src/main/java/org/keycloak/authorization/policy/evaluation/PermissionTicketAwareDecisionResultCollector.java +++ b/server-spi-private/src/main/java/org/keycloak/authorization/policy/evaluation/PermissionTicketAwareDecisionResultCollector.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -32,6 +32,7 @@ import org.keycloak.authorization.model.Scope; import org.keycloak.authorization.store.ResourceStore; import org.keycloak.authorization.store.ScopeStore; import org.keycloak.authorization.store.StoreFactory; +import org.keycloak.models.RealmModel; import org.keycloak.representations.idm.authorization.AuthorizationRequest; import org.keycloak.representations.idm.authorization.Permission; import org.keycloak.representations.idm.authorization.PermissionTicketToken; @@ -90,10 +91,11 @@ public class PermissionTicketAwareDecisionResultCollector extends DecisionPermis StoreFactory storeFactory = authorization.getStoreFactory(); ResourceStore resourceStore = storeFactory.getResourceStore(); List permissions = ticket.getPermissions(); + RealmModel realm = resourceServer.getRealm(); if (permissions != null) { for (Permission permission : permissions) { - Resource resource = resourceStore.findById(resourceServer, permission.getResourceId()); + Resource resource = resourceStore.findById(realm, resourceServer, permission.getResourceId()); if (resource == null) { resource = resourceStore.findByName(resourceServer, permission.getResourceId(), identity.getId()); @@ -116,7 +118,7 @@ public class PermissionTicketAwareDecisionResultCollector extends DecisionPermis filters.put(PermissionTicket.FilterOption.REQUESTER, identity.getId()); filters.put(PermissionTicket.FilterOption.SCOPE_IS_NULL, Boolean.TRUE.toString()); - List tickets = authorization.getStoreFactory().getPermissionTicketStore().find(resource.getResourceServer(), filters, null, null); + List tickets = authorization.getStoreFactory().getPermissionTicketStore().find(realm, resourceServer, filters, null, null); if (tickets.isEmpty()) { authorization.getStoreFactory().getPermissionTicketStore().create(resourceServer, resource, null, identity.getId()); @@ -128,7 +130,7 @@ public class PermissionTicketAwareDecisionResultCollector extends DecisionPermis Scope scope = scopeStore.findByName(resourceServer, scopeId); if (scope == null) { - scope = scopeStore.findById(resourceServer, scopeId); + scope = scopeStore.findById(realm, resourceServer, scopeId); } Map filters = new EnumMap<>(PermissionTicket.FilterOption.class); @@ -137,7 +139,7 @@ public class PermissionTicketAwareDecisionResultCollector extends DecisionPermis filters.put(PermissionTicket.FilterOption.REQUESTER, identity.getId()); filters.put(PermissionTicket.FilterOption.SCOPE_ID, scope.getId()); - List tickets = authorization.getStoreFactory().getPermissionTicketStore().find(resource.getResourceServer(), filters, null, null); + List tickets = authorization.getStoreFactory().getPermissionTicketStore().find(realm, resourceServer, filters, null, null); if (tickets.isEmpty()) { authorization.getStoreFactory().getPermissionTicketStore().create(resourceServer, resource, scope, identity.getId()); diff --git a/server-spi-private/src/main/java/org/keycloak/authorization/store/PermissionTicketStore.java b/server-spi-private/src/main/java/org/keycloak/authorization/store/PermissionTicketStore.java index 2e72ce1438..362a6b6c94 100644 --- a/server-spi-private/src/main/java/org/keycloak/authorization/store/PermissionTicketStore.java +++ b/server-spi-private/src/main/java/org/keycloak/authorization/store/PermissionTicketStore.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -36,7 +36,8 @@ public interface PermissionTicketStore { /** * Returns count of {@link PermissionTicket}, filtered by the given attributes. * - * @param resourceServer the resource server + * + * @param resourceServer the resource server. Cannot be {@code null}. * @param attributes permission tickets that do not match the attributes are not included with the count; possible filter options are given by {@link PermissionTicket.FilterOption} * @return an integer indicating the amount of permission tickets * @throws IllegalArgumentException when there is an unknown attribute in the {@code attributes} map @@ -46,10 +47,10 @@ public interface PermissionTicketStore { /** * Creates a new {@link PermissionTicket} instance. * - * @param resourceServer the resource server to which this policy belongs - * @param resource resource id - * @param scope scope id - * @param requester the policy representation + * @param resourceServer the resource server to which this permission ticket belongs. Cannot be {@code null}. + * @param resource resource. Cannot be {@code null}. + * @param scope scope. Cannot be {@code null} + * @param requester requester of the permission * @return a new instance of {@link PermissionTicket} */ PermissionTicket create(ResourceServer resourceServer, Resource resource, Scope scope, String requester); @@ -57,61 +58,48 @@ public interface PermissionTicketStore { /** * Deletes a permission from the underlying persistence mechanism. * + * @param realm realm. Cannot be {@code null}. * @param id the id of the policy to delete */ - void delete(String id); + void delete(RealmModel realm, String id); /** * Returns a {@link PermissionTicket} with the given id * - * @param resourceServer the resource server + * + * + * @param realm the realm. Cannot be {@code null}. + * @param resourceServer the resource server. Ignored if {@code null}. * @param id the identifier of the permission * @return a permission with the given identifier. */ - PermissionTicket findById(ResourceServer resourceServer, String id); - - /** - * Returns a list of {@link PermissionTicket} associated with a {@link ResourceServer}. - * - * @param resourceServer the resource server - * @return a list of permissions belonging to the given resource server - */ - List findByResourceServer(ResourceServer resourceServer); - - /** - * Returns a list of {@link PermissionTicket} associated with the given owner. - * - * @param resourceServer the resource server - * @param owner the identifier of a resource server - * @return a list of permissions belonging to the given owner - */ - List findByOwner(ResourceServer resourceServer, String owner); + PermissionTicket findById(RealmModel realm, ResourceServer resourceServer, String id); /** * Returns a list of {@link PermissionTicket} associated with the {@link org.keycloak.authorization.model.Resource resource}. * - * @param resourceServer the resource server - * @param resource the resource + * @param resourceServer the resource server. Cannot be {@code null}. + * @param resource the resource. Cannot be {@code null} * @return a list of permissions associated with the given resource - * TODO: maybe we can get rid of reosourceServer param here as resource has method getResourceServer() */ List findByResource(ResourceServer resourceServer, Resource resource); /** * Returns a list of {@link PermissionTicket} associated with the {@link org.keycloak.authorization.model.Scope scope}. * - * @param resourceServer the resource server - * @param scope the scope - * @return a list of permissions associated with the given scopes * - * TODO: maybe we can get rid of reosourceServer param here as resource has method getResourceServer() + * @param resourceServer the resource server. Cannot be {@code null}. + * @param scope the scope. Cannot be {@code null}. + * @return a list of permissions associated with the given scopes */ List findByScope(ResourceServer resourceServer, Scope scope); /** * Returns a list of {@link PermissionTicket}, filtered by the given attributes. * - * @param resourceServer a resource server that resulting tickets should belong to. Ignored if {@code null} + * + * @param realm the realm. Cannot be {@code null}. + * @param resourceServer a resource server that resulting tickets should belong to. Ignored if {@code null}. * @param attributes a map of keys and values to filter on; possible filter options are given by {@link PermissionTicket.FilterOption} * @param firstResult first result to return. Ignored if negative or {@code null}. * @param maxResults maximum number of results to return. Ignored if negative or {@code null}. @@ -120,12 +108,12 @@ public interface PermissionTicketStore { * @throws IllegalArgumentException when there is an unknown attribute in the {@code attributes} map * */ - List find(ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults); + List find(RealmModel realm, ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults); /** * Returns a list of {@link PermissionTicket} granted to the given {@code userId}. * - * @param resourceServer the resource server + * @param resourceServer the resource server. Cannot be {@code null} * @param userId the user id * @return a list of permissions granted for a particular user */ @@ -134,7 +122,7 @@ public interface PermissionTicketStore { /** * Returns a list of {@link PermissionTicket} with name equal to {@code resourceName} granted to the given {@code userId}. * - * @param resourceServer the resource server + * @param resourceServer the resource server. Cannot be {@code null}. * @param resourceName the name of a resource * @param userId the user id * @return a list of permissions granted for a particular user @@ -147,7 +135,7 @@ public interface PermissionTicketStore { * Returns a list of {@link Resource} granted to the given {@code requester} * * - * @param realm + * @param realm realm that is searched. Cannot be {@code null} * @param requester the requester * @param name the keyword to query resources by name or null if any resource * @param firstResult first result to return. Ignored if negative or {@code null}. diff --git a/server-spi-private/src/main/java/org/keycloak/authorization/store/PolicyStore.java b/server-spi-private/src/main/java/org/keycloak/authorization/store/PolicyStore.java index 61c4530be5..be17f843d7 100644 --- a/server-spi-private/src/main/java/org/keycloak/authorization/store/PolicyStore.java +++ b/server-spi-private/src/main/java/org/keycloak/authorization/store/PolicyStore.java @@ -1,13 +1,12 @@ /* - * JBoss, Home of Professional Open Source. - * Copyright 2016 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -27,6 +26,7 @@ import org.keycloak.authorization.model.Policy; import org.keycloak.authorization.model.Resource; import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.Scope; +import org.keycloak.models.RealmModel; import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation; /** @@ -40,7 +40,7 @@ public interface PolicyStore { * Creates a new {@link Policy} instance. The new instance is not necessarily persisted though, which may require * a call to the {#save} method to actually make it persistent. * - * @param resourceServer the resource server to which this policy belongs + * @param resourceServer the resource server to which this policy belongs. Cannot be {@code null}. * @param representation the policy representation * @return a new instance of {@link Policy} */ @@ -49,32 +49,35 @@ public interface PolicyStore { /** * Deletes a policy from the underlying persistence mechanism. * + * @param realm the realm that the removed policy belongs to. Cannot be {@code null} * @param id the id of the policy to delete */ - void delete(String id); + void delete(RealmModel realm, String id); /** * Returns a {@link Policy} with the given id * - * @param resourceServer the resource server + * + * @param realm the realm. Cannot be {@code null}. + * @param resourceServer the resource server. Ignored if {@code null}. * @param id the identifier of the policy * @return a policy with the given identifier. */ - Policy findById(ResourceServer resourceServer, String id); + Policy findById(RealmModel realm, ResourceServer resourceServer, String id); /** * Returns a {@link Policy} with the given name * - * @param resourceServer the resource server - * @param name the name of the policy - * @return a policy with the given name. + * @param resourceServer the resource server. Cannot be {@code null} + * @param name the name of the policy + * @return a policy with the given name or {@code null} if no such policy exists. */ Policy findByName(ResourceServer resourceServer, String name); /** - * Returns a list of {@link Policy} associated with a {@link ResourceServer} with the given resourceServerId. + * Returns a list of {@link Policy} associated with the {@link ResourceServer} * - * @param resourceServer the identifier of a resource server + * @param resourceServer the resource server. Cannot be {@code null}. * @return a list of policies that belong to the given resource server */ List findByResourceServer(ResourceServer resourceServer); @@ -82,7 +85,9 @@ public interface PolicyStore { /** * Returns a list of {@link Policy} associated with a {@link ResourceServer} with the given resourceServerId. * - * @param resourceServer the identifier of a resource server + * + * @param realm the realm. Cannot be {@code null}. + * @param resourceServer the identifier of a resource server. Ignored if {@code null}. * @param attributes a map holding the attributes that will be used as a filter; possible filter options are given by {@link Policy.FilterOption} * @param firstResult first result to return. Ignored if negative or {@code null}. * @param maxResults maximum number of results to return. Ignored if negative or {@code null}. @@ -90,13 +95,13 @@ public interface PolicyStore { * * @throws IllegalArgumentException when there is an unknown attribute in the {@code attributes} map */ - List findByResourceServer(ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults); + List find(RealmModel realm, ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults); /** - * Returns a list of {@link Policy} associated with a {@link org.keycloak.authorization.model.Resource} with the given resourceId. + * Returns a list of {@link Policy} associated with a {@link org.keycloak.authorization.model.Resource} * - * @param resourceServer the resource server - * @param resource the resource + * @param resourceServer the resource server. Cannot be {@code null}. + * @param resource the resource. Cannot be {@code null}. * @return a list of policies associated with the given resource */ default List findByResource(ResourceServer resourceServer, Resource resource) { @@ -110,8 +115,8 @@ public interface PolicyStore { /** * Searches for all policies associated with the {@link org.keycloak.authorization.model.Resource} and passes the result to the {@code consumer} * - * @param resourceServer the resourceServer - * @param resource the resource + * @param resourceServer the resourceServer. Cannot be {@code null}. + * @param resource the resource. Cannot be {@code null}. * @param consumer consumer of policies resulted from the search */ void findByResource(ResourceServer resourceServer, Resource resource, Consumer consumer); @@ -119,7 +124,7 @@ public interface PolicyStore { /** * Returns a list of {@link Policy} associated with a {@link org.keycloak.authorization.model.ResourceServer} with the given type. * - * @param resourceServer the resource server id + * @param resourceServer the resource server id. Cannot be {@code null}. * @param resourceType the type of a resource * @return a list of policies associated with the given resource type */ @@ -134,7 +139,7 @@ public interface PolicyStore { /** * Searches for policies associated with a {@link org.keycloak.authorization.model.ResourceServer} and passes the result to the consumer * - * @param resourceServer the resourceServer + * @param resourceServer the resourceServer. Cannot be {@code null}. * @param type the type of a resource * @param policyConsumer consumer of policies resulted from the search */ @@ -143,7 +148,7 @@ public interface PolicyStore { /** * Returns a list of {@link Policy} associated with a {@link org.keycloak.authorization.model.Scope} within the given scope. * - * @param resourceServer the resource server + * @param resourceServer the resource server. Cannot be {@code null}. * @param scopes the scopes * @return a list of policies associated with the given scopes */ @@ -152,7 +157,7 @@ public interface PolicyStore { /** * Returns a list of {@link Policy} associated with a {@link org.keycloak.authorization.model.Scope} with the given resource and scopes. * - * @param resourceServer the resource server + * @param resourceServer the resource server. Cannot be {@code null}. * @param resource the resource. Ignored if {@code null}. * @param scopes the scopes * @return a list of policies associated with the given scopes @@ -175,7 +180,7 @@ public interface PolicyStore { /** * Returns a list of {@link Policy} with the given type. * - * @param resourceServer the resource server id + * @param resourceServer the resource server id. Cannot be {@code null}. * @param type the type of the policy * @return a list of policies with the given type */ diff --git a/server-spi-private/src/main/java/org/keycloak/authorization/store/ResourceServerStore.java b/server-spi-private/src/main/java/org/keycloak/authorization/store/ResourceServerStore.java index 6762639c18..4391814ef4 100644 --- a/server-spi-private/src/main/java/org/keycloak/authorization/store/ResourceServerStore.java +++ b/server-spi-private/src/main/java/org/keycloak/authorization/store/ResourceServerStore.java @@ -1,13 +1,12 @@ /* - * JBoss, Home of Professional Open Source. - * Copyright 2016 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -32,7 +31,7 @@ public interface ResourceServerStore { /** *

Creates a {@link ResourceServer} instance backed by this persistent storage implementation. * - * @param client the client acting as a resource server + * @param client the client acting as a resource server. Cannot be {@code null}. * * @return an instance backed by the underlying storage implementation */ @@ -41,7 +40,7 @@ public interface ResourceServerStore { /** * Removes a {@link ResourceServer} instance, with the given client from the persistent storage. * - * @param client the client acting as a resource server + * @param client the client acting as a resource server. Cannot be {@code null}. */ void delete(ClientModel client); @@ -49,7 +48,7 @@ public interface ResourceServerStore { * Returns a {@link ResourceServer} instance based on its identifier. * * - * @param realm + * @param realm the realm. Cannot be {@code null}. * @param id the identifier of an existing resource server instance * * @return the resource server instance with the given identifier or null if no instance was found @@ -59,7 +58,7 @@ public interface ResourceServerStore { /** * Returns a {@link ResourceServer} instance based on a client. * - * @param client the client acting as a resource server + * @param client the client acting as a resource server. Cannot be {@code null}. * * @return the resource server instance or null if no instance was found */ diff --git a/server-spi-private/src/main/java/org/keycloak/authorization/store/ResourceStore.java b/server-spi-private/src/main/java/org/keycloak/authorization/store/ResourceStore.java index bae2d9dac2..da9683a69a 100644 --- a/server-spi-private/src/main/java/org/keycloak/authorization/store/ResourceStore.java +++ b/server-spi-private/src/main/java/org/keycloak/authorization/store/ResourceStore.java @@ -1,13 +1,12 @@ /* - * JBoss, Home of Professional Open Source. - * Copyright 2016 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -20,6 +19,7 @@ package org.keycloak.authorization.store; import org.keycloak.authorization.model.Resource; import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.Scope; +import org.keycloak.models.RealmModel; import java.util.ArrayList; import java.util.LinkedList; @@ -38,7 +38,7 @@ public interface ResourceStore { /** *

Creates a {@link Resource} instance backed by this persistent storage implementation. * - * @param resourceServer the resource server to where the given resource belongs to + * @param resourceServer the resource server to where the given resource belongs to. Cannot be {@code null}. * @param name the name of this resource. It must be unique. * @param owner the owner of this resource or null if the resource server is the owner * @return an instance backed by the underlying storage implementation @@ -50,7 +50,7 @@ public interface ResourceStore { /** *

Creates a {@link Resource} instance backed by this persistent storage implementation. * - * @param resourceServer the resource server to where the given resource belongs to + * @param resourceServer the resource server to where the given resource belongs to. Cannot be {@code null}. * @param id the id of this resource. It must be unique. Will be randomly generated if null. * @param name the name of this resource. It must be unique. * @param owner the owner of this resource or null if the resource server is the owner @@ -61,53 +61,45 @@ public interface ResourceStore { /** * Removes a {@link Resource} instance, with the given {@code id} from the persistent storage. * + * @param realm the realm. Cannot be {@code null}. * @param id the identifier of an existing resource instance */ - void delete(String id); + void delete(RealmModel realm, String id); /** * Returns a {@link Resource} instance based on its identifier. * - * @param resourceServer the resource server + * + * @param realm the realm. Cannot be {@code null}. + * @param resourceServer the resource server. Ignored if {@code null} * @param id the identifier of an existing resource instance * @return the resource instance with the given identifier or null if no instance was found */ - Resource findById(ResourceServer resourceServer, String id); + Resource findById(RealmModel realm, ResourceServer resourceServer, String id); /** * Finds all {@link Resource} instances with the given {@code ownerId}. * * - * @param resourceServer + * + * @param realm the realm. Cannot be {@code null}. + * @param resourceServer resource server. Ignored if {@code null} * @param ownerId the identifier of the owner * @return a list with all resource instances owned by the given owner */ - default List findByOwner(ResourceServer resourceServer, String ownerId) { + default List findByOwner(RealmModel realm, ResourceServer resourceServer, String ownerId) { List list = new LinkedList<>(); - findByOwner(resourceServer, ownerId, list::add); + findByOwner(realm, resourceServer, ownerId, list::add); return list; } - - void findByOwner(ResourceServer resourceServer, String ownerId, Consumer consumer); - - List findByOwner(ResourceServer resourceServer, String ownerId, Integer firstResult, Integer maxResults); - - /** - * Finds all {@link Resource} instances with the given uri. - * - * - * @param resourceServer - * @param uri the identifier of the uri - * @return a list with all resource instances owned by the given owner - */ - List findByUri(ResourceServer resourceServer, String uri); + void findByOwner(RealmModel realm, ResourceServer resourceServer, String ownerId, Consumer consumer); /** * Finds all {@link Resource} instances associated with a given resource server. * - * @param resourceServer the identifier of the resource server + * @param resourceServer the identifier of the resource server. Cannot be {@code null}. * @return a list with all resources associated with the given resource server */ List findByResourceServer(ResourceServer resourceServer); @@ -115,7 +107,9 @@ public interface ResourceStore { /** * Finds all {@link Resource} instances associated with a given resource server. * - * @param resourceServer the identifier of the resource server + * + * @param realm the realm. Cannot be {@code null}. + * @param resourceServer the identifier of the resource server. Ignored if {@code null}. * @param attributes a map holding the attributes that will be used as a filter; possible filter options are given by {@link Resource.FilterOption} * @param firstResult first result to return. Ignored if negative or {@code null}. * @param maxResults maximum number of results to return. Ignored if negative or {@code null}. @@ -123,13 +117,13 @@ public interface ResourceStore { * * @throws IllegalArgumentException when there is an unknown attribute in the {@code attributes} map */ - List findByResourceServer(ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults); + List find(RealmModel realm, ResourceServer resourceServer, Map attributes, Integer firstResult, Integer maxResults); /** * Finds all {@link Resource} associated with a given scope. * * - * @param resourceServer + * @param resourceServer the resource server. Cannot be {@code null}. * @param scopes one or more scope identifiers * @return a list of resources associated with the given scope(s) */ @@ -140,13 +134,12 @@ public interface ResourceStore { return result; } - void findByScopes(ResourceServer resourceServer, Set scopes, Consumer consumer); /** * Find a {@link Resource} by its name where the owner is the resource server itself. * - * @param resourceServer the resource server + * @param resourceServer the resource server. Cannot be {@code null}. * @param name the name of the resource * @return a resource with the given name */ @@ -157,7 +150,7 @@ public interface ResourceStore { /** * Find a {@link Resource} by its name where the owner is the given ownerId. * - * @param resourceServer the identifier of the resource server + * @param resourceServer the identifier of the resource server. Cannot be {@code null}. * @param name the name of the resource * @param ownerId the owner id * @return a resource with the given name @@ -165,10 +158,10 @@ public interface ResourceStore { Resource findByName(ResourceServer resourceServer, String name, String ownerId); /** - * Finds all {@link Resource} with the given type. + * Finds all {@link Resource} from {@link ResourceServer} with the given type. * * - * @param resourceServer + * @param resourceServer the resource server. Cannot be {@code null}. * @param type the type of the resource * @return a list of resources with the given type */ @@ -181,26 +174,9 @@ public interface ResourceStore { } /** - * Finds all {@link Resource} with the given type. + * Finds all {@link Resource} from {@link ResourceServer} with the given type. * - * - * @param resourceServer - * @param type the type of the resource - * @param owner the resource owner or null for any resource with a given type - * @return a list of resources with the given type - */ - default List findByType(ResourceServer resourceServer, String type, String owner) { - List list = new LinkedList<>(); - - findByType(resourceServer, type, owner, list::add); - - return list; - } - - /** - * Finds all {@link Resource} with the given type. - * - * @param resourceServer the resource server id + * @param resourceServer the resource server id. Cannot be {@code null}. * @param type the type of the resource * @param consumer the result consumer * @return a list of resources with the given type @@ -210,7 +186,7 @@ public interface ResourceStore { /** * Finds all {@link Resource} with the given type. * - * @param resourceServer the resource server id + * @param resourceServer the resource server id. Cannot be {@code null} * @param type the type of the resource * @param owner the resource owner or null for any resource with a given type * @param consumer the result consumer @@ -218,13 +194,12 @@ public interface ResourceStore { */ void findByType(ResourceServer resourceServer, String type, String owner, Consumer consumer); - default List findByTypeInstance(ResourceServer resourceServer, String type) { - List list = new LinkedList<>(); - - findByTypeInstance(resourceServer, type, list::add); - - return list; - } - - void findByTypeInstance(ResourceServer resourceServerId, String type, Consumer consumer); + /** + * Finds all {@link Resource} by type where client represented by the {@code resourceServer} is not the owner + * + * @param resourceServer the resourceServer. Cannot be {@code null}. + * @param type searched type + * @param consumer a consumer that will be fed with the resulting resources + */ + void findByTypeInstance(ResourceServer resourceServer, String type, Consumer consumer); } diff --git a/server-spi-private/src/main/java/org/keycloak/authorization/store/ScopeStore.java b/server-spi-private/src/main/java/org/keycloak/authorization/store/ScopeStore.java index ecfa93f678..e3133c8884 100644 --- a/server-spi-private/src/main/java/org/keycloak/authorization/store/ScopeStore.java +++ b/server-spi-private/src/main/java/org/keycloak/authorization/store/ScopeStore.java @@ -1,13 +1,12 @@ /* - * JBoss, Home of Professional Open Source. - * Copyright 2016 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -20,6 +19,7 @@ package org.keycloak.authorization.store; import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.Scope; +import org.keycloak.models.RealmModel; import java.util.List; import java.util.Map; @@ -35,8 +35,7 @@ public interface ScopeStore { * Creates a new {@link Scope} instance. The new instance is not necessarily persisted though, which may require * a call to the {#save} method to actually make it persistent. * - * @param resourceServer the resource server to which this scope belongs - * + * @param resourceServer the resource server to which this scope belongs. Cannot be {@code null}. * @param name the name of the scope * @return a new instance of {@link Scope} */ @@ -48,8 +47,7 @@ public interface ScopeStore { * Creates a new {@link Scope} instance. The new instance is not necessarily persisted though, which may require * a call to the {#save} method to actually make it persistent. * - * @param resourceServer the resource server to which this scope belongs - * + * @param resourceServer the resource server to which this scope belongs. Cannot be {@code null}. * @param id the id of the scope. Is generated randomly when null * @param name the name of the scope * @return a new instance of {@link Scope} @@ -59,23 +57,25 @@ public interface ScopeStore { /** * Deletes a scope from the underlying persistence mechanism. * + * @param realm the realm. Cannot be {@code null}. * @param id the id of the scope to delete */ - void delete(String id); + void delete(RealmModel realm, String id); /** * Returns a {@link Scope} with the given id * - * @param resourceServer the resource server id + * @param realm the realm. Cannot be {@code null}. + * @param resourceServer the resource server id. Ignored if {@code null}. * @param id the identifier of the scope * @return a scope with the given identifier. */ - Scope findById(ResourceServer resourceServer, String id); + Scope findById(RealmModel realm, ResourceServer resourceServer, String id); /** * Returns a {@link Scope} with the given name * - * @param resourceServer the resource server + * @param resourceServer the resource server. Cannot be {@code null}. * @param name the name of the scope * * @return a scope with the given name. @@ -83,9 +83,9 @@ public interface ScopeStore { Scope findByName(ResourceServer resourceServer, String name); /** - * Returns a list of {@link Scope} associated with a {@link ResourceServer} with the given resourceServer. + * Returns a list of {@link Scope} associated with the {@link ResourceServer}. * - * @param resourceServer the identifier of a resource server + * @param resourceServer the resource server. Cannot be {@code null}. * * @return a list of scopes that belong to the given resource server */ @@ -94,7 +94,7 @@ public interface ScopeStore { /** * Returns a list of {@link Scope} associated with a {@link ResourceServer} with the given resourceServerId. * - * @param resourceServer the resource server + * @param resourceServer the resource server. Cannot be {@code null}. * @param attributes a map holding the attributes that will be used as a filter; possible filter options are given by {@link Scope.FilterOption} * @param firstResult first result to return. Ignored if negative or {@code null}. * @param maxResults maximum number of results to return. Ignored if negative or {@code null}. diff --git a/server-spi-private/src/main/java/org/keycloak/authorization/store/syncronization/ClientApplicationSynchronizer.java b/server-spi-private/src/main/java/org/keycloak/authorization/store/syncronization/ClientApplicationSynchronizer.java index a0f78ff621..1470add658 100644 --- a/server-spi-private/src/main/java/org/keycloak/authorization/store/syncronization/ClientApplicationSynchronizer.java +++ b/server-spi-private/src/main/java/org/keycloak/authorization/store/syncronization/ClientApplicationSynchronizer.java @@ -1,13 +1,12 @@ /* - * JBoss, Home of Professional Open Source. - * Copyright 2016 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -31,6 +30,7 @@ import org.keycloak.authorization.store.ResourceServerStore; import org.keycloak.authorization.store.StoreFactory; import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.ClientModel.ClientRemovedEvent; +import org.keycloak.models.RealmModel; import org.keycloak.provider.ProviderFactory; import org.keycloak.representations.idm.authorization.ClientPolicyRepresentation; @@ -51,6 +51,7 @@ public class ClientApplicationSynchronizer implements Synchronizer search = storeFactory.getPolicyStore().findByResourceServer(null, attributes, null, null); + List search = storeFactory.getPolicyStore().find(realm, null, attributes, null, null); for (Policy policy : search) { PolicyProviderFactory policyFactory = authorizationProvider.getProviderFactory(policy.getType()); @@ -73,7 +74,7 @@ public class ClientApplicationSynchronizer implements Synchronizer attributes = new EnumMap<>(Policy.FilterOption.class); attributes.put(Policy.FilterOption.TYPE, new String[] {"group"}); attributes.put(Policy.FilterOption.CONFIG, new String[] {"groups", group.getId()}); attributes.put(Policy.FilterOption.ANY_OWNER, Policy.FilterOption.EMPTY_FILTER); - List search = policyStore.findByResourceServer(null, attributes, null, null); + List search = policyStore.find(realm, null, attributes, null, null); for (Policy policy : search) { PolicyProviderFactory policyFactory = authorizationProvider.getProviderFactory(policy.getType()); @@ -62,7 +64,7 @@ public class GroupSynchronizer implements Synchronizer { StoreFactory storeFactory = authorizationProvider.getStoreFactory(); PolicyStore policyStore = storeFactory.getPolicyStore(); UserModel userModel = event.getUser(); + RealmModel realm = event.getRealm(); Map attributes = new EnumMap<>(Policy.FilterOption.class); attributes.put(Policy.FilterOption.TYPE, new String[] {"user"}); attributes.put(Policy.FilterOption.CONFIG, new String[] {"users", userModel.getId()}); attributes.put(Policy.FilterOption.ANY_OWNER, new String[] {Boolean.TRUE.toString()}); - List search = policyStore.findByResourceServer(null, attributes, null, null); + List search = policyStore.find(realm, null, attributes, null, null); for (Policy policy : search) { PolicyProviderFactory policyFactory = authorizationProvider.getProviderFactory(policy.getType()); @@ -72,7 +74,7 @@ public class UserSynchronizer implements Synchronizer { if (users.isEmpty()) { policyFactory.onRemove(policy, authorizationProvider); - policyStore.delete(policy.getId()); + policyStore.delete(realm, policy.getId()); } else { policyFactory.onUpdate(policy, representation, authorizationProvider); } @@ -84,17 +86,18 @@ public class UserSynchronizer implements Synchronizer { PolicyStore policyStore = storeFactory.getPolicyStore(); ResourceStore resourceStore = storeFactory.getResourceStore(); UserModel userModel = event.getUser(); + RealmModel realm = event.getRealm(); - resourceStore.findByOwner(null, userModel.getId(), resource -> { + resourceStore.findByOwner(realm, null, userModel.getId(), resource -> { String resourceId = resource.getId(); policyStore.findByResource(resource.getResourceServer(), resource).forEach(policy -> { if (policy.getResources().size() == 1) { - policyStore.delete(policy.getId()); + policyStore.delete(realm, policy.getId()); } else { policy.removeResource(resource); } }); - resourceStore.delete(resourceId); + resourceStore.delete(realm, resourceId); }); } @@ -102,20 +105,21 @@ public class UserSynchronizer implements Synchronizer { StoreFactory storeFactory = authorizationProvider.getStoreFactory(); PermissionTicketStore ticketStore = storeFactory.getPermissionTicketStore(); UserModel userModel = event.getUser(); + RealmModel realm = event.getRealm(); Map attributes = new EnumMap<>(PermissionTicket.FilterOption.class); attributes.put(PermissionTicket.FilterOption.OWNER, userModel.getId()); - for (PermissionTicket ticket : ticketStore.find(null, attributes, null, null)) { - ticketStore.delete(ticket.getId()); + for (PermissionTicket ticket : ticketStore.find(realm, null, attributes, null, null)) { + ticketStore.delete(realm, ticket.getId()); } attributes.clear(); attributes.put(PermissionTicket.FilterOption.REQUESTER, userModel.getId()); - for (PermissionTicket ticket : ticketStore.find(null, attributes, null, null)) { - ticketStore.delete(ticket.getId()); + for (PermissionTicket ticket : ticketStore.find(realm, null, attributes, null, null)) { + ticketStore.delete(realm, ticket.getId()); } } } diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java index 70f4edd63e..bba9e4b3cb 100755 --- a/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java +++ b/server-spi-private/src/main/java/org/keycloak/models/utils/RepresentationToModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -2357,6 +2357,8 @@ public class RepresentationToModel { private static Policy importPolicies(AuthorizationProvider authorization, ResourceServer resourceServer, List policiesToImport, String parentPolicyName) { StoreFactory storeFactory = authorization.getStoreFactory(); + RealmModel realm = resourceServer.getRealm(); + for (PolicyRepresentation policyRepresentation : policiesToImport) { if (parentPolicyName != null && !parentPolicyName.equals(policyRepresentation.getName())) { continue; @@ -2375,7 +2377,7 @@ public class RepresentationToModel { Policy policy = policyStore.findByName(resourceServer, policyName); if (policy == null) { - policy = policyStore.findById(resourceServer, policyName); + policy = policyStore.findById(realm, resourceServer, policyName); } if (policy == null) { @@ -2395,7 +2397,7 @@ public class RepresentationToModel { } PolicyStore policyStore = storeFactory.getPolicyStore(); - Policy policy = policyStore.findById(resourceServer, policyRepresentation.getId()); + Policy policy = policyStore.findById(realm, resourceServer, policyRepresentation.getId()); if (policy == null) { policy = policyStore.findByName(resourceServer, policyRepresentation.getName()); @@ -2501,6 +2503,8 @@ public class RepresentationToModel { } return; } + ResourceServer resourceServer = policy.getResourceServer(); + RealmModel realm = resourceServer.getRealm(); for (String scopeId : scopeIds) { boolean hasScope = false; @@ -2510,8 +2514,7 @@ public class RepresentationToModel { } } if (!hasScope) { - ResourceServer resourceServer = policy.getResourceServer(); - Scope scope = storeFactory.getScopeStore().findById(resourceServer, scopeId); + Scope scope = storeFactory.getScopeStore().findById(realm, resourceServer, scopeId); if (scope == null) { scope = storeFactory.getScopeStore().findByName(resourceServer, scopeId); @@ -2543,6 +2546,7 @@ public class RepresentationToModel { private static void updateAssociatedPolicies(Set policyIds, Policy policy, StoreFactory storeFactory) { ResourceServer resourceServer = policy.getResourceServer(); + RealmModel realm = resourceServer.getRealm(); if (policyIds != null) { if (policyIds.isEmpty()) { @@ -2564,7 +2568,7 @@ public class RepresentationToModel { } if (!hasPolicy) { - Policy associatedPolicy = policyStore.findById(resourceServer, policyId); + Policy associatedPolicy = policyStore.findById(realm, resourceServer, policyId); if (associatedPolicy == null) { associatedPolicy = policyStore.findByName(resourceServer, policyId); @@ -2601,6 +2605,9 @@ public class RepresentationToModel { policy.removeResource(resource); } } + ResourceServer resourceServer = policy.getResourceServer(); + RealmModel realm = resourceServer.getRealm(); + for (String resourceId : resourceIds) { boolean hasResource = false; for (Resource resourceModel : new HashSet<>(policy.getResources())) { @@ -2609,10 +2616,10 @@ public class RepresentationToModel { } } if (!hasResource && !"".equals(resourceId)) { - Resource resource = storeFactory.getResourceStore().findById(policy.getResourceServer(), resourceId); + Resource resource = storeFactory.getResourceStore().findById(realm, resourceServer, resourceId); if (resource == null) { - resource = storeFactory.getResourceStore().findByName(policy.getResourceServer(), resourceId); + resource = storeFactory.getResourceStore().findByName(resourceServer, resourceId); if (resource == null) { throw new RuntimeException("Resource with id or name [" + resourceId + "] does not exist or is not owned by the resource server"); } @@ -2642,6 +2649,7 @@ public class RepresentationToModel { public static Resource toModel(ResourceRepresentation resource, ResourceServer resourceServer, AuthorizationProvider authorization) { ResourceStore resourceStore = authorization.getStoreFactory().getResourceStore(); + RealmModel realm = authorization.getRealm(); ResourceOwnerRepresentation owner = resource.getOwner(); if (owner == null) { @@ -2656,7 +2664,6 @@ public class RepresentationToModel { } if (!resourceServer.getClientId().equals(ownerId)) { - RealmModel realm = authorization.getRealm(); KeycloakSession keycloakSession = authorization.getKeycloakSession(); UserProvider users = keycloakSession.users(); UserModel ownerModel = users.getUserById(realm, ownerId); @@ -2675,7 +2682,7 @@ public class RepresentationToModel { Resource existing; if (resource.getId() != null) { - existing = resourceStore.findById(resourceServer, resource.getId()); + existing = resourceStore.findById(realm, resourceServer, resource.getId()); } else { existing = resourceStore.findByName(resourceServer, resource.getName(), ownerId); } @@ -2749,7 +2756,7 @@ public class RepresentationToModel { Scope existing; if (scope.getId() != null) { - existing = scopeStore.findById(resourceServer, scope.getId()); + existing = scopeStore.findById(resourceServer.getRealm(), resourceServer, scope.getId()); } else { existing = scopeStore.findByName(resourceServer, scope.getName()); } @@ -2775,13 +2782,13 @@ public class RepresentationToModel { public static PermissionTicket toModel(PermissionTicketRepresentation representation, ResourceServer resourceServer, AuthorizationProvider authorization) { PermissionTicketStore ticketStore = authorization.getStoreFactory().getPermissionTicketStore(); - PermissionTicket ticket = ticketStore.findById(resourceServer, representation.getId()); + PermissionTicket ticket = ticketStore.findById(resourceServer.getRealm(), resourceServer, representation.getId()); boolean granted = representation.isGranted(); if (granted && !ticket.isGranted()) { ticket.setGrantedTimestamp(System.currentTimeMillis()); } else if (!granted) { - ticketStore.delete(ticket.getId()); + ticketStore.delete(resourceServer.getRealm(), ticket.getId()); } return ticket; diff --git a/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java b/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java index 0f48e41ac7..65f37db603 100644 --- a/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java +++ b/services/src/main/java/org/keycloak/authorization/admin/PolicyEvaluationService.java @@ -1,13 +1,12 @@ /* - * JBoss, Home of Professional Open Source. - * Copyright 2016 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -175,7 +174,7 @@ public class PolicyEvaluationService { Set scopes = givenScopes.stream().map(scopeRepresentation -> scopeStore.findByName(resourceServer, scopeRepresentation.getName())).collect(Collectors.toSet()); if (resource.getId() != null) { - Resource resourceModel = storeFactory.getResourceStore().findById(resourceServer, resource.getId()); + Resource resourceModel = storeFactory.getResourceStore().findById(resourceServer.getRealm(), resourceServer, resource.getId()); return new ArrayList<>(Arrays.asList( Permissions.createResourcePermissions(resourceModel, resourceServer, scopes, authorization, request))).stream(); } else if (resource.getType() != null) { diff --git a/services/src/main/java/org/keycloak/authorization/admin/PolicyResourceService.java b/services/src/main/java/org/keycloak/authorization/admin/PolicyResourceService.java index cf8b56f3e5..e985ed66c5 100644 --- a/services/src/main/java/org/keycloak/authorization/admin/PolicyResourceService.java +++ b/services/src/main/java/org/keycloak/authorization/admin/PolicyResourceService.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -111,7 +111,7 @@ public class PolicyResourceService { resource.onRemove(policy, authorization); } - policyStore.delete(policy.getId()); + policyStore.delete(resourceServer.getRealm(), policy.getId()); audit(toRepresentation(policy, authorization), OperationType.DELETE); diff --git a/services/src/main/java/org/keycloak/authorization/admin/PolicyService.java b/services/src/main/java/org/keycloak/authorization/admin/PolicyService.java index 085e36d617..023280fc14 100644 --- a/services/src/main/java/org/keycloak/authorization/admin/PolicyService.java +++ b/services/src/main/java/org/keycloak/authorization/admin/PolicyService.java @@ -1,13 +1,12 @@ /* - * JBoss, Home of Professional Open Source. - * Copyright 2016 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -88,7 +87,7 @@ public class PolicyService { return doCreatePolicyTypeResource(type); } - Policy policy = authorization.getStoreFactory().getPolicyStore().findById(resourceServer, type); + Policy policy = authorization.getStoreFactory().getPolicyStore().findById(resourceServer.getRealm(), resourceServer, type); return doCreatePolicyResource(policy); } @@ -206,7 +205,7 @@ public class PolicyService { if (resource != null && !"".equals(resource.trim())) { ResourceStore resourceStore = storeFactory.getResourceStore(); - Resource resourceModel = resourceStore.findById(resourceServer, resource); + Resource resourceModel = resourceStore.findById(resourceServer.getRealm(), resourceServer, resource); if (resourceModel == null) { Map resourceFilters = new EnumMap<>(Resource.FilterOption.class); @@ -217,7 +216,7 @@ public class PolicyService { resourceFilters.put(Resource.FilterOption.OWNER, new String[]{owner}); } - Set resources = resourceStore.findByResourceServer(resourceServer, resourceFilters, -1, 1).stream().map(Resource::getId).collect(Collectors.toSet()); + Set resources = resourceStore.find(resourceServer.getRealm(), resourceServer, resourceFilters, -1, 1).stream().map(Resource::getId).collect(Collectors.toSet()); if (resources.isEmpty()) { return Response.noContent().build(); @@ -231,7 +230,7 @@ public class PolicyService { if (scope != null && !"".equals(scope.trim())) { ScopeStore scopeStore = storeFactory.getScopeStore(); - Scope scopeModel = scopeStore.findById(resourceServer, scope); + Scope scopeModel = scopeStore.findById(resourceServer.getRealm(), resourceServer, scope); if (scopeModel == null) { Map scopeFilters = new EnumMap<>(Scope.FilterOption.class); @@ -265,7 +264,7 @@ public class PolicyService { protected List doSearch(Integer firstResult, Integer maxResult, String fields, Map filters) { PolicyStore policyStore = authorization.getStoreFactory().getPolicyStore(); - return policyStore.findByResourceServer(resourceServer, filters, firstResult != null ? firstResult : -1, maxResult != null ? maxResult : Constants.DEFAULT_MAX_RESULTS).stream() + return policyStore.find(resourceServer.getRealm(), resourceServer, filters, firstResult != null ? firstResult : -1, maxResult != null ? maxResult : Constants.DEFAULT_MAX_RESULTS).stream() .map(policy -> toRepresentation(policy, fields, authorization)) .collect(Collectors.toList()); } diff --git a/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java b/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java index 59a08be091..04e6fa60d3 100644 --- a/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java +++ b/services/src/main/java/org/keycloak/authorization/admin/ResourceSetService.java @@ -1,13 +1,12 @@ /* - * JBoss, Home of Professional Open Source. - * Copyright 2016 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -141,7 +140,7 @@ public class ResourceSetService { resource.setId(id); StoreFactory storeFactory = this.authorization.getStoreFactory(); ResourceStore resourceStore = storeFactory.getResourceStore(); - Resource model = resourceStore.findById(resourceServer, resource.getId()); + Resource model = resourceStore.findById(resourceServer.getRealm(), resourceServer, resource.getId()); if (model == null) { return Response.status(Status.NOT_FOUND).build(); @@ -159,13 +158,13 @@ public class ResourceSetService { public Response delete(@PathParam("id") String id) { requireManage(); StoreFactory storeFactory = authorization.getStoreFactory(); - Resource resource = storeFactory.getResourceStore().findById(resourceServer, id); + Resource resource = storeFactory.getResourceStore().findById(resourceServer.getRealm(), resourceServer, id); if (resource == null) { return Response.status(Status.NOT_FOUND).build(); } - storeFactory.getResourceStore().delete(id); + storeFactory.getResourceStore().delete(resourceServer.getRealm(), id); audit(toRepresentation(resource, resourceServer, authorization), OperationType.DELETE); @@ -183,7 +182,7 @@ public class ResourceSetService { public Response findById(String id, Function toRepresentation) { requireView(); StoreFactory storeFactory = authorization.getStoreFactory(); - Resource model = storeFactory.getResourceStore().findById(resourceServer, id); + Resource model = storeFactory.getResourceStore().findById(resourceServer.getRealm(), resourceServer, id); if (model == null) { return Response.status(Status.NOT_FOUND).build(); @@ -199,7 +198,7 @@ public class ResourceSetService { public Response getScopes(@PathParam("id") String id) { requireView(); StoreFactory storeFactory = authorization.getStoreFactory(); - Resource model = storeFactory.getResourceStore().findById(resourceServer, id); + Resource model = storeFactory.getResourceStore().findById(resourceServer.getRealm(), resourceServer, id); if (model == null) { return Response.status(Status.NOT_FOUND).build(); @@ -243,7 +242,7 @@ public class ResourceSetService { requireView(); StoreFactory storeFactory = authorization.getStoreFactory(); ResourceStore resourceStore = storeFactory.getResourceStore(); - Resource model = resourceStore.findById(resourceServer, id); + Resource model = resourceStore.findById(resourceServer.getRealm(), resourceServer, id); if (model == null) { return Response.status(Status.NOT_FOUND).build(); @@ -264,10 +263,10 @@ public class ResourceSetService { resourceFilter.put(Resource.FilterOption.OWNER, new String[]{resourceServer.getClientId()}); resourceFilter.put(Resource.FilterOption.TYPE, new String[]{model.getType()}); - for (Resource resourceType : resourceStore.findByResourceServer(resourceServer, resourceFilter, null, null)) { - policies.addAll(policyStore.findByResource(resourceServer, resourceType)); - } + for (Resource resourceType : resourceStore.find(resourceServer.getRealm(), resourceServer, resourceFilter, null, null)) { + policies.addAll(policyStore.findByResource(resourceServer, resourceType)); } + } } @@ -300,7 +299,7 @@ public class ResourceSetService { public Response getAttributes(@PathParam("id") String id) { requireView(); StoreFactory storeFactory = authorization.getStoreFactory(); - Resource model = storeFactory.getResourceStore().findById(resourceServer, id); + Resource model = storeFactory.getResourceStore().findById(resourceServer.getRealm(), resourceServer, id); if (model == null) { return Response.status(Status.NOT_FOUND).build(); @@ -416,7 +415,7 @@ public class ResourceSetService { search.put(Resource.FilterOption.SCOPE_ID, scopes.stream().map(Scope::getId).toArray(String[]::new)); } - List resources = storeFactory.getResourceStore().findByResourceServer(this.resourceServer, search, firstResult != null ? firstResult : -1, maxResult != null ? maxResult : Constants.DEFAULT_MAX_RESULTS); + List resources = storeFactory.getResourceStore().find(resourceServer.getRealm(), this.resourceServer, search, firstResult != null ? firstResult : -1, maxResult != null ? maxResult : Constants.DEFAULT_MAX_RESULTS); if (matchingUri != null && matchingUri && resources.isEmpty()) { Map attributes = new EnumMap<>(Resource.FilterOption.class); @@ -424,7 +423,7 @@ public class ResourceSetService { attributes.put(Resource.FilterOption.URI_NOT_NULL, new String[] {"true"}); attributes.put(Resource.FilterOption.OWNER, new String[] {resourceServer.getClientId()}); - List serverResources = storeFactory.getResourceStore().findByResourceServer(this.resourceServer, attributes, firstResult != null ? firstResult : -1, maxResult != null ? maxResult : -1); + List serverResources = storeFactory.getResourceStore().find(resourceServer.getRealm(), this.resourceServer, attributes, firstResult != null ? firstResult : -1, maxResult != null ? maxResult : -1); PathMatcher> pathMatcher = new PathMatcher>() { @Override diff --git a/services/src/main/java/org/keycloak/authorization/admin/ScopeService.java b/services/src/main/java/org/keycloak/authorization/admin/ScopeService.java index 9b8c91937e..20ff5aaf13 100644 --- a/services/src/main/java/org/keycloak/authorization/admin/ScopeService.java +++ b/services/src/main/java/org/keycloak/authorization/admin/ScopeService.java @@ -1,13 +1,12 @@ /* - * JBoss, Home of Professional Open Source. - * Copyright 2016 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -29,6 +28,7 @@ import org.keycloak.events.admin.OperationType; import org.keycloak.events.admin.ResourceType; import org.keycloak.models.Constants; import org.keycloak.models.KeycloakSession; +import org.keycloak.models.RealmModel; import org.keycloak.representations.idm.authorization.PolicyRepresentation; import org.keycloak.representations.idm.authorization.ResourceRepresentation; import org.keycloak.representations.idm.authorization.ScopeRepresentation; @@ -49,7 +49,6 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; -import java.util.Arrays; import java.util.Collections; import java.util.EnumMap; import java.util.List; @@ -101,7 +100,7 @@ public class ScopeService { this.auth.realm().requireManageAuthorization(); scope.setId(id); StoreFactory storeFactory = authorization.getStoreFactory(); - Scope model = storeFactory.getScopeStore().findById(resourceServer, scope.getId()); + Scope model = storeFactory.getScopeStore().findById(resourceServer.getRealm(), resourceServer, scope.getId()); if (model == null) { return Response.status(Status.NOT_FOUND).build(); @@ -119,7 +118,8 @@ public class ScopeService { public Response delete(@PathParam("id") String id) { this.auth.realm().requireManageAuthorization(); StoreFactory storeFactory = authorization.getStoreFactory(); - Scope scope = storeFactory.getScopeStore().findById(resourceServer, id); + RealmModel realm = resourceServer.getRealm(); + Scope scope = storeFactory.getScopeStore().findById(realm, resourceServer, id); if (scope == null) { return Response.status(Status.NOT_FOUND).build(); } @@ -135,13 +135,13 @@ public class ScopeService { for (Policy policyModel : policies) { if (policyModel.getScopes().size() == 1) { - policyStore.delete(policyModel.getId()); + policyStore.delete(realm, policyModel.getId()); } else { policyModel.removeScope(scope); } } - storeFactory.getScopeStore().delete(id); + storeFactory.getScopeStore().delete(realm, id); audit(toRepresentation(scope), OperationType.DELETE); @@ -154,7 +154,7 @@ public class ScopeService { @Produces(MediaType.APPLICATION_JSON) public Response findById(@PathParam("id") String id) { this.auth.realm().requireViewAuthorization(); - Scope model = this.authorization.getStoreFactory().getScopeStore().findById(resourceServer, id); + Scope model = this.authorization.getStoreFactory().getScopeStore().findById(resourceServer.getRealm(), resourceServer, id); if (model == null) { return Response.status(Status.NOT_FOUND).build(); @@ -170,7 +170,7 @@ public class ScopeService { public Response getResources(@PathParam("id") String id) { this.auth.realm().requireViewAuthorization(); StoreFactory storeFactory = this.authorization.getStoreFactory(); - Scope model = storeFactory.getScopeStore().findById(resourceServer, id); + Scope model = storeFactory.getScopeStore().findById(resourceServer.getRealm(), resourceServer, id); if (model == null) { return Response.status(Status.NOT_FOUND).build(); @@ -193,7 +193,7 @@ public class ScopeService { public Response getPermissions(@PathParam("id") String id) { this.auth.realm().requireViewAuthorization(); StoreFactory storeFactory = this.authorization.getStoreFactory(); - Scope model = storeFactory.getScopeStore().findById(resourceServer, id); + Scope model = storeFactory.getScopeStore().findById(resourceServer.getRealm(), resourceServer, id); if (model == null) { return Response.status(Status.NOT_FOUND).build(); diff --git a/services/src/main/java/org/keycloak/authorization/admin/representation/PolicyEvaluationResponseBuilder.java b/services/src/main/java/org/keycloak/authorization/admin/representation/PolicyEvaluationResponseBuilder.java index f8b5101ea9..a1672a2a47 100644 --- a/services/src/main/java/org/keycloak/authorization/admin/representation/PolicyEvaluationResponseBuilder.java +++ b/services/src/main/java/org/keycloak/authorization/admin/representation/PolicyEvaluationResponseBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -182,6 +182,7 @@ public class PolicyEvaluationResponseBuilder { PolicyRepresentation representation = new PolicyRepresentation(); Policy policy = result.getPolicy(); + ResourceServer resourceServer = policy.getResourceServer(); representation.setId(policy.getId()); representation.setName(policy.getName()); @@ -194,7 +195,7 @@ public class PolicyEvaluationResponseBuilder { filters.put(PermissionTicket.FilterOption.POLICY_ID, policy.getId()); - List tickets = authorization.getStoreFactory().getPermissionTicketStore().find(policy.getResourceServer(), filters, -1, 1); + List tickets = authorization.getStoreFactory().getPermissionTicketStore().find(resourceServer.getRealm(), resourceServer, filters, -1, 1); if (!tickets.isEmpty()) { KeycloakSession keycloakSession = authorization.getKeycloakSession(); diff --git a/services/src/main/java/org/keycloak/authorization/authorization/AuthorizationTokenService.java b/services/src/main/java/org/keycloak/authorization/authorization/AuthorizationTokenService.java index d2f72c849e..dd1a6a599d 100644 --- a/services/src/main/java/org/keycloak/authorization/authorization/AuthorizationTokenService.java +++ b/services/src/main/java/org/keycloak/authorization/authorization/AuthorizationTokenService.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -503,6 +503,7 @@ public class AuthorizationTokenService { Map permissionsToEvaluate, ResourceStore resourceStore, ScopeStore scopeStore, AtomicInteger limit) { AccessToken rpt = request.getRpt(); + RealmModel realm = resourceServer.getRealm(); if (rpt != null && rpt.isActive()) { Authorization authorizationData = rpt.getAuthorization(); @@ -516,7 +517,7 @@ public class AuthorizationTokenService { break; } - Resource resource = resourceStore.findById(resourceServer, grantedPermission.getResourceId()); + Resource resource = resourceStore.findById(realm, resourceServer, grantedPermission.getResourceId()); if (resource != null) { ResourcePermission permission = permissionsToEvaluate.get(resource.getId()); @@ -600,7 +601,7 @@ public class AuthorizationTokenService { Resource resource; if (resourceId.indexOf('-') != -1) { - resource = resourceStore.findById(resourceServer, resourceId); + resource = resourceStore.findById(resourceServer.getRealm(), resourceServer, resourceId); } else { resource = null; } diff --git a/services/src/main/java/org/keycloak/authorization/protection/permission/AbstractPermissionService.java b/services/src/main/java/org/keycloak/authorization/protection/permission/AbstractPermissionService.java index f8fa8fc8f5..171c2835ea 100644 --- a/services/src/main/java/org/keycloak/authorization/protection/permission/AbstractPermissionService.java +++ b/services/src/main/java/org/keycloak/authorization/protection/permission/AbstractPermissionService.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -74,7 +74,7 @@ public class AbstractPermissionService { throw new ErrorResponseException("invalid_resource_id", "Resource id or name not provided.", Response.Status.BAD_REQUEST); } } else { - Resource resource = resourceStore.findById(resourceServer, resourceSetId); + Resource resource = resourceStore.findById(resourceServer.getRealm(), resourceServer, resourceSetId); if (resource != null) { resources.add(resource); diff --git a/services/src/main/java/org/keycloak/authorization/protection/permission/PermissionTicketService.java b/services/src/main/java/org/keycloak/authorization/protection/permission/PermissionTicketService.java index a1465a6cd5..d312c6e078 100644 --- a/services/src/main/java/org/keycloak/authorization/protection/permission/PermissionTicketService.java +++ b/services/src/main/java/org/keycloak/authorization/protection/permission/PermissionTicketService.java @@ -1,13 +1,12 @@ /* - * JBoss, Home of Professional Open Source. - * Copyright 2016 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -83,7 +82,7 @@ public class PermissionTicketService { throw new ErrorResponseException("invalid_permission", "created permissions should have requester or requesterName", Response.Status.BAD_REQUEST); ResourceStore rstore = this.authorization.getStoreFactory().getResourceStore(); - Resource resource = rstore.findById(resourceServer, representation.getResource()); + Resource resource = rstore.findById(resourceServer.getRealm(), resourceServer, representation.getResource()); if (resource == null ) throw new ErrorResponseException("invalid_resource_id", "Resource set with id [" + representation.getResource() + "] does not exists in this server.", Response.Status.BAD_REQUEST); if (!resource.getOwner().equals(this.identity.getId())) @@ -104,7 +103,7 @@ public class PermissionTicketService { if(representation.getScopeName() != null) scope = sstore.findByName(resourceServer, representation.getScopeName()); else - scope = sstore.findById(resourceServer, representation.getScope()); + scope = sstore.findById(resourceServer.getRealm(), resourceServer, representation.getScope()); if (scope == null && representation.getScope() !=null ) throw new ErrorResponseException("invalid_scope", "Scope [" + representation.getScope() + "] is invalid", Response.Status.BAD_REQUEST); @@ -121,7 +120,7 @@ public class PermissionTicketService { attributes.put(PermissionTicket.FilterOption.SCOPE_ID, scope.getId()); attributes.put(PermissionTicket.FilterOption.REQUESTER, user.getId()); - if (!ticketStore.find(resourceServer, attributes, null, null).isEmpty()) + if (!ticketStore.find(resourceServer.getRealm(), resourceServer, attributes, null, null).isEmpty()) throw new ErrorResponseException("invalid_permission", "Permission already exists", Response.Status.BAD_REQUEST); PermissionTicket ticket = ticketStore.create(resourceServer, resource, scope, user.getId()); @@ -139,7 +138,7 @@ public class PermissionTicketService { } PermissionTicketStore ticketStore = authorization.getStoreFactory().getPermissionTicketStore(); - PermissionTicket ticket = ticketStore.findById(resourceServer, representation.getId()); + PermissionTicket ticket = ticketStore.findById(resourceServer.getRealm(), resourceServer, representation.getId()); if (ticket == null) { throw new ErrorResponseException(OAuthErrorException.INVALID_REQUEST, "invalid_ticket", Response.Status.BAD_REQUEST); @@ -163,7 +162,7 @@ public class PermissionTicketService { } PermissionTicketStore ticketStore = authorization.getStoreFactory().getPermissionTicketStore(); - PermissionTicket ticket = ticketStore.findById(resourceServer, id); + PermissionTicket ticket = ticketStore.findById(resourceServer.getRealm(), resourceServer, id); if (ticket == null) { throw new ErrorResponseException(OAuthErrorException.INVALID_REQUEST, "invalid_ticket", Response.Status.BAD_REQUEST); @@ -172,7 +171,7 @@ public class PermissionTicketService { if (!ticket.getOwner().equals(this.identity.getId()) && !this.identity.isResourceServer() && !ticket.getRequester().equals(this.identity.getId())) throw new ErrorResponseException("not_authorised", "permissions for [" + ticket.getResource() + "] can be deleted only by the owner, the requester, or the resource server", Response.Status.FORBIDDEN); - ticketStore.delete(id); + ticketStore.delete(resourceServer.getRealm(), id); return Response.noContent().build(); } @@ -192,7 +191,7 @@ public class PermissionTicketService { Map filters = getFilters(storeFactory, resourceId, scopeId, owner, requester, granted); - return Response.ok().entity(permissionTicketStore.find(resourceServer, filters, firstResult != null ? firstResult : -1, maxResult != null ? maxResult : Constants.DEFAULT_MAX_RESULTS) + return Response.ok().entity(permissionTicketStore.find(resourceServer.getRealm(), resourceServer, filters, firstResult != null ? firstResult : -1, maxResult != null ? maxResult : Constants.DEFAULT_MAX_RESULTS) .stream() .map(permissionTicket -> ModelToRepresentation.toRepresentation(permissionTicket, authorization, returnNames == null ? false : returnNames)) .collect(Collectors.toList())) @@ -230,7 +229,7 @@ public class PermissionTicketService { if (scopeId != null) { ScopeStore scopeStore = storeFactory.getScopeStore(); - Scope scope = scopeStore.findById(resourceServer, scopeId); + Scope scope = scopeStore.findById(resourceServer.getRealm(), resourceServer, scopeId); if (scope == null) { scope = scopeStore.findByName(resourceServer, scopeId); diff --git a/services/src/main/java/org/keycloak/authorization/protection/policy/UserManagedPermissionService.java b/services/src/main/java/org/keycloak/authorization/protection/policy/UserManagedPermissionService.java index 786efe7bfe..b01d694832 100644 --- a/services/src/main/java/org/keycloak/authorization/protection/policy/UserManagedPermissionService.java +++ b/services/src/main/java/org/keycloak/authorization/protection/policy/UserManagedPermissionService.java @@ -1,13 +1,12 @@ /* - * JBoss, Home of Professional Open Source. - * Copyright 2016 Red Hat, Inc., and individual contributors - * as indicated by the @author tags. + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -132,7 +131,7 @@ public class UserManagedPermissionService { } private Policy getPolicy(@PathParam("policyId") String policyId) { - Policy existing = authorization.getStoreFactory().getPolicyStore().findById(resourceServer, policyId); + Policy existing = authorization.getStoreFactory().getPolicyStore().findById(resourceServer.getRealm(), resourceServer, policyId); if (existing == null) { throw new ErrorResponseException(OAuthErrorException.INVALID_REQUEST, "Policy with [" + policyId + "] does not exist", Status.NOT_FOUND); @@ -143,7 +142,7 @@ public class UserManagedPermissionService { private void checkRequest(String resourceId, UmaPermissionRepresentation representation) { ResourceStore resourceStore = this.authorization.getStoreFactory().getResourceStore(); - Resource resource = resourceStore.findById(resourceServer, resourceId); + Resource resource = resourceStore.findById(resourceServer.getRealm(), resourceServer, resourceId); if (resource == null) { throw new ErrorResponseException(OAuthErrorException.INVALID_REQUEST, "Resource [" + resourceId + "] cannot be found", Response.Status.BAD_REQUEST); diff --git a/services/src/main/java/org/keycloak/forms/account/freemarker/FreeMarkerAccountProvider.java b/services/src/main/java/org/keycloak/forms/account/freemarker/FreeMarkerAccountProvider.java index 173a59ec04..a7baade10e 100755 --- a/services/src/main/java/org/keycloak/forms/account/freemarker/FreeMarkerAccountProvider.java +++ b/services/src/main/java/org/keycloak/forms/account/freemarker/FreeMarkerAccountProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -186,12 +186,12 @@ public class FreeMarkerAccountProvider implements AccountProvider { if (!realm.isUserManagedAccessAllowed()) { return Response.status(Status.FORBIDDEN).build(); } - attributes.put("authorization", new AuthorizationBean(session, user, uriInfo)); + attributes.put("authorization", new AuthorizationBean(session, realm, user, uriInfo)); case RESOURCE_DETAIL: if (!realm.isUserManagedAccessAllowed()) { return Response.status(Status.FORBIDDEN).build(); } - attributes.put("authorization", new AuthorizationBean(session, user, uriInfo)); + attributes.put("authorization", new AuthorizationBean(session, realm, user, uriInfo)); } return processTemplate(theme, page, attributes, locale); diff --git a/services/src/main/java/org/keycloak/forms/account/freemarker/model/AuthorizationBean.java b/services/src/main/java/org/keycloak/forms/account/freemarker/model/AuthorizationBean.java index 19f6f0cd3f..94120a4ea9 100755 --- a/services/src/main/java/org/keycloak/forms/account/freemarker/model/AuthorizationBean.java +++ b/services/src/main/java/org/keycloak/forms/account/freemarker/model/AuthorizationBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -52,6 +52,7 @@ import org.keycloak.services.util.ResolveRelative; public class AuthorizationBean { private final KeycloakSession session; + private final RealmModel realm; private final UserModel user; private final AuthorizationProvider authorization; private final UriInfo uriInfo; @@ -61,15 +62,16 @@ public class AuthorizationBean { private Collection requestsWaitingPermission; private Collection resourcesWaitingOthersApproval; - public AuthorizationBean(KeycloakSession session, UserModel user, UriInfo uriInfo) { + public AuthorizationBean(KeycloakSession session, RealmModel realm, UserModel user, UriInfo uriInfo) { this.session = session; + this.realm = realm; this.user = user; this.uriInfo = uriInfo; authorization = session.getProvider(AuthorizationProvider.class); List pathParameters = uriInfo.getPathParameters().get("resource_id"); if (pathParameters != null && !pathParameters.isEmpty()) { - Resource resource = authorization.getStoreFactory().getResourceStore().findById(null, pathParameters.get(0)); + Resource resource = authorization.getStoreFactory().getResourceStore().findById(realm, null, pathParameters.get(0)); if (resource != null && !resource.getOwner().equals(user.getId())) { throw new RuntimeException("User [" + user.getUsername() + "] can not access resource [" + resource.getId() + "]"); @@ -105,7 +107,7 @@ public class AuthorizationBean { public List getResources() { if (resources == null) { - resources = authorization.getStoreFactory().getResourceStore().findByOwner(null, user.getId()).stream() + resources = authorization.getStoreFactory().getResourceStore().findByOwner(realm, null, user.getId()).stream() .filter(Resource::isOwnerManagedAccess) .map(ResourceBean::new) .collect(Collectors.toList()); @@ -122,7 +124,7 @@ public class AuthorizationBean { PermissionTicketStore ticketStore = authorization.getStoreFactory().getPermissionTicketStore(); - userSharedResources = toResourceRepresentation(ticketStore.find(null, filters, null, null)); + userSharedResources = toResourceRepresentation(ticketStore.find(realm,null, filters, null, null)); } return userSharedResources; } @@ -140,7 +142,7 @@ public class AuthorizationBean { } private ResourceBean getResource(String id) { - return new ResourceBean(authorization.getStoreFactory().getResourceStore().findById(null, id)); + return new ResourceBean(authorization.getStoreFactory().getResourceStore().findById(realm, null, id)); } public static class RequesterBean { @@ -296,6 +298,8 @@ public class AuthorizationBean { } public Collection getPolicies() { + ResourceServer resourceServer = getResourceServer().getResourceServerModel(); + RealmModel realm = resourceServer.getRealm(); Map filters = new EnumMap<>(Policy.FilterOption.class); filters.put(Policy.FilterOption.TYPE, new String[] {"uma"}); @@ -306,7 +310,7 @@ public class AuthorizationBean { filters.put(Policy.FilterOption.OWNER, new String[] {getClientOwner().getId()}); } - List policies = authorization.getStoreFactory().getPolicyStore().findByResourceServer(getResourceServer().getResourceServerModel(), filters, null, null); + List policies = authorization.getStoreFactory().getPolicyStore().find(realm, resourceServer, filters, null, null); if (policies.isEmpty()) { return Collections.emptyList(); @@ -318,7 +322,7 @@ public class AuthorizationBean { filters1.put(PermissionTicket.FilterOption.POLICY_ID, policy.getId()); - return authorization.getStoreFactory().getPermissionTicketStore().find(resourceServer.getResourceServerModel(), filters1, -1, 1) + return authorization.getStoreFactory().getPermissionTicketStore().find(realm, resourceServer, filters1, -1, 1) .isEmpty(); }) .map(ManagedPermissionBean::new).collect(Collectors.toList()); @@ -370,7 +374,7 @@ public class AuthorizationBean { } private List findPermissions(Map filters) { - return authorization.getStoreFactory().getPermissionTicketStore().find(null, filters, null, null); + return authorization.getStoreFactory().getPermissionTicketStore().find(realm, null, filters, null, null); } public class ResourceServerBean { diff --git a/services/src/main/java/org/keycloak/services/resources/account/AccountFormService.java b/services/src/main/java/org/keycloak/services/resources/account/AccountFormService.java index c570cde41c..d60b121b3b 100755 --- a/services/src/main/java/org/keycloak/services/resources/account/AccountFormService.java +++ b/services/src/main/java/org/keycloak/services/resources/account/AccountFormService.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -115,7 +115,6 @@ import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.UUID; -import java.util.function.Predicate; import java.util.stream.Collectors; /** @@ -772,7 +771,7 @@ public class AccountFormService extends AbstractSecuredLocalService { AuthorizationProvider authorization = session.getProvider(AuthorizationProvider.class); PermissionTicketStore ticketStore = authorization.getStoreFactory().getPermissionTicketStore(); - Resource resource = authorization.getStoreFactory().getResourceStore().findById(null, resourceId); + Resource resource = authorization.getStoreFactory().getResourceStore().findById(realm, null, resourceId); if (resource == null) { return ErrorResponse.error("Invalid resource", Response.Status.BAD_REQUEST); @@ -799,7 +798,7 @@ public class AccountFormService extends AbstractSecuredLocalService { String id = iterator.next(); if (!id.contains(":")) { - policy = policyStore.findById(resourceServer, id); + policy = policyStore.findById(realm, resourceServer, id); iterator.remove(); break; } @@ -813,7 +812,7 @@ public class AccountFormService extends AbstractSecuredLocalService { } } else { for (String id : ids) { - scopesToKeep.add(authorization.getStoreFactory().getScopeStore().findById(resourceServer, id.split(":")[1])); + scopesToKeep.add(authorization.getStoreFactory().getScopeStore().findById(realm, resourceServer, id.split(":")[1])); } for (Scope scope : policy.getScopes()) { @@ -825,10 +824,10 @@ public class AccountFormService extends AbstractSecuredLocalService { if (policy.getScopes().isEmpty()) { for (Policy associated : policy.getAssociatedPolicies()) { - policyStore.delete(associated.getId()); + policyStore.delete(realm, associated.getId()); } - policyStore.delete(policy.getId()); + policyStore.delete(realm, policy.getId()); } } else { Map filters = new EnumMap<>(PermissionTicket.FilterOption.class); @@ -842,7 +841,7 @@ public class AccountFormService extends AbstractSecuredLocalService { filters.put(PermissionTicket.FilterOption.GRANTED, Boolean.FALSE.toString()); } - List tickets = ticketStore.find(resource.getResourceServer(), filters, null, null); + List tickets = ticketStore.find(realm, resource.getResourceServer(), filters, null, null); Iterator iterator = tickets.iterator(); while (iterator.hasNext()) { @@ -865,7 +864,7 @@ public class AccountFormService extends AbstractSecuredLocalService { } for (PermissionTicket ticket : tickets) { - ticketStore.delete(ticket.getId()); + ticketStore.delete(client.getRealm(), ticket.getId()); } } @@ -898,7 +897,7 @@ public class AccountFormService extends AbstractSecuredLocalService { AuthorizationProvider authorization = session.getProvider(AuthorizationProvider.class); PermissionTicketStore ticketStore = authorization.getStoreFactory().getPermissionTicketStore(); ScopeStore scopeStore = authorization.getStoreFactory().getScopeStore(); - Resource resource = authorization.getStoreFactory().getResourceStore().findById(null, resourceId); + Resource resource = authorization.getStoreFactory().getResourceStore().findById(realm, null, resourceId); ResourceServer resourceServer = resource.getResourceServer(); if (resource == null) { @@ -932,13 +931,13 @@ public class AccountFormService extends AbstractSecuredLocalService { filters.put(PermissionTicket.FilterOption.OWNER, auth.getUser().getId()); filters.put(PermissionTicket.FilterOption.REQUESTER, user.getId()); - List tickets = ticketStore.find(resourceServer, filters, null, null); + List tickets = ticketStore.find(realm, resourceServer, filters, null, null); final String userId = user.getId(); if (tickets.isEmpty()) { if (scopes != null && scopes.length > 0) { for (String scopeId : scopes) { - Scope scope = scopeStore.findById(resourceServer, scopeId); + Scope scope = scopeStore.findById(realm, resourceServer, scopeId); PermissionTicket ticket = ticketStore.create(resourceServer, resource, scope, userId); ticket.setGrantedTimestamp(System.currentTimeMillis()); } @@ -963,7 +962,7 @@ public class AccountFormService extends AbstractSecuredLocalService { grantScopes.removeIf(alreadyGrantedScopes::contains); for (String scopeId : grantScopes) { - Scope scope = scopeStore.findById(resourceServer, scopeId); + Scope scope = scopeStore.findById(realm, resourceServer, scopeId); PermissionTicket ticket = ticketStore.create(resourceServer, resource, scope, userId); ticket.setGrantedTimestamp(System.currentTimeMillis()); } @@ -993,7 +992,7 @@ public class AccountFormService extends AbstractSecuredLocalService { } for (String resourceId : resourceIds) { - Resource resource = authorization.getStoreFactory().getResourceStore().findById(null, resourceId); + Resource resource = authorization.getStoreFactory().getResourceStore().findById(realm, null, resourceId); if (resource == null) { return ErrorResponse.error("Invalid resource", Response.Status.BAD_REQUEST); @@ -1010,8 +1009,9 @@ public class AccountFormService extends AbstractSecuredLocalService { filters.put(PermissionTicket.FilterOption.GRANTED, Boolean.FALSE.toString()); } - for (PermissionTicket ticket : ticketStore.find(resource.getResourceServer(), filters, null, null)) { - ticketStore.delete(ticket.getId()); + RealmModel realm = resource.getResourceServer().getRealm(); + for (PermissionTicket ticket : ticketStore.find(realm, resource.getResourceServer(), filters, null, null)) { + ticketStore.delete(realm, ticket.getId()); } } diff --git a/services/src/main/java/org/keycloak/services/resources/account/resources/ResourceService.java b/services/src/main/java/org/keycloak/services/resources/account/resources/ResourceService.java index f9872d5fdf..53b1349c72 100644 --- a/services/src/main/java/org/keycloak/services/resources/account/resources/ResourceService.java +++ b/services/src/main/java/org/keycloak/services/resources/account/resources/ResourceService.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -39,6 +39,7 @@ import org.keycloak.authorization.model.PermissionTicket; import org.keycloak.authorization.model.ResourceServer; import org.keycloak.models.AccountRoles; import org.keycloak.models.KeycloakSession; +import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserProvider; import org.keycloak.services.managers.Auth; @@ -87,7 +88,7 @@ public class ResourceService extends AbstractResourceService { filters.put(PermissionTicket.FilterOption.GRANTED, Boolean.TRUE.toString()); filters.put(PermissionTicket.FilterOption.RESOURCE_ID, resource.getId()); - Collection resources = toPermissions(ticketStore.find(null, filters, null, null)); + Collection resources = toPermissions(ticketStore.find(resourceServer.getRealm(), resourceServer, filters, null, null)); Collection permissions = Collections.EMPTY_LIST; if (!resources.isEmpty()) { @@ -127,15 +128,17 @@ public class ResourceService extends AbstractResourceService { } Map filters = new EnumMap<>(PermissionTicket.FilterOption.class); + RealmModel realm = resourceServer.getRealm(); filters.put(PermissionTicket.FilterOption.RESOURCE_ID, resource.getId()); + for (Permission permission : permissions) { UserModel user = getUser(permission.getUsername()); filters.put(PermissionTicket.FilterOption.REQUESTER, user.getId()); - List tickets = ticketStore.find(resource.getResourceServer(), filters, null, null); + List tickets = ticketStore.find(realm, resourceServer, filters, null, null); // grants all requested permissions if (tickets.isEmpty()) { @@ -171,7 +174,7 @@ public class ResourceService extends AbstractResourceService { // remove all tickets that are not within the requested permissions for (PermissionTicket ticket : tickets) { - ticketStore.delete(ticket.getId()); + ticketStore.delete(realm, ticket.getId()); } } } @@ -196,7 +199,7 @@ public class ResourceService extends AbstractResourceService { Map requests = new HashMap<>(); - for (PermissionTicket ticket : ticketStore.find(null, filters, null, null)) { + for (PermissionTicket ticket : ticketStore.find(resourceServer.getRealm(), resourceServer, filters, null, null)) { requests.computeIfAbsent(ticket.getRequester(), requester -> new Permission(ticket, provider)).addScope(ticket.getScope().getName()); } @@ -213,7 +216,7 @@ public class ResourceService extends AbstractResourceService { org.keycloak.authorization.model.Scope scope = scopeStore.findByName(resourceServer, scopeId); if (scope == null) { - scope = scopeStore.findById(resourceServer, scopeId); + scope = scopeStore.findById(resourceServer.getRealm(), resourceServer, scopeId); } return scope; diff --git a/services/src/main/java/org/keycloak/services/resources/account/resources/ResourcesService.java b/services/src/main/java/org/keycloak/services/resources/account/resources/ResourcesService.java index 8fbc72cc4c..2a58f26106 100644 --- a/services/src/main/java/org/keycloak/services/resources/account/resources/ResourcesService.java +++ b/services/src/main/java/org/keycloak/services/resources/account/resources/ResourcesService.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -73,7 +73,7 @@ public class ResourcesService extends AbstractResourceService { filters.put(org.keycloak.authorization.model.Resource.FilterOption.NAME, new String[] { name }); } - return queryResponse((f, m) -> resourceStore.findByResourceServer(null, filters, f, m).stream() + return queryResponse((f, m) -> resourceStore.find(auth.getRealm(), null, filters, f, m).stream() .map(resource -> new Resource(resource, user, provider)), first, max); } @@ -123,7 +123,7 @@ public class ResourcesService extends AbstractResourceService { filters.put(PermissionTicket.FilterOption.REQUESTER, user.getId()); filters.put(PermissionTicket.FilterOption.GRANTED, Boolean.FALSE.toString()); - final List permissionTickets = ticketStore.find(null, filters, null, null); + final List permissionTickets = ticketStore.find(auth.getRealm(), null, filters, null, null); final List resourceList = new ArrayList<>(permissionTickets.size()); for (PermissionTicket ticket : permissionTickets) { @@ -138,7 +138,7 @@ public class ResourcesService extends AbstractResourceService { @Path("{id}") public Object getResource(@PathParam("id") String id) { - org.keycloak.authorization.model.Resource resource = resourceStore.findById(null, id); + org.keycloak.authorization.model.Resource resource = resourceStore.findById(auth.getRealm(), null, id); if (resource == null) { throw new NotFoundException("resource_not_found"); @@ -167,7 +167,7 @@ public class ResourcesService extends AbstractResourceService { filters.put(PermissionTicket.FilterOption.GRANTED, Boolean.TRUE.toString()); filters.put(PermissionTicket.FilterOption.RESOURCE_ID, resource.getId()); - tickets = ticketStore.find(resource.getResourceServer(), filters, null, null); + tickets = ticketStore.find(auth.getRealm(), resource.getResourceServer(), filters, null, null); } else { tickets = ticketStore.findGranted(resource.getResourceServer(), resource.getName(), user.getId()); } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissions.java index 48470eab08..eb0ba99423 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissions.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/ClientPermissions.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -165,7 +165,7 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionM private void deletePolicy(String name, ResourceServer server) { Policy policy = authz.getStoreFactory().getPolicyStore().findByName(server, name); if (policy != null) { - authz.getStoreFactory().getPolicyStore().delete(policy.getId()); + authz.getStoreFactory().getPolicyStore().delete(server.getRealm(), policy.getId()); } } @@ -181,7 +181,7 @@ class ClientPermissions implements ClientPermissionEvaluator, ClientPermissionM deletePolicy(getConfigurePermissionName(client), server); deletePolicy(getExchangeToPermissionName(client), server); Resource resource = authz.getStoreFactory().getResourceStore().findByName(server, getResourceName(client));; - if (resource != null) authz.getStoreFactory().getResourceStore().delete(resource.getId()); + if (resource != null) authz.getStoreFactory().getResourceStore().delete(server.getRealm(), resource.getId()); } @Override diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissions.java index 73256fc967..e99cbf0d7d 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissions.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/GroupPermissions.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -28,6 +28,7 @@ import org.keycloak.authorization.store.ResourceStore; import org.keycloak.common.Profile; import org.keycloak.models.AdminRoles; import org.keycloak.models.GroupModel; +import org.keycloak.models.RealmModel; import org.keycloak.representations.idm.authorization.Permission; import org.keycloak.services.ForbiddenException; @@ -443,27 +444,30 @@ class GroupPermissions implements GroupPermissionEvaluator, GroupPermissionManag private void deletePermissions(GroupModel group) { ResourceServer server = root.realmResourceServer(); if (server == null) return; + + RealmModel realm = server.getRealm(); + Policy managePermission = managePermission(group); if (managePermission != null) { - policyStore.delete(managePermission.getId()); + policyStore.delete(realm, managePermission.getId()); } Policy viewPermission = viewPermission(group); if (viewPermission != null) { - policyStore.delete(viewPermission.getId()); + policyStore.delete(realm, viewPermission.getId()); } Policy manageMembersPermission = manageMembersPermission(group); if (manageMembersPermission != null) { - policyStore.delete(manageMembersPermission.getId()); + policyStore.delete(realm, manageMembersPermission.getId()); } Policy viewMembersPermission = viewMembersPermission(group); if (viewMembersPermission != null) { - policyStore.delete(viewMembersPermission.getId()); + policyStore.delete(realm, viewMembersPermission.getId()); } Policy manageMembershipPermission = manageMembershipPermission(group); if (manageMembershipPermission != null) { - policyStore.delete(manageMembershipPermission.getId()); + policyStore.delete(realm, manageMembershipPermission.getId()); } Resource resource = groupResource(group); - if (resource != null) resourceStore.delete(resource.getId()); + if (resource != null) resourceStore.delete(realm, resource.getId()); } } diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/IdentityProviderPermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/IdentityProviderPermissions.java index bb1bb59d45..a4a90a33b0 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/IdentityProviderPermissions.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/IdentityProviderPermissions.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -91,7 +91,7 @@ class IdentityProviderPermissions implements IdentityProviderPermissionManageme private void deletePolicy(String name, ResourceServer server) { Policy policy = authz.getStoreFactory().getPolicyStore().findByName(server, name); if (policy != null) { - authz.getStoreFactory().getPolicyStore().delete(policy.getId()); + authz.getStoreFactory().getPolicyStore().delete(server.getRealm(), policy.getId()); } } @@ -101,7 +101,7 @@ class IdentityProviderPermissions implements IdentityProviderPermissionManageme if (server == null) return; deletePolicy(getExchangeToPermissionName(idp), server); Resource resource = authz.getStoreFactory().getResourceStore().findByName(server, getResourceName(idp));; - if (resource != null) authz.getStoreFactory().getResourceStore().delete(resource.getId()); + if (resource != null) authz.getStoreFactory().getResourceStore().delete(server.getRealm(), resource.getId()); } @Override diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/RolePermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RolePermissions.java index fee335122b..f045a38d26 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/RolePermissions.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/RolePermissions.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -74,15 +74,18 @@ class RolePermissions implements RolePermissionEvaluator, RolePermissionManageme private void disablePermissions(RoleModel role) { ResourceServer server = resourceServer(role); if (server == null) return; + + RealmModel realm = server.getRealm(); + Policy policy = mapRolePermission(role); - if (policy != null) authz.getStoreFactory().getPolicyStore().delete(policy.getId()); + if (policy != null) authz.getStoreFactory().getPolicyStore().delete(realm, policy.getId()); policy = mapClientScopePermission(role); - if (policy != null) authz.getStoreFactory().getPolicyStore().delete(policy.getId()); + if (policy != null) authz.getStoreFactory().getPolicyStore().delete(realm, policy.getId()); policy = mapCompositePermission(role); - if (policy != null) authz.getStoreFactory().getPolicyStore().delete(policy.getId()); + if (policy != null) authz.getStoreFactory().getPolicyStore().delete(realm, policy.getId()); Resource resource = authz.getStoreFactory().getResourceStore().findByName(server, getRoleResourceName(role)); - if (resource != null) authz.getStoreFactory().getResourceStore().delete(resource.getId()); + if (resource != null) authz.getStoreFactory().getResourceStore().delete(realm, resource.getId()); } @Override diff --git a/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissions.java b/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissions.java index f7249b39b7..fc5aa8d482 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissions.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/permissions/UserPermissions.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -35,6 +35,7 @@ import org.keycloak.models.ClientModel; import org.keycloak.models.GroupModel; import org.keycloak.models.ImpersonationConstants; import org.keycloak.models.KeycloakSession; +import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.representations.idm.authorization.Permission; import org.keycloak.services.ForbiddenException; @@ -526,39 +527,42 @@ class UserPermissions implements UserPermissionEvaluator, UserPermissionManageme private void deletePermissionSetup() { ResourceServer server = root.realmResourceServer(); if (server == null) return; + + RealmModel realm = server.getRealm(); + Policy policy = managePermission(); if (policy != null) { - policyStore.delete(policy.getId()); + policyStore.delete(realm, policy.getId()); } policy = viewPermission(); if (policy != null) { - policyStore.delete(policy.getId()); + policyStore.delete(realm, policy.getId()); } policy = mapRolesPermission(); if (policy != null) { - policyStore.delete(policy.getId()); + policyStore.delete(realm, policy.getId()); } policy = manageGroupMembershipPermission(); if (policy != null) { - policyStore.delete(policy.getId()); + policyStore.delete(realm, policy.getId()); } policy = adminImpersonatingPermission(); if (policy != null) { - policyStore.delete(policy.getId()); + policyStore.delete(realm, policy.getId()); } policy = userImpersonatedPermission(); if (policy != null) { - policyStore.delete(policy.getId()); + policyStore.delete(realm, policy.getId()); } Resource usersResource = resourceStore.findByName(server, USERS_RESOURCE); if (usersResource != null) { - resourceStore.delete(usersResource.getId()); + resourceStore.delete(realm, usersResource.getId()); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/UmaRepresentationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/UmaRepresentationTest.java index f502842833..85dba874b9 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/UmaRepresentationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/UmaRepresentationTest.java @@ -1,3 +1,20 @@ +/* + * Copyright 2022 Red Hat, Inc. and/or its affiliates + * and other contributors as indicated by the @author tags. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.keycloak.testsuite.authz; import org.junit.Assert; @@ -9,6 +26,7 @@ import org.keycloak.forms.account.freemarker.model.AuthorizationBean; import org.keycloak.forms.account.freemarker.model.AuthorizationBean.ResourceBean; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; +import org.keycloak.models.RealmModel; import org.keycloak.models.UserModel; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.authorization.*; @@ -134,10 +152,11 @@ public class UmaRepresentationTest extends AbstractResourceServerTest { } public static void testCanRepresentResourceBeanOfResourceOwnedByUser(KeycloakSession session) { - session.getContext().setRealm(session.realms().getRealmByName("authz-test")); + RealmModel realm = session.realms().getRealmByName("authz-test"); + session.getContext().setRealm(realm); AuthorizationProvider authorization = session.getProvider(AuthorizationProvider.class); - AuthorizationBean authorizationBean = new AuthorizationBean(session, null, session.getContext().getUri()); + AuthorizationBean authorizationBean = new AuthorizationBean(session, realm, null, session.getContext().getUri()); ClientModel client = session.getContext().getRealm().getClientByClientId("resource-server-test"); UserModel user = session.userStorageManager().getUserByUsername(session.getContext().getRealm(), "marta"); ResourceServer resourceServer = authorization.getStoreFactory().getResourceServerStore().findByClient(client); @@ -161,10 +180,11 @@ public class UmaRepresentationTest extends AbstractResourceServerTest { } public static void testCanRepresentResourceBeanOfResourceOwnedByClient(KeycloakSession session) { - session.getContext().setRealm(session.realms().getRealmByName("authz-test")); + RealmModel realm = session.realms().getRealmByName("authz-test"); + session.getContext().setRealm(realm); AuthorizationProvider authorization = session.getProvider(AuthorizationProvider.class); - AuthorizationBean authorizationBean = new AuthorizationBean(session, null, session.getContext().getUri()); + AuthorizationBean authorizationBean = new AuthorizationBean(session, realm, null, session.getContext().getUri()); ClientModel client = session.getContext().getRealm().getClientByClientId("resource-server-test"); ResourceServer resourceServer = authorization.getStoreFactory().getResourceServerStore().findByClient(client); ResourceBean resourceBean = authorizationBean.new ResourceBean( diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/UserManagedPermissionServiceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/UserManagedPermissionServiceTest.java index bcfecfa478..4acb3549b2 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/UserManagedPermissionServiceTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/UserManagedPermissionServiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 Red Hat, Inc. and/or its affiliates + * Copyright 2022 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -580,11 +580,11 @@ public class UserManagedPermissionServiceTest extends AbstractResourceServerTest PolicyStore policyStore = provider.getStoreFactory().getPolicyStore(); List policies = policyStore - .findByResourceServer(resourceServer, filters, null, null); + .find(realm, resourceServer, filters, null, null); assertTrue(policies.isEmpty()); policies = policyStore - .findByResourceServer(resourceServer, Collections.emptyMap(), null, null); + .find(realm, resourceServer, Collections.emptyMap(), null, null); assertTrue(policies.isEmpty()); } @@ -1007,7 +1007,7 @@ public class UserManagedPermissionServiceTest extends AbstractResourceServerTest filters.put(OWNER, new String[] {user.getId()}); List policies = provider.getStoreFactory().getPolicyStore() - .findByResourceServer(resourceServer, filters, null, null); + .find(realm, resourceServer, filters, null, null); assertEquals(1, policies.size()); Policy policy = policies.get(0); @@ -1016,13 +1016,13 @@ public class UserManagedPermissionServiceTest extends AbstractResourceServerTest Resource resource = policy.getResources().iterator().next(); assertEquals("Resource A", resource.getName()); - provider.getStoreFactory().getResourceStore().delete(resource.getId()); + provider.getStoreFactory().getResourceStore().delete(realm, resource.getId()); filters = new HashMap<>(); filters.put(OWNER, new String[] {user.getId()}); policies = provider.getStoreFactory().getPolicyStore() - .findByResourceServer(resourceServer, filters, null, null); + .find(realm, resourceServer, filters, null, null); assertTrue(policies.isEmpty()); } @@ -1061,7 +1061,7 @@ public class UserManagedPermissionServiceTest extends AbstractResourceServerTest filters.put(OWNER, new String[] {user.getId()}); List policies = provider.getStoreFactory().getPolicyStore() - .findByResourceServer(resourceServer, filters, null, null); + .find(realm, resourceServer, filters, null, null); assertEquals(1, policies.size()); Policy policy = policies.get(0); @@ -1077,7 +1077,7 @@ public class UserManagedPermissionServiceTest extends AbstractResourceServerTest filters.put(OWNER, new String[] {user.getId()}); policies = provider.getStoreFactory().getPolicyStore() - .findByResourceServer(resourceServer, filters, null, null); + .find(realm, resourceServer, filters, null, null); assertTrue(policies.isEmpty()); } @@ -1116,7 +1116,7 @@ public class UserManagedPermissionServiceTest extends AbstractResourceServerTest filters.put(OWNER, new String[] {user.getId()}); List policies = provider.getStoreFactory().getPolicyStore() - .findByResourceServer(resourceServer, filters, null, null); + .find(realm, resourceServer, filters, null, null); assertEquals(1, policies.size()); Policy policy = policies.get(0); @@ -1132,7 +1132,7 @@ public class UserManagedPermissionServiceTest extends AbstractResourceServerTest filters.put(OWNER, new String[] {user.getId()}); policies = provider.getStoreFactory().getPolicyStore() - .findByResourceServer(resourceServer, filters, null, null); + .find(realm, resourceServer, filters, null, null); assertTrue(policies.isEmpty()); }