diff --git a/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/role/RolePolicyProviderFactory.java b/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/role/RolePolicyProviderFactory.java index c8fc82d7f3..b3f50748ae 100644 --- a/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/role/RolePolicyProviderFactory.java +++ b/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/role/RolePolicyProviderFactory.java @@ -20,31 +20,24 @@ package org.keycloak.authorization.policy.provider.role; import org.keycloak.Config; import org.keycloak.authorization.AuthorizationProvider; import org.keycloak.authorization.model.Policy; -import org.keycloak.authorization.model.ResourceServer; import org.keycloak.authorization.policy.provider.PolicyProvider; import org.keycloak.authorization.policy.provider.PolicyProviderFactory; -import org.keycloak.authorization.store.PolicyStore; -import org.keycloak.authorization.store.ResourceServerStore; -import org.keycloak.authorization.store.StoreFactory; import org.keycloak.models.ClientModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.RealmModel; -import org.keycloak.models.RoleContainerModel; -import org.keycloak.models.RoleContainerModel.RoleRemovedEvent; import org.keycloak.models.RoleModel; import org.keycloak.representations.idm.authorization.PolicyRepresentation; import org.keycloak.representations.idm.authorization.RolePolicyRepresentation; +import org.keycloak.representations.idm.authorization.RolePolicyRepresentation.RoleDefinition; import org.keycloak.util.JsonSerialization; import org.keycloak.utils.StringUtil; import java.io.IOException; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; @@ -78,25 +71,14 @@ public class RolePolicyProviderFactory implements PolicyProviderFactory roleDefinitions = Arrays.asList(JsonSerialization.readValue(roles, RolePolicyRepresentation.RoleDefinition[].class)); - roleDefinitions.removeIf(definition -> getRole(definition, authorization.getRealm()) == null); - representation.setRoles(new HashSet<>(roleDefinitions)); - } + String fetchRoles = policy.getConfig().get("fetchRoles"); - String fetchRoles = policy.getConfig().get("fetchRoles"); - - if (StringUtil.isNotBlank(fetchRoles)) { - representation.setFetchRoles(Boolean.parseBoolean(fetchRoles)); - } - } catch (IOException cause) { - throw new RuntimeException("Failed to deserialize roles", cause); + if (StringUtil.isNotBlank(fetchRoles)) { + representation.setFetchRoles(Boolean.parseBoolean(fetchRoles)); } return representation; @@ -119,11 +101,7 @@ public class RolePolicyProviderFactory implements PolicyProviderFactory(Arrays.asList(JsonSerialization.readValue(representation.getConfig().get("roles"), RolePolicyRepresentation.RoleDefinition[].class)))); - } catch (IOException cause) { - throw new RuntimeException("Failed to deserialize roles during import", cause); - } + updateRoles(policy, authorization, getRoles(representation.getConfig().get("roles"), authorization.getRealm())); String fetchRoles = representation.getConfig().get("fetchRoles"); if (StringUtil.isNotBlank(fetchRoles)) { @@ -210,18 +188,18 @@ public class RolePolicyProviderFactory implements PolicyProviderFactory[] getRoles(Policy policy) { - String roles = policy.getConfig().get("roles"); - - if (roles != null) { + private Set getRoles(String rawRoles, RealmModel realm) { + if (rawRoles != null) { try { - return JsonSerialization.readValue(roles.getBytes(), Map[].class); + Set roles = new HashSet<>(Arrays.asList(JsonSerialization.readValue(rawRoles, RoleDefinition[].class))); + roles.removeIf(definition -> getRole(definition, realm) == null); + return roles; } catch (IOException e) { - throw new RuntimeException("Could not parse roles [" + roles + "] from policy config [" + policy.getName() + ".", e); + throw new RuntimeException("Could not parse roles from config: [" + rawRoles + "]", e); } } - return new Map[] {}; + return Collections.emptySet(); } private RoleModel getRole(RolePolicyRepresentation.RoleDefinition definition, RealmModel realm) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/RolePolicyManagementTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/RolePolicyManagementTest.java index bb6a25f6fe..443ac6497f 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/RolePolicyManagementTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/RolePolicyManagementTest.java @@ -42,6 +42,7 @@ import org.keycloak.representations.idm.authorization.Logic; import org.keycloak.representations.idm.authorization.PolicyRepresentation; import org.keycloak.representations.idm.authorization.RolePolicyRepresentation; import org.keycloak.testsuite.util.RealmBuilder; +import org.keycloak.testsuite.util.RoleBuilder; import org.keycloak.testsuite.util.RolesBuilder; /** @@ -179,6 +180,30 @@ public class RolePolicyManagementTest extends AbstractPolicyManagementTest { } } + @Test + public void testDeleteRole() { + RoleRepresentation role = RoleBuilder.create().name(KeycloakModelUtils.generateId()).build(); + getRealm().roles().create(role); + AuthorizationResource authorization = getClient().authorization(); + RolePolicyRepresentation representation = new RolePolicyRepresentation(); + + representation.setName(KeycloakModelUtils.generateId()); + representation.addRole(role.getName(), false); + + RolePoliciesResource policies = authorization.policies().role(); + + try (Response response = policies.create(representation)) { + RolePolicyRepresentation created = response.readEntity(RolePolicyRepresentation.class); + RolePolicyResource rolePolicy = policies.findById(created.getId()); + RolePolicyRepresentation rolePolicyRep = rolePolicy.toRepresentation(); + assertEquals(1, rolePolicyRep.getRoles().size()); + + getRealm().roles().deleteRole(role.getName()); + rolePolicyRep = rolePolicy.toRepresentation(); + assertTrue(rolePolicyRep.getRoles().isEmpty()); + } + } + @Test public void testGenericConfig() { AuthorizationResource authorization = getClient().authorization();