Skip to main content

tuwunel_api_admin/rooms/
state.rs

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