claude_agent/auth/providers/
environment.rs1use async_trait::async_trait;
4
5use crate::auth::{Credential, CredentialProvider};
6use crate::{Error, Result};
7
8const DEFAULT_ENV_VAR: &str = "ANTHROPIC_API_KEY";
9
10pub struct EnvironmentProvider {
12 env_var: String,
13}
14
15impl EnvironmentProvider {
16 pub fn new() -> Self {
18 Self {
19 env_var: DEFAULT_ENV_VAR.to_string(),
20 }
21 }
22
23 pub fn with_var(env_var: impl Into<String>) -> Self {
25 Self {
26 env_var: env_var.into(),
27 }
28 }
29}
30
31impl Default for EnvironmentProvider {
32 fn default() -> Self {
33 Self::new()
34 }
35}
36
37#[async_trait]
38impl CredentialProvider for EnvironmentProvider {
39 fn name(&self) -> &str {
40 "environment"
41 }
42
43 async fn resolve(&self) -> Result<Credential> {
44 std::env::var(&self.env_var)
45 .map(Credential::api_key)
46 .map_err(|_| Error::auth(format!("{} not set", self.env_var)))
47 }
48}
49
50#[cfg(test)]
51mod tests {
52 use super::*;
53
54 #[tokio::test]
55 async fn test_environment_provider_missing() {
56 unsafe { std::env::remove_var("TEST_API_KEY_NOT_SET") };
57 let provider = EnvironmentProvider::with_var("TEST_API_KEY_NOT_SET");
58 assert!(provider.resolve().await.is_err());
59 }
60
61 #[tokio::test]
62 async fn test_environment_provider_set() {
63 unsafe { std::env::set_var("TEST_API_KEY_SET", "test-key") };
64 let provider = EnvironmentProvider::with_var("TEST_API_KEY_SET");
65 let cred = provider.resolve().await.unwrap();
66 assert!(matches!(cred, Credential::ApiKey(k) if k == "test-key"));
67 unsafe { std::env::remove_var("TEST_API_KEY_SET") };
68 }
69}