use super::defaults::{
default_client_auth_mode, default_cors_origins, default_max_connections_per_ip,
default_max_message_size, default_require_auth, default_token_binding_subprotocol,
};
use crate::security::token_binding::TokenBindingScheme;
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct SecurityConfig {
#[serde(default = "default_cors_origins")]
pub cors_origins: String,
#[serde(default = "default_require_auth")]
pub require_websocket_auth: bool,
#[serde(default = "default_require_auth")]
pub require_metrics_auth: bool,
#[serde(default)]
pub metrics_auth_token: Option<String>,
#[serde(default = "default_max_message_size")]
pub max_message_size: usize,
#[serde(default = "default_max_connections_per_ip")]
pub max_connections_per_ip: usize,
#[serde(default)]
pub transport: TransportSecurityConfig,
#[serde(default)]
pub authorized_apps: Vec<AppAuthEntry>,
}
impl Default for SecurityConfig {
fn default() -> Self {
Self {
cors_origins: default_cors_origins(),
require_websocket_auth: default_require_auth(),
require_metrics_auth: default_require_auth(),
metrics_auth_token: None,
max_message_size: default_max_message_size(),
max_connections_per_ip: default_max_connections_per_ip(),
transport: TransportSecurityConfig::default(),
authorized_apps: Vec::new(),
}
}
}
#[derive(Debug, Deserialize, Serialize, Clone, Default)]
pub struct TransportSecurityConfig {
#[serde(default)]
pub tls: TlsServerConfig,
#[serde(default)]
pub token_binding: TokenBindingConfig,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct TlsServerConfig {
#[serde(default)]
pub enabled: bool,
#[serde(default)]
pub certificate_path: Option<String>,
#[serde(default)]
pub private_key_path: Option<String>,
#[serde(default)]
pub client_ca_cert_path: Option<String>,
#[serde(default = "default_client_auth_mode")]
pub client_auth: ClientAuthMode,
}
impl Default for TlsServerConfig {
fn default() -> Self {
Self {
enabled: false,
certificate_path: None,
private_key_path: None,
client_ca_cert_path: None,
client_auth: default_client_auth_mode(),
}
}
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct TokenBindingConfig {
#[serde(default)]
pub enabled: bool,
#[serde(default)]
pub required: bool,
#[serde(default)]
pub require_client_fingerprint: bool,
#[serde(default = "default_token_binding_subprotocol")]
pub subprotocol: String,
#[serde(default)]
pub scheme: TokenBindingScheme,
}
impl Default for TokenBindingConfig {
fn default() -> Self {
Self {
enabled: false,
required: false,
require_client_fingerprint: false,
subprotocol: default_token_binding_subprotocol(),
scheme: TokenBindingScheme::SecWebsocketKeySha256,
}
}
}
#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq, Eq, Default)]
#[serde(rename_all = "lowercase")]
pub enum ClientAuthMode {
#[default]
None,
Optional,
Require,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct AppAuthEntry {
pub app_id: String,
pub app_secret: String,
pub app_name: String,
#[serde(default)]
pub max_rooms: Option<u32>,
#[serde(default)]
pub max_players_per_room: Option<u8>,
#[serde(default)]
pub rate_limit_per_minute: Option<u32>,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct AuthMaintenanceConfig {
#[serde(default = "super::defaults::default_rate_limit_cache_cleanup_interval_secs")]
pub rate_limit_cache_cleanup_interval_secs: u64,
#[serde(default = "super::defaults::default_rate_limit_cache_retention_secs")]
pub rate_limit_cache_retention_secs: u64,
#[serde(default = "super::defaults::default_rate_limit_cache_alert_rows")]
pub rate_limit_cache_alert_rows: u64,
}
impl Default for AuthMaintenanceConfig {
fn default() -> Self {
Self {
rate_limit_cache_cleanup_interval_secs:
super::defaults::default_rate_limit_cache_cleanup_interval_secs(),
rate_limit_cache_retention_secs:
super::defaults::default_rate_limit_cache_retention_secs(),
rate_limit_cache_alert_rows: super::defaults::default_rate_limit_cache_alert_rows(),
}
}
}