in src/main/java/com/epam/digital/data/platform/keycloak/rest/api/ext/UserApiProvider.java [187:249]
public SearchUsersByAttributesResponseDto searchUsersByAttributes(
@Context final HttpRequest request, SearchUsersByAttributesRequestDto requestDto) {
final var realm = session.getContext().getRealm();
authenticateRealmAdminRequest(request.getHttpHeaders());
validateRequestRealm(request, realm.getName());
final var continueToken = new AtomicInteger(
Objects.requireNonNullElse(requestDto.getPagination().getContinueToken(), 0));
if (continueToken.get() < 0) {
// continue token shows that all pages were selected
return SearchUsersByAttributesResponseDto.builder().users(List.of())
.pagination(Pagination.builder().continueToken(-1).build()).build();
}
final var limit = new AtomicInteger(
Objects.requireNonNullElse(requestDto.getPagination().getLimit(), 0));
if (limit.get() <= 0) {
// limit set to null of less than or equal 0 shows that pagination is disabled
limit.set(-1);
}
final var foundUsers = new ArrayList<UserRepresentation>();
final var oldContinueToken = new AtomicInteger(continueToken.get());
do {
oldContinueToken.set(continueToken.get());
session.users().getUsersStream(realm, continueToken.get(), limit.get())
// skip all remaining users if list is filled
.filter(userModel -> limit.get() < 0 || foundUsers.size() < (limit.get() + 1))
// set count of all processed users as continue token
.peek(userModel -> continueToken.incrementAndGet())
// filter users by attributesEquals
.filter(userModel -> UserFilter.isUserMatchesAttributesEquals(userModel,
requestDto.getAttributesEquals()))
// filter users by attributesStartWith
.filter(userModel -> UserFilter.isUserMatchesAttributesStartsWith(userModel,
requestDto.getAttributesStartsWith()))
// filter users by attributesThatAreStartFor
.filter(userModel -> UserFilter.isUserMatchesAttributesThatAreStartFor(userModel,
requestDto.getAttributesThatAreStartFor()))
// map to UserRepresentation
.map(userModel -> ModelToRepresentation.toRepresentation(session, realm, userModel))
// add to list of found users
.forEach(foundUsers::add);
} while (limit.get() > 0 // if limit<=0 then we need only 1 iteration
// if continueToken hasn't changed then user stream was empty, so end loop
&& oldContinueToken.get() != continueToken.get()
// if found enough users end the loop
&& foundUsers.size() < (limit.get() + 1));
if (limit.get() < 0 || foundUsers.size() <= limit.get()) {
// if there were found users only for this page then it's last page
continueToken.set(-1);
} else {
// remove last found user as they're from next page
foundUsers.remove(limit.get());
continueToken.decrementAndGet();
}
return SearchUsersByAttributesResponseDto.builder().users(foundUsers)
.pagination(Pagination.builder().continueToken(continueToken.get()).build())
.build();
}