use std::sync::Arc; use serde::{Deserialize, Serialize}; use crate::{Error, Result, 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) } 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 } }