[KEYCLOAK-17452] - Removing policies created from a user-managed policy
This commit is contained in:
parent
228de42859
commit
068a1811f2
2 changed files with 86 additions and 0 deletions
|
@ -358,6 +358,17 @@ public final class AuthorizationProvider implements Provider {
|
||||||
if (policy != null) {
|
if (policy != null) {
|
||||||
ResourceServer resourceServer = policy.getResourceServer();
|
ResourceServer resourceServer = policy.getResourceServer();
|
||||||
|
|
||||||
|
// if uma policy (owned by a user) also remove associated policies
|
||||||
|
if (policy.getOwner() != null) {
|
||||||
|
for (Policy associatedPolicy : policy.getAssociatedPolicies()) {
|
||||||
|
// only remove associated policies created from the policy being deleted
|
||||||
|
if (associatedPolicy.getOwner() != null) {
|
||||||
|
policy.removeAssociatedPolicy(associatedPolicy);
|
||||||
|
policyStore.delete(associatedPolicy.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
findDependentPolicies(policy.getId(), resourceServer.getId()).forEach(dependentPolicy -> {
|
findDependentPolicies(policy.getId(), resourceServer.getId()).forEach(dependentPolicy -> {
|
||||||
dependentPolicy.removeAssociatedPolicy(policy);
|
dependentPolicy.removeAssociatedPolicy(policy);
|
||||||
if (dependentPolicy.getAssociatedPolicies().isEmpty()) {
|
if (dependentPolicy.getAssociatedPolicies().isEmpty()) {
|
||||||
|
|
|
@ -17,24 +17,35 @@
|
||||||
package org.keycloak.testsuite.authz;
|
package org.keycloak.testsuite.authz;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
import static org.keycloak.authorization.model.Policy.FilterOption.OWNER;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.ws.rs.NotFoundException;
|
import javax.ws.rs.NotFoundException;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.keycloak.authorization.AuthorizationProvider;
|
||||||
import org.keycloak.authorization.client.AuthorizationDeniedException;
|
import org.keycloak.authorization.client.AuthorizationDeniedException;
|
||||||
import org.keycloak.authorization.client.resource.AuthorizationResource;
|
import org.keycloak.authorization.client.resource.AuthorizationResource;
|
||||||
import org.keycloak.authorization.client.resource.PolicyResource;
|
import org.keycloak.authorization.client.resource.PolicyResource;
|
||||||
import org.keycloak.authorization.client.resource.ProtectionResource;
|
import org.keycloak.authorization.client.resource.ProtectionResource;
|
||||||
import org.keycloak.authorization.client.util.HttpResponseException;
|
import org.keycloak.authorization.client.util.HttpResponseException;
|
||||||
|
import org.keycloak.authorization.model.Policy;
|
||||||
|
import org.keycloak.authorization.model.Resource;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.Profile;
|
||||||
|
import org.keycloak.models.ClientModel;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.UserModel;
|
||||||
import org.keycloak.representations.AccessToken;
|
import org.keycloak.representations.AccessToken;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.representations.idm.authorization.AuthorizationRequest;
|
import org.keycloak.representations.idm.authorization.AuthorizationRequest;
|
||||||
|
@ -49,6 +60,7 @@ import org.keycloak.representations.idm.authorization.UmaPermissionRepresentatio
|
||||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
|
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
import org.keycloak.testsuite.arquillian.annotation.AuthServerContainerExclude.AuthServer;
|
||||||
import org.keycloak.testsuite.arquillian.annotation.DisableFeature;
|
import org.keycloak.testsuite.arquillian.annotation.DisableFeature;
|
||||||
|
import org.keycloak.testsuite.runonserver.RunOnServer;
|
||||||
import org.keycloak.testsuite.util.ClientBuilder;
|
import org.keycloak.testsuite.util.ClientBuilder;
|
||||||
import org.keycloak.testsuite.util.GroupBuilder;
|
import org.keycloak.testsuite.util.GroupBuilder;
|
||||||
import org.keycloak.testsuite.util.RealmBuilder;
|
import org.keycloak.testsuite.util.RealmBuilder;
|
||||||
|
@ -862,6 +874,69 @@ public class UserManagedPermissionServiceTest extends AbstractResourceServerTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRemovePoliciesOnResourceDelete() {
|
||||||
|
ResourceRepresentation resource = new ResourceRepresentation();
|
||||||
|
|
||||||
|
resource.setName("Resource A");
|
||||||
|
resource.setOwnerManagedAccess(true);
|
||||||
|
resource.setOwner("marta");
|
||||||
|
resource.addScope("Scope A", "Scope B", "Scope C");
|
||||||
|
|
||||||
|
resource = getAuthzClient().protection().resource().create(resource);
|
||||||
|
|
||||||
|
UmaPermissionRepresentation newPermission = new UmaPermissionRepresentation();
|
||||||
|
|
||||||
|
newPermission.setName("Custom User-Managed Permission");
|
||||||
|
newPermission.setDescription("Users from specific roles are allowed to access");
|
||||||
|
newPermission.addScope("Scope A", "Scope B", "Scope C");
|
||||||
|
newPermission.addRole("role_a", "role_b", "role_c", "role_d");
|
||||||
|
newPermission.addGroup("/group_a", "/group_a/group_b", "/group_c");
|
||||||
|
newPermission.addClient("client-a", "resource-server-test");
|
||||||
|
|
||||||
|
if (Profile.isFeatureEnabled(Profile.Feature.UPLOAD_SCRIPTS)) {
|
||||||
|
newPermission.setCondition("$evaluation.grant()");
|
||||||
|
}
|
||||||
|
|
||||||
|
newPermission.addUser("kolo");
|
||||||
|
|
||||||
|
ProtectionResource protection = getAuthzClient().protection("marta", "password");
|
||||||
|
|
||||||
|
protection.policy(resource.getId()).create(newPermission);
|
||||||
|
|
||||||
|
getTestingClient().server().run((RunOnServer) UserManagedPermissionServiceTest::testRemovePoliciesOnResourceDelete);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void testRemovePoliciesOnResourceDelete(KeycloakSession session) {
|
||||||
|
RealmModel realm = session.realms().getRealmByName("authz-test");
|
||||||
|
ClientModel client = realm.getClientByClientId("resource-server-test");
|
||||||
|
AuthorizationProvider provider = session.getProvider(AuthorizationProvider.class);
|
||||||
|
UserModel user = session.users().getUserByUsername(realm, "marta");
|
||||||
|
Map<Policy.FilterOption, String[]> filters = new HashMap<>();
|
||||||
|
|
||||||
|
filters.put(Policy.FilterOption.TYPE, new String[] {"uma"});
|
||||||
|
filters.put(OWNER, new String[] {user.getId()});
|
||||||
|
|
||||||
|
List<Policy> policies = provider.getStoreFactory().getPolicyStore()
|
||||||
|
.findByResourceServer(filters, client.getId(), -1, -1);
|
||||||
|
assertEquals(1, policies.size());
|
||||||
|
|
||||||
|
Policy policy = policies.get(0);
|
||||||
|
assertFalse(policy.getResources().isEmpty());
|
||||||
|
|
||||||
|
Resource resource = policy.getResources().iterator().next();
|
||||||
|
assertEquals("Resource A", resource.getName());
|
||||||
|
|
||||||
|
provider.getStoreFactory().getResourceStore().delete(resource.getId());
|
||||||
|
|
||||||
|
filters = new HashMap<>();
|
||||||
|
|
||||||
|
filters.put(OWNER, new String[] {user.getId()});
|
||||||
|
policies = provider.getStoreFactory().getPolicyStore()
|
||||||
|
.findByResourceServer(filters, client.getId(), -1, -1);
|
||||||
|
assertTrue(policies.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
private List<PolicyRepresentation> getAssociatedPolicies(UmaPermissionRepresentation permission) {
|
private List<PolicyRepresentation> getAssociatedPolicies(UmaPermissionRepresentation permission) {
|
||||||
return getClient(getRealm()).authorization().policies().policy(permission.getId()).associatedPolicies();
|
return getClient(getRealm()).authorization().policies().policy(permission.getId()).associatedPolicies();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue