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 eb350be7ae..1bd41e2d86 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 @@ -24,6 +24,7 @@ import java.util.List; import java.util.Map; import javax.persistence.EntityManager; +import javax.persistence.FlushModeType; import javax.persistence.NoResultException; import javax.persistence.Query; import javax.persistence.TypedQuery; @@ -34,14 +35,10 @@ import javax.persistence.criteria.Root; import org.keycloak.authorization.AuthorizationProvider; import org.keycloak.authorization.jpa.entities.PolicyEntity; -import org.keycloak.authorization.jpa.entities.ResourceServerEntity; import org.keycloak.authorization.model.Policy; -import org.keycloak.authorization.model.Resource; import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.store.PolicyStore; -import org.keycloak.authorization.store.StoreFactory; import org.keycloak.models.utils.KeycloakModelUtils; -import org.keycloak.models.utils.RepresentationToModel; import org.keycloak.representations.idm.authorization.AbstractPolicyRepresentation; /** @@ -96,8 +93,10 @@ public class JPAPolicyStore implements PolicyStore { public Policy findByName(String name, String resourceServerId) { TypedQuery query = entityManager.createNamedQuery("findPolicyIdByName", String.class); + query.setFlushMode(FlushModeType.COMMIT); query.setParameter("serverId", resourceServerId); query.setParameter("name", name); + try { String id = query.getSingleResult(); return provider.getStoreFactory().getPolicyStore().findById(id, resourceServerId); @@ -167,6 +166,7 @@ public class JPAPolicyStore implements PolicyStore { public List findByResource(final String resourceId, String resourceServerId) { TypedQuery query = entityManager.createNamedQuery("findPolicyIdByResource", String.class); + query.setFlushMode(FlushModeType.COMMIT); query.setParameter("resourceId", resourceId); query.setParameter("serverId", resourceServerId); @@ -182,6 +182,7 @@ public class JPAPolicyStore implements PolicyStore { public List findByResourceType(final String resourceType, String resourceServerId) { TypedQuery query = entityManager.createNamedQuery("findPolicyIdByResourceType", String.class); + query.setFlushMode(FlushModeType.COMMIT); query.setParameter("type", resourceType); query.setParameter("serverId", resourceServerId); @@ -202,6 +203,7 @@ public class JPAPolicyStore implements PolicyStore { // Use separate subquery to handle DB2 and MSSSQL TypedQuery query = entityManager.createNamedQuery("findPolicyIdByScope", String.class); + query.setFlushMode(FlushModeType.COMMIT); query.setParameter("scopeIds", scopeIds); query.setParameter("serverId", resourceServerId); @@ -217,6 +219,7 @@ public class JPAPolicyStore implements PolicyStore { public List findByType(String type, String resourceServerId) { TypedQuery query = entityManager.createNamedQuery("findPolicyIdByType", String.class); + query.setFlushMode(FlushModeType.COMMIT); query.setParameter("serverId", resourceServerId); query.setParameter("type", type); @@ -233,6 +236,7 @@ public class JPAPolicyStore implements PolicyStore { TypedQuery query = entityManager.createNamedQuery("findPolicyIdByDependentPolices", String.class); + query.setFlushMode(FlushModeType.COMMIT); query.setParameter("serverId", resourceServerId); query.setParameter("policyId", policyId); 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 8a647d8a85..599ad709f9 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 @@ -19,13 +19,13 @@ package org.keycloak.authorization.jpa.store; import org.keycloak.authorization.AuthorizationProvider; import org.keycloak.authorization.jpa.entities.ResourceEntity; -import org.keycloak.authorization.jpa.entities.ResourceServerEntity; import org.keycloak.authorization.model.Resource; import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.store.ResourceStore; import org.keycloak.models.utils.KeycloakModelUtils; import javax.persistence.EntityManager; +import javax.persistence.FlushModeType; import javax.persistence.NoResultException; import javax.persistence.Query; import javax.persistence.TypedQuery; @@ -34,7 +34,6 @@ import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import java.util.ArrayList; -import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -62,6 +61,7 @@ public class JPAResourceStore implements ResourceStore { entity.setOwner(owner); this.entityManager.persist(entity); + this.entityManager.flush(); return new ResourceAdapter(entity, entityManager, provider.getStoreFactory()); } @@ -90,6 +90,7 @@ public class JPAResourceStore implements ResourceStore { public List findByOwner(String ownerId, String resourceServerId) { TypedQuery query = entityManager.createNamedQuery("findResourceIdByOwner", String.class); + query.setFlushMode(FlushModeType.COMMIT); query.setParameter("owner", ownerId); query.setParameter("serverId", resourceServerId); @@ -105,6 +106,7 @@ public class JPAResourceStore implements ResourceStore { public List findByUri(String uri, String resourceServerId) { TypedQuery query = entityManager.createNamedQuery("findResourceIdByUri", String.class); + query.setFlushMode(FlushModeType.COMMIT); query.setParameter("uri", uri); query.setParameter("serverId", resourceServerId); @@ -173,6 +175,7 @@ public class JPAResourceStore implements ResourceStore { public List findByScope(List scopes, String resourceServerId) { TypedQuery query = entityManager.createNamedQuery("findResourceIdByScope", String.class); + query.setFlushMode(FlushModeType.COMMIT); query.setParameter("scopeIds", scopes); query.setParameter("serverId", resourceServerId); @@ -188,8 +191,10 @@ public class JPAResourceStore implements ResourceStore { public Resource findByName(String name, String resourceServerId) { TypedQuery query = entityManager.createNamedQuery("findResourceIdByName", String.class); + query.setFlushMode(FlushModeType.COMMIT); query.setParameter("serverId", resourceServerId); query.setParameter("name", name); + try { String id = query.getSingleResult(); return provider.getStoreFactory().getResourceStore().findById(id, resourceServerId); @@ -202,6 +207,7 @@ public class JPAResourceStore implements ResourceStore { public List findByType(String type, String resourceServerId) { TypedQuery query = entityManager.createNamedQuery("findResourceIdByType", String.class); + query.setFlushMode(FlushModeType.COMMIT); query.setParameter("type", type); query.setParameter("serverId", resourceServerId); 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 f8a9350442..befde658ac 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 @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; import javax.persistence.EntityManager; +import javax.persistence.FlushModeType; import javax.persistence.NoResultException; import javax.persistence.Query; import javax.persistence.TypedQuery; @@ -32,7 +33,6 @@ import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import org.keycloak.authorization.AuthorizationProvider; -import org.keycloak.authorization.jpa.entities.ResourceServerEntity; import org.keycloak.authorization.jpa.entities.ScopeEntity; import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.model.Scope; @@ -61,6 +61,7 @@ public class JPAScopeStore implements ScopeStore { entity.setResourceServer(ResourceServerAdapter.toEntity(entityManager, resourceServer)); this.entityManager.persist(entity); + this.entityManager.flush(); return new ScopeAdapter(entity, entityManager, provider.getStoreFactory()); } @@ -91,8 +92,10 @@ public class JPAScopeStore implements ScopeStore { try { TypedQuery query = entityManager.createNamedQuery("findScopeIdByName", String.class); + query.setFlushMode(FlushModeType.COMMIT); query.setParameter("serverId", resourceServerId); query.setParameter("name", name); + String id = query.getSingleResult(); return provider.getStoreFactory().getScopeStore().findById(id, resourceServerId); } catch (NoResultException nre) { @@ -104,6 +107,7 @@ public class JPAScopeStore implements ScopeStore { public List findByResourceServer(final String serverId) { TypedQuery query = entityManager.createNamedQuery("findScopeIdByResourceServer", String.class); + query.setFlushMode(FlushModeType.COMMIT); query.setParameter("serverId", serverId); List result = query.getResultList(); 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 a18c27a087..c3a776b8ce 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 @@ -1929,24 +1929,21 @@ public class RepresentationToModel { resourceServer.setPolicyEnforcementMode(rep.getPolicyEnforcementMode()); resourceServer.setAllowRemoteResourceManagement(rep.isAllowRemoteResourceManagement()); - rep.getScopes().forEach(scope -> { + for (ScopeRepresentation scope : rep.getScopes()) { toModel(scope, resourceServer, authorization); - }); + } KeycloakSession session = authorization.getKeycloakSession(); RealmModel realm = authorization.getRealm(); - rep.getResources().forEach(resourceRepresentation -> { - ResourceOwnerRepresentation owner = resourceRepresentation.getOwner(); + for (ResourceRepresentation resource : rep.getResources()) { + ResourceOwnerRepresentation owner = resource.getOwner(); if (owner == null) { owner = new ResourceOwnerRepresentation(); - resourceRepresentation.setOwner(owner); - } - - owner.setId(resourceServer.getClientId()); - - if (owner.getName() != null) { + owner.setId(resourceServer.getClientId()); + resource.setOwner(owner); + } else if (owner.getName() != null) { UserModel user = session.users().getUserByUsername(owner.getName(), realm); if (user != null) { @@ -1954,8 +1951,8 @@ public class RepresentationToModel { } } - toModel(resourceRepresentation, resourceServer, authorization); - }); + toModel(resource, resourceServer, authorization); + } importPolicies(authorization, resourceServer, rep.getPolicies(), null); } @@ -1974,7 +1971,9 @@ public class RepresentationToModel { PolicyStore policyStore = storeFactory.getPolicyStore(); try { List policies = (List) JsonSerialization.readValue(applyPolicies, List.class); - config.put("applyPolicies", JsonSerialization.writeValueAsString(policies.stream().map(policyName -> { + Set policyIds = new HashSet<>(); + + for (String policyName : policies) { Policy policy = policyStore.findByName(policyName, resourceServer.getId()); if (policy == null) { @@ -1988,8 +1987,10 @@ public class RepresentationToModel { } } - return policy.getId(); - }).collect(Collectors.toList()))); + policyIds.add(policy.getId()); + } + + config.put("applyPolicies", JsonSerialization.writeValueAsString(policyIds)); } catch (Exception e) { throw new RuntimeException("Error while importing policy [" + policyRepresentation.getName() + "].", e); } @@ -2028,33 +2029,40 @@ public class RepresentationToModel { if (representation instanceof PolicyRepresentation) { PolicyRepresentation policy = PolicyRepresentation.class.cast(representation); - String resourcesConfig = policy.getConfig().get("resources"); - if (resourcesConfig != null) { - try { - resources = JsonSerialization.readValue(resourcesConfig, Set.class); - } catch (IOException e) { - throw new RuntimeException(e); + if (resources == null) { + String resourcesConfig = policy.getConfig().get("resources"); + + if (resourcesConfig != null) { + try { + resources = JsonSerialization.readValue(resourcesConfig, Set.class); + } catch (IOException e) { + throw new RuntimeException(e); + } } } - String scopesConfig = policy.getConfig().get("scopes"); + if (scopes == null) { + String scopesConfig = policy.getConfig().get("scopes"); - if (scopesConfig != null) { - try { - scopes = JsonSerialization.readValue(scopesConfig, Set.class); - } catch (IOException e) { - throw new RuntimeException(e); + if (scopesConfig != null) { + try { + scopes = JsonSerialization.readValue(scopesConfig, Set.class); + } catch (IOException e) { + throw new RuntimeException(e); + } } } - String policiesConfig = policy.getConfig().get("applyPolicies"); + if (policies == null) { + String policiesConfig = policy.getConfig().get("applyPolicies"); - if (policiesConfig != null) { - try { - policies = JsonSerialization.readValue(policiesConfig, Set.class); - } catch (IOException e) { - throw new RuntimeException(e); + if (policiesConfig != null) { + try { + policies = JsonSerialization.readValue(policiesConfig, Set.class); + } catch (IOException e) { + throw new RuntimeException(e); + } } }