diff --git a/Cargo.lock b/Cargo.lock index 2edb0af0..b510794c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3406,7 +3406,7 @@ dependencies = [ [[package]] name = "ruma" version = "0.12.6" -source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6" +source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" dependencies = [ "assign", "js_int", @@ -3425,7 +3425,7 @@ dependencies = [ [[package]] name = "ruma-appservice-api" version = "0.12.2" -source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6" +source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" dependencies = [ "js_int", "ruma-common", @@ -3437,7 +3437,7 @@ dependencies = [ [[package]] name = "ruma-client-api" version = "0.20.4" -source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6" +source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" dependencies = [ "as_variant", "assign", @@ -3460,7 +3460,7 @@ dependencies = [ [[package]] name = "ruma-common" version = "0.15.4" -source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6" +source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" dependencies = [ "as_variant", "base64", @@ -3493,7 +3493,7 @@ dependencies = [ [[package]] name = "ruma-events" version = "0.30.5" -source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6" +source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" dependencies = [ "as_variant", "indexmap", @@ -3519,7 +3519,7 @@ dependencies = [ [[package]] name = "ruma-federation-api" version = "0.11.2" -source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6" +source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" dependencies = [ "bytes", "headers", @@ -3541,7 +3541,7 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" version = "0.10.1" -source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6" +source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" dependencies = [ "js_int", "thiserror 2.0.14", @@ -3550,7 +3550,7 @@ dependencies = [ [[package]] name = "ruma-macros" version = "0.15.2" -source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6" +source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" dependencies = [ "cfg-if", "proc-macro-crate", @@ -3565,7 +3565,7 @@ dependencies = [ [[package]] name = "ruma-push-gateway-api" version = "0.11.0" -source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6" +source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" dependencies = [ "js_int", "ruma-common", @@ -3577,7 +3577,7 @@ dependencies = [ [[package]] name = "ruma-signatures" version = "0.17.1" -source = "git+https://github.com/matrix-construct/ruma?rev=8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6#8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6" +source = "git+https://github.com/matrix-construct/ruma?rev=93f28d777073e60687e8013e59d8d16b5adbdf9a#93f28d777073e60687e8013e59d8d16b5adbdf9a" dependencies = [ "base64", "ed25519-dalek", diff --git a/Cargo.toml b/Cargo.toml index 952792d8..4cb0f5eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -317,7 +317,7 @@ default-features = false [workspace.dependencies.ruma] git = "https://github.com/matrix-construct/ruma" -rev = "8bc15ba4f145e7b995d36e82e8624c3ac3ce0ef6" +rev = "93f28d777073e60687e8013e59d8d16b5adbdf9a" features = [ "__compat", "appservice-api-c", diff --git a/src/core/matrix/pdu/format.rs b/src/core/matrix/pdu/format.rs index 5c92002c..5bcd5eb6 100644 --- a/src/core/matrix/pdu/format.rs +++ b/src/core/matrix/pdu/format.rs @@ -1,6 +1,12 @@ -use ruma::{CanonicalJsonObject, CanonicalJsonValue, RoomVersionId}; +use ruma::{ + CanonicalJsonObject, CanonicalJsonValue, EventId, RoomVersionId, + room_version_rules::{EventsReferenceFormatVersion, RoomVersionRules}, +}; -use crate::{is_equal_to, matrix::room_version}; +use crate::{ + Result, err, extract_variant, is_equal_to, + matrix::{PduEvent, room_version}, +}; pub fn into_outgoing_federation( mut pdu_json: CanonicalJsonObject, @@ -35,5 +41,67 @@ pub fn into_outgoing_federation( } } + if matches!(room_rules.events_reference_format, EventsReferenceFormatVersion::V1) { + if let Some(value) = pdu_json.get_mut("auth_events") { + mutate_outgoing_reference_format(value); + } + if let Some(value) = pdu_json.get_mut("prev_events") { + mutate_outgoing_reference_format(value); + } + } + pdu_json } + +fn mutate_outgoing_reference_format(value: &mut CanonicalJsonValue) { + value + .as_array_mut() + .into_iter() + .flatten() + .for_each(|value| { + if let Some(event_id) = value.as_str().map(ToOwned::to_owned) { + *value = CanonicalJsonValue::Array(vec![ + CanonicalJsonValue::String(event_id), + CanonicalJsonValue::Object([(String::new(), "".into())].into()), + ]); + } + }); +} + +pub fn from_incoming_federation( + event_id: &EventId, + pdu_json: &mut CanonicalJsonObject, + room_rules: &RoomVersionRules, +) -> Result { + if matches!(room_rules.events_reference_format, EventsReferenceFormatVersion::V1) { + if let Some(value) = pdu_json.get_mut("auth_events") { + mutate_incoming_reference_format(value); + } + if let Some(value) = pdu_json.get_mut("prev_events") { + mutate_incoming_reference_format(value); + } + } + + pdu_json.insert("event_id".to_owned(), CanonicalJsonValue::String(event_id.into())); + + serde_json::from_value::(serde_json::to_value(&pdu_json)?) + .map_err(|e| err!(Request(BadJson(debug_warn!("Event is not a valid PDU: {e}"))))) +} + +fn mutate_incoming_reference_format(value: &mut CanonicalJsonValue) { + value + .as_array_mut() + .into_iter() + .flat_map(|vec| vec.iter_mut()) + .for_each(|value| { + let event_id = value + .as_array() + .into_iter() + .find_map(|vec| vec.first()) + .and_then(|val| extract_variant!(val, CanonicalJsonValue::String)) + .cloned() + .unwrap_or_default(); + + *value = CanonicalJsonValue::String(event_id); + }); +} diff --git a/src/service/rooms/event_handler/handle_outlier_pdu.rs b/src/service/rooms/event_handler/handle_outlier_pdu.rs index c287dbbe..4a5480e5 100644 --- a/src/service/rooms/event_handler/handle_outlier_pdu.rs +++ b/src/service/rooms/event_handler/handle_outlier_pdu.rs @@ -1,11 +1,11 @@ use futures::{StreamExt, TryFutureExt}; use ruma::{ - CanonicalJsonObject, CanonicalJsonValue, EventId, RoomId, RoomVersionId, ServerName, - events::TimelineEventType, + CanonicalJsonObject, EventId, RoomId, RoomVersionId, ServerName, events::TimelineEventType, }; use tuwunel_core::{ Err, Result, debug, debug_info, err, implement, matrix::{Event, PduEvent, event::TypeExt, room_version}, + pdu::format::from_incoming_federation, ref_at, state_res, trace, utils::{future::TryExtExt, stream::IterStream}, warn, @@ -66,12 +66,11 @@ pub(super) async fn handle_outlier_pdu( }, }; - // Now that we have checked the signature and hashes we can add the eventID and - // convert to our PduEvent type - pdu_json.insert("event_id".to_owned(), CanonicalJsonValue::String(event_id.to_string())); + let room_rules = room_version::rules(room_version)?; - let event = serde_json::from_value::(serde_json::to_value(&pdu_json)?) - .map_err(|e| err!(Request(BadJson(debug_warn!("Event is not a valid PDU: {e}")))))?; + // Now that we have checked the signature and hashes we can make mutations and + // convert to our PduEvent type. + let event = from_incoming_federation(event_id, &mut pdu_json, &room_rules)?; check_room_id(room_id, &event)?; @@ -89,7 +88,6 @@ pub(super) async fn handle_outlier_pdu( // auth events debug!("Checking based on auth events"); - let room_rules = room_version::rules(room_version)?; let is_hydra = !room_rules .event_format .allow_room_create_in_auth_events;