dmsc/auth/
mod.rs

1//! Copyright © 2025-2026 Wenze Wei. All Rights Reserved.
2//!
3//! This file is part of DMSC.
4//! The DMSC project belongs to the Dunimd Team.
5//!
6//! Licensed under the Apache License, Version 2.0 (the "License");
7//! You may not use this file except in compliance with the License.
8//! You may obtain a copy of the License at
9//!
10//!     http://www.apache.org/licenses/LICENSE-2.0
11//!
12//! Unless required by applicable law or agreed to in writing, software
13//! distributed under the License is distributed on an "AS IS" BASIS,
14//! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15//! See the License for the specific language governing permissions and
16//! limitations under the License.
17
18//! # Authentication Module
19//! 
20//! This module provides comprehensive authentication and authorization functionality for DMSC,
21//! offering multiple authentication methods and a robust permission system.
22//! 
23//! ## Key Components
24//! 
25//! - **DMSCAuthModule**: Main auth module implementing service module traits
26//! - **DMSCAuthConfig**: Configuration for authentication behavior
27//! - **DMSCJWTManager**: JWT token management for stateless authentication
28//! - **DMSCSessionManager**: Session management for stateful authentication
29//! - **DMSCPermissionManager**: Permission and role management
30//! - **DMSCOAuthManager**: OAuth provider integration
31//! - **DMSCJWTClaims**: JWT token claims structure
32//! - **DMSCJWTValidationOptions**: JWT validation options
33//! - **DMSCOAuthProvider**: OAuth provider interface
34//! - **DMSCOAuthToken**: OAuth token structure
35//! - **DMSCOAuthUserInfo**: OAuth user information
36//! - **DMSCPermission**: Permission structure
37//! - **DMSCRole**: Role structure with permissions
38//! - **DMSCSession**: Session structure
39//! 
40//! ## Design Principles
41//! 
42//! 1. **Multiple Authentication Methods**: Supports JWT, sessions, OAuth, and API keys
43//! 2. **Configurable**: Highly configurable authentication behavior
44//! 3. **Async Support**: Full async/await compatibility for session and OAuth operations
45//! 4. **Role-Based Access Control**: Comprehensive permission system with roles
46//! 5. **Stateless and Stateful Options**: Supports both stateless (JWT) and stateful (session) authentication
47//! 6. **Service Module Integration**: Implements service module traits for seamless integration
48//! 7. **Thread-safe**: Uses Arc and RwLock for safe concurrent access
49//! 8. **Non-critical**: Auth failures should not break the entire application
50//! 9. **Extensible**: Easy to add new authentication methods and OAuth providers
51//! 10. **Secure by Default**: Sensible default configurations for security
52//! 
53//! ## Usage
54//! 
55//! ```rust,ignore
56//! use dmsc::prelude::*;
57//! use dmsc::auth::{DMSCAuthConfig, DMSCJWTManager, DMSCJWTClaims};
58//! use serde_json::json;
59//! 
60//! async fn example() -> DMSCResult<()> {
61//!     // Create auth configuration
62//!     let auth_config = DMSCAuthConfig {
63//!         enabled: true,
64//!         jwt_secret: "secure-secret-key".to_string(),
65//!         jwt_expiry_secs: 3600,
66//!         session_timeout_secs: 86400,
67//!         oauth_providers: vec![],
68//!         enable_api_keys: true,
69//!         enable_session_auth: true,
70//!     };
71//!     
72//!     // Create auth module
73//!     let auth_module = DMSCAuthModule::new(auth_config);
74//!     
75//!     // Get JWT manager
76//!     let jwt_manager = auth_module.jwt_manager();
77//!     
78//!     // Create JWT claims
79//!     let claims = DMSCJWTClaims {
80//!         sub: "user-123".to_string(),
81//!         email: "user@example.com".to_string(),
82//!         roles: vec!["user".to_string()],
83//!         permissions: vec!["read:data".to_string()],
84//!         extra: json!({ "custom": "value" }),
85//!     };
86//!     
87//!     // Generate JWT token
88//!     let token = jwt_manager.generate_token(claims)?;
89//!     println!("Generated JWT token: {}", token);
90//!     
91//!     // Validate JWT token
92//!     let validated_claims = jwt_manager.validate_token(&token)?;
93//!     println!("Validated claims: {:?}", validated_claims);
94//!     
95//!     // Get session manager
96//!     let session_manager = auth_module.session_manager();
97//!     
98//!     // Create a session
99//!     let session = session_manager.write().await.create_session("user-123").await?;
100//!     println!("Created session: {}", session.id);
101//!     
102//!     Ok(())
103//! }
104//! ```
105
106mod jwt;
107mod oauth;
108mod permissions;
109mod session;
110mod security;
111mod revocation;
112
113pub use jwt::{DMSCJWTManager, DMSCJWTClaims, DMSCJWTValidationOptions};
114pub use oauth::{DMSCOAuthManager, DMSCOAuthToken, DMSCOAuthUserInfo, DMSCOAuthProvider};
115pub use permissions::{DMSCPermissionManager, DMSCPermission, DMSCRole};
116pub use session::{DMSCSessionManager, DMSCSession};
117pub use security::DMSCSecurityManager;
118pub use revocation::{DMSCJWTRevocationList, DMSCRevokedTokenInfo};
119
120use crate::core::{DMSCResult, DMSCError, DMSCServiceContext};
121use rand::RngCore;
122use serde::Deserialize;
123use std::env;
124use std::sync::Arc;
125use tokio::sync::RwLock;
126#[cfg(feature = "pyo3")]
127use tokio::runtime::Handle;
128
129const DEFAULT_JWT_SECRET_ENV: &str = "DMSC_JWT_SECRET";
130const FALLBACK_SECRET_LENGTH: usize = 64;
131
132fn load_jwt_secret_from_env() -> String {
133    env::var(DEFAULT_JWT_SECRET_ENV).unwrap_or_else(|_| {
134        let mut secret = vec![0u8; FALLBACK_SECRET_LENGTH];
135        rand::thread_rng().fill_bytes(&mut secret);
136        hex::encode(secret)
137    })
138}
139
140fn load_oauth_env_var(provider_name: &str, suffix: &str) -> Result<String, DMSCError> {
141    let env_var = format!("DMSC_OAUTH_{}_{}", provider_name.to_uppercase(), suffix);
142    env::var(&env_var).map_err(|_| {
143        DMSCError::Config(format!(
144            "OAuth {} is not set for provider '{}'. Please set the environment variable {}",
145            suffix.to_lowercase(),
146            provider_name,
147            env_var
148        ))
149    })
150}
151
152fn get_oauth_url(provider_name: &str, endpoint: &str) -> String {
153    match load_oauth_env_var(provider_name, endpoint) {
154        Ok(url) if !url.is_empty() => url,
155        _ => format!("https://{}.com/oauth/{}", provider_name, endpoint)
156    }
157}
158
159#[cfg(feature = "pyo3")]
160use pyo3::PyResult;
161
162/// Configuration for the authentication module.
163/// 
164/// This struct defines the configuration options for authentication behavior, including
165/// JWT settings, session settings, OAuth providers, and enabled authentication methods.
166/// 
167/// ## Security
168/// 
169/// The JWT secret is loaded from the `DMSC_JWT_SECRET` environment variable. If not set,
170/// a cryptographically secure random secret is generated automatically.
171/// 
172/// **Important**: For production environments, always set the `DMSC_JWT_SECRET` environment
173/// variable to a strong, unique value. Do not rely on auto-generated secrets in production.
174#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass)]
175#[derive(Debug, Clone)]
176#[derive(Deserialize)]
177pub struct DMSCAuthConfig {
178    /// Whether authentication is enabled
179    pub enabled: bool,
180    /// Secret key for JWT token generation and validation
181    pub jwt_secret: String,
182    /// JWT token expiry time in seconds
183    pub jwt_expiry_secs: u64,
184    /// Session timeout in seconds
185    pub session_timeout_secs: u64,
186    /// List of OAuth providers to enable
187    pub oauth_providers: Vec<String>,
188    /// Whether API key authentication is enabled
189    pub enable_api_keys: bool,
190    /// Whether session authentication is enabled
191    pub enable_session_auth: bool,
192    /// OAuth token cache backend type (Memory or Redis)
193    #[cfg(feature = "cache")]
194    pub oauth_cache_backend_type: crate::cache::DMSCCacheBackendType,
195    /// Redis URL for OAuth token cache (used when backend is Redis)
196    #[cfg(feature = "cache")]
197    pub oauth_cache_redis_url: String,
198}
199
200impl Default for DMSCAuthConfig {
201    fn default() -> Self {
202        Self {
203            enabled: true,
204            jwt_secret: load_jwt_secret_from_env(),
205            jwt_expiry_secs: 3600,
206            session_timeout_secs: 86400,
207            oauth_providers: vec![],
208            enable_api_keys: true,
209            enable_session_auth: true,
210            #[cfg(feature = "cache")]
211            oauth_cache_backend_type: crate::cache::DMSCCacheBackendType::Memory,
212            #[cfg(feature = "cache")]
213            oauth_cache_redis_url: "redis://127.0.0.1:6379".to_string(),
214        }
215    }
216}
217
218/// Main authentication module for DMSC.
219/// 
220/// This module provides comprehensive authentication and authorization functionality,
221/// including JWT management, session management, permission management, and OAuth integration.
222#[cfg_attr(feature = "pyo3", pyo3::prelude::pyclass)]
223pub struct DMSCAuthModule {
224    /// Authentication configuration
225    config: DMSCAuthConfig,
226    /// JWT manager for stateless authentication
227    jwt_manager: Arc<DMSCJWTManager>,
228    /// Session manager for stateful authentication, protected by a RwLock for thread-safe access
229    session_manager: Arc<RwLock<DMSCSessionManager>>,
230    /// Permission manager for role-based access control, protected by a RwLock for thread-safe access
231    permission_manager: Arc<RwLock<DMSCPermissionManager>>,
232    /// OAuth manager for OAuth provider integration, protected by a RwLock for thread-safe access
233    oauth_manager: Arc<RwLock<DMSCOAuthManager>>,
234    /// JWT token revocation list for token invalidation
235    revocation_list: Arc<DMSCJWTRevocationList>,
236}
237
238impl DMSCAuthModule {
239    /// Creates a new authentication module with the given configuration.
240    /// 
241    /// **Performance Note**: This method creates a permission manager using the synchronous
242    /// `new()` method which uses `blocking_write` during initialization. For async contexts,
243    /// consider using `new_async()` to avoid blocking the runtime.
244    /// 
245    /// # Parameters
246    /// 
247    /// - `config`: The authentication configuration to use
248    /// 
249    /// # Returns
250    /// 
251    /// A `DMSCResult` containing the new `DMSCAuthModule` instance
252    /// 
253    /// # Errors
254    /// 
255    /// Returns an error if Redis cache creation fails when Redis backend is configured
256    pub async fn new(config: DMSCAuthConfig) -> crate::core::error::DMSCResult<Self> {
257        let jwt_manager = Arc::new(DMSCJWTManager::create(config.jwt_secret.clone(), config.jwt_expiry_secs));
258        let session_manager = Arc::new(RwLock::new(DMSCSessionManager::new(config.session_timeout_secs)));
259        let permission_manager = Arc::new(RwLock::new(DMSCPermissionManager::new()));
260        
261        #[cfg(feature = "cache")]
262        let cache: Arc<dyn crate::cache::DMSCCache> = match config.oauth_cache_backend_type {
263            crate::cache::DMSCCacheBackendType::Memory => {
264                Arc::new(crate::cache::DMSCMemoryCache::new())
265            }
266            crate::cache::DMSCCacheBackendType::Redis => {
267                let cache = crate::cache::DMSCRedisCache::new(&config.oauth_cache_redis_url).await
268                    .map_err(|e| crate::core::error::DMSCError::RedisError(format!("Failed to create Redis cache for OAuth: {}", e)))?;
269                Arc::new(cache)
270            }
271            _ => Arc::new(crate::cache::DMSCMemoryCache::new()),
272        };
273        
274        #[cfg(not(feature = "cache"))]
275        let cache = Arc::new(crate::cache::DMSCMemoryCache::new());
276        
277        let oauth_manager = Arc::new(RwLock::new(DMSCOAuthManager::new(cache)));
278        let revocation_list = Arc::new(DMSCJWTRevocationList::new());
279
280        Ok(Self {
281            config,
282            jwt_manager,
283            session_manager,
284            permission_manager,
285            oauth_manager,
286            revocation_list,
287        })
288    }
289
290    /// Creates a new authentication module with the given configuration (synchronous version).
291    /// 
292    /// This is a synchronous wrapper for use in the builder pattern.
293    /// 
294    /// # Parameters
295    /// 
296    /// - `config`: The authentication configuration to use
297    /// 
298    /// # Returns
299    /// 
300    /// A new `DMSCAuthModule` instance
301    pub fn with_config(config: DMSCAuthConfig) -> Self {
302        let jwt_manager = Arc::new(DMSCJWTManager::create(config.jwt_secret.clone(), config.jwt_expiry_secs));
303        let session_manager = Arc::new(RwLock::new(DMSCSessionManager::new(config.session_timeout_secs)));
304        let permission_manager = Arc::new(RwLock::new(DMSCPermissionManager::new()));
305        let cache = Arc::new(crate::cache::DMSCMemoryCache::new());
306        let oauth_manager = Arc::new(RwLock::new(DMSCOAuthManager::new(cache)));
307        let revocation_list = Arc::new(DMSCJWTRevocationList::new());
308
309        Self {
310            config,
311            jwt_manager,
312            session_manager,
313            permission_manager,
314            oauth_manager,
315            revocation_list,
316        }
317    }
318
319    /// Creates a new authentication module with the given configuration asynchronously.
320    /// 
321    /// This method is preferred for async contexts as it avoids blocking the runtime
322    /// during permission manager initialization by using the async `new_async()` method.
323    /// 
324    /// # Parameters
325    /// 
326    /// - `config`: The authentication configuration to use
327    /// 
328    /// # Returns
329    /// 
330    /// A `DMSCResult` containing the new `DMSCAuthModule` instance
331    /// 
332    /// # Errors
333    /// 
334    /// Returns an error if Redis cache creation fails when Redis backend is configured
335    pub async fn new_async(config: DMSCAuthConfig) -> crate::core::error::DMSCResult<Self> {
336        let jwt_manager = Arc::new(DMSCJWTManager::create(config.jwt_secret.clone(), config.jwt_expiry_secs));
337        let session_manager = Arc::new(RwLock::new(DMSCSessionManager::new(config.session_timeout_secs)));
338        let permission_manager = Arc::new(RwLock::new(DMSCPermissionManager::new_async().await));
339        
340        #[cfg(feature = "cache")]
341        let cache: Arc<dyn crate::cache::DMSCCache> = match config.oauth_cache_backend_type {
342            crate::cache::DMSCCacheBackendType::Memory => {
343                Arc::new(crate::cache::DMSCMemoryCache::new())
344            }
345            crate::cache::DMSCCacheBackendType::Redis => {
346                let cache = crate::cache::DMSCRedisCache::new(&config.oauth_cache_redis_url).await
347                    .map_err(|e| crate::core::error::DMSCError::RedisError(format!("Failed to create Redis cache: {}", e)))?;
348                Arc::new(cache)
349            }
350            _ => Arc::new(crate::cache::DMSCMemoryCache::new()),
351        };
352        
353        #[cfg(not(feature = "cache"))]
354        let cache = Arc::new(crate::cache::DMSCMemoryCache::new());
355        
356        let oauth_manager = Arc::new(RwLock::new(DMSCOAuthManager::new(cache)));
357        let revocation_list = Arc::new(DMSCJWTRevocationList::new());
358
359        Ok(Self {
360            config,
361            jwt_manager,
362            session_manager,
363            permission_manager,
364            oauth_manager,
365            revocation_list,
366        })
367    }
368
369    /// Returns a reference to the JWT revocation list.
370    /// 
371    /// # Returns
372    /// 
373    /// An Arc<DMSCJWTRevocationList> providing thread-safe access to the token revocation list
374    pub fn revocation_list(&self) -> Arc<DMSCJWTRevocationList> {
375        self.revocation_list.clone()
376    }
377
378    /// Returns a reference to the JWT manager.
379    /// 
380    /// # Returns
381    /// 
382    /// An Arc<DMSCJWTManager> providing thread-safe access to the JWT manager
383    pub fn jwt_manager(&self) -> Arc<DMSCJWTManager> {
384        self.jwt_manager.clone()
385    }
386
387    /// Returns a reference to the session manager.
388    /// 
389    /// # Returns
390    /// 
391    /// An Arc<RwLock<DMSCSessionManager>> providing thread-safe access to the session manager
392    pub fn session_manager(&self) -> Arc<RwLock<DMSCSessionManager>> {
393        self.session_manager.clone()
394    }
395
396    /// Returns a reference to the permission manager.
397    /// 
398    /// # Returns
399    /// 
400    /// An Arc<RwLock<DMSCPermissionManager>> providing thread-safe access to the permission manager
401    pub fn permission_manager(&self) -> Arc<RwLock<DMSCPermissionManager>> {
402        self.permission_manager.clone()
403    }
404
405    /// Returns a reference to the OAuth manager.
406    /// 
407    /// # Returns
408    /// 
409    /// An Arc<RwLock<DMSCOAuthManager>> providing thread-safe access to the OAuth manager
410    pub fn oauth_manager(&self) -> Arc<RwLock<DMSCOAuthManager>> {
411        self.oauth_manager.clone()
412    }
413}
414
415#[cfg(feature = "pyo3")]
416/// Python bindings for the DMSC Authentication Module.
417///
418/// This module provides Python interface to DMSC authentication functionality,
419/// enabling Python applications to leverage DMSC's authentication capabilities.
420///
421/// ## Supported Operations
422///
423/// - JWT token generation and validation
424/// - Session management for stateful authentication
425/// - Permission and role management for RBAC
426/// - OAuth provider integration
427///
428/// ## Python Usage Example
429///
430/// ```python
431/// from dmsc import DMSCAuthConfig, DMSCJWTManager
432///
433/// # Create auth configuration
434/// config = DMSCAuthConfig(
435///     enabled=True,
436///     jwt_secret="secure-secret-key",
437///     jwt_expiry_secs=3600,
438///     session_timeout_secs=86400,
439///     oauth_providers=["google", "github"],
440///     enable_api_keys=True,
441///     enable_session_auth=True,
442/// )
443///
444/// # Create auth module
445/// auth_module = DMSCAuthModule(config)
446///
447/// # Get JWT manager and generate token
448/// jwt_manager = auth_module.jwt_manager()
449/// token = jwt_manager.generate_token("user123", ["user"], ["read:data"])
450/// ```
451#[pyo3::prelude::pymethods]
452impl DMSCAuthModule {
453    #[new]
454    fn py_new(config: DMSCAuthConfig) -> PyResult<Self> {
455        let rt = Handle::current();
456        rt.block_on(async {
457            Self::new(config).await
458                .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(e.to_string()))
459        })
460    }
461
462    #[getter]
463    fn get_config(&self) -> DMSCAuthConfig {
464        self.config.clone()
465    }
466
467    #[getter]
468    fn get_jwt_expiry_secs(&self) -> u64 {
469        self.jwt_manager.get_token_expiry()
470    }
471
472    #[getter]
473    fn get_session_timeout_secs(&self) -> u64 {
474        self.config.session_timeout_secs
475    }
476
477    #[getter]
478    fn is_enabled(&self) -> bool {
479        self.config.enabled
480    }
481
482    #[getter]
483    fn is_api_keys_enabled(&self) -> bool {
484        self.config.enable_api_keys
485    }
486
487    #[getter]
488    fn is_session_auth_enabled(&self) -> bool {
489        self.config.enable_session_auth
490    }
491
492    #[getter]
493    fn get_oauth_providers(&self) -> Vec<String> {
494        self.config.oauth_providers.clone()
495    }
496
497    fn validate_jwt_token(&self, token: &str) -> bool {
498        self.jwt_manager.validate_token(token).is_ok()
499    }
500
501    fn generate_test_token(&self, subject: &str, roles: Vec<String>, permissions: Vec<String>) -> PyResult<String> {
502        self.jwt_manager.generate_token(subject, roles, permissions)
503            .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(e.to_string()))
504    }
505}
506
507impl crate::core::ServiceModule for DMSCAuthModule {
508    fn name(&self) -> &str {
509        "DMSC.Auth"
510    }
511
512    fn is_critical(&self) -> bool {
513        false
514    }
515
516    fn priority(&self) -> i32 {
517        20
518    }
519
520    fn dependencies(&self) -> Vec<&str> {
521        vec![]
522    }
523
524    fn init(&mut self, _ctx: &mut crate::core::DMSCServiceContext) -> crate::core::DMSCResult<()> {
525        Ok(())
526    }
527
528    fn start(&mut self, _ctx: &mut crate::core::DMSCServiceContext) -> crate::core::DMSCResult<()> {
529        Ok(())
530    }
531
532    fn shutdown(&mut self, _ctx: &mut crate::core::DMSCServiceContext) -> crate::core::DMSCResult<()> {
533        Ok(())
534    }
535}
536
537#[async_trait::async_trait]
538impl crate::core::DMSCModule for DMSCAuthModule {
539    /// Returns the name of the authentication module.
540    /// 
541    /// # Returns
542    /// 
543    /// The module name as a string
544    fn name(&self) -> &str {
545        "DMSC.Auth"
546    }
547
548    /// Indicates whether the authentication module is critical.
549    /// 
550    /// The authentication module is non-critical, meaning that if it fails to initialize or operate,
551    /// it should not break the entire application. This allows the core functionality to continue
552    /// even if authentication features are unavailable.
553    /// 
554    /// # Returns
555    /// 
556    /// `false` since authentication is non-critical
557    fn is_critical(&self) -> bool {
558        false // Auth failures should not break the application
559    }
560
561    /// Initializes the authentication module asynchronously.
562    /// 
563    /// This method performs the following steps:
564    /// 1. Loads configuration from the service context
565    /// 2. Updates the module configuration if provided
566    /// 3. Reinitializes the JWT manager with the new configuration
567    /// 4. Initializes OAuth providers if configured
568    /// 
569    /// # Parameters
570    /// 
571    /// - `ctx`: The service context containing configuration
572    /// 
573    /// # Returns
574    /// 
575    /// A `DMSCResult<()>` indicating success or failure
576    async fn init(&mut self, ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
577        log::info!("Initializing DMSC Auth Module");
578
579        // Load configuration
580        let binding = ctx.config();
581        let cfg = binding.config();
582        
583        // Update configuration if provided
584        if let Some(auth_config) = cfg.get("auth") {
585            self.config = serde_yaml::from_str(auth_config)
586                .unwrap_or_else(|_| DMSCAuthConfig::default());
587        }
588
589        // Initialize JWT manager with new config
590        self.jwt_manager = Arc::new(DMSCJWTManager::create(self.config.jwt_secret.clone(), self.config.jwt_expiry_secs));
591
592        // Initialize OAuth providers if configured
593        if !self.config.oauth_providers.is_empty() {
594            for provider_name in &self.config.oauth_providers {
595                let client_id = load_oauth_env_var(provider_name, "CLIENT_ID")?;
596                let client_secret = load_oauth_env_var(provider_name, "CLIENT_SECRET")?;
597
598                let provider_config = crate::auth::oauth::DMSCOAuthProvider {
599                    id: provider_name.clone(),
600                    name: provider_name.clone(),
601                    client_id,
602                    client_secret,
603                    auth_url: get_oauth_url(provider_name, "authorize"),
604                    token_url: get_oauth_url(provider_name, "token"),
605                    user_info_url: get_oauth_url(provider_name, "userinfo"),
606                    scopes: vec!["openid".to_string(), "profile".to_string(), "email".to_string()],
607                    enabled: true,
608                    redirect_uri: None,
609                };
610                
611                let oauth_mgr = self.oauth_manager.write().await;
612                oauth_mgr.register_provider(provider_config).await?;
613                log::info!("OAuth provider registered: {provider_name}");
614            }
615        }
616
617        log::info!("DMSC Auth Module initialized successfully");
618        Ok(())
619    }
620
621    /// Performs asynchronous cleanup after the application has shut down.
622    /// 
623    /// This method cleans up all sessions managed by the session manager.
624    /// 
625    /// # Parameters
626    /// 
627    /// - `_ctx`: The service context (not used in this implementation)
628    /// 
629    /// # Returns
630    /// 
631    /// A `DMSCResult<()>` indicating success or failure
632    async fn after_shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
633        log::info!("Cleaning up DMSC Auth Module");
634        
635        // Cleanup sessions
636        let session_mgr = self.session_manager.write().await;
637        session_mgr.cleanup_all().await?;
638        
639        log::info!("DMSC Auth Module cleanup completed");
640        Ok(())
641    }
642}