Skip to main content

tuwunel_api/client/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_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) => services
37			.state_accessor
38			.room_state_type_pdus(&body.room_id, event_type)
39			.map_ok(Event::into_pdu)
40			.left_stream(),
41
42		| None => services
43			.state_accessor
44			.room_state_full_pdus(&body.room_id)
45			.map_ok(Event::into_pdu)
46			.right_stream(),
47	};
48
49	let state = pdus
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}