feat: Enable pagination for the users list route

This commit is contained in:
timedout
2026-05-25 14:17:25 +01:00
committed by Ginger
parent 374a216fc8
commit 61a3749c24
4 changed files with 42 additions and 24 deletions
+3 -3
View File
@@ -1,10 +1,10 @@
use axum::extract::State;
use conduwuit::{info, utils::ReadyExt, warn, Err, Result};
use conduwuit::{Err, Result, info, utils::ReadyExt, warn};
use futures::{FutureExt, StreamExt};
use ruma::{events::room::message::RoomMessageEventContent, OwnedRoomAliasId};
use ruma::{OwnedRoomAliasId, events::room::message::RoomMessageEventContent};
use ruminuwuity::admin::continuwuity::rooms;
use crate::{client::leave_room, Ruma};
use crate::{Ruma, client::leave_room};
/// # `PUT /_continuwuity/admin/v1/rooms/{roomID}/ban`
///
+25 -19
View File
@@ -1,5 +1,5 @@
use axum::extract::State;
use conduwuit::Err;
use conduwuit::{Err, utils::stream::WidebandExt};
use futures::StreamExt;
use ruminuwuity::admin::continuwuity::users;
use tokio::join;
@@ -19,24 +19,30 @@ pub(crate) async fn list_users_route(
return Err!(Request(Forbidden("Only server administrators can use this endpoint")));
}
let mut users = Vec::new();
while let Some(user_id) = services.users.list_local_users().next().await {
let (deactivated, suspended, locked, admin, login_disabled) = join!(
services.users.is_deactivated(&user_id),
services.users.is_suspended(&user_id),
services.users.is_locked(&user_id),
services.users.is_admin(&user_id),
services.users.is_login_disabled(&user_id),
);
users.push(users::list::v1::User {
user_id: user_id.clone(),
deactivated: deactivated.unwrap_or_default(),
suspended: suspended.unwrap_or_default(),
locked: locked.unwrap_or_default(),
admin,
login_disabled,
});
}
let users = services
.users
.list_local_users()
.skip(body.offset.unwrap_or_default())
.take(body.limit.unwrap_or(100).min(100))
.wide_filter_map(|user_id| async move {
let (deactivated, suspended, locked, admin, login_disabled) = join!(
services.users.is_deactivated(&user_id),
services.users.is_suspended(&user_id),
services.users.is_locked(&user_id),
services.users.is_admin(&user_id),
services.users.is_login_disabled(&user_id),
);
Some(users::list::v1::User {
user_id: user_id.clone(),
deactivated: deactivated.unwrap_or_default(),
suspended: suspended.unwrap_or_default(),
locked: locked.unwrap_or_default(),
admin,
login_disabled,
})
})
.collect()
.await;
Ok(users::list::v1::Response::new(users))
}
+1 -1
View File
@@ -284,7 +284,7 @@ pub fn build(router: Router<State>, state: State) -> Router<State> {
router = router
.ruma_route(&admin_api::users::list_users_route)
.ruma_route(&admin_api::rooms::ban_room)
.ruma_route(&admin_api::rooms::list_rooms)
.ruma_route(&admin_api::rooms::list_rooms);
};
router
@@ -7,7 +7,7 @@ pub mod v1 {
use serde::Deserialize;
metadata! {
method: PUT,
method: GET,
rate_limited: false,
authentication: AccessToken,
history: {
@@ -30,6 +30,18 @@ pub mod v1 {
#[ruma_api(query)]
#[serde(default, skip_serializing_if = "ruma::serde::is_default")]
pub include_suspended: bool,
/// The maximum number of results to return in this page. Maximum (and
/// default) is 100.
#[ruma_api(query)]
#[serde(default, skip_serializing_if = "ruma::serde::is_default")]
pub limit: Option<usize>,
/// The number of results to skip over before returning results. Default
/// is 0.
#[ruma_api(query)]
#[serde(default, skip_serializing_if = "ruma::serde::is_default")]
pub offset: Option<usize>,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, serde::Serialize)]