From b76f4f9c1b289653b80106bbc3973ccf40543b69 Mon Sep 17 00:00:00 2001 From: Pedro Igor Date: Fri, 11 Oct 2024 14:35:21 -0300 Subject: [PATCH] Avoid iterating over user policies when removing users Closes #19358 Signed-off-by: Pedro Igor --- .../user/UserPolicyProviderFactory.java | 57 ++++++++----------- .../syncronization/UserSynchronizer.java | 26 +-------- .../authz/admin/UserPolicyManagementTest.java | 7 +++ 3 files changed, 31 insertions(+), 59 deletions(-) diff --git a/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/user/UserPolicyProviderFactory.java b/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/user/UserPolicyProviderFactory.java index a973396608..3ddccce0f1 100644 --- a/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/user/UserPolicyProviderFactory.java +++ b/authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/user/UserPolicyProviderFactory.java @@ -78,7 +78,9 @@ public class UserPolicyProviderFactory implements PolicyProviderFactory) JsonSerialization.readValue(users, Set.class).stream() + .filter(id -> getUser((String) id, authorization) != null) + .collect(Collectors.toSet())); } } catch (IOException cause) { throw new RuntimeException("Failed to deserialize roles", cause); @@ -94,12 +96,12 @@ public class UserPolicyProviderFactory implements PolicyProviderFactory users) { - KeycloakSession session = authorization.getKeycloakSession(); - RealmModel realm = authorization.getRealm(); - UserProvider userProvider = session.users(); Set updatedUsers = new HashSet<>(); if (users != null) { for (String userId : users) { - UserModel user = null; - - try { - user = userProvider.getUserByUsername(realm, userId); - } catch (Exception ignore) { - } - - if (user == null) { - user = userProvider.getUserById(realm, userId); - } + UserModel user = getUser(userId, authorization); if (user == null) { throw new RuntimeException("Error while updating policy [" + policy.getName() + "]. User [" + userId + "] could not be found."); @@ -172,6 +158,23 @@ public class UserPolicyProviderFactory implements PolicyProviderFactory { removeFromUserPermissionTickets(event, authorizationProvider); removeUserResources(event, authorizationProvider); - removeFromUserPolicies(event, authorizationProvider); - } - - private void removeFromUserPolicies(UserRemovedEvent event, AuthorizationProvider authorizationProvider) { - StoreFactory storeFactory = authorizationProvider.getStoreFactory(); - PolicyStore policyStore = storeFactory.getPolicyStore(); - UserModel userModel = event.getUser(); - 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.find(null, attributes, null, null); - - for (Policy policy : search) { - PolicyProviderFactory policyFactory = authorizationProvider.getProviderFactory(policy.getType()); - UserPolicyRepresentation representation = UserPolicyRepresentation.class.cast(policyFactory.toRepresentation(policy, authorizationProvider)); - Set users = representation.getUsers(); - - users.remove(userModel.getId()); - - policyFactory.onUpdate(policy, representation, authorizationProvider); - } } private void removeUserResources(UserRemovedEvent event, AuthorizationProvider authorizationProvider) { @@ -106,7 +82,7 @@ public class UserSynchronizer implements Synchronizer { } attributes.clear(); - + attributes.put(PermissionTicket.FilterOption.REQUESTER, userModel.getId()); for (PermissionTicket ticket : ticketStore.find(null, attributes, null, null)) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/UserPolicyManagementTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/UserPolicyManagementTest.java index b2a5ce03b4..e62cfef5a5 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/UserPolicyManagementTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/admin/UserPolicyManagementTest.java @@ -107,6 +107,13 @@ public class UserPolicyManagementTest extends AbstractPolicyManagementTest { permission.update(representation); assertRepresentation(representation, permission); + + String userName = representation.getUsers().iterator().next(); + UserRepresentation user = getRealm().users().search(userName).get(0); + getRealm().users().delete(user.getId()).close(); + + representation.getUsers().clear(); + assertRepresentation(representation, permission); } @Test