Skip to main content

tuwunel_api/client/admin/rooms/
state.rs

1use axum::extract::State;
2use futures::{TryStreamExt, future::Either};
3use ruma::events::StateEventType;
4use synapse_admin_api::rooms::admin_state::v1::{Request, Response};
5use tuwunel_core::{Result, matrix::Event, utils::stream::TryBroadbandExt};
6
7use crate::{
8	Ruma,
9	client::{admin::require_admin, with_membership},
10};
11
12/// # `GET /_synapse/admin/v1/rooms/{room_id}/state`
13///
14/// Returns the room's current state, optionally filtered to a single event
15/// type, bypassing the visibility gate the client-server state endpoint
16/// applies.
17pub(crate) async fn admin_room_state_route(
18	State(services): State<crate::State>,
19	body: Ruma<Request>,
20) -> Result<Response> {
21	let sender_user = body.sender_user();
22
23	require_admin(&services, sender_user).await?;
24
25	let encrypted = services
26		.state_accessor
27		.is_encrypted_room(&body.room_id)
28		.await;
29
30	let event_type = body
31		.event_type
32		.as_deref()
33		.map(StateEventType::from);
34
35	let pdus = match &event_type {
36		| Some(event_type) => Either::Left(
37			services
38				.state_accessor
39				.room_state_type_pdus(&body.room_id, event_type)
40				.map_ok(Event::into_pdu),
41		),
42		| None => Either::Right(
43			services
44				.state_accessor
45				.room_state_full_pdus(&body.room_id)
46				.map_ok(Event::into_pdu),
47		),
48	};
49
50	let state = pdus
51		.broad_and_then(async |pdu| {
52			Ok(with_membership(&services, pdu, sender_user, encrypted).await)
53		})
54		.map_ok(Event::into_format)
55		.try_collect()
56		.await?;
57
58	Ok(Response { state })
59}