diff --git a/src/api/client/membership.rs b/src/api/client/membership.rs index c25c08d1..3adee631 100644 --- a/src/api/client/membership.rs +++ b/src/api/client/membership.rs @@ -780,14 +780,9 @@ async fn join_room_by_id_helper_remote( info!("send_join finished"); if join_authorized_via_users_server.is_some() { + use RoomVersionId::*; match &room_version_id { - RoomVersionId::V1 - | RoomVersionId::V2 - | RoomVersionId::V3 - | RoomVersionId::V4 - | RoomVersionId::V5 - | RoomVersionId::V6 - | RoomVersionId::V7 => { + V1 | V2 | V3 | V4 | V5 | V6 | V7 => { warn!( "Found `join_authorised_via_users_server` but room {} is version {}. Ignoring.", room_id, &room_version_id @@ -795,7 +790,7 @@ async fn join_room_by_id_helper_remote( }, // only room versions 8 and above using `join_authorized_via_users_server` (restricted joins) need to // validate and send signatures - RoomVersionId::V8 | RoomVersionId::V9 | RoomVersionId::V10 | RoomVersionId::V11 => { + V8 | V9 | V10 | V11 => { if let Some(signed_raw) = &send_join_response.room_state.event { info!( "There is a signed event. This room is probably using restricted joins. Adding signature to \ diff --git a/src/api/client/room.rs b/src/api/client/room.rs index ccdf4dc0..adf58b04 100644 --- a/src/api/client/room.rs +++ b/src/api/client/room.rs @@ -118,6 +118,8 @@ pub(crate) async fn create_room_route(body: Ruma) -> R let content = match &body.creation_content { Some(content) => { + use RoomVersionId::*; + let mut content = content .deserialize_as::() .map_err(|e| { @@ -125,16 +127,7 @@ pub(crate) async fn create_room_route(body: Ruma) -> R Error::bad_database("Failed to deserialise content as canonical JSON.") })?; match room_version { - RoomVersionId::V1 - | RoomVersionId::V2 - | RoomVersionId::V3 - | RoomVersionId::V4 - | RoomVersionId::V5 - | RoomVersionId::V6 - | RoomVersionId::V7 - | RoomVersionId::V8 - | RoomVersionId::V9 - | RoomVersionId::V10 => { + V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => { content.insert( "creator".into(), json!(&sender_user).try_into().map_err(|e| { @@ -143,7 +136,7 @@ pub(crate) async fn create_room_route(body: Ruma) -> R })?, ); }, - RoomVersionId::V11 => {}, // V11 removed the "creator" key + V11 => {}, // V11 removed the "creator" key _ => { warn!("Unexpected or unsupported room version {room_version}"); return Err(Error::BadRequest( @@ -152,7 +145,6 @@ pub(crate) async fn create_room_route(body: Ruma) -> R )); }, } - content.insert( "room_version".into(), json!(room_version.as_str()) @@ -162,18 +154,11 @@ pub(crate) async fn create_room_route(body: Ruma) -> R content }, None => { + use RoomVersionId::*; + let content = match room_version { - RoomVersionId::V1 - | RoomVersionId::V2 - | RoomVersionId::V3 - | RoomVersionId::V4 - | RoomVersionId::V5 - | RoomVersionId::V6 - | RoomVersionId::V7 - | RoomVersionId::V8 - | RoomVersionId::V9 - | RoomVersionId::V10 => RoomCreateEventContent::new_v1(sender_user.clone()), - RoomVersionId::V11 => RoomCreateEventContent::new_v11(), + V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => RoomCreateEventContent::new_v1(sender_user.clone()), + V11 => RoomCreateEventContent::new_v11(), _ => { warn!("Unexpected or unsupported room version {room_version}"); return Err(Error::BadRequest( @@ -623,36 +608,30 @@ pub(crate) async fn upgrade_room_route(body: Ruma) -> // Send a m.room.create event containing a predecessor field and the applicable // room_version - match body.new_version { - RoomVersionId::V1 - | RoomVersionId::V2 - | RoomVersionId::V3 - | RoomVersionId::V4 - | RoomVersionId::V5 - | RoomVersionId::V6 - | RoomVersionId::V7 - | RoomVersionId::V8 - | RoomVersionId::V9 - | RoomVersionId::V10 => { - create_event_content.insert( - "creator".into(), - json!(&sender_user).try_into().map_err(|e| { - info!("Error forming creation event: {e}"); - Error::BadRequest(ErrorKind::BadJson, "Error forming creation event") - })?, - ); - }, - RoomVersionId::V11 => { - // "creator" key no longer exists in V11 rooms - create_event_content.remove("creator"); - }, - _ => { - warn!("Unexpected or unsupported room version {}", body.new_version); - return Err(Error::BadRequest( - ErrorKind::BadJson, - "Unexpected or unsupported room version found", - )); - }, + { + use RoomVersionId::*; + match body.new_version { + V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => { + create_event_content.insert( + "creator".into(), + json!(&sender_user).try_into().map_err(|e| { + info!("Error forming creation event: {e}"); + Error::BadRequest(ErrorKind::BadJson, "Error forming creation event") + })?, + ); + }, + V11 => { + // "creator" key no longer exists in V11 rooms + create_event_content.remove("creator"); + }, + _ => { + warn!("Unexpected or unsupported room version {}", body.new_version); + return Err(Error::BadRequest( + ErrorKind::BadJson, + "Unexpected or unsupported room version found", + )); + }, + } } create_event_content.insert( diff --git a/src/api/server/make_join.rs b/src/api/server/make_join.rs index c909ea33..b5dadf7f 100644 --- a/src/api/server/make_join.rs +++ b/src/api/server/make_join.rs @@ -7,7 +7,7 @@ use ruma::{ }, StateEventType, TimelineEventType, }, - RoomId, RoomVersionId, UserId, + CanonicalJsonObject, RoomId, RoomVersionId, UserId, }; use serde_json::value::to_raw_value; use tracing::warn; @@ -144,27 +144,7 @@ pub(crate) async fn create_join_event_template_route( drop(state_lock); // room v3 and above removed the "event_id" field from remote PDU format - match room_version_id { - RoomVersionId::V1 | RoomVersionId::V2 => {}, - RoomVersionId::V3 - | RoomVersionId::V4 - | RoomVersionId::V5 - | RoomVersionId::V6 - | RoomVersionId::V7 - | RoomVersionId::V8 - | RoomVersionId::V9 - | RoomVersionId::V10 - | RoomVersionId::V11 => { - pdu_json.remove("event_id"); - }, - _ => { - warn!("Unexpected or unsupported room version {room_version_id}"); - return Err(Error::BadRequest( - ErrorKind::BadJson, - "Unexpected or unsupported room version found", - )); - }, - }; + maybe_strip_event_id(&mut pdu_json, &room_version_id)?; Ok(prepare_join_event::v1::Response { room_version: Some(room_version_id), @@ -179,6 +159,8 @@ pub(crate) async fn create_join_event_template_route( pub(crate) fn user_can_perform_restricted_join( user_id: &UserId, room_id: &RoomId, room_version_id: &RoomVersionId, ) -> Result { + use RoomVersionId::*; + let join_rules_event = services() .rooms @@ -198,16 +180,7 @@ pub(crate) fn user_can_perform_restricted_join( return Ok(false); }; - if matches!( - room_version_id, - RoomVersionId::V1 - | RoomVersionId::V2 - | RoomVersionId::V3 - | RoomVersionId::V4 - | RoomVersionId::V5 - | RoomVersionId::V6 - | RoomVersionId::V7 - ) { + if matches!(room_version_id, V1 | V2 | V3 | V4 | V5 | V6 | V7) { return Ok(false); } @@ -239,3 +212,23 @@ pub(crate) 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 => {}, + V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 | V11 => { + pdu_json.remove("event_id"); + }, + _ => { + warn!("Unexpected or unsupported room version {room_version_id}"); + return Err(Error::BadRequest( + ErrorKind::BadJson, + "Unexpected or unsupported room version found", + )); + }, + }; + + Ok(()) +} diff --git a/src/api/server/make_leave.rs b/src/api/server/make_leave.rs index eea3e4f8..63fc2b2e 100644 --- a/src/api/server/make_leave.rs +++ b/src/api/server/make_leave.rs @@ -1,14 +1,15 @@ +use conduit::{Error, Result}; use ruma::{ api::{client::error::ErrorKind, federation::membership::prepare_leave_event}, events::{ room::member::{MembershipState, RoomMemberEventContent}, TimelineEventType, }, - RoomVersionId, }; use serde_json::value::to_raw_value; -use crate::{service::pdu::PduBuilder, services, Error, Result, Ruma}; +use super::make_join::maybe_strip_event_id; +use crate::{service::pdu::PduBuilder, services, Ruma}; /// # `PUT /_matrix/federation/v1/make_leave/{roomId}/{eventId}` /// @@ -64,26 +65,7 @@ pub(crate) async fn create_leave_event_template_route( drop(state_lock); // room v3 and above removed the "event_id" field from remote PDU format - match room_version_id { - RoomVersionId::V1 | RoomVersionId::V2 => {}, - RoomVersionId::V3 - | RoomVersionId::V4 - | RoomVersionId::V5 - | RoomVersionId::V6 - | RoomVersionId::V7 - | RoomVersionId::V8 - | RoomVersionId::V9 - | RoomVersionId::V10 - | RoomVersionId::V11 => { - pdu_json.remove("event_id"); - }, - _ => { - return Err(Error::BadRequest( - ErrorKind::BadJson, - "Unexpected or unsupported room version found", - )); - }, - }; + maybe_strip_event_id(&mut pdu_json, &room_version_id)?; Ok(prepare_leave_event::v1::Response { room_version: Some(room_version_id), diff --git a/src/service/admin/create.rs b/src/service/admin/create.rs index 57df344a..fbb6a078 100644 --- a/src/service/admin/create.rs +++ b/src/service/admin/create.rs @@ -41,25 +41,20 @@ pub async fn create_admin_room() -> Result<()> { services().users.create(server_user, None)?; let room_version = services().globals.default_room_version(); - let mut content = match room_version { - RoomVersionId::V1 - | RoomVersionId::V2 - | RoomVersionId::V3 - | RoomVersionId::V4 - | RoomVersionId::V5 - | RoomVersionId::V6 - | RoomVersionId::V7 - | RoomVersionId::V8 - | RoomVersionId::V9 - | RoomVersionId::V10 => RoomCreateEventContent::new_v1(server_user.clone()), - RoomVersionId::V11 => RoomCreateEventContent::new_v11(), - _ => { - warn!("Unexpected or unsupported room version {}", room_version); - return Err(Error::BadRequest( - ErrorKind::BadJson, - "Unexpected or unsupported room version found", - )); - }, + + let mut content = { + use RoomVersionId::*; + match room_version { + V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => RoomCreateEventContent::new_v1(server_user.clone()), + V11 => RoomCreateEventContent::new_v11(), + _ => { + warn!("Unexpected or unsupported room version {}", room_version); + return Err(Error::BadRequest( + ErrorKind::BadJson, + "Unexpected or unsupported room version found", + )); + }, + } }; content.federate = true; diff --git a/src/service/rooms/event_handler/mod.rs b/src/service/rooms/event_handler/mod.rs index 9490a404..33c00643 100644 --- a/src/service/rooms/event_handler/mod.rs +++ b/src/service/rooms/event_handler/mod.rs @@ -551,49 +551,44 @@ impl Service { // Soft fail check before doing state res debug!("Performing soft-fail check"); - let soft_fail = !state_res::event_auth::auth_check(&room_version, &incoming_pdu, None::, |k, s| { - auth_events.get(&(k.clone(), s.to_owned())) - }) - .map_err(|_e| Error::BadRequest(ErrorKind::forbidden(), "Auth check failed."))? - || incoming_pdu.kind == TimelineEventType::RoomRedaction - && match room_version_id { - RoomVersionId::V1 - | RoomVersionId::V2 - | RoomVersionId::V3 - | RoomVersionId::V4 - | RoomVersionId::V5 - | RoomVersionId::V6 - | RoomVersionId::V7 - | RoomVersionId::V8 - | RoomVersionId::V9 - | RoomVersionId::V10 => { - if let Some(redact_id) = &incoming_pdu.redacts { - !services().rooms.state_accessor.user_can_redact( - redact_id, - &incoming_pdu.sender, - &incoming_pdu.room_id, - true, - )? - } else { - false - } - }, - _ => { - let content = serde_json::from_str::(incoming_pdu.content.get()) - .map_err(|_| Error::bad_database("Invalid content in redaction pdu."))?; + let soft_fail = { + use RoomVersionId::*; - if let Some(redact_id) = &content.redacts { - !services().rooms.state_accessor.user_can_redact( - redact_id, - &incoming_pdu.sender, - &incoming_pdu.room_id, - true, - )? - } else { - false - } - }, - }; + !state_res::event_auth::auth_check(&room_version, &incoming_pdu, None::, |k, s| { + auth_events.get(&(k.clone(), s.to_owned())) + }) + .map_err(|_e| Error::BadRequest(ErrorKind::forbidden(), "Auth check failed."))? + || incoming_pdu.kind == TimelineEventType::RoomRedaction + && match room_version_id { + V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => { + if let Some(redact_id) = &incoming_pdu.redacts { + !services().rooms.state_accessor.user_can_redact( + redact_id, + &incoming_pdu.sender, + &incoming_pdu.room_id, + true, + )? + } else { + false + } + }, + _ => { + let content = serde_json::from_str::(incoming_pdu.content.get()) + .map_err(|_| Error::bad_database("Invalid content in redaction pdu."))?; + + if let Some(redact_id) = &content.redacts { + !services().rooms.state_accessor.user_can_redact( + redact_id, + &incoming_pdu.sender, + &incoming_pdu.room_id, + true, + )? + } else { + false + } + }, + } + }; // 13. Use state resolution to find new room state diff --git a/src/service/rooms/timeline/mod.rs b/src/service/rooms/timeline/mod.rs index e255e978..0bc5ade1 100644 --- a/src/service/rooms/timeline/mod.rs +++ b/src/service/rooms/timeline/mod.rs @@ -389,18 +389,11 @@ impl Service { match pdu.kind { TimelineEventType::RoomRedaction => { + use RoomVersionId::*; + let room_version_id = services().rooms.state.get_room_version(&pdu.room_id)?; match room_version_id { - RoomVersionId::V1 - | RoomVersionId::V2 - | RoomVersionId::V3 - | RoomVersionId::V4 - | RoomVersionId::V5 - | RoomVersionId::V6 - | RoomVersionId::V7 - | RoomVersionId::V8 - | RoomVersionId::V9 - | RoomVersionId::V10 => { + V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => { if let Some(redact_id) = &pdu.redacts { if services().rooms.state_accessor.user_can_redact( redact_id, @@ -412,7 +405,7 @@ impl Service { } } }, - RoomVersionId::V11 => { + V11 => { let content = serde_json::from_str::(pdu.content.get()).map_err(|e| { warn!("Invalid content in redaction pdu: {e}"); @@ -868,17 +861,9 @@ impl Service { // If redaction event is not authorized, do not append it to the timeline if pdu.kind == TimelineEventType::RoomRedaction { + use RoomVersionId::*; match services().rooms.state.get_room_version(&pdu.room_id)? { - RoomVersionId::V1 - | RoomVersionId::V2 - | RoomVersionId::V3 - | RoomVersionId::V4 - | RoomVersionId::V5 - | RoomVersionId::V6 - | RoomVersionId::V7 - | RoomVersionId::V8 - | RoomVersionId::V9 - | RoomVersionId::V10 => { + V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 | V10 => { if let Some(redact_id) = &pdu.redacts { if !services().rooms.state_accessor.user_can_redact( redact_id,