diff --git a/Cargo.lock b/Cargo.lock index f78a22e6d..10aa06460 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3223,6 +3223,7 @@ dependencies = [ "base64ct", "chrono", "crc", + "mas-config", "mas-iana", "mas-jose", "oauth2-types", diff --git a/crates/cli/src/util.rs b/crates/cli/src/util.rs index 454276150..caa76664d 100644 --- a/crates/cli/src/util.rs +++ b/crates/cli/src/util.rs @@ -156,6 +156,7 @@ pub async fn policy_factory_from_config( .map(|c| SessionLimitConfig { soft_limit: c.soft_limit, hard_limit: c.hard_limit, + hard_limit_eviction: c.hard_limit_eviction, }); let data = mas_policy::Data::new(matrix_config.homeserver.clone(), session_limit_config) @@ -242,6 +243,7 @@ pub fn site_config_from_config( .map(|c| SessionLimitConfig { soft_limit: c.soft_limit, hard_limit: c.hard_limit, + hard_limit_eviction: c.hard_limit_eviction, }), }) } diff --git a/crates/config/src/sections/experimental.rs b/crates/config/src/sections/experimental.rs index c55cd8823..0f99d9e9a 100644 --- a/crates/config/src/sections/experimental.rs +++ b/crates/config/src/sections/experimental.rs @@ -141,14 +141,18 @@ pub struct SessionLimitConfig { /// /// This is not enforced in uninteractive contexts (like the legacy compability /// login API). See [`hard_limit`] for enforcement on that side. + /// + /// [`hard_limit`]: Self::hard_limit pub soft_limit: NonZeroU64, /// Upon login, when `hard_limit_eviction: false`, will refuse the new login (policy /// violation error), otherwise, see [`hard_limit_eviction`]. /// /// The hard limit is enforced in all contexts (interactive/uninteractive). + /// + /// [`hard_limit_eviction`]: Self::hard_limit_eviction pub hard_limit: NonZeroU64, /// Whether we should automatically choose the least recently used devices to remove - /// when the [`hard_limit`] is reached; in order to allow the new login to continue. + /// when the [`Self::hard_limit`] is reached; in order to allow the new login to continue. /// /// Disabled by default /// @@ -156,10 +160,10 @@ pub struct SessionLimitConfig { /// encrypted history on the device will be lost and can only be recovered if you /// have another verified active device or have a recovery key setup. /// - /// When using [`hard_limit_eviction`], the [`hard_limit`] must be at-least 2 to - /// avoid catastropically losing encrypted history and digital identity in - /// pathological cases. Keep in mind this is a bare minimum restriction and you can - /// still run into trouble. + /// When using [`hard_limit_eviction`], the [`hard_limit`] must be + /// at-least 2 to avoid catastropically losing encrypted history and digital + /// identity in pathological cases. Keep in mind this is a bare minimum restriction + /// and you can still run into trouble. /// /// This is most applicable in scenarios where your homeserver has many legacy /// bots/scripts that login over and over (which ideally should be using [personal @@ -167,6 +171,9 @@ pub struct SessionLimitConfig { /// tokens](https://github.com/element-hq/matrix-authentication-service/issues/4492)) /// and you want to avoid breaking their operation while maintaining some level of /// sanity with the number of devices that people can have. + /// + /// [`hard_limit`]: Self::hard_limit + /// [`hard_limit_eviction`]: Self::hard_limit_eviction #[serde(default = "default_false")] pub hard_limit_eviction: bool, } @@ -186,7 +193,7 @@ impl ConfigurationSection for SessionLimitConfig { error }; - // See [`hard_limit_eviction`] docstring + // See [`SessionLimitConfig::hard_limit_eviction`] docstring if self.hard_limit_eviction && self.hard_limit.get() < 2 { return Err(error_on_field(figment::error::Error::from( "Session `hard_limit` must be at-least 2 when automatic `hard_limit_eviction` is set.", diff --git a/crates/config/src/sections/mod.rs b/crates/config/src/sections/mod.rs index eb4ff2a44..ae805c230 100644 --- a/crates/config/src/sections/mod.rs +++ b/crates/config/src/sections/mod.rs @@ -34,7 +34,7 @@ pub use self::{ clients::{ClientAuthMethodConfig, ClientConfig, ClientsConfig}, database::{DatabaseConfig, PgSslMode}, email::{EmailConfig, EmailSmtpMode, EmailTransportKind}, - experimental::ExperimentalConfig, + experimental::{ExperimentalConfig, SessionLimitConfig as ExperimentalSessionLimitConfig}, http::{ BindConfig as HttpBindConfig, HttpConfig, ListenerConfig as HttpListenerConfig, Resource as HttpResource, TlsConfig as HttpTlsConfig, UnixOrTcp, diff --git a/crates/data-model/Cargo.toml b/crates/data-model/Cargo.toml index 7e9be8282..a1ff799bd 100644 --- a/crates/data-model/Cargo.toml +++ b/crates/data-model/Cargo.toml @@ -31,6 +31,7 @@ regex.workspace = true woothee.workspace = true mas-iana.workspace = true +# Added for rustdoc links +mas-config.workspace = true mas-jose.workspace = true oauth2-types.workspace = true - diff --git a/crates/data-model/src/site_config.rs b/crates/data-model/src/site_config.rs index bb92dc3e4..c27cbeb05 100644 --- a/crates/data-model/src/site_config.rs +++ b/crates/data-model/src/site_config.rs @@ -39,10 +39,12 @@ pub struct SessionExpirationConfig { pub compat_session_inactivity_ttl: Option, } +/// See [`mas_config::sections::ExperimentalSessionLimitConfig`] #[derive(Serialize, Debug, Clone)] pub struct SessionLimitConfig { pub soft_limit: NonZeroU64, pub hard_limit: NonZeroU64, + pub hard_limit_eviction: bool, } /// Random site configuration we want accessible in various places. diff --git a/docs/config.schema.json b/docs/config.schema.json index 34dc725f9..cfd93717a 100644 --- a/docs/config.schema.json +++ b/docs/config.schema.json @@ -2898,19 +2898,19 @@ "type": "object", "properties": { "soft_limit": { - "description": "Upon login in interactive contexts, if the soft limit is reached, it will\n display a policy violation screen (web UI) to remove sessions before creating\n the new session.\n\n This is not enforced in uninteractive contexts (like the legacy compability\n login API). See [`hard_limit`] for enforcement on that side.", + "description": "Upon login in interactive contexts, if the soft limit is reached, it will\n display a policy violation screen (web UI) to remove sessions before creating\n the new session.\n\n This is not enforced in uninteractive contexts (like the legacy compability\n login API). See [`hard_limit`] for enforcement on that side.\n\n [`hard_limit`]: Self::hard_limit", "type": "integer", "format": "uint64", "minimum": 1 }, "hard_limit": { - "description": "Upon login, when `hard_limit_eviction: false`, will refuse the new login (policy\n violation error), otherwise, see [`hard_limit_eviction`].\n\n The hard limit is enforced in all contexts (interactive/uninteractive).", + "description": "Upon login, when `hard_limit_eviction: false`, will refuse the new login (policy\n violation error), otherwise, see [`hard_limit_eviction`].\n\n The hard limit is enforced in all contexts (interactive/uninteractive).\n\n [`hard_limit_eviction`]: Self::hard_limit_eviction", "type": "integer", "format": "uint64", "minimum": 1 }, "hard_limit_eviction": { - "description": "Whether we should automatically choose the least recently used devices to remove\n when the [`hard_limit`] is reached; in order to allow the new login to continue.\n\n Disabled by default\n\n WARNING: Removing sessions is a potentially damaging operation. Any end-to-end\n encrypted history on the device will be lost and can only be recovered if you\n have another verified active device or have a recovery key setup.\n\n When using [`hard_limit_eviction`], the [`hard_limit`] must be at-least 2 to\n avoid catastropically losing encrypted history and digital identity in\n pathological cases. Keep in mind this is a bare minimum restriction and you can\n still run into trouble.\n\n This is most applicable in scenarios where your homeserver has many legacy\n bots/scripts that login over and over (which ideally should be using [personal\n access\n tokens](https://github.com/element-hq/matrix-authentication-service/issues/4492))\n and you want to avoid breaking their operation while maintaining some level of\n sanity with the number of devices that people can have.", + "description": "Whether we should automatically choose the least recently used devices to remove\n when the [`Self::hard_limit`] is reached; in order to allow the new login to continue.\n\n Disabled by default\n\n WARNING: Removing sessions is a potentially damaging operation. Any end-to-end\n encrypted history on the device will be lost and can only be recovered if you\n have another verified active device or have a recovery key setup.\n\n When using [`hard_limit_eviction`], the [`hard_limit`] must be\n at-least 2 to avoid catastropically losing encrypted history and digital\n identity in pathological cases. Keep in mind this is a bare minimum restriction\n and you can still run into trouble.\n\n This is most applicable in scenarios where your homeserver has many legacy\n bots/scripts that login over and over (which ideally should be using [personal\n access\n tokens](https://github.com/element-hq/matrix-authentication-service/issues/4492))\n and you want to avoid breaking their operation while maintaining some level of\n sanity with the number of devices that people can have.\n\n [`hard_limit`]: Self::hard_limit\n [`hard_limit_eviction`]: Self::hard_limit_eviction", "type": "boolean", "default": false }