From 15b832ff013788050641d5dfa2ea8dbd87f785de Mon Sep 17 00:00:00 2001 From: Ginger Date: Tue, 7 Apr 2026 10:44:05 -0400 Subject: [PATCH] refactor: Replace more uses of RoomVersionId with RoomVersionRules --- src/core/matrix/event.rs | 6 +- src/core/matrix/event/id.rs | 13 +- src/core/matrix/event/redact.rs | 18 +-- .../fetch_and_handle_outliers.rs | 6 +- .../rooms/event_handler/handle_outlier_pdu.rs | 15 +- src/service/rooms/event_handler/mod.rs | 12 +- .../rooms/event_handler/parse_incoming_pdu.rs | 34 ++-- .../event_handler/upgrade_outlier_pdu.rs | 11 +- src/service/rooms/timeline/create.rs | 4 +- src/service/server_keys/get.rs | 6 +- src/service/server_keys/mod.rs | 5 +- src/service/server_keys/sign.rs | 13 +- src/service/server_keys/util.rs | 151 +----------------- src/service/server_keys/verify.rs | 30 ++-- 14 files changed, 88 insertions(+), 236 deletions(-) diff --git a/src/core/matrix/event.rs b/src/core/matrix/event.rs index b2cd5731d..cd8541963 100644 --- a/src/core/matrix/event.rs +++ b/src/core/matrix/event.rs @@ -11,7 +11,7 @@ use ruma::{ CanonicalJsonObject, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, RoomId, - RoomVersionId, UserId, events::TimelineEventType, + RoomVersionId, UserId, events::TimelineEventType, room_version_rules::RoomVersionRules, }; use serde::Deserialize; use serde_json::{Value as JsonValue, value::RawValue as RawJsonValue}; @@ -95,11 +95,11 @@ fn get_content(&self) -> Result } #[inline] - fn redacts_id(&self, room_version: &RoomVersionId) -> Option + fn redacts_id(&self, room_version_rules: &RoomVersionRules) -> Option where Self: Sized, { - redact::redacts_id(self, room_version) + redact::redacts_id(self, room_version_rules) } #[inline] diff --git a/src/core/matrix/event/id.rs b/src/core/matrix/event/id.rs index 9270e2a73..80636af6a 100644 --- a/src/core/matrix/event/id.rs +++ b/src/core/matrix/event/id.rs @@ -1,4 +1,4 @@ -use ruma::{CanonicalJsonObject, OwnedEventId, RoomVersionId}; +use ruma::{CanonicalJsonObject, OwnedEventId, room_version_rules::RoomVersionRules}; use serde_json::value::RawValue as RawJsonValue; use crate::{Err, Result, err}; @@ -9,12 +9,12 @@ /// CanonicalJsonValue>`. pub fn gen_event_id_canonical_json( pdu: &RawJsonValue, - room_version_id: &RoomVersionId, + room_version_rules: &RoomVersionRules, ) -> Result<(OwnedEventId, CanonicalJsonObject)> { let value: CanonicalJsonObject = serde_json::from_str(pdu.get()) .map_err(|e| err!(BadServerResponse(warn!("Error parsing incoming event: {e:?}"))))?; - let event_id = gen_event_id(&value, room_version_id)?; + let event_id = gen_event_id(&value, room_version_rules)?; Ok((event_id, value)) } @@ -22,12 +22,9 @@ pub fn gen_event_id_canonical_json( /// Generates a correct eventId for the incoming pdu. pub fn gen_event_id( value: &CanonicalJsonObject, - room_version_id: &RoomVersionId, + room_version_rules: &RoomVersionRules, ) -> Result { - let Some(rules) = room_version_id.rules() else { - return Err!("Cannot generate event ID for unknown room version {room_version_id}"); - }; - let reference_hash = ruma::signatures::reference_hash(value, &rules)?; + let reference_hash = ruma::signatures::reference_hash(value, room_version_rules)?; let event_id: OwnedEventId = format!("${reference_hash}").try_into()?; Ok(event_id) diff --git a/src/core/matrix/event/redact.rs b/src/core/matrix/event/redact.rs index 5deac8745..019683923 100644 --- a/src/core/matrix/event/redact.rs +++ b/src/core/matrix/event/redact.rs @@ -1,6 +1,7 @@ use ruma::{ OwnedEventId, RoomVersionId, events::{TimelineEventType, room::redaction::RoomRedactionEventContent}, + room_version_rules::RoomVersionRules, }; use serde::Deserialize; use serde_json::value::{RawValue as RawJsonValue, to_raw_value}; @@ -61,7 +62,7 @@ pub(super) fn is_redacted(event: &E) -> bool { #[must_use] pub(super) fn redacts_id( event: &E, - room_version: &RoomVersionId, + room_version_rules: &RoomVersionRules, ) -> Option { use RoomVersionId::*; @@ -69,14 +70,13 @@ pub(super) fn redacts_id( return None; } - match *room_version { - | V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => - event.redacts().map(ToOwned::to_owned), - | _ => - event - .get_content::() - .ok()? - .redacts, + if room_version_rules.redaction.content_field_redacts { + event.redacts().map(ToOwned::to_owned) + } else { + event + .get_content::() + .ok()? + .redacts } } diff --git a/src/service/rooms/event_handler/fetch_and_handle_outliers.rs b/src/service/rooms/event_handler/fetch_and_handle_outliers.rs index 1ecdb82b2..e465131fb 100644 --- a/src/service/rooms/event_handler/fetch_and_handle_outliers.rs +++ b/src/service/rooms/event_handler/fetch_and_handle_outliers.rs @@ -12,7 +12,7 @@ api::federation::event::get_event, }; -use super::get_room_version; +use super::get_room_version_rules; /// Find the event and auth it. Once the event is validated (steps 1 - 8) /// it is appended to the outliers Tree. @@ -117,13 +117,13 @@ pub(super) async fn fetch_and_handle_outliers<'a, Pdu, Events>( { | Ok(res) => { debug!("Got {next_id} over federation from {origin}"); - let Ok(room_version_id) = get_room_version(create_event) else { + let Ok(room_version_rules) = get_room_version_rules(create_event) else { back_off((*next_id).to_owned()); continue; }; let Ok((calculated_event_id, value)) = - gen_event_id_canonical_json(&res.pdu, &room_version_id) + gen_event_id_canonical_json(&res.pdu, &room_version_rules) else { back_off((*next_id).to_owned()); continue; diff --git a/src/service/rooms/event_handler/handle_outlier_pdu.rs b/src/service/rooms/event_handler/handle_outlier_pdu.rs index 58564d901..ea467754b 100644 --- a/src/service/rooms/event_handler/handle_outlier_pdu.rs +++ b/src/service/rooms/event_handler/handle_outlier_pdu.rs @@ -10,7 +10,7 @@ events::StateEventType, }; -use super::{check_room_id, get_room_version}; +use super::{check_room_id, get_room_version_rules}; use crate::rooms::timeline::pdu_fits; #[implement(super::Service)] @@ -41,21 +41,20 @@ pub(super) async fn handle_outlier_pdu<'a, Pdu>( // 2. Check signatures, otherwise drop // 3. check content hash, redact if doesn't match - let room_version = get_room_version(create_event)?; - let room_rules = room_version - .rules() - .expect("room version should have defined rules"); + let room_version_rules = get_room_version_rules(create_event)?; let mut incoming_pdu = match self .services .server_keys - .verify_event(&value, Some(&room_version)) + .verify_event(&value, &room_version_rules) .await { | Ok(ruma::signatures::Verified::All) => value, | Ok(ruma::signatures::Verified::Signatures) => { // Redact debug_info!("Calculated hash does not match (redaction): {event_id}"); - let Ok(obj) = ruma::canonical_json::redact(value, &room_rules.redaction, None) else { + let Ok(obj) = + ruma::canonical_json::redact(value, &room_version_rules.redaction, None) + else { return Err!(Request(InvalidParam("Redaction failed"))); }; @@ -187,7 +186,7 @@ pub(super) async fn handle_outlier_pdu<'a, Pdu>( }; let auth_check = state_res::event_auth::auth_check( - &room_rules, + &room_version_rules, &pdu_event, None, // TODO: third party invite state_fetch, diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index cf7a153b0..17ba310da 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -16,8 +16,8 @@ use async_trait::async_trait; use conduwuit::{Err, Event, PduEvent, Result, Server, SyncRwLock, utils::MutexMap}; use ruma::{ - OwnedEventId, OwnedRoomId, RoomId, RoomVersionId, - events::room::create::RoomCreateEventContent, + OwnedEventId, OwnedRoomId, RoomId, events::room::create::RoomCreateEventContent, + room_version_rules::RoomVersionRules, }; use crate::{Dep, globals, rooms, sending, server_keys}; @@ -114,9 +114,11 @@ fn check_room_id(room_id: &RoomId, pdu: &Pdu) -> Result { Ok(()) } -fn get_room_version(create_event: &Pdu) -> Result { +fn get_room_version_rules(create_event: &Pdu) -> Result { let content: RoomCreateEventContent = create_event.get_content()?; - let room_version = content.room_version; + let Some(room_version_rules) = content.room_version.rules() else { + return Err!(Request(UnsupportedRoomVersion("Room version has no defined rules"))); + }; - Ok(room_version) + Ok(room_version_rules) } diff --git a/src/service/rooms/event_handler/parse_incoming_pdu.rs b/src/service/rooms/event_handler/parse_incoming_pdu.rs index 06cfb3df9..570e25e03 100644 --- a/src/service/rooms/event_handler/parse_incoming_pdu.rs +++ b/src/service/rooms/event_handler/parse_incoming_pdu.rs @@ -32,20 +32,22 @@ pub async fn parse_incoming_pdu(&self, pdu: &RawJsonValue) -> Result { .get("content") .and_then(CanonicalJsonValue::as_object) .ok_or_else(|| err!(Request(InvalidParam("Missing or invalid content in pdu"))))?; + let room_version = content .get("room_version") .and_then(CanonicalJsonValue::as_str) .unwrap_or("1"); - let vi = RoomVersionId::try_from(room_version).unwrap_or(RoomVersionId::V1); - if vi + + let room_version_rules = RoomVersionId::try_from(room_version) + .unwrap_or(RoomVersionId::V1) .rules() - .expect("room version should have defined rules") - .room_id_format - == RoomIdFormatVersion::V2 - { - let (event_id, _) = gen_event_id_canonical_json(pdu, &vi).map_err(|e| { - err!(Request(InvalidParam("Could not convert event to canonical json: {e}"))) - })?; + .expect("room version should have defined rules"); + + if room_version_rules.room_id_format == RoomIdFormatVersion::V2 { + let (event_id, _) = + gen_event_id_canonical_json(pdu, &room_version_rules).map_err(|e| { + err!(Request(InvalidParam("Could not convert event to canonical json: {e}"))) + })?; RoomId::parse(event_id.as_str().replace('$', "!")).expect("valid room ID") } else { // V11 or below room, room_id must be present @@ -57,14 +59,18 @@ pub async fn parse_incoming_pdu(&self, pdu: &RawJsonValue) -> Result { } }; - let room_version_id = self + let room_version_rules = self .services .state .get_room_version(&room_id) .await - .unwrap_or(RoomVersionId::V1); - let (event_id, value) = gen_event_id_canonical_json(pdu, &room_version_id).map_err(|e| { - err!(Request(InvalidParam("Could not convert event to canonical json: {e}"))) - })?; + .unwrap_or(RoomVersionId::V1) + .rules() + .expect("room version should have defined rules"); + + let (event_id, value) = + gen_event_id_canonical_json(pdu, &room_version_rules).map_err(|e| { + err!(Request(InvalidParam("Could not convert event to canonical json: {e}"))) + })?; Ok((room_id, event_id, value)) } diff --git a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs index 957c52829..d930f7b5c 100644 --- a/src/service/rooms/event_handler/upgrade_outlier_pdu.rs +++ b/src/service/rooms/event_handler/upgrade_outlier_pdu.rs @@ -10,7 +10,7 @@ use futures::{FutureExt, StreamExt, future::ready}; use ruma::{CanonicalJsonValue, RoomId, ServerName, events::StateEventType}; -use super::get_room_version; +use super::get_room_version_rules; use crate::rooms::{ state_compressor::{CompressedState, HashSetCompressStateEvent}, timeline::RawPduId, @@ -52,10 +52,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( "Upgrading PDU from outlier to timeline" ); let timer = Instant::now(); - let room_version_id = get_room_version(create_event)?; - let room_version_rules = room_version_id - .rules() - .expect("room version should have defined rules"); + let room_version_rules = get_room_version_rules(create_event)?; // 10. Fetch missing state and auth chain events by calling /state_ids at // backwards extremities doing all the checks in this list starting at 1. @@ -153,7 +150,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( event_id = %incoming_pdu.event_id, "Performing soft-fail check" ); - let mut soft_fail = match (auth_check, incoming_pdu.redacts_id(&room_version_id)) { + let mut soft_fail = match (auth_check, incoming_pdu.redacts_id(&room_version_rules)) { | (false, _) => true, | (true, None) => false, | (true, Some(redact_id)) => @@ -286,7 +283,7 @@ pub(super) async fn upgrade_outlier_to_timeline_pdu( // TODO: this is supposed to hide redactions from policy servers, however, for // full efficacy it also needs to hide redactions for unknown events. This // needs to be investigated at a later time. - if let Some(redact_id) = incoming_pdu.redacts_id(&room_version_id) { + if let Some(redact_id) = incoming_pdu.redacts_id(&room_version_rules) { debug!( redact_id = %redact_id, "Checking if redaction is for a soft-failed event" diff --git a/src/service/rooms/timeline/create.rs b/src/service/rooms/timeline/create.rs index a5047e2c7..97b6299db 100644 --- a/src/service/rooms/timeline/create.rs +++ b/src/service/rooms/timeline/create.rs @@ -289,7 +289,7 @@ pub async fn create_hash_and_sign_event( if let Err(e) = self .services .server_keys - .hash_and_sign_event(&mut pdu_json, &room_version) + .hash_and_sign_event(&mut pdu_json, &room_version_rules) { return match e { | Error::SignatureJson(ruma::signatures::JsonError::PduTooLarge) => { @@ -299,7 +299,7 @@ pub async fn create_hash_and_sign_event( }; } // Generate event id - pdu.event_id = gen_event_id(&pdu_json, &room_version)?; + pdu.event_id = gen_event_id(&pdu_json, &room_version_rules)?; pdu_json.insert("event_id".into(), CanonicalJsonValue::String(pdu.event_id.clone().into())); // Verify that the *full* PDU isn't over 64KiB. // Ruma only validates that it's under 64KiB before signing and hashing. diff --git a/src/service/server_keys/get.rs b/src/service/server_keys/get.rs index 70fa676cc..9140fedfa 100644 --- a/src/service/server_keys/get.rs +++ b/src/service/server_keys/get.rs @@ -3,7 +3,7 @@ use conduwuit::{Err, Result, debug_error, implement, trace}; use ruma::{ CanonicalJsonObject, RoomVersionId, ServerName, ServerSigningKeyId, - api::federation::discovery::VerifyKey, + api::federation::discovery::VerifyKey, room_version_rules::RoomVersionRules, }; use super::{PubKeyMap, PubKeys, extract_key}; @@ -13,9 +13,9 @@ pub async fn get_event_keys( &self, object: &CanonicalJsonObject, - version: &RoomVersionId, + room_version_rules: &RoomVersionRules, ) -> Result { - let required = match required_keys(object, version) { + let required = match required_keys(object, &room_version_rules.signatures) { | Ok(required) => required, | Err(e) => { debug_error!("Failed to determine keys required to verify: {e}"); diff --git a/src/service/server_keys/mod.rs b/src/service/server_keys/mod.rs index ff25f97b6..e886d69c2 100644 --- a/src/service/server_keys/mod.rs +++ b/src/service/server_keys/mod.rs @@ -18,6 +18,7 @@ CanonicalJsonObject, MilliSecondsSinceUnixEpoch, OwnedServerSigningKeyId, RoomVersionId, ServerName, ServerSigningKeyId, api::federation::discovery::{ServerSigningKeys, VerifyKey}, + room_version_rules::RoomVersionRules, serde::Raw, signatures::{Ed25519KeyPair, PublicKeyMap, PublicKeySet}, }; @@ -117,10 +118,10 @@ async fn add_signing_keys(&self, new_keys: ServerSigningKeys) { pub async fn required_keys_exist( &self, object: &CanonicalJsonObject, - version: &RoomVersionId, + room_version_rules: &RoomVersionRules, ) -> bool { trace!(?object, "Checking required keys exist"); - let Ok(required_keys) = required_keys(object, version) else { + let Ok(required_keys) = required_keys(object, &room_version_rules.signatures) else { debug_error!("Failed to determine required keys"); return false; }; diff --git a/src/service/server_keys/sign.rs b/src/service/server_keys/sign.rs index 128dba171..27637c22f 100644 --- a/src/service/server_keys/sign.rs +++ b/src/service/server_keys/sign.rs @@ -1,5 +1,5 @@ use conduwuit::{Result, implement}; -use ruma::{CanonicalJsonObject, RoomVersionId}; +use ruma::{CanonicalJsonObject, RoomVersionId, room_version_rules::RoomVersionRules}; #[implement(super::Service)] pub fn sign_json(&self, object: &mut CanonicalJsonObject) -> Result { @@ -13,16 +13,11 @@ pub fn sign_json(&self, object: &mut CanonicalJsonObject) -> Result { pub fn hash_and_sign_event( &self, object: &mut CanonicalJsonObject, - room_version: &RoomVersionId, + room_version_rules: &RoomVersionRules, ) -> Result { use ruma::signatures::hash_and_sign_event; let server_name = self.services.globals.server_name().as_str(); - hash_and_sign_event( - server_name, - self.keypair(), - object, - &room_version.rules().unwrap().redaction, - ) - .map_err(Into::into) + hash_and_sign_event(server_name, self.keypair(), object, &room_version_rules.redaction) + .map_err(Into::into) } diff --git a/src/service/server_keys/util.rs b/src/service/server_keys/util.rs index 1706b7f80..b9f185dda 100644 --- a/src/service/server_keys/util.rs +++ b/src/service/server_keys/util.rs @@ -4,157 +4,14 @@ CanonicalJsonObject, CanonicalJsonValue, IdParseError, OwnedEventId, OwnedServerName, OwnedServerSigningKeyId, RoomVersionId, UserId, canonical_json::JsonType, - signatures::{JsonError, VerificationError}, + room_version_rules::SignaturesRules, + signatures::{JsonError, VerificationError, required_server_signatures_to_verify_event}, }; -/// Whether the given event is an `m.room.member` invite that was created as the -/// result of a third-party invite. -/// -/// Returns an error if the object has not the expected format of an -/// `m.room.member` event. -pub(super) fn is_invite_via_third_party_id( - object: &CanonicalJsonObject, -) -> Result { - let Some(CanonicalJsonValue::String(raw_type)) = object.get("type") else { - return Err(JsonError::NotOfType { - target: "type".to_owned(), - of_type: JsonType::String, - } - .into()); - }; - - if raw_type != "m.room.member" { - return Ok(false); - } - - let Some(CanonicalJsonValue::Object(content)) = object.get("content") else { - return Err(JsonError::NotOfType { - target: "content".to_owned(), - of_type: JsonType::Object, - } - .into()); - }; - - let Some(CanonicalJsonValue::String(membership)) = content.get("membership") else { - return Err(JsonError::NotOfType { - target: "membership".to_owned(), - of_type: JsonType::String, - } - .into()); - }; - - if membership != "invite" { - return Ok(false); - } - - match content.get("third_party_invite") { - | Some(CanonicalJsonValue::Object(_)) => Ok(true), - | None => Ok(false), - | _ => Err(JsonError::NotOfType { - target: "third_party_invite".to_owned(), - of_type: JsonType::Object, - } - .into()), - } -} - -/// Extracts the server names to check signatures for given event. -/// -/// Respects the rules for [validating signatures on received events] for -/// populating the result: -/// -/// - Add the server of the sender, except if it's an invite event that results -/// from a third-party invite. -/// - For room versions 1 and 2, add the server of the `event_id`. -/// - For room versions that support restricted join rules, if it's a join event -/// with a `join_authorised_via_users_server`, add the server of that user. -/// -/// [validating signatures on received events]: https://spec.matrix.org/latest/server-server-api/#validating-hashes-and-signatures-on-received-events -pub fn servers_to_check_signatures( - object: &CanonicalJsonObject, - version: &RoomVersionId, -) -> Result, VerificationError> { - let mut servers_to_check = BTreeSet::new(); - - if !is_invite_via_third_party_id(object)? { - match object.get("sender") { - | Some(CanonicalJsonValue::String(raw_sender)) => { - let user_id = <&UserId>::try_from(raw_sender.as_str()).map_err(|source| { - VerificationError::ParseIdentifier { identifier_type: "user ID", source } - })?; - - servers_to_check.insert(user_id.server_name().to_owned()); - }, - | _ => - return Err(JsonError::NotOfType { - target: "sender".to_owned(), - of_type: JsonType::String, - } - .into()), - }; - } - - match version { - | RoomVersionId::V1 | RoomVersionId::V2 => match object.get("event_id") { - | Some(CanonicalJsonValue::String(raw_event_id)) => { - let event_id: OwnedEventId = raw_event_id.parse().map_err(|source| { - VerificationError::ParseIdentifier { identifier_type: "event ID", source } - })?; - - let server_name = event_id - .server_name() - .ok_or_else(|| VerificationError::ParseIdentifier { - identifier_type: "event ID", - source: IdParseError::InvalidServerName, - })? - .to_owned(); - - servers_to_check.insert(server_name); - }, - | _ => { - return Err(JsonError::MissingField { path: "event_id".to_owned() }.into()); - }, - }, - | RoomVersionId::V3 - | RoomVersionId::V4 - | RoomVersionId::V5 - | RoomVersionId::V6 - | RoomVersionId::V7 => {}, - // TODO: And for all future versions that have join_authorised_via_users_server - | RoomVersionId::V8 - | RoomVersionId::V9 - | RoomVersionId::V10 - | RoomVersionId::V11 - | RoomVersionId::V12 => { - if let Some(authorized_user) = object - .get("content") - .and_then(|c| c.as_object()) - .and_then(|c| c.get("join_authorised_via_users_server")) - { - let authorized_user = authorized_user.as_str().ok_or_else(|| -> JsonError { - JsonError::NotOfType { - target: "join_authorised_via_users_server".to_owned(), - of_type: JsonType::String, - } - .into() - })?; - let authorized_user = <&UserId>::try_from(authorized_user).map_err(|source| { - VerificationError::ParseIdentifier { identifier_type: "user ID", source } - })?; - - servers_to_check.insert(authorized_user.server_name().to_owned()); - } - }, - | _ => unimplemented!(), - } - - Ok(servers_to_check) -} - /// Extracts the server names and key ids to check signatures for given event. pub fn required_keys( object: &CanonicalJsonObject, - version: &RoomVersionId, + rules: &SignaturesRules, ) -> Result>, VerificationError> { use CanonicalJsonValue::Object; let mut map = BTreeMap::>::new(); @@ -162,7 +19,7 @@ pub fn required_keys( return Ok(map); }; - for server in servers_to_check_signatures(object, version)? { + for server in required_server_signatures_to_verify_event(object, rules)? { let Some(Object(set)) = signatures.get(server.as_str()) else { continue; }; diff --git a/src/service/server_keys/verify.rs b/src/service/server_keys/verify.rs index 6f3f5b0d4..73647bac9 100644 --- a/src/service/server_keys/verify.rs +++ b/src/service/server_keys/verify.rs @@ -2,7 +2,8 @@ Err, Result, debug_warn, implement, matrix::event::gen_event_id_canonical_json, trace, }; use ruma::{ - CanonicalJsonObject, CanonicalJsonValue, OwnedEventId, RoomVersionId, signatures::Verified, + CanonicalJsonObject, CanonicalJsonValue, OwnedEventId, RoomVersionId, + room_version_rules::RoomVersionRules, signatures::Verified, }; use serde_json::value::RawValue as RawJsonValue; @@ -10,10 +11,10 @@ pub async fn validate_and_add_event_id( &self, pdu: &RawJsonValue, - room_version: &RoomVersionId, + room_version_rules: &RoomVersionRules, ) -> Result<(OwnedEventId, CanonicalJsonObject)> { - let (event_id, mut value) = gen_event_id_canonical_json(pdu, room_version)?; - if let Err(e) = self.verify_event(&value, Some(room_version)).await { + let (event_id, mut value) = gen_event_id_canonical_json(pdu, room_version_rules)?; + if let Err(e) = self.verify_event(&value, room_version_rules).await { return Err!(BadServerResponse(debug_error!( "Event {event_id} failed verification: {e:?}" ))); @@ -28,12 +29,12 @@ pub async fn validate_and_add_event_id( pub async fn validate_and_add_event_id_no_fetch( &self, pdu: &RawJsonValue, - room_version: &RoomVersionId, + room_version_rules: &RoomVersionRules, ) -> Result<(OwnedEventId, CanonicalJsonObject)> { trace!(?pdu, "Validating PDU without fetching keys"); - let (event_id, mut value) = gen_event_id_canonical_json(pdu, room_version)?; + let (event_id, mut value) = gen_event_id_canonical_json(pdu, room_version_rules)?; trace!(event_id = event_id.as_str(), "Generated event ID, checking required keys"); - if !self.required_keys_exist(&value, room_version).await { + if !self.required_keys_exist(&value, room_version_rules).await { debug_warn!( "Event {event_id} is missing required keys, cannot verify without fetching keys" ); @@ -42,7 +43,7 @@ pub async fn validate_and_add_event_id_no_fetch( ))); } trace!("All required keys exist, verifying event"); - if let Err(e) = self.verify_event(&value, Some(room_version)).await { + if let Err(e) = self.verify_event(&value, room_version_rules).await { debug_warn!("Event verification failed"); return Err!(BadServerResponse(debug_error!( "Event {event_id} failed verification: {e:?}" @@ -59,21 +60,18 @@ pub async fn validate_and_add_event_id_no_fetch( pub async fn verify_event( &self, event: &CanonicalJsonObject, - room_version: Option<&RoomVersionId>, + room_version_rules: &RoomVersionRules, ) -> Result { - let room_version = room_version.unwrap_or(&RoomVersionId::V12); - let keys = self.get_event_keys(event, room_version).await?; - ruma::signatures::verify_event(&keys, event, &room_version.rules().unwrap()) - .map_err(Into::into) + let keys = self.get_event_keys(event, room_version_rules).await?; + ruma::signatures::verify_event(&keys, event, room_version_rules).map_err(Into::into) } #[implement(super::Service)] pub async fn verify_json( &self, event: &CanonicalJsonObject, - room_version: Option<&RoomVersionId>, + room_version_rules: &RoomVersionRules, ) -> Result { - let room_version = room_version.unwrap_or(&RoomVersionId::V12); - let keys = self.get_event_keys(event, room_version).await?; + let keys = self.get_event_keys(event, room_version_rules).await?; ruma::signatures::verify_json(&keys, event).map_err(Into::into) }