diff --git a/src/admin/debug/commands.rs b/src/admin/debug/commands.rs index 754c9840..f9d4a521 100644 --- a/src/admin/debug/commands.rs +++ b/src/admin/debug/commands.rs @@ -6,7 +6,7 @@ use std::{ }; use conduit::{debug_error, err, info, trace, utils, utils::string::EMPTY, warn, Error, PduEvent, Result}; -use futures::StreamExt; +use futures::{FutureExt, StreamExt}; use ruma::{ api::{client::error::ErrorKind, federation::event::get_room_state}, events::room::message::RoomMessageEventContent, @@ -246,6 +246,7 @@ pub(super) async fn get_remote_pdu( .rooms .timeline .backfill_pdu(&server, response.pdu) + .boxed() .await?; let json_text = serde_json::to_string_pretty(&json).expect("canonical json is valid json"); diff --git a/src/api/client/membership.rs b/src/api/client/membership.rs index fa71c0c8..bf8e5c33 100644 --- a/src/api/client/membership.rs +++ b/src/api/client/membership.rs @@ -374,7 +374,9 @@ pub(crate) async fn invite_user_route( return Ok(invite_user::v3::Response {}); } - invite_helper(&services, sender_user, user_id, &body.room_id, body.reason.clone(), false).await?; + invite_helper(&services, sender_user, user_id, &body.room_id, body.reason.clone(), false) + .boxed() + .await?; Ok(invite_user::v3::Response {}) } else { Err(Error::BadRequest(ErrorKind::NotFound, "User not found.")) diff --git a/src/api/client/room.rs b/src/api/client/room.rs index 4224d3fa..b6683ef4 100644 --- a/src/api/client/room.rs +++ b/src/api/client/room.rs @@ -2,7 +2,7 @@ use std::{cmp::max, collections::BTreeMap}; use axum::extract::State; use conduit::{debug_info, debug_warn, err, Err}; -use futures::{FutureExt, StreamExt}; +use futures::{FutureExt, StreamExt, TryFutureExt}; use ruma::{ api::client::{ error::ErrorKind, @@ -486,34 +486,28 @@ pub(crate) async fn create_room_route( /// - You have to currently be joined to the room (TODO: Respect history /// visibility) pub(crate) async fn get_room_event_route( - State(services): State, body: Ruma, + State(services): State, ref body: Ruma, ) -> Result { - let sender_user = body.sender_user.as_ref().expect("user is authenticated"); - - let event = services - .rooms - .timeline - .get_pdu(&body.event_id) - .await - .map_err(|_| err!(Request(NotFound("Event {} not found.", &body.event_id))))?; - - if !services - .rooms - .state_accessor - .user_can_see_event(sender_user, &event.room_id, &body.event_id) - .await - { - return Err(Error::BadRequest( - ErrorKind::forbidden(), - "You don't have permission to view this event.", - )); - } - - let mut event = (*event).clone(); - event.add_age()?; - Ok(get_room_event::v3::Response { - event: event.to_room_event(), + event: services + .rooms + .timeline + .get_pdu_owned(&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?, }) } diff --git a/src/api/mod.rs b/src/api/mod.rs index ed8aacf2..fc68af5b 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1,3 +1,5 @@ +#![allow(clippy::toplevel_ref_arg)] + pub mod client; pub mod router; pub mod server; diff --git a/src/api/server/send_join.rs b/src/api/server/send_join.rs index f2ede9d0..60ec8c1f 100644 --- a/src/api/server/send_join.rs +++ b/src/api/server/send_join.rs @@ -253,7 +253,9 @@ pub(crate) async fn create_join_event_v1_route( } } - let room_state = create_join_event(&services, body.origin(), &body.room_id, &body.pdu).await?; + let room_state = create_join_event(&services, body.origin(), &body.room_id, &body.pdu) + .boxed() + .await?; Ok(create_join_event::v1::Response { room_state, @@ -296,7 +298,9 @@ pub(crate) async fn create_join_event_v2_route( auth_chain, state, event, - } = create_join_event(&services, body.origin(), &body.room_id, &body.pdu).await?; + } = create_join_event(&services, body.origin(), &body.room_id, &body.pdu) + .boxed() + .await?; let room_state = create_join_event::v2::RoomState { members_omitted: false, auth_chain, diff --git a/src/service/rooms/timeline/data.rs b/src/service/rooms/timeline/data.rs index 19dc5325..f062e7e4 100644 --- a/src/service/rooms/timeline/data.rs +++ b/src/service/rooms/timeline/data.rs @@ -123,15 +123,18 @@ impl Data { /// /// Checks the `eventid_outlierpdu` Tree if not found in the timeline. pub(super) async fn get_pdu(&self, event_id: &EventId) -> Result> { + self.get_pdu_owned(event_id).await.map(Arc::new) + } + + /// Returns the pdu. + /// + /// Checks the `eventid_outlierpdu` Tree if not found in the timeline. + pub(super) async fn get_pdu_owned(&self, event_id: &EventId) -> Result { if let Ok(pdu) = self.get_non_outlier_pdu(event_id).await { - return Ok(Arc::new(pdu)); + return Ok(pdu); } - self.eventid_outlierpdu - .get(event_id) - .await - .deserialized() - .map(Arc::new) + self.eventid_outlierpdu.get(event_id).await.deserialized() } /// Like get_non_outlier_pdu(), but without the expense of fetching and diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index 86a47919..8255be7d 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -244,6 +244,11 @@ impl Service { /// Checks the `eventid_outlierpdu` Tree if not found in the timeline. pub async fn get_pdu(&self, event_id: &EventId) -> Result> { self.db.get_pdu(event_id).await } + /// Returns the pdu. + /// + /// Checks the `eventid_outlierpdu` Tree if not found in the timeline. + pub async fn get_pdu_owned(&self, event_id: &EventId) -> Result { self.db.get_pdu_owned(event_id).await } + /// Checks if pdu exists /// /// Checks the `eventid_outlierpdu` Tree if not found in the timeline. @@ -885,6 +890,7 @@ impl Service { vec![(*pdu.event_id).to_owned()], state_lock, ) + .boxed() .await?; // We set the room state after inserting the pdu, so that we never have a moment @@ -1104,7 +1110,7 @@ impl Service { match response { Ok(response) => { for pdu in response.pdus { - if let Err(e) = self.backfill_pdu(backfill_server, pdu).await { + if let Err(e) = self.backfill_pdu(backfill_server, pdu).boxed().await { warn!("Failed to add backfilled pdu in room {room_id}: {e}"); } }