code_mesh_core/auth/
storage.rs

1//! Authentication storage implementation
2
3use async_trait::async_trait;
4use super::{AuthStorage, AuthCredentials};
5use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7use tokio::fs;
8
9#[derive(Serialize, Deserialize)]
10struct AuthData {
11    credentials: HashMap<String, AuthCredentials>,
12}
13
14#[async_trait]
15impl AuthStorage for super::FileAuthStorage {
16    async fn get(&self, provider_id: &str) -> crate::Result<Option<AuthCredentials>> {
17        if !self.path.exists() {
18            return Ok(None);
19        }
20        
21        let data = fs::read_to_string(&self.path).await?;
22        let auth_data: AuthData = serde_json::from_str(&data)?;
23        
24        Ok(auth_data.credentials.get(provider_id).cloned())
25    }
26    
27    async fn set(&self, provider_id: &str, credentials: AuthCredentials) -> crate::Result<()> {
28        // Create parent directory if needed
29        if let Some(parent) = self.path.parent() {
30            fs::create_dir_all(parent).await?;
31        }
32        
33        // Load existing data or create new
34        let mut auth_data = if self.path.exists() {
35            let data = fs::read_to_string(&self.path).await?;
36            serde_json::from_str(&data)?
37        } else {
38            AuthData {
39                credentials: HashMap::new(),
40            }
41        };
42        
43        // Update credentials
44        auth_data.credentials.insert(provider_id.to_string(), credentials);
45        
46        // Write back with restrictive permissions
47        let json = serde_json::to_string_pretty(&auth_data)?;
48        fs::write(&self.path, json).await?;
49        
50        // Set file permissions (Unix only)
51        #[cfg(unix)]
52        {
53            use std::os::unix::fs::PermissionsExt;
54            let mut perms = fs::metadata(&self.path).await?.permissions();
55            perms.set_mode(0o600);
56            fs::set_permissions(&self.path, perms).await?;
57        }
58        
59        Ok(())
60    }
61    
62    async fn remove(&self, provider_id: &str) -> crate::Result<()> {
63        if !self.path.exists() {
64            return Ok(());
65        }
66        
67        let data = fs::read_to_string(&self.path).await?;
68        let mut auth_data: AuthData = serde_json::from_str(&data)?;
69        
70        auth_data.credentials.remove(provider_id);
71        
72        let json = serde_json::to_string_pretty(&auth_data)?;
73        fs::write(&self.path, json).await?;
74        
75        Ok(())
76    }
77    
78    async fn list(&self) -> crate::Result<Vec<String>> {
79        if !self.path.exists() {
80            return Ok(Vec::new());
81        }
82        
83        let data = fs::read_to_string(&self.path).await?;
84        let auth_data: AuthData = serde_json::from_str(&data)?;
85        
86        Ok(auth_data.credentials.keys().cloned().collect())
87    }
88}