Bump ruma to 2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b (RoomVersion -> RoomVersionRules)

<https://github.com/ruma/ruma/pull/2045>

Co-authored-by: Jonas Platte <jplatte+git@posteo.de>
This commit is contained in:
Olivia Lee 2025-07-13 22:17:29 -07:00 committed by Jonas Platte
parent c4c294d64c
commit 8c9800735b
No known key found for this signature in database
GPG key ID: 7D261D771D915378
10 changed files with 133 additions and 106 deletions

22
Cargo.lock generated
View file

@ -2442,7 +2442,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma" name = "ruma"
version = "0.12.1" version = "0.12.1"
source = "git+https://github.com/ruma/ruma.git?rev=3924283c5e94d2020f0991ce35c27667f8c61f0a#3924283c5e94d2020f0991ce35c27667f8c61f0a" source = "git+https://github.com/ruma/ruma.git?rev=2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b#2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b"
dependencies = [ dependencies = [
"assign", "assign",
"js_int", "js_int",
@ -2461,7 +2461,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-appservice-api" name = "ruma-appservice-api"
version = "0.12.1" version = "0.12.1"
source = "git+https://github.com/ruma/ruma.git?rev=3924283c5e94d2020f0991ce35c27667f8c61f0a#3924283c5e94d2020f0991ce35c27667f8c61f0a" source = "git+https://github.com/ruma/ruma.git?rev=2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b#2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b"
dependencies = [ dependencies = [
"js_int", "js_int",
"ruma-common", "ruma-common",
@ -2473,7 +2473,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-client-api" name = "ruma-client-api"
version = "0.20.1" version = "0.20.1"
source = "git+https://github.com/ruma/ruma.git?rev=3924283c5e94d2020f0991ce35c27667f8c61f0a#3924283c5e94d2020f0991ce35c27667f8c61f0a" source = "git+https://github.com/ruma/ruma.git?rev=2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b#2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b"
dependencies = [ dependencies = [
"as_variant", "as_variant",
"assign", "assign",
@ -2496,7 +2496,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-common" name = "ruma-common"
version = "0.15.1" version = "0.15.1"
source = "git+https://github.com/ruma/ruma.git?rev=3924283c5e94d2020f0991ce35c27667f8c61f0a#3924283c5e94d2020f0991ce35c27667f8c61f0a" source = "git+https://github.com/ruma/ruma.git?rev=2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b#2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b"
dependencies = [ dependencies = [
"as_variant", "as_variant",
"base64", "base64",
@ -2527,7 +2527,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-events" name = "ruma-events"
version = "0.30.1" version = "0.30.1"
source = "git+https://github.com/ruma/ruma.git?rev=3924283c5e94d2020f0991ce35c27667f8c61f0a#3924283c5e94d2020f0991ce35c27667f8c61f0a" source = "git+https://github.com/ruma/ruma.git?rev=2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b#2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b"
dependencies = [ dependencies = [
"as_variant", "as_variant",
"indexmap 2.10.0", "indexmap 2.10.0",
@ -2550,7 +2550,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-federation-api" name = "ruma-federation-api"
version = "0.11.0" version = "0.11.0"
source = "git+https://github.com/ruma/ruma.git?rev=3924283c5e94d2020f0991ce35c27667f8c61f0a#3924283c5e94d2020f0991ce35c27667f8c61f0a" source = "git+https://github.com/ruma/ruma.git?rev=2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b#2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b"
dependencies = [ dependencies = [
"bytes", "bytes",
"headers", "headers",
@ -2572,7 +2572,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-identifiers-validation" name = "ruma-identifiers-validation"
version = "0.10.1" version = "0.10.1"
source = "git+https://github.com/ruma/ruma.git?rev=3924283c5e94d2020f0991ce35c27667f8c61f0a#3924283c5e94d2020f0991ce35c27667f8c61f0a" source = "git+https://github.com/ruma/ruma.git?rev=2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b#2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b"
dependencies = [ dependencies = [
"js_int", "js_int",
"thiserror 2.0.12", "thiserror 2.0.12",
@ -2581,7 +2581,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-macros" name = "ruma-macros"
version = "0.15.1" version = "0.15.1"
source = "git+https://github.com/ruma/ruma.git?rev=3924283c5e94d2020f0991ce35c27667f8c61f0a#3924283c5e94d2020f0991ce35c27667f8c61f0a" source = "git+https://github.com/ruma/ruma.git?rev=2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b#2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"proc-macro-crate", "proc-macro-crate",
@ -2596,7 +2596,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-push-gateway-api" name = "ruma-push-gateway-api"
version = "0.11.0" version = "0.11.0"
source = "git+https://github.com/ruma/ruma.git?rev=3924283c5e94d2020f0991ce35c27667f8c61f0a#3924283c5e94d2020f0991ce35c27667f8c61f0a" source = "git+https://github.com/ruma/ruma.git?rev=2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b#2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b"
dependencies = [ dependencies = [
"js_int", "js_int",
"ruma-common", "ruma-common",
@ -2608,7 +2608,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-signatures" name = "ruma-signatures"
version = "0.17.0" version = "0.17.0"
source = "git+https://github.com/ruma/ruma.git?rev=3924283c5e94d2020f0991ce35c27667f8c61f0a#3924283c5e94d2020f0991ce35c27667f8c61f0a" source = "git+https://github.com/ruma/ruma.git?rev=2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b#2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b"
dependencies = [ dependencies = [
"base64", "base64",
"ed25519-dalek", "ed25519-dalek",
@ -2624,7 +2624,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-state-res" name = "ruma-state-res"
version = "0.13.0" version = "0.13.0"
source = "git+https://github.com/ruma/ruma.git?rev=3924283c5e94d2020f0991ce35c27667f8c61f0a#3924283c5e94d2020f0991ce35c27667f8c61f0a" source = "git+https://github.com/ruma/ruma.git?rev=2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b#2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b"
dependencies = [ dependencies = [
"js_int", "js_int",
"ruma-common", "ruma-common",

View file

@ -145,7 +145,7 @@ xdg = "2.5.2"
[dependencies.ruma] [dependencies.ruma]
git = "https://github.com/ruma/ruma.git" git = "https://github.com/ruma/ruma.git"
rev = "3924283c5e94d2020f0991ce35c27667f8c61f0a" rev = "2ea8b833e3a80c1d650964a1f3e83ee569cf5c0b"
features = [ features = [
"compat-server-signing-key-version", "compat-server-signing-key-version",
"compat-empty-string-null", "compat-empty-string-null",

View file

@ -25,9 +25,10 @@ use ruma::{
}, },
StateEventType, TimelineEventType, StateEventType, TimelineEventType,
}, },
room_version_rules::RoomVersionRules,
state_res, CanonicalJsonObject, CanonicalJsonValue, EventId, state_res, CanonicalJsonObject, CanonicalJsonValue, EventId,
MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, OwnedServerName, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, OwnedServerName,
OwnedUserId, RoomId, RoomVersionId, UserId, OwnedUserId, RoomId, UserId,
}; };
use serde_json::value::{to_raw_value, RawValue as RawJsonValue}; use serde_json::value::{to_raw_value, RawValue as RawJsonValue};
use tokio::sync::RwLock; use tokio::sync::RwLock;
@ -662,6 +663,10 @@ async fn join_room_by_id_helper(
)) ))
} }
}; };
let room_version_rules = room_version_id
.rules()
.expect("ruma should support all room versions we advertise");
let mut join_event_stub: CanonicalJsonObject = serde_json::from_str( let mut join_event_stub: CanonicalJsonObject = serde_json::from_str(
make_join_response.event.get(), make_join_response.event.get(),
) )
@ -716,7 +721,7 @@ async fn join_room_by_id_helper(
services().globals.server_name().as_str(), services().globals.server_name().as_str(),
services().globals.keypair(), services().globals.keypair(),
&mut join_event_stub, &mut join_event_stub,
&room_version_id, &room_version_rules.redaction,
) )
.expect("event is valid, we just created it"); .expect("event is valid, we just created it");
@ -725,7 +730,7 @@ async fn join_room_by_id_helper(
"${}", "${}",
ruma::signatures::reference_hash( ruma::signatures::reference_hash(
&join_event_stub, &join_event_stub,
&room_version_id &room_version_rules
) )
.expect("ruma can calculate reference hashes") .expect("ruma can calculate reference hashes")
); );
@ -761,7 +766,7 @@ async fn join_room_by_id_helper(
}; };
let Ok((signed_event_id, signed_value)) = let Ok((signed_event_id, signed_value)) =
gen_event_id_canonical_json(&signed_raw, &room_version_id) gen_event_id_canonical_json(&signed_raw, &room_version_rules)
else { else {
// Event could not be converted to canonical json // Event could not be converted to canonical json
return Err(Error::BadRequest( return Err(Error::BadRequest(
@ -814,6 +819,9 @@ async fn join_room_by_id_helper(
)) ))
} }
}; };
let room_version_rules = room_version_id
.rules()
.expect("ruma should support all room versions we advertise");
let mut join_event_stub: CanonicalJsonObject = serde_json::from_str( let mut join_event_stub: CanonicalJsonObject = serde_json::from_str(
make_join_response.event.get(), make_join_response.event.get(),
@ -871,7 +879,7 @@ async fn join_room_by_id_helper(
services().globals.server_name().as_str(), services().globals.server_name().as_str(),
services().globals.keypair(), services().globals.keypair(),
&mut join_event_stub, &mut join_event_stub,
&room_version_id, &room_version_rules.redaction,
) )
.expect("event is valid, we just created it"); .expect("event is valid, we just created it");
@ -880,7 +888,7 @@ async fn join_room_by_id_helper(
"${}", "${}",
ruma::signatures::reference_hash( ruma::signatures::reference_hash(
&join_event_stub, &join_event_stub,
&room_version_id &room_version_rules
) )
.expect("ruma can calculate reference hashes") .expect("ruma can calculate reference hashes")
); );
@ -920,7 +928,7 @@ async fn join_room_by_id_helper(
restricted joins. Adding signature to our event" restricted joins. Adding signature to our event"
); );
let Ok((signed_event_id, signed_value)) = let Ok((signed_event_id, signed_value)) =
gen_event_id_canonical_json(signed_raw, &room_version_id) gen_event_id_canonical_json(signed_raw, &room_version_rules)
else { else {
// Event could not be converted to canonical json // Event could not be converted to canonical json
return Err(Error::BadRequest( return Err(Error::BadRequest(
@ -985,14 +993,14 @@ async fn join_room_by_id_helper(
.event_handler .event_handler
.fetch_join_signing_keys( .fetch_join_signing_keys(
&send_join_response, &send_join_response,
&room_version_id, &room_version_rules,
&pub_key_map, &pub_key_map,
) )
.await?; .await?;
info!("Going through send_join response room_state"); info!("Going through send_join response room_state");
for result in send_join_response.room_state.state.iter().map(|pdu| { for result in send_join_response.room_state.state.iter().map(|pdu| {
validate_and_add_event_id(pdu, &room_version_id, &pub_key_map) validate_and_add_event_id(pdu, &room_version_rules, &pub_key_map)
}) { }) {
let Ok((event_id, value)) = result.await else { let Ok((event_id, value)) = result.await else {
continue; continue;
@ -1025,7 +1033,11 @@ async fn join_room_by_id_helper(
info!("Going through send_join response auth_chain"); info!("Going through send_join response auth_chain");
for result in for result in
send_join_response.room_state.auth_chain.iter().map(|pdu| { send_join_response.room_state.auth_chain.iter().map(|pdu| {
validate_and_add_event_id(pdu, &room_version_id, &pub_key_map) validate_and_add_event_id(
pdu,
&room_version_rules,
&pub_key_map,
)
}) })
{ {
let Ok((event_id, value)) = result.await else { let Ok((event_id, value)) = result.await else {
@ -1037,9 +1049,7 @@ async fn join_room_by_id_helper(
info!("Running send_join auth check"); info!("Running send_join auth check");
state_res::event_auth::auth_check( state_res::event_auth::auth_check(
&state_res::RoomVersion::new(&room_version_id).map_err(|_| { &room_version_rules.authorization,
Error::UnsupportedRoomVersion(room_version_id.clone())
})?,
&parsed_join_pdu, &parsed_join_pdu,
|k, s| { |k, s| {
services() services()
@ -1171,7 +1181,7 @@ async fn make_join_request(
async fn validate_and_add_event_id( async fn validate_and_add_event_id(
pdu: &RawJsonValue, pdu: &RawJsonValue,
room_version: &RoomVersionId, room_version_rules: &RoomVersionRules,
pub_key_map: &RwLock<BTreeMap<String, SigningKeys>>, pub_key_map: &RwLock<BTreeMap<String, SigningKeys>>,
) -> Result<(OwnedEventId, CanonicalJsonObject)> { ) -> Result<(OwnedEventId, CanonicalJsonObject)> {
let mut value: CanonicalJsonObject = serde_json::from_str(pdu.get()) let mut value: CanonicalJsonObject = serde_json::from_str(pdu.get())
@ -1181,7 +1191,7 @@ async fn validate_and_add_event_id(
})?; })?;
let event_id = EventId::parse(format!( let event_id = EventId::parse(format!(
"${}", "${}",
ruma::signatures::reference_hash(&value, room_version) ruma::signatures::reference_hash(&value, room_version_rules)
.expect("ruma can calculate reference hashes") .expect("ruma can calculate reference hashes")
)) ))
.expect("ruma's reference hashes are valid event ids"); .expect("ruma's reference hashes are valid event ids");
@ -1246,7 +1256,7 @@ async fn validate_and_add_event_id(
.filter_keys_server_map(unfiltered_keys, origin_server_ts); .filter_keys_server_map(unfiltered_keys, origin_server_ts);
if let Err(error) = if let Err(error) =
ruma::signatures::verify_event(&keys, &value, room_version) ruma::signatures::verify_event(&keys, &value, room_version_rules)
{ {
warn!( warn!(
%event_id, %event_id,
@ -1319,6 +1329,9 @@ pub(crate) async fn invite_helper(
.rooms .rooms
.state .state
.get_create_content::<ExtractVersion>(room_id)?; .get_create_content::<ExtractVersion>(room_id)?;
let Some(room_version_rules) = room_version_id.rules() else {
return Err(Error::UnsupportedRoomVersion(room_version_id));
};
let response = services() let response = services()
.sending .sending
@ -1341,7 +1354,7 @@ pub(crate) async fn invite_helper(
// We do not add the event_id field to the pdu here because of signature // We do not add the event_id field to the pdu here because of signature
// and hashes checks // and hashes checks
let Ok((event_id, value)) = let Ok((event_id, value)) =
gen_event_id_canonical_json(&response.event, &room_version_id) gen_event_id_canonical_json(&response.event, &room_version_rules)
else { else {
// Event could not be converted to canonical json // Event could not be converted to canonical json
return Err(Error::BadRequest( return Err(Error::BadRequest(
@ -1631,6 +1644,9 @@ async fn remote_leave_room(user_id: &UserId, room_id: &RoomId) -> Result<()> {
)) ))
} }
}; };
let room_version_rules = room_version_id
.rules()
.expect("ruma should support all room versions we advertise");
let mut leave_event_stub = serde_json::from_str::<CanonicalJsonObject>( let mut leave_event_stub = serde_json::from_str::<CanonicalJsonObject>(
make_leave_response.event.get(), make_leave_response.event.get(),
@ -1666,15 +1682,18 @@ async fn remote_leave_room(user_id: &UserId, room_id: &RoomId) -> Result<()> {
services().globals.server_name().as_str(), services().globals.server_name().as_str(),
services().globals.keypair(), services().globals.keypair(),
&mut leave_event_stub, &mut leave_event_stub,
&room_version_id, &room_version_rules.redaction,
) )
.expect("event is valid, we just created it"); .expect("event is valid, we just created it");
// Generate event id // Generate event id
let event_id = EventId::parse(format!( let event_id = EventId::parse(format!(
"${}", "${}",
ruma::signatures::reference_hash(&leave_event_stub, &room_version_id) ruma::signatures::reference_hash(
.expect("ruma can calculate reference hashes") &leave_event_stub,
&room_version_rules
)
.expect("ruma can calculate reference hashes")
)) ))
.expect("ruma's reference hashes are valid event ids"); .expect("ruma's reference hashes are valid event ids");

View file

@ -718,9 +718,12 @@ pub(crate) fn parse_incoming_pdu(
.rooms .rooms
.state .state
.get_create_content::<ExtractVersion>(&room_id)?; .get_create_content::<ExtractVersion>(&room_id)?;
let Some(room_version_rules) = room_version_id.rules() else {
return Err(Error::UnsupportedRoomVersion(room_version_id));
};
let Ok((event_id, value)) = let Ok((event_id, value)) =
gen_event_id_canonical_json(pdu, &room_version_id) gen_event_id_canonical_json(pdu, &room_version_rules)
else { else {
// Event could not be converted to canonical json // Event could not be converted to canonical json
return Err(Error::BadRequest( return Err(Error::BadRequest(
@ -1634,8 +1637,12 @@ async fn create_join_event(
// hashes checks // hashes checks
let room_version_id = let room_version_id =
services().rooms.state.get_create_content::<ExtractVersion>(room_id)?; services().rooms.state.get_create_content::<ExtractVersion>(room_id)?;
let Some(room_version_rules) = room_version_id.rules() else {
return Err(Error::UnsupportedRoomVersion(room_version_id));
};
let Ok((event_id, value)) = let Ok((event_id, value)) =
gen_event_id_canonical_json(pdu, &room_version_id) gen_event_id_canonical_json(pdu, &room_version_rules)
else { else {
// Event could not be converted to canonical json // Event could not be converted to canonical json
return Err(Error::BadRequest( return Err(Error::BadRequest(
@ -1787,6 +1794,10 @@ pub(crate) async fn create_invite_route(
"Server does not support this room version.", "Server does not support this room version.",
)); ));
} }
let room_version_rules = body
.room_version
.rules()
.expect("ruma should support all room versions we advertise");
let mut signed_event = let mut signed_event =
utils::to_canonical_object(&body.event).map_err(|_| { utils::to_canonical_object(&body.event).map_err(|_| {
@ -1800,7 +1811,7 @@ pub(crate) async fn create_invite_route(
services().globals.server_name().as_str(), services().globals.server_name().as_str(),
services().globals.keypair(), services().globals.keypair(),
&mut signed_event, &mut signed_event,
&body.room_version, &room_version_rules.redaction,
) )
.map_err(|_| { .map_err(|_| {
Error::BadRequest(ErrorKind::InvalidParam, "Failed to sign event.") Error::BadRequest(ErrorKind::InvalidParam, "Failed to sign event.")
@ -1809,7 +1820,7 @@ pub(crate) async fn create_invite_route(
// Generate event id // Generate event id
let event_id = EventId::parse(format!( let event_id = EventId::parse(format!(
"${}", "${}",
ruma::signatures::reference_hash(&signed_event, &body.room_version) ruma::signatures::reference_hash(&signed_event, &room_version_rules)
.expect("ruma can calculate reference hashes") .expect("ruma can calculate reference hashes")
)) ))
.expect("ruma's reference hashes are valid event ids"); .expect("ruma's reference hashes are valid event ids");

View file

@ -22,10 +22,11 @@ use ruma::{
}, },
TimelineEventType, TimelineEventType,
}, },
room_version_rules::RoomVersionRules,
serde::Raw, serde::Raw,
signatures::verify_json, signatures::verify_json,
EventId, MilliSecondsSinceUnixEpoch, OwnedMxcUri, OwnedRoomId, EventId, MilliSecondsSinceUnixEpoch, OwnedMxcUri, OwnedRoomId,
OwnedServerName, RoomId, RoomVersionId, ServerName, UserId, OwnedServerName, RoomId, ServerName, UserId,
}; };
use serde_json::value::to_raw_value; use serde_json::value::to_raw_value;
use tokio::sync::{mpsc, Mutex, RwLock}; use tokio::sync::{mpsc, Mutex, RwLock};
@ -592,7 +593,7 @@ impl Service {
Ok(value) => { Ok(value) => {
match ruma::signatures::reference_hash( match ruma::signatures::reference_hash(
&value, &value,
&RoomVersionId::V6, &RoomVersionRules::V6,
) { ) {
Ok(hash) => { Ok(hash) => {
let event_id = let event_id =

View file

@ -8,10 +8,11 @@ use ruma::{
AnyStateEvent, AnyStrippedStateEvent, AnySyncStateEvent, AnyStateEvent, AnyStrippedStateEvent, AnySyncStateEvent,
AnySyncTimelineEvent, AnyTimelineEvent, StateEvent, TimelineEventType, AnySyncTimelineEvent, AnyTimelineEvent, StateEvent, TimelineEventType,
}, },
room_version_rules::{RedactionRules, RoomVersionRules},
serde::Raw, serde::Raw,
state_res, CanonicalJsonObject, CanonicalJsonValue, EventId, state_res, CanonicalJsonObject, CanonicalJsonValue, EventId,
MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, OwnedUserId, RoomId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, OwnedUserId, RoomId,
RoomVersionId, UInt, UserId, UInt, UserId,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::{ use serde_json::{
@ -59,7 +60,7 @@ impl PduEvent {
#[tracing::instrument(skip(self))] #[tracing::instrument(skip(self))]
pub(crate) fn redact( pub(crate) fn redact(
&mut self, &mut self,
room_version_id: &RoomVersionId, rules: &RedactionRules,
reason: &PduEvent, reason: &PduEvent,
) -> crate::Result<()> { ) -> crate::Result<()> {
self.unsigned = None; self.unsigned = None;
@ -68,14 +69,10 @@ impl PduEvent {
serde_json::from_str(self.content.get()).map_err(|_| { serde_json::from_str(self.content.get()).map_err(|_| {
Error::bad_database("PDU in db has invalid content.") Error::bad_database("PDU in db has invalid content.")
})?; })?;
redact_content_in_place( redact_content_in_place(&mut content, rules, self.kind.to_string())
&mut content, .map_err(|e| {
room_version_id, Error::Redaction(self.sender.server_name().to_owned(), e)
self.kind.to_string(), })?;
)
.map_err(|e| {
Error::Redaction(self.sender.server_name().to_owned(), e)
})?;
self.unsigned = Some(to_raw_value(&json!({ self.unsigned = Some(to_raw_value(&json!({
"redacted_because": serde_json::to_value(reason).expect("to_value(PduEvent) always works") "redacted_because": serde_json::to_value(reason).expect("to_value(PduEvent) always works")
@ -489,7 +486,7 @@ impl Ord for PduEvent {
/// CanonicalJsonValue>`. /// CanonicalJsonValue>`.
pub(crate) fn gen_event_id_canonical_json( pub(crate) fn gen_event_id_canonical_json(
pdu: &RawJsonValue, pdu: &RawJsonValue,
room_version_id: &RoomVersionId, rules: &RoomVersionRules,
) -> crate::Result<(OwnedEventId, CanonicalJsonObject)> { ) -> crate::Result<(OwnedEventId, CanonicalJsonObject)> {
let value: CanonicalJsonObject = let value: CanonicalJsonObject =
serde_json::from_str(pdu.get()).map_err(|error| { serde_json::from_str(pdu.get()).map_err(|error| {
@ -500,7 +497,7 @@ pub(crate) fn gen_event_id_canonical_json(
let event_id = format!( let event_id = format!(
"${}", "${}",
// Anything higher than version3 behaves the same // Anything higher than version3 behaves the same
ruma::signatures::reference_hash(&value, room_version_id) ruma::signatures::reference_hash(&value, rules)
.expect("ruma can calculate reference hashes") .expect("ruma can calculate reference hashes")
) )
.try_into() .try_into()

View file

@ -23,6 +23,7 @@ use ruma::{
TimelineEventType, TimelineEventType,
}, },
int, int,
room_version_rules::RoomVersionRules,
state_res::{self, StateMap}, state_res::{self, StateMap},
uint, CanonicalJsonObject, CanonicalJsonValue, EventId, uint, CanonicalJsonObject, CanonicalJsonValue, EventId,
MilliSecondsSinceUnixEpoch, OwnedServerName, OwnedServerSigningKeyId, MilliSecondsSinceUnixEpoch, OwnedServerName, OwnedServerSigningKeyId,
@ -121,13 +122,16 @@ impl Service {
.rooms .rooms
.state .state
.get_create_content::<ExtractVersion>(room_id)?; .get_create_content::<ExtractVersion>(room_id)?;
let Some(room_version_rules) = room_version_id.rules() else {
return Err(Error::UnsupportedRoomVersion(room_version_id.clone()));
};
let (incoming_pdu, val) = self let (incoming_pdu, val) = self
.handle_outlier_pdu( .handle_outlier_pdu(
origin, origin,
event_id, event_id,
room_id, room_id,
&room_version_id, &room_version_rules,
value, value,
false, false,
pub_key_map, pub_key_map,
@ -151,7 +155,7 @@ impl Service {
.fetch_unknown_prev_events( .fetch_unknown_prev_events(
origin, origin,
room_id, room_id,
&room_version_id, &room_version_rules,
pub_key_map, pub_key_map,
incoming_pdu.prev_events.clone(), incoming_pdu.prev_events.clone(),
) )
@ -303,7 +307,7 @@ impl Service {
origin: &'a ServerName, origin: &'a ServerName,
event_id: &'a EventId, event_id: &'a EventId,
room_id: &'a RoomId, room_id: &'a RoomId,
room_version_id: &'a RoomVersionId, room_version_rules: &'a RoomVersionRules,
mut value: CanonicalJsonObject, mut value: CanonicalJsonObject,
auth_events_known: bool, auth_events_known: bool,
pub_key_map: &'a RwLock<BTreeMap<String, SigningKeys>>, pub_key_map: &'a RwLock<BTreeMap<String, SigningKeys>>,
@ -315,11 +319,6 @@ impl Service {
// 2. Check signatures, otherwise drop // 2. Check signatures, otherwise drop
// 3. check content hash, redact if doesn't match // 3. check content hash, redact if doesn't match
let ruma_room_version =
state_res::RoomVersion::new(room_version_id).map_err(|_| {
Error::UnsupportedRoomVersion(room_version_id.clone())
})?;
// TODO: For RoomVersion6 we must check that Raw<..> is canonical, // TODO: For RoomVersion6 we must check that Raw<..> is canonical,
// do we anywhere? // do we anywhere?
// //
@ -369,7 +368,7 @@ impl Service {
let mut val = match ruma::signatures::verify_event( let mut val = match ruma::signatures::verify_event(
&filtered_keys, &filtered_keys,
&value, &value,
room_version_id, room_version_rules,
) { ) {
Err(error) => { Err(error) => {
// Drop // Drop
@ -384,7 +383,7 @@ impl Service {
warn!(%event_id, "Calculated hash does not match"); warn!(%event_id, "Calculated hash does not match");
let Ok(obj) = ruma::canonical_json::redact( let Ok(obj) = ruma::canonical_json::redact(
value, value,
room_version_id, &room_version_rules.redaction,
None, None,
) else { ) else {
return Err(Error::BadRequest( return Err(Error::BadRequest(
@ -445,7 +444,7 @@ impl Service {
.map(|x| Arc::from(&**x)) .map(|x| Arc::from(&**x))
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
room_id, room_id,
room_version_id, room_version_rules,
pub_key_map, pub_key_map,
) )
.await; .await;
@ -502,7 +501,7 @@ impl Service {
} }
state_res::event_auth::auth_check( state_res::event_auth::auth_check(
&ruma_room_version, &room_version_rules.authorization,
&incoming_pdu, &incoming_pdu,
|k, s| auth_events.get(&(k.to_string().into(), s.to_owned())), |k, s| auth_events.get(&(k.to_string().into(), s.to_owned())),
) )
@ -560,10 +559,9 @@ impl Service {
"Upgrading event to timeline pdu", "Upgrading event to timeline pdu",
); );
let ruma_room_version = state_res::RoomVersion::new(room_version_id) let Some(room_version_rules) = room_version_id.rules() else {
.map_err(|_| { return Err(Error::UnsupportedRoomVersion(room_version_id.clone()));
Error::UnsupportedRoomVersion(room_version_id.clone()) };
})?;
// 10. Fetch missing state and auth chain events by calling /state_ids // 10. Fetch missing state and auth chain events by calling /state_ids
// at backwards extremities doing all the checks in this list // at backwards extremities doing all the checks in this list
@ -710,7 +708,7 @@ impl Service {
let lock = services().globals.stateres_mutex.lock(); let lock = services().globals.stateres_mutex.lock();
let result = state_res::resolve( let result = state_res::resolve(
room_version_id, &room_version_rules.authorization,
&fork_states, &fork_states,
auth_chain_sets, auth_chain_sets,
|event_id| { |event_id| {
@ -779,7 +777,7 @@ impl Service {
origin, origin,
&collect, &collect,
room_id, room_id,
room_version_id, &room_version_rules,
pub_key_map, pub_key_map,
) )
.await; .await;
@ -865,7 +863,7 @@ impl Service {
// 11. Check the auth of the event passes based on the state of the // 11. Check the auth of the event passes based on the state of the
// event // event
state_res::event_auth::auth_check( state_res::event_auth::auth_check(
&ruma_room_version, &room_version_rules.authorization,
&incoming_pdu, &incoming_pdu,
|k, s| { |k, s| {
services() services()
@ -895,7 +893,7 @@ impl Service {
// Soft fail check before doing state res // Soft fail check before doing state res
let auth_events = services().rooms.state.get_auth_events( let auth_events = services().rooms.state.get_auth_events(
room_id, room_id,
&ruma_room_version, &room_version_rules.authorization,
&incoming_pdu.kind, &incoming_pdu.kind,
&incoming_pdu.sender, &incoming_pdu.sender,
incoming_pdu.state_key.as_deref(), incoming_pdu.state_key.as_deref(),
@ -903,7 +901,7 @@ impl Service {
)?; )?;
let auth_fail_against_current = state_res::event_auth::auth_check( let auth_fail_against_current = state_res::event_auth::auth_check(
&ruma_room_version, &room_version_rules.authorization,
&incoming_pdu, &incoming_pdu,
|k, s| auth_events.get(&(k.clone(), s.to_owned())), |k, s| auth_events.get(&(k.clone(), s.to_owned())),
) )
@ -979,7 +977,7 @@ impl Service {
} }
let new_room_state = self let new_room_state = self
.resolve_state(room_id, room_version_id, state_after) .resolve_state(room_id, &room_version_rules, state_after)
.await?; .await?;
// Set the new room state to the resolved state // Set the new room state to the resolved state
@ -1055,11 +1053,11 @@ impl Service {
Ok(pdu_id) Ok(pdu_id)
} }
#[tracing::instrument(skip(self, room_version_id, incoming_state))] #[tracing::instrument(skip(self, room_version_rules, incoming_state))]
async fn resolve_state( async fn resolve_state(
&self, &self,
room_id: &RoomId, room_id: &RoomId,
room_version_id: &RoomVersionId, room_version_rules: &RoomVersionRules,
incoming_state: HashMap<ShortStateKey, Arc<EventId>>, incoming_state: HashMap<ShortStateKey, Arc<EventId>>,
) -> Result<Arc<HashSet<CompressedStateEvent>>> { ) -> Result<Arc<HashSet<CompressedStateEvent>>> {
debug!("Loading current room state ids"); debug!("Loading current room state ids");
@ -1121,7 +1119,7 @@ impl Service {
let lock = services().globals.stateres_mutex.lock(); let lock = services().globals.stateres_mutex.lock();
let Ok(state) = state_res::resolve( let Ok(state) = state_res::resolve(
room_version_id, &room_version_rules.authorization,
&fork_states, &fork_states,
auth_chain_sets, auth_chain_sets,
fetch_event, fetch_event,
@ -1169,7 +1167,7 @@ impl Service {
origin: &'a ServerName, origin: &'a ServerName,
events: &'a [Arc<EventId>], events: &'a [Arc<EventId>],
room_id: &'a RoomId, room_id: &'a RoomId,
room_version_id: &'a RoomVersionId, room_version_rules: &'a RoomVersionRules,
pub_key_map: &'a RwLock<BTreeMap<String, SigningKeys>>, pub_key_map: &'a RwLock<BTreeMap<String, SigningKeys>>,
) -> BoxFuture<'a, Vec<(Arc<PduEvent>, Option<CanonicalJsonObject>)>> { ) -> BoxFuture<'a, Vec<(Arc<PduEvent>, Option<CanonicalJsonObject>)>> {
Box::pin(async move { Box::pin(async move {
@ -1271,7 +1269,7 @@ impl Service {
let Ok((calculated_event_id, value)) = let Ok((calculated_event_id, value)) =
pdu::gen_event_id_canonical_json( pdu::gen_event_id_canonical_json(
&res.pdu, &res.pdu,
room_version_id, room_version_rules,
) )
else { else {
back_off((*next_id).to_owned()).await; back_off((*next_id).to_owned()).await;
@ -1344,7 +1342,7 @@ impl Service {
origin, origin,
next_id, next_id,
room_id, room_id,
room_version_id, room_version_rules,
value.clone(), value.clone(),
true, true,
pub_key_map, pub_key_map,
@ -1377,7 +1375,7 @@ impl Service {
&self, &self,
origin: &ServerName, origin: &ServerName,
room_id: &RoomId, room_id: &RoomId,
room_version_id: &RoomVersionId, room_version_rules: &RoomVersionRules,
pub_key_map: &RwLock<BTreeMap<String, SigningKeys>>, pub_key_map: &RwLock<BTreeMap<String, SigningKeys>>,
initial_set: Vec<Arc<EventId>>, initial_set: Vec<Arc<EventId>>,
) -> Result<( ) -> Result<(
@ -1401,7 +1399,7 @@ impl Service {
origin, origin,
&[prev_event_id.clone()], &[prev_event_id.clone()],
room_id, room_id,
room_version_id, room_version_rules,
pub_key_map, pub_key_map,
) )
.await .await
@ -1534,7 +1532,7 @@ impl Service {
OwnedServerName, OwnedServerName,
BTreeMap<OwnedServerSigningKeyId, QueryCriteria>, BTreeMap<OwnedServerSigningKeyId, QueryCriteria>,
>, >,
room_version: &RoomVersionId, room_version_rules: &RoomVersionRules,
pub_key_map: &mut RwLockWriteGuard<'_, BTreeMap<String, SigningKeys>>, pub_key_map: &mut RwLockWriteGuard<'_, BTreeMap<String, SigningKeys>>,
) -> Result<()> { ) -> Result<()> {
let value: CanonicalJsonObject = serde_json::from_str(pdu.get()) let value: CanonicalJsonObject = serde_json::from_str(pdu.get())
@ -1545,7 +1543,7 @@ impl Service {
let event_id = format!( let event_id = format!(
"${}", "${}",
ruma::signatures::reference_hash(&value, room_version) ruma::signatures::reference_hash(&value, room_version_rules)
.expect("ruma can calculate reference hashes") .expect("ruma can calculate reference hashes")
); );
let event_id = <&EventId>::try_from(event_id.as_str()) let event_id = <&EventId>::try_from(event_id.as_str())
@ -1649,7 +1647,7 @@ impl Service {
pub(crate) async fn fetch_join_signing_keys( pub(crate) async fn fetch_join_signing_keys(
&self, &self,
event: &create_join_event::v2::Response, event: &create_join_event::v2::Response,
room_version: &RoomVersionId, room_version_rules: &RoomVersionRules,
pub_key_map: &RwLock<BTreeMap<String, SigningKeys>>, pub_key_map: &RwLock<BTreeMap<String, SigningKeys>>,
) -> Result<()> { ) -> Result<()> {
let mut servers: BTreeMap< let mut servers: BTreeMap<
@ -1672,7 +1670,7 @@ impl Service {
.get_server_keys_from_cache( .get_server_keys_from_cache(
pdu, pdu,
&mut servers, &mut servers,
room_version, room_version_rules,
&mut pkm, &mut pkm,
) )
.await .await

View file

@ -11,6 +11,7 @@ use ruma::{
AnyStrippedStateEvent, StateEventType, TimelineEventType, AnyStrippedStateEvent, StateEventType, TimelineEventType,
}, },
room::RoomType, room::RoomType,
room_version_rules::AuthorizationRules,
serde::Raw, serde::Raw,
state_res::{self, StateMap}, state_res::{self, StateMap},
EventId, OwnedEventId, OwnedRoomId, RoomId, RoomVersionId, UserId, EventId, OwnedEventId, OwnedRoomId, RoomId, RoomVersionId, UserId,
@ -430,11 +431,11 @@ impl Service {
} }
/// This fetches auth events from the current state. /// This fetches auth events from the current state.
#[tracing::instrument(skip(self, room_version))] #[tracing::instrument(skip(self, rules))]
pub(crate) fn get_auth_events( pub(crate) fn get_auth_events(
&self, &self,
room_id: &RoomId, room_id: &RoomId,
room_version: &state_res::RoomVersion, rules: &AuthorizationRules,
kind: &TimelineEventType, kind: &TimelineEventType,
sender: &UserId, sender: &UserId,
state_key: Option<&str>, state_key: Option<&str>,
@ -446,11 +447,7 @@ impl Service {
}; };
let auth_events = state_res::auth_types_for_event( let auth_events = state_res::auth_types_for_event(
kind, kind, sender, state_key, content, rules,
sender,
state_key,
content,
room_version,
) )
.expect("content is a valid JSON object"); .expect("content is a valid JSON object");

View file

@ -770,14 +770,13 @@ impl Service {
} }
})?; })?;
let ruma_room_version = state_res::RoomVersion::new(&room_version_id) let Some(room_version_rules) = room_version_id.rules() else {
.map_err(|_| { return Err(Error::UnsupportedRoomVersion(room_version_id));
Error::UnsupportedRoomVersion(room_version_id.clone()) };
})?;
let auth_events = services().rooms.state.get_auth_events( let auth_events = services().rooms.state.get_auth_events(
room_id, room_id,
&ruma_room_version, &room_version_rules.authorization,
&event_type, &event_type,
sender, sender,
state_key.as_deref(), state_key.as_deref(),
@ -845,9 +844,11 @@ impl Service {
signatures: None, signatures: None,
}; };
state_res::auth_check(&ruma_room_version, &pdu, |k, s| { state_res::auth_check(
auth_events.get(&(k.clone(), s.to_owned())) &room_version_rules.authorization,
}) &pdu,
|k, s| auth_events.get(&(k.clone(), s.to_owned())),
)
.map_err(|error| { .map_err(|error| {
error!(%error, "Auth check failed"); error!(%error, "Auth check failed");
Error::BadRequest(ErrorKind::InvalidParam, "Auth check failed.") Error::BadRequest(ErrorKind::InvalidParam, "Auth check failed.")
@ -870,7 +871,7 @@ impl Service {
services().globals.server_name().as_str(), services().globals.server_name().as_str(),
services().globals.keypair(), services().globals.keypair(),
&mut pdu_json, &mut pdu_json,
&room_version_id, &room_version_rules.redaction,
) { ) {
Ok(()) => {} Ok(()) => {}
Err(e) => { Err(e) => {
@ -890,7 +891,7 @@ impl Service {
// Generate event id // Generate event id
pdu.event_id = EventId::parse_arc(format!( pdu.event_id = EventId::parse_arc(format!(
"${}", "${}",
ruma::signatures::reference_hash(&pdu_json, &room_version_id) ruma::signatures::reference_hash(&pdu_json, &room_version_rules)
.expect("ruma can calculate reference hashes") .expect("ruma can calculate reference hashes")
)) ))
.expect("ruma's reference hashes are valid event ids"); .expect("ruma's reference hashes are valid event ids");
@ -1199,7 +1200,10 @@ impl Service {
.rooms .rooms
.state .state
.get_create_content::<ExtractVersion>(&pdu.room_id)?; .get_create_content::<ExtractVersion>(&pdu.room_id)?;
pdu.redact(&room_version_id, reason)?; let Some(room_version_rules) = room_version_id.rules() else {
return Err(Error::UnsupportedRoomVersion(room_version_id));
};
pdu.redact(&room_version_rules.redaction, reason)?;
self.replace_pdu( self.replace_pdu(
&pdu_id, &pdu_id,

View file

@ -5,12 +5,12 @@ use crate::Error;
/// Properties that we care about in grapevine that differ between supported /// Properties that we care about in grapevine that differ between supported
/// room versions. /// room versions.
/// ///
/// This is similar to [`ruma::state_res::RoomVersion`], except that it has /// This is similar to [`ruma::room_version_rules::RoomVersionRules`], except
/// properties that are relevant to us instead of only properties relevant to /// that it only has the properties that are relevant to us instead of all
/// ruma state resolution. /// properties relevant to ruma state resolution.
/// ///
/// When branching for different room versions, prefer constructing a /// When branching for different room versions, prefer constructing a
/// `RoomVersion` and branching on it's properties over branching based on the /// `RoomVersion` and branching on its properties over branching based on the
/// [`RoomVersionId`] directly. If there is a relevant property that is not /// [`RoomVersionId`] directly. If there is a relevant property that is not
/// already included in `RoomVersion`, add it. In particular, comparisons like /// already included in `RoomVersion`, add it. In particular, comparisons like
/// `room_version_id < RoomVersionId::V11` do not work, because room versions /// `room_version_id < RoomVersionId::V11` do not work, because room versions