tuwunel_api_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_api_client::{HierarchyArgs, get_client_hierarchy};
7use tuwunel_core::Result;
8use tuwunel_service::rooms::spaces::PaginationToken;
9
10use crate::{Ruma, require_admin};
11
12pub(crate) async fn admin_room_hierarchy_route(
17 State(services): State<crate::State>,
18 body: Ruma<Request>,
19) -> Result<Response> {
20 require_admin(&services, body.sender_user()).await?;
21
22 let limit = body
23 .limit
24 .unwrap_or_else(|| UInt::from(50_u32))
25 .min(UInt::from(50_u32));
26
27 let max_depth = body
28 .max_depth
29 .and_then(|max_depth| max_depth.try_into().ok())
30 .unwrap_or(usize::MAX);
31
32 let skip_room_ids = body
33 .from
34 .as_deref()
35 .and_then(|from| PaginationToken::from_str(from).ok())
36 .map(|token| token.short_room_ids)
37 .unwrap_or_default();
38
39 let response = get_client_hierarchy(&services, HierarchyArgs {
40 sender_user: body.sender_user(),
41 room_id: &body.room_id,
42 limit: limit.try_into().unwrap_or(50),
43 max_depth,
44 suggested_only: false,
45 skip_room_ids: &skip_room_ids,
46 bypass_visibility: true,
47 })
48 .await?;
49
50 let rooms: Vec<Raw<RoomSummary>> = response
51 .rooms
52 .iter()
53 .filter_map(|chunk| Raw::new(chunk).ok().map(Raw::cast_unchecked))
54 .collect();
55
56 Ok(Response { rooms, next_batch: response.next_batch })
57}