Add briefRepresentation query parameter to getUsersInRole endpoint
Closes #29480 Signed-off-by: rmartinc <rmartinc@redhat.com>
This commit is contained in:
parent
6b135ff6e7
commit
592c2250fc
8 changed files with 60 additions and 22 deletions
|
@ -120,9 +120,8 @@ public interface RoleResource {
|
|||
|
||||
/**
|
||||
* Get role members.
|
||||
* <p/>
|
||||
* Returns users that have the given role, sorted by username ascending, paginated according to the query
|
||||
* parameters.
|
||||
* <p>Returns users that have the given role, sorted by username ascending, paginated according to the query
|
||||
* parameters.</p>
|
||||
*
|
||||
* @param firstResult Pagination offset
|
||||
* @param maxResults Pagination size
|
||||
|
@ -133,11 +132,27 @@ public interface RoleResource {
|
|||
@Produces(MediaType.APPLICATION_JSON)
|
||||
List<UserRepresentation> getUserMembers(@QueryParam("first") Integer firstResult,
|
||||
@QueryParam("max") Integer maxResults);
|
||||
|
||||
/**
|
||||
* Get role members.
|
||||
* <p>Returns users that have the given role, sorted by username ascending, paginated according to the query
|
||||
* parameters.</p>
|
||||
*
|
||||
* @param briefRepresentation If the user should be returned in brief or full representation
|
||||
* @param firstResult Pagination offset
|
||||
* @param maxResults Pagination size
|
||||
* @return a list of users with the given role
|
||||
*/
|
||||
@GET
|
||||
@Path("users")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
List<UserRepresentation> getUserMembers(@QueryParam("briefRepresentation") Boolean briefRepresentation,
|
||||
@QueryParam("first") Integer firstResult,
|
||||
@QueryParam("max") Integer maxResults);
|
||||
|
||||
/**
|
||||
* Get role groups
|
||||
* <p/>
|
||||
* Returns groups that have the given role
|
||||
* Get role groups.
|
||||
* <p>Returns groups that have the given role.</p>
|
||||
*
|
||||
* @return a list of groups with the given role
|
||||
*/
|
||||
|
@ -147,9 +162,8 @@ public interface RoleResource {
|
|||
Set<GroupRepresentation> getRoleGroupMembers();
|
||||
|
||||
/**
|
||||
* Get role groups
|
||||
* <p/>
|
||||
* Returns groups that have the given role, paginated according to the query parameters
|
||||
* Get role groups.
|
||||
* <p>Returns groups that have the given role, paginated according to the query parameters.</p>
|
||||
*
|
||||
* @param firstResult Pagination offset
|
||||
* @param maxResults Pagination size
|
||||
|
@ -162,9 +176,8 @@ public interface RoleResource {
|
|||
@QueryParam("max") Integer maxResults);
|
||||
|
||||
/**
|
||||
* Get role members
|
||||
* <p/>
|
||||
* Returns users that have the given role
|
||||
* Get role members.
|
||||
* <p>Returns users that have the given role.</p>
|
||||
*
|
||||
* @return a set of users with the given role
|
||||
*
|
||||
|
@ -177,9 +190,8 @@ public interface RoleResource {
|
|||
Set<UserRepresentation> getRoleUserMembers();
|
||||
|
||||
/**
|
||||
* Get role members
|
||||
* <p/>
|
||||
* Returns users that have the given role, paginated according to the query parameters
|
||||
* Get role members.
|
||||
* <p>Returns users that have the given role, paginated according to the query parameters.</p>
|
||||
*
|
||||
* @param firstResult Pagination offset
|
||||
* @param maxResults Pagination size
|
||||
|
|
|
@ -30,6 +30,7 @@ export const UsersInRoleTab = () => {
|
|||
return adminClient.clients.findUsersWithRole({
|
||||
roleName: role.name!,
|
||||
id: clientId,
|
||||
briefRepresentation: true,
|
||||
first,
|
||||
max,
|
||||
});
|
||||
|
@ -37,6 +38,7 @@ export const UsersInRoleTab = () => {
|
|||
|
||||
return adminClient.roles.findUsersWithRole({
|
||||
name: role.name!,
|
||||
briefRepresentation: true,
|
||||
first,
|
||||
max,
|
||||
});
|
||||
|
|
|
@ -139,7 +139,13 @@ export class Clients extends Resource<{ realm?: string }> {
|
|||
});
|
||||
|
||||
public findUsersWithRole = this.makeRequest<
|
||||
{ id: string; roleName: string; first?: number; max?: number },
|
||||
{
|
||||
id: string;
|
||||
roleName: string;
|
||||
briefRepresentation?: boolean;
|
||||
first?: number;
|
||||
max?: number;
|
||||
},
|
||||
UserRepresentation[]
|
||||
>({
|
||||
method: "GET",
|
||||
|
|
|
@ -58,7 +58,12 @@ export class Roles extends Resource<{ realm?: string }> {
|
|||
});
|
||||
|
||||
public findUsersWithRole = this.makeRequest<
|
||||
{ name: string; first?: number; max?: number },
|
||||
{
|
||||
name: string;
|
||||
briefRepresentation?: boolean;
|
||||
first?: number;
|
||||
max?: number;
|
||||
},
|
||||
UserRepresentation[]
|
||||
>({
|
||||
method: "GET",
|
||||
|
|
|
@ -733,7 +733,10 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore {
|
|||
TypedQuery<UserEntity> query = em.createNamedQuery("usersInRole", UserEntity.class);
|
||||
query.setParameter("roleId", role.getId());
|
||||
|
||||
return closing(paginateQuery(query, firstResult, maxResults).getResultStream().map(user -> new UserAdapter(session, realm, em, user)));
|
||||
final UserProvider users = session.users();
|
||||
return closing(paginateQuery(query, firstResult, maxResults).getResultStream())
|
||||
.map(userEntity -> users.getUserById(realm, userEntity.getId()))
|
||||
.filter(Objects::nonNull);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.keycloak.models.ModelDuplicateException;
|
|||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleContainerModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.ModelToRepresentation;
|
||||
import org.keycloak.representations.idm.GroupRepresentation;
|
||||
import org.keycloak.representations.idm.ManagementPermissionReference;
|
||||
|
@ -477,6 +478,7 @@ public class RoleContainerResource extends RoleResource {
|
|||
* @param roleName the role name.
|
||||
* @param firstResult first result to return. Ignored if negative or {@code null}.
|
||||
* @param maxResults maximum number of results to return. Ignored if negative or {@code null}.
|
||||
* @param briefRepresentation Boolean which defines whether brief representations are returned (default: false)
|
||||
* @return a non-empty {@code Stream} of users.
|
||||
*/
|
||||
@Path("{role-name}/users")
|
||||
|
@ -486,6 +488,7 @@ public class RoleContainerResource extends RoleResource {
|
|||
@Tag(name = KeycloakOpenAPI.Admin.Tags.ROLES)
|
||||
@Operation( summary = "Returns a stream of users that have the specified role name.")
|
||||
public Stream<UserRepresentation> getUsersInRole(final @Parameter(description = "the role name.") @PathParam("role-name") String roleName,
|
||||
@Parameter(description = "Boolean which defines whether brief representations are returned (default: false)") @QueryParam("briefRepresentation") Boolean briefRepresentation,
|
||||
@Parameter(description = "first result to return. Ignored if negative or {@code null}.") @QueryParam("first") Integer firstResult,
|
||||
@Parameter(description = "maximum number of results to return. Ignored if negative or {@code null}.") @QueryParam("max") Integer maxResults) {
|
||||
|
||||
|
@ -498,8 +501,11 @@ public class RoleContainerResource extends RoleResource {
|
|||
throw new NotFoundException("Could not find role");
|
||||
}
|
||||
|
||||
final Function<UserModel, UserRepresentation> toRepresentation = briefRepresentation != null && briefRepresentation
|
||||
? ModelToRepresentation::toBriefRepresentation
|
||||
: user -> ModelToRepresentation.toRepresentation(session, realm, user);
|
||||
return session.users().getRoleMembersStream(realm, role, firstResult, maxResults)
|
||||
.map(user -> ModelToRepresentation.toRepresentation(session, realm, user));
|
||||
.map(toRepresentation);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -239,8 +239,10 @@ public class ClientRolesTest extends AbstractClientTest {
|
|||
// pagination
|
||||
List<UserRepresentation> usersInRole1 = roleResource.getUserMembers(0, 5);
|
||||
assertEquals(createUsernames(0, 5), extractUsernames(usersInRole1));
|
||||
List<UserRepresentation> usersInRole2 = roleResource.getUserMembers(5, 10);
|
||||
Assert.assertNotNull("Not in full representation", usersInRole1.get(0).getNotBefore());
|
||||
List<UserRepresentation> usersInRole2 = roleResource.getUserMembers(true, 5, 10);
|
||||
assertEquals(createUsernames(5, 10), extractUsernames(usersInRole2));
|
||||
Assert.assertNull("Not in brief representation", usersInRole2.get(0).getNotBefore());
|
||||
}
|
||||
|
||||
private static List<String> createUsernames(int startIndex, int endIndex) {
|
||||
|
|
|
@ -352,12 +352,14 @@ public class RealmRolesTest extends AbstractAdminTest {
|
|||
|
||||
List<UserRepresentation> roleUserMembers = roleResource.getUserMembers(0, 1);
|
||||
assertEquals(Collections.singletonList("test-role-member"), extractUsernames(roleUserMembers));
|
||||
Assert.assertNotNull("Not in full representation", roleUserMembers.get(0).getNotBefore());
|
||||
|
||||
roleUserMembers = roleResource.getUserMembers(1, 1);
|
||||
roleUserMembers = roleResource.getUserMembers(true, 1, 1);
|
||||
assertThat(roleUserMembers, hasSize(1));
|
||||
assertEquals(Collections.singletonList("test-role-member2"), extractUsernames(roleUserMembers));
|
||||
Assert.assertNull("Not in brief representation", roleUserMembers.get(0).getNotBefore());
|
||||
|
||||
roleUserMembers = roleResource.getUserMembers(2, 1);
|
||||
roleUserMembers = roleResource.getUserMembers(true, 2, 1);
|
||||
assertThat(roleUserMembers, is(empty()));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue