use std::sync::Arc; use serde::{Deserialize, Serialize}; use crate::{Error, Result, oauth::OAuthToken, storage::StorageManager}; #[derive(Serialize, Deserialize, Debug)] pub struct ApiCredentials { pub api_key: String, pub endpoint: String, } pub const OLLAMA_CLOUD_CREDENTIAL_ID: &str = "provider_ollama_cloud"; pub struct CredentialManager { storage: Arc, master_key: Arc>, namespace: String, } impl CredentialManager { pub fn new(storage: Arc, master_key: Arc>) -> Self { Self { storage, master_key, namespace: "owlen".to_string(), } } fn namespaced_key(&self, tool_name: &str) -> String { format!("{}_{}", self.namespace, tool_name) } fn oauth_storage_key(&self, resource: &str) -> String { self.namespaced_key(&format!("oauth_{resource}")) } pub async fn store_credentials( &self, tool_name: &str, credentials: &ApiCredentials, ) -> Result<()> { let key = self.namespaced_key(tool_name); let payload = serde_json::to_vec(credentials).map_err(|e| { Error::Storage(format!( "Failed to serialize credentials for secure storage: {e}" )) })?; self.storage .store_secure_item(&key, &payload, &self.master_key) .await } pub async fn get_credentials(&self, tool_name: &str) -> Result> { let key = self.namespaced_key(tool_name); match self .storage .load_secure_item(&key, &self.master_key) .await? { Some(bytes) => { let creds = serde_json::from_slice(&bytes).map_err(|e| { Error::Storage(format!("Failed to deserialize stored credentials: {e}")) })?; Ok(Some(creds)) } None => Ok(None), } } pub async fn delete_credentials(&self, tool_name: &str) -> Result<()> { let key = self.namespaced_key(tool_name); self.storage.delete_secure_item(&key).await } pub async fn store_oauth_token(&self, resource: &str, token: &OAuthToken) -> Result<()> { let key = self.oauth_storage_key(resource); let payload = serde_json::to_vec(token).map_err(|err| { Error::Storage(format!( "Failed to serialize OAuth token for secure storage: {err}" )) })?; self.storage .store_secure_item(&key, &payload, &self.master_key) .await } pub async fn load_oauth_token(&self, resource: &str) -> Result> { let key = self.oauth_storage_key(resource); let raw = self .storage .load_secure_item(&key, &self.master_key) .await?; if let Some(bytes) = raw { let token = serde_json::from_slice(&bytes).map_err(|err| { Error::Storage(format!("Failed to deserialize stored OAuth token: {err}")) })?; Ok(Some(token)) } else { Ok(None) } } pub async fn delete_oauth_token(&self, resource: &str) -> Result<()> { let key = self.oauth_storage_key(resource); self.storage.delete_secure_item(&key).await } }