Skip to main content

tuwunel_api/server/
event.rs

1use axum::extract::State;
2use futures::{FutureExt, future::try_join};
3use ruma::{MilliSecondsSinceUnixEpoch, OwnedRoomId, api::federation::event::get_event};
4use tuwunel_core::{Result, err};
5
6use super::AccessCheck;
7use crate::Ruma;
8
9/// # `GET /_matrix/federation/v1/event/{eventId}`
10///
11/// Retrieves a single event from the server.
12///
13/// - Only works if a user of this server is currently invited or joined the
14///   room
15pub(crate) async fn get_event_route(
16	State(services): State<crate::State>,
17	body: Ruma<get_event::v1::Request>,
18) -> Result<get_event::v1::Response> {
19	let event = services
20		.timeline
21		.get_pdu_json(&body.event_id)
22		.await
23		.map_err(|_| err!(Request(NotFound("Event not found."))))?;
24
25	let room_id: OwnedRoomId = event
26		.get("room_id")
27		.and_then(|val| val.as_str())
28		.ok_or_else(|| err!(Database("Invalid event in database.")))?
29		.try_into()
30		.map_err(|_| err!(Database("Invalid room_id in event in database.")))?;
31
32	let access_check = AccessCheck {
33		services: &services,
34		origin: body.origin(),
35		room_id: &room_id,
36		event_id: Some(&body.event_id),
37	};
38
39	let pdu = services
40		.federation
41		.format_pdu_into(event, None)
42		.map(Ok);
43
44	let ((), pdu) = try_join(access_check.check(), pdu).await?;
45
46	Ok(get_event::v1::Response {
47		origin: services.globals.server_name().to_owned(),
48		origin_server_ts: MilliSecondsSinceUnixEpoch::now(),
49		pdu,
50	})
51}