diff --git a/src/api/client/capabilities.rs b/src/api/client/capabilities.rs index 5cae8a1a..b050f1de 100644 --- a/src/api/client/capabilities.rs +++ b/src/api/client/capabilities.rs @@ -12,7 +12,7 @@ use ruma::{ }, }; use serde_json::json; -use tuwunel_core::{Result, Server}; +use tuwunel_core::Result; use crate::Ruma; @@ -24,8 +24,10 @@ pub(crate) async fn get_capabilities_route( State(services): State, _body: Ruma, ) -> Result { - let available: BTreeMap = - Server::available_room_versions().collect(); + let available: BTreeMap = services + .config + .supported_room_versions() + .collect(); let mut capabilities = Capabilities::default(); capabilities.room_versions = RoomVersionsCapability { diff --git a/src/api/client/room/create.rs b/src/api/client/room/create.rs index 67fd52ec..a8c87443 100644 --- a/src/api/client/room/create.rs +++ b/src/api/client/room/create.rs @@ -82,7 +82,7 @@ pub(crate) async fn create_room_route( .as_ref() .map_or(Ok(&services.server.config.default_room_version), |version| { services - .server + .config .supported_room_version(version) .then_ok_or_else(version, || { err!(Request(UnsupportedRoomVersion( diff --git a/src/api/client/room/upgrade.rs b/src/api/client/room/upgrade.rs index 47686828..8d28128c 100644 --- a/src/api/client/room/upgrade.rs +++ b/src/api/client/room/upgrade.rs @@ -78,7 +78,7 @@ pub(crate) async fn upgrade_room_route( let version_rules = room_version::rules(new_version)?; if !services - .server + .config .supported_room_version(new_version) { return Err!(Request(UnsupportedRoomVersion( diff --git a/src/api/server/invite.rs b/src/api/server/invite.rs index b98ae393..cc26f146 100644 --- a/src/api/server/invite.rs +++ b/src/api/server/invite.rs @@ -41,7 +41,7 @@ pub(crate) async fn create_invite_route( .await?; if !services - .server + .config .supported_room_version(&body.room_version) { return Err(Error::BadRequest( diff --git a/src/core/config/check.rs b/src/core/config/check.rs index 13f59500..dd268989 100644 --- a/src/core/config/check.rs +++ b/src/core/config/check.rs @@ -4,7 +4,7 @@ use either::Either; use itertools::Itertools; use super::{DEPRECATED_KEYS, IdentityProvider}; -use crate::{Config, Err, Result, Server, debug, debug_info, error, warn}; +use crate::{Config, Err, Result, debug, debug_info, error, warn}; /// Performs check() with additional checks specific to reloading old config /// with new config. @@ -294,9 +294,7 @@ pub fn check(config: &Config) -> Result { )); } - if !Server::available_room_versions() - .any(|(version, _)| version == config.default_room_version) - { + if !config.supported_room_version(&config.default_room_version) { return Err!(Config( "default_room_version", "Room version {:?} is not available", diff --git a/src/core/config/mod.rs b/src/core/config/mod.rs index 3c080377..185edfca 100644 --- a/src/core/config/mod.rs +++ b/src/core/config/mod.rs @@ -1,6 +1,7 @@ pub mod check; pub mod manager; pub mod proxy; +pub mod room_version; use std::{ collections::{BTreeMap, BTreeSet}, diff --git a/src/core/config/room_version.rs b/src/core/config/room_version.rs new file mode 100644 index 00000000..576548c9 --- /dev/null +++ b/src/core/config/room_version.rs @@ -0,0 +1,56 @@ +use ruma::{RoomVersionId, api::client::discovery::get_capabilities::v3::RoomVersionStability}; + +use crate::Config; + +/// Partially supported non-compliant room versions +pub const UNSTABLE_ROOM_VERSIONS: &[RoomVersionId] = + &[RoomVersionId::V2, RoomVersionId::V3, RoomVersionId::V4, RoomVersionId::V5]; + +/// Supported and stable room versions +pub const STABLE_ROOM_VERSIONS: &[RoomVersionId] = &[ + RoomVersionId::V6, + RoomVersionId::V7, + RoomVersionId::V8, + RoomVersionId::V9, + RoomVersionId::V10, + RoomVersionId::V11, + RoomVersionId::V12, +]; + +/// Experimental and prototype room versions under development. +pub const EXPERIMENTAL_ROOM_VERSIONS: &[RoomVersionId] = &[]; + +impl Config { + #[inline] + #[must_use] + pub fn supported_room_version(&self, version: &RoomVersionId) -> bool { + self.supported_room_versions() + .any(|(supported_version, _)| &supported_version == version) + } + + #[inline] + pub fn supported_room_versions( + &self, + ) -> impl Iterator + '_ { + let stable_room_versions = STABLE_ROOM_VERSIONS + .iter() + .cloned() + .map(|version| (version, RoomVersionStability::Stable)); + + let unstable_room_versions = UNSTABLE_ROOM_VERSIONS + .iter() + .filter(|_| self.allow_unstable_room_versions) + .cloned() + .map(|version| (version, RoomVersionStability::Unstable)); + + let experimental_room_versions = EXPERIMENTAL_ROOM_VERSIONS + .iter() + .filter(|_| self.allow_experimental_room_versions) + .cloned() + .map(|version| (version, RoomVersionStability::Unstable)); + + stable_room_versions + .chain(unstable_room_versions) + .chain(experimental_room_versions) + } +} diff --git a/src/core/info/mod.rs b/src/core/info/mod.rs index 00a4484e..1602d8ab 100644 --- a/src/core/info/mod.rs +++ b/src/core/info/mod.rs @@ -2,7 +2,6 @@ //! etc information which can be queried by admins or used by developers. pub mod cargo; -pub mod room_version; pub mod rustc; pub mod version; diff --git a/src/core/info/room_version.rs b/src/core/info/room_version.rs deleted file mode 100644 index a05a03fb..00000000 --- a/src/core/info/room_version.rs +++ /dev/null @@ -1,72 +0,0 @@ -//! Room version support - -use std::iter::once; - -use ruma::{RoomVersionId, api::client::discovery::get_capabilities::v3::RoomVersionStability}; - -use crate::{at, is_equal_to}; - -/// Partially supported non-compliant room versions -pub const UNSTABLE_ROOM_VERSIONS: &[RoomVersionId] = - &[RoomVersionId::V2, RoomVersionId::V3, RoomVersionId::V4, RoomVersionId::V5]; - -/// Supported and stable room versions -pub const STABLE_ROOM_VERSIONS: &[RoomVersionId] = &[ - RoomVersionId::V6, - RoomVersionId::V7, - RoomVersionId::V8, - RoomVersionId::V9, - RoomVersionId::V10, - RoomVersionId::V11, - RoomVersionId::V12, -]; - -/// Experimental and prototype room versions under development. -pub const EXPERIMENTAL_ROOM_VERSIONS: &[RoomVersionId] = &[]; - -type RoomVersion = (RoomVersionId, RoomVersionStability); - -impl crate::Server { - #[inline] - pub fn supported_room_version(&self, version: &RoomVersionId) -> bool { - self.supported_room_versions() - .any(is_equal_to!(*version)) - } - - #[inline] - pub fn supported_room_versions(&self) -> impl Iterator + '_ { - let experimental_room_versions = EXPERIMENTAL_ROOM_VERSIONS - .iter() - .cloned() - .zip(once(RoomVersionStability::Unstable).cycle()) - .filter(|_| self.config.allow_experimental_room_versions); - - Self::available_room_versions() - .filter(|(_, stability)| self.supported_stability(stability)) - .chain(experimental_room_versions) - .map(at!(0)) - } - - #[inline] - pub fn available_room_versions() -> impl Iterator { - available_room_versions() - } - - #[inline] - fn supported_stability(&self, stability: &RoomVersionStability) -> bool { - self.config.allow_unstable_room_versions || *stability == RoomVersionStability::Stable - } -} - -pub fn available_room_versions() -> impl Iterator { - let unstable_room_versions = UNSTABLE_ROOM_VERSIONS - .iter() - .cloned() - .zip(once(RoomVersionStability::Unstable).cycle()); - - STABLE_ROOM_VERSIONS - .iter() - .cloned() - .zip(once(RoomVersionStability::Stable).cycle()) - .chain(unstable_room_versions) -} diff --git a/src/service/membership/join.rs b/src/service/membership/join.rs index bac3eaf0..f1c70b68 100644 --- a/src/service/membership/join.rs +++ b/src/service/membership/join.rs @@ -27,7 +27,7 @@ use ruma::{ }; use serde_json::value::RawValue as RawJsonValue; use tuwunel_core::{ - Err, Result, debug, debug_error, debug_info, debug_warn, err, error, implement, info, + Err, Result, at, debug, debug_error, debug_info, debug_warn, err, error, implement, info, matrix::{event::gen_event_id_canonical_json, room_version}, pdu::{PduBuilder, format::from_incoming_federation}, state_res, trace, @@ -155,7 +155,7 @@ pub async fn join_remote( if !self .services - .server + .config .supported_room_version(&room_version_id) { return Err!(BadServerResponse( @@ -619,7 +619,7 @@ pub async fn join_local( if !self .services - .server + .config .supported_room_version(&room_version_id) { return Err!(BadServerResponse( @@ -797,8 +797,9 @@ async fn make_join_request( user_id: sender_user.to_owned(), ver: self .services - .server + .config .supported_room_versions() + .map(at!(0)) .collect(), }) .await; diff --git a/src/service/membership/knock.rs b/src/service/membership/knock.rs index f9aae856..0d76306f 100644 --- a/src/service/membership/knock.rs +++ b/src/service/membership/knock.rs @@ -12,8 +12,8 @@ use ruma::{ }, }; use tuwunel_core::{ - Err, Event, PduCount, Result, debug, debug_info, debug_warn, err, extract_variant, implement, - info, + Err, Event, PduCount, Result, at, debug, debug_info, debug_warn, err, extract_variant, + implement, info, matrix::event::gen_event_id, pdu::{PduBuilder, PduEvent}, trace, utils, warn, @@ -195,7 +195,7 @@ async fn knock_room_helper_local( if !self .services - .server + .config .supported_room_version(&room_version_id) { return Err!(BadServerResponse( @@ -370,7 +370,7 @@ async fn knock_room_helper_remote( if !self .services - .server + .config .supported_room_version(&room_version_id) { return Err!(BadServerResponse( @@ -644,8 +644,9 @@ async fn make_knock_request( user_id: sender_user.to_owned(), ver: self .services - .server + .config .supported_room_versions() + .map(at!(0)) .collect(), }) .await; diff --git a/src/service/membership/leave.rs b/src/service/membership/leave.rs index 67a84e43..41ae305c 100644 --- a/src/service/membership/leave.rs +++ b/src/service/membership/leave.rs @@ -288,7 +288,7 @@ async fn remote_leave( if !self .services - .server + .config .supported_room_version(&room_version_id) { return Err!(BadServerResponse(warn!(