Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion crates/cli/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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,
}),
})
}

Expand Down
15 changes: 15 additions & 0 deletions crates/config/src/sections/experimental.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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,
}
}
}
Expand All @@ -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,
}
4 changes: 3 additions & 1 deletion crates/data-model/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
Expand Down
10 changes: 10 additions & 0 deletions crates/data-model/src/site_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)]
Expand Down Expand Up @@ -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>,
}
1 change: 1 addition & 0 deletions crates/handlers/src/test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}

Expand Down
28 changes: 28 additions & 0 deletions docs/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
]
}
}
},
Expand Down Expand Up @@ -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
}
}
}
}
}