diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/membership/UserRolesRetrieveStrategy.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/membership/UserRolesRetrieveStrategy.java index 06f53e15a7d..ec86bd8ef93 100644 --- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/membership/UserRolesRetrieveStrategy.java +++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/membership/UserRolesRetrieveStrategy.java @@ -19,6 +19,8 @@ package org.keycloak.storage.ldap.mappers.membership; import org.keycloak.models.LDAPConstants; +import org.keycloak.models.RealmModel; +import org.keycloak.models.UserModel; import org.keycloak.storage.ldap.LDAPConfig; import org.keycloak.storage.ldap.LDAPUtils; import org.keycloak.storage.ldap.idm.model.LDAPDn; @@ -26,10 +28,12 @@ import org.keycloak.storage.ldap.idm.model.LDAPObject; import org.keycloak.storage.ldap.idm.query.Condition; import org.keycloak.storage.ldap.idm.query.internal.LDAPQuery; import org.keycloak.storage.ldap.idm.query.internal.LDAPQueryConditionsBuilder; +import org.keycloak.utils.StreamsUtil; import java.util.Collections; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -42,6 +46,8 @@ public interface UserRolesRetrieveStrategy { List getLDAPRoleMappings(CommonLDAPGroupMapper roleOrGroupMapper, LDAPObject ldapUser, LDAPConfig ldapConfig); + List getLDAPRoleMembers(RealmModel realm, CommonLDAPGroupMapper roleOrGroupMapper, LDAPObject ldapRoleOrGroup, int firstResult, int maxResults); + void beforeUserLDAPQuery(CommonLDAPGroupMapper roleOrGroupMapper, LDAPQuery query); @@ -67,6 +73,12 @@ public interface UserRolesRetrieveStrategy { } } + @Override + public List getLDAPRoleMembers(RealmModel realm, CommonLDAPGroupMapper roleOrGroupMapper, LDAPObject ldapRoleOrGroup, int firstResult, int maxResults) { + MembershipType membershipType = roleOrGroupMapper.getConfig().getMembershipTypeLdapAttribute(); + return membershipType.getGroupMembers(realm, roleOrGroupMapper, ldapRoleOrGroup, firstResult, maxResults); + } + @Override public void beforeUserLDAPQuery(CommonLDAPGroupMapper roleOrGroupMapper, LDAPQuery query) { } @@ -113,6 +125,15 @@ public interface UserRolesRetrieveStrategy { return roles; } + @Override + public List getLDAPRoleMembers(RealmModel realm, CommonLDAPGroupMapper roleOrGroupMapper, LDAPObject ldapRoleOrGroup, int firstResult, int maxResults) { + String memberOfLdapAttrName = roleOrGroupMapper.getConfig().getMemberOfLdapAttribute(); + String roleOrGroupDn = ldapRoleOrGroup.getDn().toString(); + return StreamsUtil.paginatedStream( + roleOrGroupMapper.getLdapProvider().searchForUserByUserAttributeStream(realm, memberOfLdapAttrName, roleOrGroupDn), firstResult, maxResults) + .toList(); + } + @Override public void beforeUserLDAPQuery(CommonLDAPGroupMapper roleOrGroupMapper, LDAPQuery query) { String memberOfLdapAttrName = roleOrGroupMapper.getConfig().getMemberOfLdapAttribute(); diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/membership/group/GroupLDAPStorageMapper.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/membership/group/GroupLDAPStorageMapper.java index 0202ae2a1af..b09b0b68e4f 100644 --- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/membership/group/GroupLDAPStorageMapper.java +++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/membership/group/GroupLDAPStorageMapper.java @@ -580,8 +580,9 @@ public class GroupLDAPStorageMapper extends AbstractLDAPStorageMapper implements return Collections.emptyList(); } - MembershipType membershipType = config.getMembershipTypeLdapAttribute(); - return membershipType.getGroupMembers(realm, this, ldapGroup, firstResult, maxResults); + String strategyKey = config.getUserGroupsRetrieveStrategy(); + UserRolesRetrieveStrategy strategy = factory.getUserGroupsRetrieveStrategy(strategyKey); + return strategy.getLDAPRoleMembers(realm, this, ldapGroup, firstResult, maxResults); } public void addGroupMappingInLDAP(RealmModel realm, GroupModel kcGroup, LDAPObject ldapUser) { diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/membership/role/RoleLDAPStorageMapper.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/membership/role/RoleLDAPStorageMapper.java index ace97227c6b..8f867cdcd96 100644 --- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/membership/role/RoleLDAPStorageMapper.java +++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/mappers/membership/role/RoleLDAPStorageMapper.java @@ -500,7 +500,8 @@ public class RoleLDAPStorageMapper extends AbstractLDAPStorageMapper implements return Collections.emptyList(); } - MembershipType membershipType = config.getMembershipTypeLdapAttribute(); - return membershipType.getGroupMembers(realm, this, ldapGroup, firstResult, maxResults); + String strategyKey = config.getUserRolesRetrieveStrategy(); + UserRolesRetrieveStrategy strategy = factory.getUserRolesRetrieveStrategy(strategyKey); + return strategy.getLDAPRoleMembers(realm, this, ldapGroup, firstResult, maxResults); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPGroupMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPGroupMapperTest.java index 0c628f4a228..83b80813c54 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPGroupMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPGroupMapperTest.java @@ -17,6 +17,7 @@ package org.keycloak.testsuite.federation.ldap; +import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.ClassRule; import org.junit.FixMethodOrder; @@ -52,6 +53,9 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; import static org.keycloak.testsuite.util.LDAPTestUtils.getGroupDescriptionLDAPAttrName; /** @@ -582,6 +586,11 @@ public class LDAPGroupMapperTest extends AbstractLDAPTest { Assert.assertFalse(carlosGroups.contains(group12)); Assert.assertEquals(1, carlosGroups.size()); + + // check the user is listed as the sole member of group1 + List group1Members = session.users().getGroupMembersStream(appRealm, group1, 0, 10).toList(); + assertThat(group1Members, hasSize(1)); + assertThat(group1Members.get(0).getUsername(), equalTo("carloskeycloak")); }); // Revert mappers