Fix matchRole lookup to include group-inherited and composite roles
All checks were successful
/ Verify (push) Successful in 1m8s
/ Verify (pull_request) Successful in 46s

getRoleMembersStream only returns users with the role assigned
directly, so exported attributes silently excluded users who have
matchRole via group membership. Filter all realm users with
hasRole() instead, matching the resolution already used for authRole.
This commit is contained in:
Stefan Bethke 2026-07-12 13:07:16 +02:00
commit 2c3c0a3dab

View file

@ -2,6 +2,7 @@ package de.ccc.hamburg.keycloak.attribute_endpoints;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
@ -118,7 +119,11 @@ public class AttributeEndpointsResourceProvider implements RealmResourceProvider
.toList();
UserProvider userProvider = session.users();
Stream<UserModel> users = userProvider.getRoleMembersStream(realm, matchRole);
// getRoleMembersStream only returns users with matchRole assigned directly; it misses
// users who have the role via group membership (incl. parent groups) or composite roles.
// hasRole() resolves the role the same way authUser.hasRole(authRole) does above.
Stream<UserModel> users = userProvider.searchForUserStream(realm, Map.of())
.filter(user -> user.hasRole(matchRole));
List<String> attribute_list = users
.map(user -> {