From fe1ce521aa77f07bb6102c1305c440ca904938d5 Mon Sep 17 00:00:00 2001
From: strawberry <strawberry@puppygock.gay>
Date: Wed, 4 Dec 2024 18:33:12 -0500
Subject: [PATCH] add ignored user checks on /context and /event, misc cleanup

Signed-off-by: strawberry <strawberry@puppygock.gay>
---
 src/api/client/context.rs    |  8 +++--
 src/api/client/room/event.rs | 65 ++++++++++++++++++++++--------------
 2 files changed, 46 insertions(+), 27 deletions(-)

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<crate::State>, ref body: Ruma<get_room_event::v3::Request>,
 ) -> Result<get_room_event::v3::Response> {
+	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,
 	})
 }