Skip to main content

ave_bridge/auth/
mod.rs

1// Ave HTTP Auth System - Configuration
2//
3// This module defines the configuration structure for the authentication system
4
5use serde::{Deserialize, Serialize};
6use std::path::PathBuf;
7
8/// Authentication system configuration
9#[derive(Debug, Clone, Deserialize, Serialize)]
10#[serde(default)]
11pub struct AuthConfig {
12    /// Enable or disable authentication
13    /// If false, all endpoints are accessible without authentication
14    pub enable: bool,
15
16    /// Path to the SQLite database file
17    pub database_path: PathBuf,
18
19    /// Durable writes: PRAGMA synchronous=FULL (true) vs NORMAL (false).
20    pub durability: bool,
21
22    /// Superadmin bootstrap credentials
23    /// Only used on first run to create initial superadmin account
24    pub superadmin: String,
25
26    /// API key settings
27    pub api_key: ApiKeyConfig,
28
29    /// Account lockout settings
30    pub lockout: LockoutConfig,
31
32    /// Rate limiting settings
33    pub rate_limit: RateLimitConfig,
34
35    /// Session settings
36    pub session: SessionConfig,
37}
38
39impl Default for AuthConfig {
40    fn default() -> Self {
41        Self {
42            enable: false,
43            database_path: PathBuf::from("auth"),
44            durability: false,
45            superadmin: String::default(),
46            api_key: ApiKeyConfig::default(),
47            lockout: LockoutConfig::default(),
48            rate_limit: RateLimitConfig::default(),
49            session: SessionConfig::default(),
50        }
51    }
52}
53
54/// API key configuration
55#[derive(Debug, Clone, Deserialize, Serialize)]
56#[serde(default)]
57pub struct ApiKeyConfig {
58    /// Default TTL for API keys in seconds
59    /// 0 = no expiration
60    pub default_ttl_seconds: i64,
61
62    /// Maximum number of API keys per user
63    /// 0 = unlimited
64    pub max_keys_per_user: u32,
65
66    /// Prefix used when generating API keys
67    pub prefix: String,
68}
69
70impl Default for ApiKeyConfig {
71    fn default() -> Self {
72        Self {
73            default_ttl_seconds: 2592000,
74            max_keys_per_user: 10,
75            prefix: "ave_node_".to_string(),
76        }
77    }
78}
79
80/// Account lockout configuration
81#[derive(Debug, Clone, Deserialize, Serialize)]
82#[serde(default)]
83pub struct LockoutConfig {
84    /// Maximum failed login attempts before lockout
85    /// 0 = no lockout
86    pub max_attempts: u32,
87
88    /// Lockout duration in seconds
89    pub duration_seconds: i64,
90}
91
92impl Default for LockoutConfig {
93    fn default() -> Self {
94        Self {
95            max_attempts: 10,
96            duration_seconds: 300,
97        }
98    }
99}
100
101/// Rate limiting configuration
102#[derive(Debug, Clone, Deserialize, Serialize)]
103#[serde(default)]
104pub struct RateLimitConfig {
105    /// Enable rate limiting
106    pub enable: bool,
107
108    /// Time window in seconds (default for all endpoints)
109    pub window_seconds: i64,
110
111    /// Maximum requests per window (default for all endpoints)
112    pub max_requests: u32,
113
114    /// Rate limit by API key
115    pub limit_by_key: bool,
116
117    /// Rate limit by IP address
118    pub limit_by_ip: bool,
119
120    /// Cleanup old rate limit entries interval in seconds
121    pub cleanup_interval_seconds: i64,
122
123    /// Sensitive endpoints with stricter rate limits
124    /// Map of endpoint path to EndpointRateLimit
125    #[serde(default)]
126    pub sensitive_endpoints: Vec<EndpointRateLimit>,
127}
128
129/// Rate limit configuration for a specific endpoint
130#[derive(Debug, Clone, Deserialize, Serialize)]
131pub struct EndpointRateLimit {
132    /// Endpoint path (e.g., "/login", "/change-password")
133    pub endpoint: String,
134
135    /// Maximum requests per window for this endpoint
136    pub max_requests: u32,
137
138    /// Optional: Custom window size for this endpoint (None = use default)
139    pub window_seconds: Option<i64>,
140}
141
142impl Default for RateLimitConfig {
143    fn default() -> Self {
144        Self {
145            enable: true,
146            window_seconds: 60,
147            max_requests: 100,
148            limit_by_key: true,
149            limit_by_ip: true,
150            cleanup_interval_seconds: 3600,
151            // Default sensitive endpoints with stricter limits
152            sensitive_endpoints: vec![
153                EndpointRateLimit {
154                    endpoint: "/login".to_string(),
155                    max_requests: 10,
156                    window_seconds: None, // Use default 60 seconds
157                },
158                EndpointRateLimit {
159                    endpoint: "/change-password".to_string(),
160                    max_requests: 5,
161                    window_seconds: None,
162                },
163                EndpointRateLimit {
164                    endpoint: "/admin/users".to_string(),
165                    max_requests: 20,
166                    window_seconds: None,
167                },
168            ],
169        }
170    }
171}
172
173/// Session configuration
174#[derive(Debug, Clone, Deserialize, Serialize)]
175#[serde(default)]
176pub struct SessionConfig {
177    /// Enable audit logging
178    pub audit_enable: bool,
179
180    /// Audit log retention in days (0 = keep forever)
181    pub audit_retention_days: u32,
182
183    /// Maximum number of audit logs to keep (0 = unlimited)
184    /// When exceeded, oldest logs are deleted (LRU cache behavior)
185    pub audit_max_entries: u32,
186}
187
188impl Default for SessionConfig {
189    fn default() -> Self {
190        Self {
191            audit_enable: true,
192            audit_retention_days: 90,
193            // Limit to 1 million entries (prevents unbounded growth)
194            // Approximately 11.5 days at 1 req/sec, or 1 day at 11.5 req/sec
195            audit_max_entries: 1_000_000,
196        }
197    }
198}