Add configuration for session limiting

This commit is contained in:
Olivier 'reivilibre
2025-10-30 16:30:33 +00:00
parent c2ea8f7fa1
commit dc535d7451
6 changed files with 65 additions and 2 deletions

View File

@@ -13,7 +13,7 @@ use mas_config::{
PolicyConfig, TemplatesConfig,
};
use mas_context::LogContext;
use mas_data_model::{SessionExpirationConfig, SiteConfig};
use mas_data_model::{SessionExpirationConfig, SessionLimitConfig, SiteConfig};
use mas_email::{MailTransport, Mailer};
use mas_handlers::passwords::PasswordManager;
use mas_matrix::{HomeserverConnection, ReadOnlyHomeserverConnection};
@@ -225,6 +225,13 @@ pub fn site_config_from_config(
session_expiration,
login_with_email_allowed: account_config.login_with_email_allowed,
plan_management_iframe_uri: experimental_config.plan_management_iframe_uri.clone(),
session_limit: experimental_config
.session_limit
.as_ref()
.map(|c| SessionLimitConfig {
soft_limit: c.soft_limit,
hard_limit: c.hard_limit,
}),
})
}

View File

@@ -81,6 +81,13 @@ pub struct ExperimentalConfig {
/// validation.
#[serde(skip_serializing_if = "Option::is_none")]
pub plan_management_iframe_uri: Option<String>,
/// Experimental feature to limit the number of application sessions per
/// user.
///
/// Disabled by default.
#[serde(skip_serializing_if = "Option::is_none")]
pub session_limit: Option<SessionLimitConfig>,
}
impl Default for ExperimentalConfig {
@@ -90,6 +97,7 @@ impl Default for ExperimentalConfig {
compat_token_ttl: default_token_ttl(),
inactive_session_expiration: None,
plan_management_iframe_uri: None,
session_limit: None,
}
}
}
@@ -106,3 +114,10 @@ impl ExperimentalConfig {
impl ConfigurationSection for ExperimentalConfig {
const PATH: Option<&'static str> = Some("experimental");
}
/// Configuration options for the inactive session expiration feature
#[derive(Clone, Debug, Deserialize, JsonSchema, Serialize)]
pub struct SessionLimitConfig {
pub soft_limit: u64,
pub hard_limit: u64,
}

View File

@@ -39,7 +39,9 @@ pub use self::{
DeviceCodeGrantState, InvalidRedirectUriError, JwksOrJwksUri, Pkce, Session, SessionState,
},
policy_data::PolicyData,
site_config::{CaptchaConfig, CaptchaService, SessionExpirationConfig, SiteConfig},
site_config::{
CaptchaConfig, CaptchaService, SessionExpirationConfig, SessionLimitConfig, SiteConfig,
},
tokens::{
AccessToken, AccessTokenState, RefreshToken, RefreshTokenState, TokenFormatError, TokenType,
},

View File

@@ -5,6 +5,7 @@
// Please see LICENSE files in the repository root for full details.
use chrono::Duration;
use serde::Serialize;
use url::Url;
/// Which Captcha service is being used
@@ -36,6 +37,12 @@ pub struct SessionExpirationConfig {
pub compat_session_inactivity_ttl: Option<Duration>,
}
#[derive(Serialize, Debug, Clone)]
pub struct SessionLimitConfig {
pub soft_limit: u64,
pub hard_limit: u64,
}
/// Random site configuration we want accessible in various places.
#[allow(clippy::struct_excessive_bools)]
#[derive(Debug, Clone)]
@@ -99,4 +106,7 @@ pub struct SiteConfig {
/// The iframe URL to show in the plan tab of the UI
pub plan_management_iframe_uri: Option<String>,
/// Limits on the number of application sessions that each user can have
pub session_limit: Option<SessionLimitConfig>,
}

View File

@@ -148,6 +148,7 @@ pub fn test_site_config() -> SiteConfig {
session_expiration: None,
login_with_email_allowed: true,
plan_management_iframe_uri: None,
session_limit: None,
}
}

View File

@@ -2659,6 +2659,14 @@
"plan_management_iframe_uri": {
"description": "Experimental feature to show a plan management tab and iframe. This value is passed through \"as is\" to the client without any validation.",
"type": "string"
},
"session_limit": {
"description": "Experimental feature to limit the number of application sessions per user.\n\nDisabled by default.",
"allOf": [
{
"$ref": "#/definitions/SessionLimitConfig"
}
]
}
}
},
@@ -2692,6 +2700,26 @@
"type": "boolean"
}
}
},
"SessionLimitConfig": {
"description": "Configuration options for the inactive session expiration feature",
"type": "object",
"required": [
"hard_limit",
"soft_limit"
],
"properties": {
"soft_limit": {
"type": "integer",
"format": "uint64",
"minimum": 0.0
},
"hard_limit": {
"type": "integer",
"format": "uint64",
"minimum": 0.0
}
}
}
}
}