From 6172b9c8ec87eec5aa7cd2de8555d7d8a8bff695 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Sat, 30 Aug 2025 02:40:49 +0000 Subject: [PATCH] Replace legacy federation proto-event formatter. Signed-off-by: Jason Volk --- src/api/server/make_join.rs | 36 +++++++++++------------------------- src/api/server/make_knock.rs | 30 ++++++++++++++++-------------- src/api/server/make_leave.rs | 23 ++++++++++++----------- 3 files changed, 39 insertions(+), 50 deletions(-) diff --git a/src/api/server/make_join.rs b/src/api/server/make_join.rs index c9bb364d..02a382f8 100644 --- a/src/api/server/make_join.rs +++ b/src/api/server/make_join.rs @@ -1,7 +1,7 @@ use axum::extract::State; -use futures::{StreamExt, pin_mut}; +use futures::{StreamExt, TryFutureExt, pin_mut}; use ruma::{ - CanonicalJsonObject, OwnedUserId, RoomId, RoomVersionId, UserId, + OwnedUserId, RoomId, RoomVersionId, UserId, api::{client::error::ErrorKind, federation::membership::prepare_join_event}, events::{ StateEventType, @@ -11,9 +11,8 @@ use ruma::{ }, }, }; -use serde_json::value::to_raw_value; use tuwunel_core::{ - Err, Error, Result, debug_info, matrix::pdu::PduBuilder, utils::IterStream, warn, + Err, Error, Result, at, debug_info, matrix::pdu::PduBuilder, utils::IterStream, warn, }; use tuwunel_service::Services; @@ -71,6 +70,7 @@ pub(crate) async fn create_join_event_template_route( .state .get_room_version(&body.room_id) .await?; + if !body.ver.contains(&room_version_id) { return Err(Error::BadRequest( ErrorKind::IncompatibleRoomVersion { room_version: room_version_id }, @@ -119,7 +119,7 @@ pub(crate) async fn create_join_event_template_route( } }; - let (_pdu, mut pdu_json) = services + let pdu_json = services .timeline .create_hash_and_sign_event( PduBuilder::state(body.user_id.to_string(), &RoomMemberEventContent { @@ -130,16 +130,17 @@ pub(crate) async fn create_join_event_template_route( &body.room_id, &state_lock, ) + .map_ok(at!(1)) .await?; drop(state_lock); - // room v3 and above removed the "event_id" field from remote PDU format - maybe_strip_event_id(&mut pdu_json, &room_version_id)?; - Ok(prepare_join_event::v1::Response { - room_version: Some(room_version_id), - event: to_raw_value(&pdu_json).expect("CanonicalJson can be serialized to JSON"), + room_version: Some(room_version_id.clone()), + event: services + .federation + .format_pdu_into(pdu_json, Some(&room_version_id)) + .await, }) } @@ -221,18 +222,3 @@ pub(crate) async fn user_can_perform_restricted_join( ))) } } - -pub(crate) fn maybe_strip_event_id( - pdu_json: &mut CanonicalJsonObject, - room_version_id: &RoomVersionId, -) -> Result { - use RoomVersionId::*; - - match room_version_id { - | V1 | V2 => Ok(()), - | _ => { - pdu_json.remove("event_id"); - Ok(()) - }, - } -} diff --git a/src/api/server/make_knock.rs b/src/api/server/make_knock.rs index 5b8dad6e..b9c51d8b 100644 --- a/src/api/server/make_knock.rs +++ b/src/api/server/make_knock.rs @@ -1,12 +1,12 @@ use RoomVersionId::*; use axum::extract::State; +use futures::TryFutureExt; use ruma::{ RoomVersionId, api::{client::error::ErrorKind, federation::membership::prepare_knock_event}, events::room::member::{MembershipState, RoomMemberEventContent}, }; -use serde_json::value::to_raw_value; -use tuwunel_core::{Err, Error, Result, debug_warn, matrix::pdu::PduBuilder, warn}; +use tuwunel_core::{Err, Error, Result, at, debug_warn, matrix::pdu::PduBuilder, warn}; use crate::Ruma; @@ -56,21 +56,21 @@ pub(crate) async fn create_knock_event_template_route( } } - let room_version_id = services + let room_version = services .state .get_room_version(&body.room_id) .await?; - if matches!(room_version_id, V1 | V2 | V3 | V4 | V5 | V6) { + if matches!(room_version, V1 | V2 | V3 | V4 | V5 | V6) { return Err(Error::BadRequest( - ErrorKind::IncompatibleRoomVersion { room_version: room_version_id }, + ErrorKind::IncompatibleRoomVersion { room_version }, "Room version does not support knocking.", )); } - if !body.ver.contains(&room_version_id) { + if !body.ver.contains(&room_version) { return Err(Error::BadRequest( - ErrorKind::IncompatibleRoomVersion { room_version: room_version_id }, + ErrorKind::IncompatibleRoomVersion { room_version }, "Your homeserver does not support the features required to knock on this room.", )); } @@ -88,11 +88,12 @@ pub(crate) async fn create_knock_event_template_route( &body.user_id, &body.room_id ); + return Err!(Request(Forbidden("You cannot knock on a room you are banned from."))); } } - let (_pdu, mut pdu_json) = services + let pdu_json = services .timeline .create_hash_and_sign_event( PduBuilder::state( @@ -103,15 +104,16 @@ pub(crate) async fn create_knock_event_template_route( &body.room_id, &state_lock, ) + .map_ok(at!(1)) .await?; drop(state_lock); - // room v3 and above removed the "event_id" field from remote PDU format - super::maybe_strip_event_id(&mut pdu_json, &room_version_id)?; + let event = services + .federation + .format_pdu_into(pdu_json, Some(&room_version)) + .await; - Ok(prepare_knock_event::v1::Response { - room_version: room_version_id, - event: to_raw_value(&pdu_json).expect("CanonicalJson can be serialized to JSON"), - }) + // room v3 and above removed the "event_id" field from remote PDU format + Ok(prepare_knock_event::v1::Response { room_version, event }) } diff --git a/src/api/server/make_leave.rs b/src/api/server/make_leave.rs index a3b99c85..f4ce3bce 100644 --- a/src/api/server/make_leave.rs +++ b/src/api/server/make_leave.rs @@ -1,12 +1,11 @@ use axum::extract::State; +use futures::TryFutureExt; use ruma::{ api::federation::membership::prepare_leave_event, events::room::member::{MembershipState, RoomMemberEventContent}, }; -use serde_json::value::to_raw_value; -use tuwunel_core::{Err, Result, matrix::pdu::PduBuilder}; +use tuwunel_core::{Err, Result, at, matrix::pdu::PduBuilder}; -use super::make_join::maybe_strip_event_id; use crate::Ruma; /// # `GET /_matrix/federation/v1/make_leave/{roomId}/{eventId}` @@ -32,13 +31,15 @@ pub(crate) async fn create_leave_event_template_route( .acl_check(body.origin(), &body.room_id) .await?; - let room_version_id = services + let room_version = services .state .get_room_version(&body.room_id) + .map_ok(Some) .await?; + let state_lock = services.state.mutex.lock(&body.room_id).await; - let (_pdu, mut pdu_json) = services + let pdu_json = services .timeline .create_hash_and_sign_event( PduBuilder::state( @@ -49,15 +50,15 @@ pub(crate) async fn create_leave_event_template_route( &body.room_id, &state_lock, ) + .map_ok(at!(1)) .await?; drop(state_lock); - // room v3 and above removed the "event_id" field from remote PDU format - maybe_strip_event_id(&mut pdu_json, &room_version_id)?; + let event = services + .federation + .format_pdu_into(pdu_json, room_version.as_ref()) + .await; - Ok(prepare_leave_event::v1::Response { - room_version: Some(room_version_id), - event: to_raw_value(&pdu_json).expect("CanonicalJson can be serialized to JSON"), - }) + Ok(prepare_leave_event::v1::Response { room_version, event }) }