quantrs2_device/performance_analytics_dashboard/
session.rs

1//! Session and User Management for Performance Dashboard
2//!
3//! This module handles user sessions, permissions, preferences, and access control
4//! for the performance analytics dashboard.
5
6use crate::DeviceResult;
7use serde::{Deserialize, Serialize};
8use std::collections::HashMap;
9use std::time::{Duration, SystemTime};
10
11/// User session management
12pub struct SessionManager {
13    active_sessions: HashMap<String, UserSession>,
14    session_config: SessionConfig,
15    auth_provider: Box<dyn AuthProvider + Send + Sync>,
16    permission_manager: PermissionManager,
17}
18
19/// User session information
20#[derive(Debug, Clone)]
21pub struct UserSession {
22    pub session_id: String,
23    pub user_id: String,
24    pub permissions: Vec<Permission>,
25    pub preferences: UserPreferences,
26    pub last_activity: SystemTime,
27    pub session_data: HashMap<String, String>,
28    pub auth_token: Option<String>,
29    pub expires_at: SystemTime,
30}
31
32/// Session configuration
33#[derive(Debug, Clone)]
34pub struct SessionConfig {
35    pub session_timeout: Duration,
36    pub max_concurrent_sessions: usize,
37    pub require_authentication: bool,
38    pub enable_session_persistence: bool,
39    pub cookie_settings: CookieSettings,
40    pub security_settings: SecuritySettings,
41}
42
43/// Cookie settings
44#[derive(Debug, Clone)]
45pub struct CookieSettings {
46    pub secure: bool,
47    pub http_only: bool,
48    pub same_site: SameSitePolicy,
49    pub domain: Option<String>,
50    pub path: String,
51    pub max_age: Duration,
52}
53
54/// Same-site policy
55#[derive(Debug, Clone, PartialEq)]
56pub enum SameSitePolicy {
57    Strict,
58    Lax,
59    None,
60}
61
62/// Security settings
63#[derive(Debug, Clone)]
64pub struct SecuritySettings {
65    pub csrf_protection: bool,
66    pub rate_limiting: bool,
67    pub ip_whitelist: Option<Vec<String>>,
68    pub require_https: bool,
69    pub enable_audit_logging: bool,
70}
71
72/// User permissions
73#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
74pub enum Permission {
75    ReadDashboard,
76    WriteDashboard,
77    ManageAlerts,
78    ExportData,
79    ViewReports,
80    ManageUsers,
81    SystemAdmin,
82    Custom(String),
83}
84
85/// User preferences
86#[derive(Debug, Clone, Serialize, Deserialize)]
87pub struct UserPreferences {
88    pub dashboard_layout: String,
89    pub default_time_range: String,
90    pub chart_preferences: ChartPreferences,
91    pub notification_preferences: NotificationPreferences,
92    pub display_preferences: DisplayPreferences,
93    pub custom_preferences: HashMap<String, String>,
94}
95
96/// Chart preferences
97#[derive(Debug, Clone, Serialize, Deserialize)]
98pub struct ChartPreferences {
99    pub preferred_chart_types: Vec<String>,
100    pub color_scheme: String,
101    pub animation_enabled: bool,
102    pub interactive_features: bool,
103    pub default_aggregation: String,
104    pub refresh_interval: u64,
105}
106
107/// Notification preferences
108#[derive(Debug, Clone, Serialize, Deserialize)]
109pub struct NotificationPreferences {
110    pub email_notifications: bool,
111    pub browser_notifications: bool,
112    pub slack_notifications: bool,
113    pub notification_frequency: NotificationFrequency,
114    pub alert_thresholds: HashMap<String, f64>,
115    pub quiet_hours: Option<QuietHours>,
116}
117
118/// Notification frequency
119#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
120pub enum NotificationFrequency {
121    Immediate,
122    Hourly,
123    Daily,
124    Weekly,
125    Custom(Duration),
126}
127
128/// Quiet hours configuration
129#[derive(Debug, Clone, Serialize, Deserialize)]
130pub struct QuietHours {
131    pub start_time: String, // HH:MM format
132    pub end_time: String,   // HH:MM format
133    pub timezone: String,
134    pub days_of_week: Vec<DayOfWeek>,
135}
136
137/// Days of the week
138#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
139pub enum DayOfWeek {
140    Monday,
141    Tuesday,
142    Wednesday,
143    Thursday,
144    Friday,
145    Saturday,
146    Sunday,
147}
148
149/// Display preferences
150#[derive(Debug, Clone, Serialize, Deserialize)]
151pub struct DisplayPreferences {
152    pub theme: String,
153    pub font_size: String,
154    pub density: DisplayDensity,
155    pub sidebar_collapsed: bool,
156    pub show_tooltips: bool,
157    pub language: String,
158    pub timezone: String,
159}
160
161/// Display density
162#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
163pub enum DisplayDensity {
164    Compact,
165    Normal,
166    Spacious,
167}
168
169/// Authentication provider trait
170pub trait AuthProvider {
171    fn authenticate(&self, credentials: &Credentials) -> DeviceResult<AuthResult>;
172    fn validate_token(&self, token: &str) -> DeviceResult<TokenValidation>;
173    fn refresh_token(&self, refresh_token: &str) -> DeviceResult<AuthResult>;
174    fn logout(&self, token: &str) -> DeviceResult<()>;
175}
176
177/// Authentication credentials
178#[derive(Debug, Clone)]
179pub struct Credentials {
180    pub username: Option<String>,
181    pub password: Option<String>,
182    pub token: Option<String>,
183    pub oauth_code: Option<String>,
184    pub provider: AuthProviderType,
185}
186
187/// Authentication provider types
188#[derive(Debug, Clone, PartialEq)]
189pub enum AuthProviderType {
190    Local,
191    LDAP,
192    OAuth2,
193    SAML,
194    JWT,
195    Custom(String),
196}
197
198/// Authentication result
199#[derive(Debug, Clone)]
200pub struct AuthResult {
201    pub success: bool,
202    pub user_info: Option<UserInfo>,
203    pub access_token: Option<String>,
204    pub refresh_token: Option<String>,
205    pub expires_at: Option<SystemTime>,
206    pub error_message: Option<String>,
207}
208
209/// User information
210#[derive(Debug, Clone)]
211pub struct UserInfo {
212    pub user_id: String,
213    pub username: String,
214    pub email: String,
215    pub full_name: String,
216    pub roles: Vec<Role>,
217    pub groups: Vec<String>,
218    pub metadata: HashMap<String, String>,
219}
220
221/// User role
222#[derive(Debug, Clone)]
223pub struct Role {
224    pub role_id: String,
225    pub role_name: String,
226    pub permissions: Vec<Permission>,
227    pub description: String,
228}
229
230/// Token validation result
231#[derive(Debug, Clone)]
232pub struct TokenValidation {
233    pub valid: bool,
234    pub user_id: Option<String>,
235    pub expires_at: Option<SystemTime>,
236    pub scopes: Vec<String>,
237}
238
239/// Permission manager for access control
240pub struct PermissionManager {
241    role_definitions: HashMap<String, Role>,
242    permission_cache: HashMap<String, Vec<Permission>>,
243    access_policies: Vec<AccessPolicy>,
244}
245
246/// Access policy
247#[derive(Debug, Clone)]
248pub struct AccessPolicy {
249    pub policy_id: String,
250    pub resource: String,
251    pub action: String,
252    pub conditions: Vec<AccessCondition>,
253    pub effect: PolicyEffect,
254}
255
256/// Policy effect
257#[derive(Debug, Clone, PartialEq)]
258pub enum PolicyEffect {
259    Allow,
260    Deny,
261}
262
263/// Access condition
264#[derive(Debug, Clone)]
265pub struct AccessCondition {
266    pub condition_type: ConditionType,
267    pub operator: ConditionOperator,
268    pub value: String,
269}
270
271/// Condition types
272#[derive(Debug, Clone, PartialEq)]
273pub enum ConditionType {
274    UserRole,
275    UserGroup,
276    TimeOfDay,
277    DayOfWeek,
278    IpAddress,
279    ResourceOwner,
280    Custom(String),
281}
282
283/// Condition operators
284#[derive(Debug, Clone, PartialEq)]
285pub enum ConditionOperator {
286    Equals,
287    NotEquals,
288    Contains,
289    StartsWith,
290    EndsWith,
291    GreaterThan,
292    LessThan,
293    InRange,
294    Custom(String),
295}
296
297/// Session activity tracking
298#[derive(Debug, Clone)]
299pub struct SessionActivity {
300    pub session_id: String,
301    pub user_id: String,
302    pub activity_type: ActivityType,
303    pub timestamp: SystemTime,
304    pub ip_address: String,
305    pub user_agent: String,
306    pub resource_accessed: Option<String>,
307    pub metadata: HashMap<String, String>,
308}
309
310/// Activity types
311#[derive(Debug, Clone, PartialEq)]
312pub enum ActivityType {
313    Login,
314    Logout,
315    DashboardView,
316    ChartInteraction,
317    DataExport,
318    ConfigurationChange,
319    AlertAcknowledgement,
320    Custom(String),
321}
322
323/// Audit logging
324pub struct AuditLogger {
325    log_config: AuditLogConfig,
326    log_storage: Box<dyn LogStorage + Send + Sync>,
327    log_buffer: Vec<AuditEvent>,
328}
329
330/// Audit log configuration
331#[derive(Debug, Clone)]
332pub struct AuditLogConfig {
333    pub enabled: bool,
334    pub log_level: AuditLogLevel,
335    pub retention_period: Duration,
336    pub include_sensitive_data: bool,
337    pub encryption_enabled: bool,
338}
339
340/// Audit log levels
341#[derive(Debug, Clone, PartialEq)]
342pub enum AuditLogLevel {
343    Debug,
344    Info,
345    Warning,
346    Error,
347    Critical,
348}
349
350/// Audit event
351#[derive(Debug, Clone)]
352pub struct AuditEvent {
353    pub event_id: String,
354    pub timestamp: SystemTime,
355    pub user_id: Option<String>,
356    pub session_id: Option<String>,
357    pub event_type: AuditEventType,
358    pub resource: String,
359    pub action: String,
360    pub result: AuditResult,
361    pub ip_address: String,
362    pub user_agent: String,
363    pub details: HashMap<String, String>,
364}
365
366/// Audit event types
367#[derive(Debug, Clone, PartialEq)]
368pub enum AuditEventType {
369    Authentication,
370    Authorization,
371    DataAccess,
372    DataModification,
373    SystemChange,
374    SecurityEvent,
375    Custom(String),
376}
377
378/// Audit result
379#[derive(Debug, Clone, PartialEq)]
380pub enum AuditResult {
381    Success,
382    Failure,
383    Unauthorized,
384    Forbidden,
385    Error,
386}
387
388/// Log storage trait
389pub trait LogStorage {
390    fn store(&self, event: &AuditEvent) -> DeviceResult<()>;
391    fn query(&self, criteria: &QueryCriteria) -> DeviceResult<Vec<AuditEvent>>;
392    fn purge_old_logs(&self, before: SystemTime) -> DeviceResult<usize>;
393}
394
395/// Query criteria for log retrieval
396#[derive(Debug, Clone)]
397pub struct QueryCriteria {
398    pub start_time: Option<SystemTime>,
399    pub end_time: Option<SystemTime>,
400    pub user_id: Option<String>,
401    pub event_type: Option<AuditEventType>,
402    pub resource: Option<String>,
403    pub result: Option<AuditResult>,
404    pub limit: Option<usize>,
405}
406
407impl SessionManager {
408    pub fn new(config: SessionConfig, auth_provider: Box<dyn AuthProvider + Send + Sync>) -> Self {
409        Self {
410            active_sessions: HashMap::new(),
411            session_config: config,
412            auth_provider,
413            permission_manager: PermissionManager::new(),
414        }
415    }
416
417    pub async fn create_session(&mut self, credentials: &Credentials) -> DeviceResult<UserSession> {
418        // Authenticate user
419        let auth_result = self.auth_provider.authenticate(credentials)?;
420
421        if !auth_result.success {
422            return Err(crate::DeviceError::APIError(
423                "Authentication failed".to_string(),
424            ));
425        }
426
427        let user_info = auth_result
428            .user_info
429            .ok_or_else(|| crate::DeviceError::APIError("Missing user information".to_string()))?;
430
431        // Create session
432        let session_id = self.generate_session_id();
433        let expires_at = SystemTime::now() + self.session_config.session_timeout;
434
435        let permissions = self.permission_manager.get_user_permissions(&user_info)?;
436        let preferences = self.load_user_preferences(&user_info.user_id).await?;
437
438        let session = UserSession {
439            session_id: session_id.clone(),
440            user_id: user_info.user_id.clone(),
441            permissions,
442            preferences,
443            last_activity: SystemTime::now(),
444            session_data: HashMap::new(),
445            auth_token: auth_result.access_token,
446            expires_at,
447        };
448
449        // Check concurrent session limit
450        self.enforce_session_limits(&user_info.user_id)?;
451
452        self.active_sessions
453            .insert(session_id.clone(), session.clone());
454
455        Ok(session)
456    }
457
458    pub fn validate_session(&mut self, session_id: &str) -> DeviceResult<&mut UserSession> {
459        // First check if session exists and is not expired
460        if let Some(session) = self.active_sessions.get(session_id) {
461            if SystemTime::now() > session.expires_at {
462                self.active_sessions.remove(session_id);
463                return Err(crate::DeviceError::APIError("Session expired".to_string()));
464            }
465        } else {
466            return Err(crate::DeviceError::APIError("Invalid session".to_string()));
467        }
468
469        // Now get mutable reference and update last activity
470        let session = self.active_sessions.get_mut(session_id).unwrap();
471        session.last_activity = SystemTime::now();
472
473        Ok(session)
474    }
475
476    pub fn terminate_session(&mut self, session_id: &str) -> DeviceResult<()> {
477        if let Some(session) = self.active_sessions.remove(session_id) {
478            // Logout from auth provider if token exists
479            if let Some(token) = &session.auth_token {
480                let _ = self.auth_provider.logout(token);
481            }
482        }
483
484        Ok(())
485    }
486
487    pub fn cleanup_expired_sessions(&mut self) -> DeviceResult<usize> {
488        let now = SystemTime::now();
489        let expired_sessions: Vec<String> = self
490            .active_sessions
491            .iter()
492            .filter(|(_, session)| now > session.expires_at)
493            .map(|(id, _)| id.clone())
494            .collect();
495
496        let count = expired_sessions.len();
497        for session_id in expired_sessions {
498            self.active_sessions.remove(&session_id);
499        }
500
501        Ok(count)
502    }
503
504    pub async fn update_user_preferences(
505        &mut self,
506        user_id: &str,
507        preferences: UserPreferences,
508    ) -> DeviceResult<()> {
509        // Update preferences for all active sessions of this user
510        for session in self.active_sessions.values_mut() {
511            if session.user_id == user_id {
512                session.preferences = preferences.clone();
513            }
514        }
515
516        // Persist preferences
517        self.save_user_preferences(user_id, &preferences).await?;
518
519        Ok(())
520    }
521
522    pub fn get_session_statistics(&self) -> SessionStatistics {
523        let total_sessions = self.active_sessions.len();
524        let mut sessions_by_user = HashMap::new();
525        let mut recent_activity_count = 0;
526        let recent_threshold = SystemTime::now() - Duration::from_secs(5 * 60);
527
528        for session in self.active_sessions.values() {
529            *sessions_by_user.entry(session.user_id.clone()).or_insert(0) += 1;
530
531            if session.last_activity > recent_threshold {
532                recent_activity_count += 1;
533            }
534        }
535
536        SessionStatistics {
537            total_active_sessions: total_sessions,
538            sessions_by_user,
539            recent_activity_count,
540            average_session_duration: self.calculate_average_session_duration(),
541        }
542    }
543
544    fn generate_session_id(&self) -> String {
545        // Generate secure session ID
546        format!(
547            "session_{}",
548            SystemTime::now()
549                .duration_since(std::time::UNIX_EPOCH)
550                .unwrap()
551                .as_nanos()
552        )
553    }
554
555    fn enforce_session_limits(&mut self, user_id: &str) -> DeviceResult<()> {
556        let user_session_count = self
557            .active_sessions
558            .values()
559            .filter(|s| s.user_id == user_id)
560            .count();
561
562        if user_session_count >= self.session_config.max_concurrent_sessions {
563            // Remove oldest session for this user
564            if let Some((oldest_session_id, _)) = self
565                .active_sessions
566                .iter()
567                .filter(|(_, s)| s.user_id == user_id)
568                .min_by_key(|(_, s)| s.last_activity)
569                .map(|(id, s)| (id.clone(), s.clone()))
570            {
571                self.active_sessions.remove(&oldest_session_id);
572            }
573        }
574
575        Ok(())
576    }
577
578    async fn load_user_preferences(&self, user_id: &str) -> DeviceResult<UserPreferences> {
579        // Simplified preference loading - in real implementation, load from database
580        Ok(UserPreferences::default())
581    }
582
583    async fn save_user_preferences(
584        &self,
585        user_id: &str,
586        preferences: &UserPreferences,
587    ) -> DeviceResult<()> {
588        // Simplified preference saving - in real implementation, save to database
589        Ok(())
590    }
591
592    fn calculate_average_session_duration(&self) -> Duration {
593        if self.active_sessions.is_empty() {
594            return Duration::from_secs(0);
595        }
596
597        let now = SystemTime::now();
598        let total_duration: Duration = self
599            .active_sessions
600            .values()
601            .map(|s| {
602                now.duration_since(s.last_activity)
603                    .unwrap_or(Duration::from_secs(0))
604            })
605            .sum();
606
607        total_duration / self.active_sessions.len() as u32
608    }
609}
610
611/// Session statistics
612#[derive(Debug, Clone)]
613pub struct SessionStatistics {
614    pub total_active_sessions: usize,
615    pub sessions_by_user: HashMap<String, usize>,
616    pub recent_activity_count: usize,
617    pub average_session_duration: Duration,
618}
619
620impl PermissionManager {
621    pub fn new() -> Self {
622        Self {
623            role_definitions: Self::create_default_roles(),
624            permission_cache: HashMap::new(),
625            access_policies: Vec::new(),
626        }
627    }
628
629    pub fn get_user_permissions(&mut self, user_info: &UserInfo) -> DeviceResult<Vec<Permission>> {
630        // Check cache first
631        if let Some(cached_permissions) = self.permission_cache.get(&user_info.user_id) {
632            return Ok(cached_permissions.clone());
633        }
634
635        // Calculate permissions from roles
636        let mut permissions = Vec::new();
637        for role in &user_info.roles {
638            if let Some(role_def) = self.role_definitions.get(&role.role_id) {
639                permissions.extend(role_def.permissions.clone());
640            }
641        }
642
643        // Remove duplicates
644        permissions.sort();
645        permissions.dedup();
646
647        // Cache permissions
648        self.permission_cache
649            .insert(user_info.user_id.clone(), permissions.clone());
650
651        Ok(permissions)
652    }
653
654    pub fn check_permission(
655        &self,
656        user_permissions: &[Permission],
657        required_permission: &Permission,
658    ) -> bool {
659        user_permissions.contains(required_permission)
660            || user_permissions.contains(&Permission::SystemAdmin)
661    }
662
663    pub fn evaluate_access_policy(
664        &self,
665        user_info: &UserInfo,
666        resource: &str,
667        action: &str,
668    ) -> DeviceResult<bool> {
669        for policy in &self.access_policies {
670            if policy.resource == resource && policy.action == action {
671                if self.evaluate_conditions(&policy.conditions, user_info)? {
672                    return Ok(policy.effect == PolicyEffect::Allow);
673                }
674            }
675        }
676
677        // Default deny
678        Ok(false)
679    }
680
681    fn create_default_roles() -> HashMap<String, Role> {
682        let mut roles = HashMap::new();
683
684        roles.insert(
685            "admin".to_string(),
686            Role {
687                role_id: "admin".to_string(),
688                role_name: "Administrator".to_string(),
689                permissions: vec![Permission::SystemAdmin],
690                description: "Full system access".to_string(),
691            },
692        );
693
694        roles.insert(
695            "viewer".to_string(),
696            Role {
697                role_id: "viewer".to_string(),
698                role_name: "Viewer".to_string(),
699                permissions: vec![Permission::ReadDashboard, Permission::ViewReports],
700                description: "Read-only access".to_string(),
701            },
702        );
703
704        roles.insert(
705            "operator".to_string(),
706            Role {
707                role_id: "operator".to_string(),
708                role_name: "Operator".to_string(),
709                permissions: vec![
710                    Permission::ReadDashboard,
711                    Permission::WriteDashboard,
712                    Permission::ManageAlerts,
713                    Permission::ExportData,
714                    Permission::ViewReports,
715                ],
716                description: "Operational access".to_string(),
717            },
718        );
719
720        roles
721    }
722
723    fn evaluate_conditions(
724        &self,
725        conditions: &[AccessCondition],
726        user_info: &UserInfo,
727    ) -> DeviceResult<bool> {
728        for condition in conditions {
729            if !self.evaluate_single_condition(condition, user_info)? {
730                return Ok(false);
731            }
732        }
733        Ok(true)
734    }
735
736    fn evaluate_single_condition(
737        &self,
738        condition: &AccessCondition,
739        user_info: &UserInfo,
740    ) -> DeviceResult<bool> {
741        match &condition.condition_type {
742            ConditionType::UserRole => {
743                let has_role = user_info.roles.iter().any(|r| r.role_id == condition.value);
744                Ok(match condition.operator {
745                    ConditionOperator::Equals => has_role,
746                    ConditionOperator::NotEquals => !has_role,
747                    _ => false,
748                })
749            }
750            ConditionType::UserGroup => {
751                let in_group = user_info.groups.contains(&condition.value);
752                Ok(match condition.operator {
753                    ConditionOperator::Equals => in_group,
754                    ConditionOperator::NotEquals => !in_group,
755                    _ => false,
756                })
757            }
758            _ => Ok(true), // Simplified - other conditions not implemented
759        }
760    }
761}
762
763impl AuditLogger {
764    pub fn new(config: AuditLogConfig, storage: Box<dyn LogStorage + Send + Sync>) -> Self {
765        Self {
766            log_config: config,
767            log_storage: storage,
768            log_buffer: Vec::new(),
769        }
770    }
771
772    pub fn log_event(&mut self, event: AuditEvent) -> DeviceResult<()> {
773        if !self.log_config.enabled {
774            return Ok(());
775        }
776
777        // Add to buffer
778        self.log_buffer.push(event);
779
780        // Flush if buffer is full
781        if self.log_buffer.len() >= 100 {
782            self.flush_buffer()?;
783        }
784
785        Ok(())
786    }
787
788    pub fn flush_buffer(&mut self) -> DeviceResult<()> {
789        for event in &self.log_buffer {
790            self.log_storage.store(event)?;
791        }
792        self.log_buffer.clear();
793        Ok(())
794    }
795
796    pub fn query_logs(&self, criteria: &QueryCriteria) -> DeviceResult<Vec<AuditEvent>> {
797        self.log_storage.query(criteria)
798    }
799}
800
801// Default implementations
802impl Default for UserPreferences {
803    fn default() -> Self {
804        Self {
805            dashboard_layout: "grid".to_string(),
806            default_time_range: "last_hour".to_string(),
807            chart_preferences: ChartPreferences::default(),
808            notification_preferences: NotificationPreferences::default(),
809            display_preferences: DisplayPreferences::default(),
810            custom_preferences: HashMap::new(),
811        }
812    }
813}
814
815impl Default for ChartPreferences {
816    fn default() -> Self {
817        Self {
818            preferred_chart_types: vec!["line".to_string(), "bar".to_string()],
819            color_scheme: "scientific".to_string(),
820            animation_enabled: true,
821            interactive_features: true,
822            default_aggregation: "minute".to_string(),
823            refresh_interval: 30,
824        }
825    }
826}
827
828impl Default for NotificationPreferences {
829    fn default() -> Self {
830        Self {
831            email_notifications: true,
832            browser_notifications: false,
833            slack_notifications: false,
834            notification_frequency: NotificationFrequency::Immediate,
835            alert_thresholds: HashMap::new(),
836            quiet_hours: None,
837        }
838    }
839}
840
841impl Default for DisplayPreferences {
842    fn default() -> Self {
843        Self {
844            theme: "light".to_string(),
845            font_size: "medium".to_string(),
846            density: DisplayDensity::Normal,
847            sidebar_collapsed: false,
848            show_tooltips: true,
849            language: "en".to_string(),
850            timezone: "UTC".to_string(),
851        }
852    }
853}
854
855impl Default for SessionConfig {
856    fn default() -> Self {
857        Self {
858            session_timeout: Duration::from_secs(8 * 3600),
859            max_concurrent_sessions: 5,
860            require_authentication: true,
861            enable_session_persistence: false,
862            cookie_settings: CookieSettings {
863                secure: true,
864                http_only: true,
865                same_site: SameSitePolicy::Strict,
866                domain: None,
867                path: "/".to_string(),
868                max_age: Duration::from_secs(8 * 3600),
869            },
870            security_settings: SecuritySettings {
871                csrf_protection: true,
872                rate_limiting: true,
873                ip_whitelist: None,
874                require_https: true,
875                enable_audit_logging: true,
876            },
877        }
878    }
879}
880
881impl Default for AuditLogConfig {
882    fn default() -> Self {
883        Self {
884            enabled: true,
885            log_level: AuditLogLevel::Info,
886            retention_period: Duration::from_secs(90 * 24 * 3600),
887            include_sensitive_data: false,
888            encryption_enabled: true,
889        }
890    }
891}