Skip to main content

tuwunel_api/server/
event_auth.rs

1use std::{borrow::Borrow, iter::once};
2
3use axum::extract::State;
4use futures::StreamExt;
5use ruma::api::federation::authorization::get_event_authorization;
6use tuwunel_core::{
7	Result,
8	utils::stream::{BroadbandExt, ReadyExt},
9};
10
11use super::{AccessCheck, utils::require_event_in_room};
12use crate::Ruma;
13
14/// # `GET /_matrix/federation/v1/event_auth/{roomId}/{eventId}`
15///
16/// Retrieves the auth chain for a given event.
17///
18/// - This does not include the event itself
19pub(crate) async fn get_event_authorization_route(
20	State(services): State<crate::State>,
21	body: Ruma<get_event_authorization::v1::Request>,
22) -> Result<get_event_authorization::v1::Response> {
23	let access_check = AccessCheck {
24		services: &services,
25		origin: body.origin(),
26		room_id: &body.room_id,
27		event_id: None,
28	};
29
30	access_check.check().await?;
31
32	require_event_in_room(&services, &body.event_id, &body.room_id).await?;
33
34	let room_version = services
35		.state
36		.get_room_version(&body.room_id)
37		.await?;
38
39	let auth_chain = services
40		.auth_chain
41		.event_ids_iter(&body.room_id, &room_version, once(body.event_id.borrow()))
42		.ready_filter_map(Result::ok)
43		.broad_filter_map(async |id| {
44			let pdu = services.timeline.get_pdu_json(&id).await.ok()?;
45
46			let pdu = services
47				.federation
48				.format_pdu_into(pdu, Some(&room_version))
49				.await;
50
51			Some(pdu)
52		})
53		.collect()
54		.await;
55
56	Ok(get_event_authorization::v1::Response { auth_chain })
57}