From 2e992dad4459444622f1fbf02e33469f0c5f6405 Mon Sep 17 00:00:00 2001 From: Alex Morel Date: Thu, 20 Jun 2024 17:36:46 +0200 Subject: [PATCH] Refactor Scim Event listener --- .../libre/scim/core/AbstractScimService.java | 8 ---- .../java/sh/libre/scim/core/KeycloakDao.java | 7 +++ .../scim/event/ScimEventListenerProvider.java | 46 +++++++++++-------- 3 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/main/java/sh/libre/scim/core/AbstractScimService.java b/src/main/java/sh/libre/scim/core/AbstractScimService.java index 11d6276084..e32f178977 100644 --- a/src/main/java/sh/libre/scim/core/AbstractScimService.java +++ b/src/main/java/sh/libre/scim/core/AbstractScimService.java @@ -89,14 +89,6 @@ public abstract class AbstractScimService getGroupsStream() { return getKeycloakSession().groups().getGroupsStream(getRealm()); } @@ -71,4 +76,6 @@ public class KeycloakDao { public UserModel addUser(String username) { return getKeycloakSession().users().addUser(getRealm(), username); } + + } diff --git a/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java b/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java index 6463853843..0a57d5afca 100644 --- a/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java +++ b/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java @@ -11,7 +11,10 @@ import org.keycloak.events.admin.ResourceType; import org.keycloak.models.GroupModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.UserModel; +import sh.libre.scim.core.KeycloakDao; +import sh.libre.scim.core.KeycloakId; import sh.libre.scim.core.ScimDispatcher; +import sh.libre.scim.core.ScimResourceType; import java.util.Map; import java.util.regex.Matcher; @@ -30,6 +33,8 @@ public class ScimEventListenerProvider implements EventListenerProvider { private final KeycloakSession session; + private final KeycloakDao keycloackDao; + private final Map patterns = Map.of( ResourceType.USER, Pattern.compile("users/(.+)"), ResourceType.GROUP, Pattern.compile("groups/([\\w-]+)(/children)?"), @@ -40,15 +45,15 @@ public class ScimEventListenerProvider implements EventListenerProvider { public ScimEventListenerProvider(KeycloakSession session) { this.session = session; + this.keycloackDao = new KeycloakDao(session); this.dispatcher = ScimDispatcher.createForSession(session); } - @Override public void onEvent(Event event) { // React to User-related event : creation, deletion, update EventType eventType = event.getType(); - String eventUserId = event.getUserId(); + KeycloakId eventUserId = new KeycloakId(event.getUserId()); switch (eventType) { case REGISTER -> { LOGGER.infof("[SCIM] Propagate User Registration - %s", eventUserId); @@ -85,21 +90,26 @@ public class ScimEventListenerProvider implements EventListenerProvider { // Step 2: propagate event (if needed) according to its resource type switch (event.getResourceType()) { case USER -> { - String userId = matcher.group(1); + KeycloakId userId = new KeycloakId(matcher.group(1)); handleUserEvent(event, userId); } case GROUP -> { - String groupId = matcher.group(1); + KeycloakId groupId = new KeycloakId(matcher.group(1)); handleGroupEvent(event, groupId); } case GROUP_MEMBERSHIP -> { - String userId = matcher.group(1); - String groupId = matcher.group(2); + KeycloakId userId = new KeycloakId(matcher.group(1)); + KeycloakId groupId = new KeycloakId(matcher.group(2)); handleGroupMemberShipEvent(event, userId, groupId); } case REALM_ROLE_MAPPING -> { - String type = matcher.group(1); - String id = matcher.group(2); + String rawResourceType = matcher.group(1); + ScimResourceType type = switch (rawResourceType) { + case "users" -> ScimResourceType.USER; + case "groups" -> ScimResourceType.GROUP; + default -> throw new IllegalArgumentException("Unsuported resource type : " + rawResourceType); + }; + KeycloakId id = new KeycloakId(matcher.group(2)); handleRoleMappingEvent(event, type, id); } case COMPONENT -> { @@ -114,7 +124,7 @@ public class ScimEventListenerProvider implements EventListenerProvider { } - private void handleUserEvent(AdminEvent userEvent, String userId) { + private void handleUserEvent(AdminEvent userEvent, KeycloakId userId) { LOGGER.infof("[SCIM] Propagate User %s - %s", userEvent.getOperationType(), userId); switch (userEvent.getOperationType()) { case CREATE -> { @@ -141,7 +151,7 @@ public class ScimEventListenerProvider implements EventListenerProvider { * @param event the event to propagate * @param groupId event target's id */ - private void handleGroupEvent(AdminEvent event, String groupId) { + private void handleGroupEvent(AdminEvent event, KeycloakId groupId) { LOGGER.infof("[SCIM] Propagate Group %s - %s", event.getOperationType(), groupId); switch (event.getOperationType()) { case CREATE -> { @@ -159,7 +169,7 @@ public class ScimEventListenerProvider implements EventListenerProvider { } } - private void handleGroupMemberShipEvent(AdminEvent groupMemberShipEvent, String userId, String groupId) { + private void handleGroupMemberShipEvent(AdminEvent groupMemberShipEvent, KeycloakId userId, KeycloakId groupId) { LOGGER.infof("[SCIM] Propagate GroupMemberShip %s - User %s Group %s", groupMemberShipEvent.getOperationType(), userId, groupId); GroupModel group = getGroup(groupId); group.setSingleAttribute("scim-dirty", BooleanUtils.TRUE); @@ -167,14 +177,14 @@ public class ScimEventListenerProvider implements EventListenerProvider { dispatcher.dispatchUserModificationToAll(client -> client.replace(user)); } - private void handleRoleMappingEvent(AdminEvent roleMappingEvent, String type, String id) { + private void handleRoleMappingEvent(AdminEvent roleMappingEvent, ScimResourceType type, KeycloakId id) { LOGGER.infof("[SCIM] Propagate RoleMapping %s - %s %s", roleMappingEvent.getOperationType(), type, id); switch (type) { - case "users" -> { + case USER -> { UserModel user = getUser(id); dispatcher.dispatchUserModificationToAll(client -> client.replace(user)); } - case "groups" -> { + case GROUP -> { GroupModel group = getGroup(id); session.users() .getGroupMembersStream(session.getContext().getRealm(), group) @@ -208,12 +218,12 @@ public class ScimEventListenerProvider implements EventListenerProvider { } - private UserModel getUser(String id) { - return session.users().getUserById(session.getContext().getRealm(), id); + private UserModel getUser(KeycloakId id) { + return keycloackDao.getUserById(id); } - private GroupModel getGroup(String id) { - return session.groups().getGroupById(session.getContext().getRealm(), id); + private GroupModel getGroup(KeycloakId id) { + return keycloackDao.getGroupById(id); } @Override