tuwunel_api/client/admin/rooms/
hierarchy.rs1use std::str::FromStr;
2
3use axum::extract::State;
4use ruma::{UInt, room::RoomSummary, serde::Raw};
5use synapse_admin_api::rooms::admin_hierarchy::v1::{Request, Response};
6use tuwunel_core::Result;
7use tuwunel_service::rooms::spaces::PaginationToken;
8
9use crate::{
10 Ruma,
11 client::{
12 admin::require_admin,
13 space::{HierarchyArgs, get_client_hierarchy},
14 },
15};
16
17pub(crate) async fn admin_room_hierarchy_route(
22 State(services): State<crate::State>,
23 body: Ruma<Request>,
24) -> Result<Response> {
25 require_admin(&services, body.sender_user()).await?;
26
27 let limit = body
28 .limit
29 .unwrap_or_else(|| UInt::from(50_u32))
30 .min(UInt::from(50_u32));
31
32 let max_depth = body
33 .max_depth
34 .and_then(|max_depth| max_depth.try_into().ok())
35 .unwrap_or(usize::MAX);
36
37 let skip_room_ids = body
38 .from
39 .as_deref()
40 .and_then(|from| PaginationToken::from_str(from).ok())
41 .map(|token| token.short_room_ids)
42 .unwrap_or_default();
43
44 let response = get_client_hierarchy(&services, HierarchyArgs {
45 sender_user: body.sender_user(),
46 room_id: &body.room_id,
47 limit: limit.try_into().unwrap_or(50),
48 max_depth,
49 suggested_only: false,
50 skip_room_ids: &skip_room_ids,
51 bypass_visibility: true,
52 })
53 .await?;
54
55 let rooms: Vec<Raw<RoomSummary>> = response
56 .rooms
57 .iter()
58 .filter_map(|chunk| Raw::new(chunk).ok().map(Raw::cast_unchecked))
59 .collect();
60
61 Ok(Response { rooms, next_batch: response.next_batch })
62}