use crate::config::AccountConfig;
use crate::secret::Secret;
pub async fn get_password(account_name: &str, config: &AccountConfig) -> crate::Result<String> {
let env_key = format!(
"AGENTMAIL_PASSWORD_{}",
account_name.to_uppercase().replace(['-', ' '], "_")
);
if let Ok(pw) = std::env::var(&env_key) {
return Ok(pw);
}
if let Some(ref secret) = config.password {
let pw = secret.get().await.map_err(|e| {
crate::AgentmailError::Credential(format!(
"Failed to retrieve password for account '{}': {}",
account_name, e
))
})?;
return Ok(pw);
}
let default_secret = Secret::new_keyring(format!("mail.{}", config.username));
if let Ok(pw) = default_secret.get().await {
return Ok(pw);
}
Err(crate::AgentmailError::Credential(format!(
"No password found for account '{}' (user='{}').\n\
Configure it in config.toml:\n \
password.keyring = \"{}\"\n \
password.cmd = \"security find-internet-password -s {} -a {} -w\"\n\
Or store it: agentmail set-password --account {}",
account_name, config.username, config.username, config.host, config.username, account_name
)))
}
pub async fn set_password(
account_name: &str,
config: &AccountConfig,
password: &str,
) -> crate::Result<()> {
let mut secret = match config.password {
Some(ref s @ Secret::Keyring(_)) => s.clone(),
_ => Secret::new_keyring(format!("mail.{}", config.username)),
};
secret.set(password).await.map_err(|e| {
crate::AgentmailError::Credential(format!(
"Failed to store password for account '{}': {}",
account_name, e
))
})?;
Ok(())
}