diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RoleResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RoleResource.java index 7ef7b89807..0f30010de8 100755 --- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RoleResource.java +++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/RoleResource.java @@ -28,6 +28,7 @@ import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import java.util.List; import java.util.Set; @@ -72,10 +73,32 @@ public interface RoleResource { @Path("composites") @Consumes(MediaType.APPLICATION_JSON) void deleteComposites(List rolesToRemove); - + + /** + * Get role members + *

+ * Returns users that have the given role + * + * @return a list of users with the given role + */ @GET @Path("users") @Produces(MediaType.APPLICATION_JSON) Set getRoleUserMembers(); + /** + * Get role members + *

+ * Returns users that have the given role, paginated according to the query parameters + * + * @param firstResult Pagination offset + * @param maxResults Pagination size + * @return a list of users with the given role + */ + @GET + @Path("users") + @Produces(MediaType.APPLICATION_JSON) + Set getRoleUserMembers(@QueryParam("first") Integer firstResult, + @QueryParam("max") Integer maxResults); + } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmRolesTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmRolesTest.java index 8d00bb26e8..45c41cbd66 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmRolesTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmRolesTest.java @@ -19,7 +19,6 @@ package org.keycloak.testsuite.admin.realm; import org.junit.Before; import org.junit.Test; -import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.RoleResource; import org.keycloak.admin.client.resource.RolesResource; import org.keycloak.admin.client.resource.UserResource; @@ -40,18 +39,22 @@ import javax.ws.rs.core.Response; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.collection.IsCollectionWithSize.hasSize; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.keycloak.testsuite.Assert.assertNames; -import static org.keycloak.testsuite.auth.page.AuthRealm.TEST; /** * @author Stian Thorgersen @@ -257,5 +260,46 @@ public class RealmRolesTest extends AbstractAdminTest { assertEquals(0, roleResource.getRoleUserMembers().size()); } - + + @Test + public void testRoleMembershipWithPagination() { + RoleResource role = resource.get("role-with-users"); + + // Add a second user + UserRepresentation userRep2 = new UserRepresentation(); + userRep2.setUsername("test-role-member2"); + userRep2.setEmail("test-role-member2@test-role-member.com"); + userRep2.setRequiredActions(Collections.emptyList()); + userRep2.setEnabled(true); + adminClient.realm(REALM_NAME).users().create(userRep2); + + List users = adminClient.realm(REALM_NAME).users().search("test-role-member", null, null, null, null, null); + assertThat(users, hasSize(2)); + for (UserRepresentation userRepFromList : users) { + UserResource user = adminClient.realm(REALM_NAME).users().get(userRepFromList.getId()); + UserRepresentation userRep = user.toRepresentation(); + + RoleResource roleResource = adminClient.realm(REALM_NAME).roles().get(role.toRepresentation().getName()); + List rolesToAdd = new LinkedList<>(); + rolesToAdd.add(roleResource.toRepresentation()); + adminClient.realm(REALM_NAME).users().get(userRep.getId()).roles().realmLevel().add(rolesToAdd); + } + + RoleResource roleResource = adminClient.realm(REALM_NAME).roles().get(role.toRepresentation().getName()); + Set roleUserMembers = roleResource.getRoleUserMembers(0, 1); + + Set expectedMembers = new HashSet<>(); + assertThat(roleUserMembers, hasSize(1)); + expectedMembers.add(roleUserMembers.iterator().next().getUsername()); + + roleUserMembers = roleResource.getRoleUserMembers(1, 1); + assertThat(roleUserMembers, hasSize(1)); + expectedMembers.add(roleUserMembers.iterator().next().getUsername()); + + roleUserMembers = roleResource.getRoleUserMembers(2, 1); + assertThat(roleUserMembers, is(empty())); + + assertThat(expectedMembers, containsInAnyOrder("test-role-member", "test-role-member2")); + } + }