diff --git a/src/main/java/sh/libre/scim/core/UserAdapter.java b/src/main/java/sh/libre/scim/core/UserAdapter.java index 4d7b21d634..bc233cb3b7 100644 --- a/src/main/java/sh/libre/scim/core/UserAdapter.java +++ b/src/main/java/sh/libre/scim/core/UserAdapter.java @@ -3,10 +3,13 @@ package sh.libre.scim.core; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; import java.util.stream.Stream; import com.unboundid.scim2.common.types.Email; import com.unboundid.scim2.common.types.Meta; +import com.unboundid.scim2.common.types.Role; import com.unboundid.scim2.common.types.UserResource; import org.jboss.logging.Logger; @@ -21,6 +24,7 @@ public class UserAdapter extends Adapter { private String displayName; private String email; private Boolean active; + private String[] roles; public UserAdapter(KeycloakSession session, String componentId) { super(session, componentId, "User", Logger.getLogger(UserAdapter.class)); @@ -66,6 +70,14 @@ public class UserAdapter extends Adapter { } } + public String[] getRoles() { + return roles; + } + + public void setRoles(String[] roles) { + this.roles = roles; + } + @Override public Class getResourceClass() { return UserResource.class; @@ -84,6 +96,15 @@ public class UserAdapter extends Adapter { } setEmail(user.getEmail()); setActive(user.isEnabled()); + var rolesSet = new HashSet(); + user.getGroupsStream().flatMap(g -> g.getRoleMappingsStream()) + .filter((r) -> r.getFirstAttribute("scim").equals("true")).map((r) -> r.getName()) + .forEach(r -> rolesSet.add(r)); + user.getRoleMappingsStream().filter((r) -> r.getFirstAttribute("scim").equals("true")) + .map((r) -> r.getName()).forEach(r -> rolesSet.add(r)); + var roles = new String[rolesSet.size()]; + rolesSet.toArray(roles); + setRoles(roles); } @Override @@ -120,6 +141,13 @@ public class UserAdapter extends Adapter { } user.setMeta(meta); } + List roles = new ArrayList(); + for (var r : this.roles) { + var role = new Role(); + role.setValue(r); + roles.add(role); + } + user.setRoles(roles); return user; } diff --git a/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java b/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java index 13ccbada4f..2a48ec6982 100644 --- a/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java +++ b/src/main/java/sh/libre/scim/event/ScimEventListenerProvider.java @@ -1,7 +1,6 @@ package sh.libre.scim.event; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.regex.*; import org.jboss.logging.Logger; import org.keycloak.events.Event; @@ -13,7 +12,6 @@ import org.keycloak.events.admin.ResourceType; import org.keycloak.models.GroupModel; import org.keycloak.models.KeycloakSession; import org.keycloak.models.UserModel; -import org.keycloak.representations.idm.GroupRepresentation; import sh.libre.scim.core.GroupAdapter; import sh.libre.scim.core.ScimDispatcher; @@ -81,12 +79,16 @@ public class ScimEventListenerProvider implements EventListenerProvider { } } if (event.getResourceType() == ResourceType.GROUP_MEMBERSHIP) { - ObjectMapper obj = new ObjectMapper(); - try { - var groupRepresentation = obj.readValue(event.getRepresentation(), GroupRepresentation.class); - var group = getGroup(groupRepresentation.getId()); + Pattern pattern = Pattern.compile("users/(.+)/groups/(.+)"); + Matcher matcher = pattern.matcher(event.getResourcePath()); + if (matcher.find()) { + var userId = matcher.group(1); + var groupId = matcher.group(2); + LOGGER.infof("%s %s from %s", event.getOperationType(), userId, groupId); + var group = getGroup(groupId); dispatcher.run((client) -> client.replace(GroupAdapter.class, group)); - } catch (JsonProcessingException e) { + var user = getUser(userId); + dispatcher.run((client) -> client.replace(UserAdapter.class, user)); } } }