diff --git a/src/api/client/context.rs b/src/api/client/context.rs index acd7d80b..45c04eb6 100644 --- a/src/api/client/context.rs +++ b/src/api/client/context.rs @@ -79,11 +79,15 @@ pub(crate) async fn get_context_route( let (base_token, base_event, visible) = try_join!(base_token, base_event, visible)?; - if base_event.room_id != body.room_id { + if base_event.room_id != body.room_id || base_event.event_id != body.event_id { return Err!(Request(NotFound("Base event not found."))); } - if !visible { + if !visible + || ignored_filter(&services, (base_token, base_event.clone()), sender_user) + .await + .is_none() + { return Err!(Request(Forbidden("You don't have permission to view this event."))); } diff --git a/src/api/client/room/event.rs b/src/api/client/room/event.rs index 090c70a7..6deb567f 100644 --- a/src/api/client/room/event.rs +++ b/src/api/client/room/event.rs @@ -1,38 +1,53 @@ use axum::extract::State; -use conduit::{err, Result}; -use futures::TryFutureExt; +use conduit::{err, Err, Event, Result}; +use futures::{try_join, FutureExt, TryFutureExt}; use ruma::api::client::room::get_room_event; -use crate::Ruma; +use crate::{client::ignored_filter, Ruma}; /// # `GET /_matrix/client/r0/rooms/{roomId}/event/{eventId}` /// /// Gets a single event. -/// -/// - You have to currently be joined to the room (TODO: Respect history -/// visibility) pub(crate) async fn get_room_event_route( State(services): State, ref body: Ruma, ) -> Result { + let event = services + .rooms + .timeline + .get_pdu(&body.event_id) + .map_err(|_| err!(Request(NotFound("Event {} not found.", &body.event_id)))); + + let token = services + .rooms + .timeline + .get_pdu_count(&body.event_id) + .map_err(|_| err!(Request(NotFound("Event not found.")))); + + let visible = services + .rooms + .state_accessor + .user_can_see_event(body.sender_user(), &body.room_id, &body.event_id) + .map(Ok); + + let (token, mut event, visible) = try_join!(token, event, visible)?; + + if !visible + || ignored_filter(&services, (token, event.clone()), body.sender_user()) + .await + .is_none() + { + return Err!(Request(Forbidden("You don't have permission to view this event."))); + } + + if event.event_id() != &body.event_id || event.room_id() != body.room_id { + return Err!(Request(NotFound("Event not found"))); + } + + event.add_age().ok(); + + let event = event.to_room_event(); + Ok(get_room_event::v3::Response { - event: services - .rooms - .timeline - .get_pdu(&body.event_id) - .map_err(|_| err!(Request(NotFound("Event {} not found.", &body.event_id)))) - .and_then(|event| async move { - services - .rooms - .state_accessor - .user_can_see_event(body.sender_user(), &event.room_id, &body.event_id) - .await - .then_some(event) - .ok_or_else(|| err!(Request(Forbidden("You don't have permission to view this event.")))) - }) - .map_ok(|mut event| { - event.add_age().ok(); - event.to_room_event() - }) - .await?, + event, }) }