kraken_api_client/auth/
credentials.rs1use secrecy::{ExposeSecret, SecretString};
4use std::sync::Arc;
5
6#[derive(Clone)]
8pub struct Credentials {
9 pub api_key: String,
11 api_secret: SecretString,
13}
14
15impl Credentials {
16 pub fn new(api_key: impl Into<String>, api_secret: impl Into<String>) -> Self {
18 Self {
19 api_key: api_key.into(),
20 api_secret: SecretString::from(api_secret.into()),
21 }
22 }
23
24 pub fn expose_secret(&self) -> &str {
28 self.api_secret.expose_secret()
29 }
30}
31
32impl std::fmt::Debug for Credentials {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 f.debug_struct("Credentials")
35 .field("api_key", &self.api_key)
36 .field("api_secret", &"[REDACTED]")
37 .finish()
38 }
39}
40
41pub trait CredentialsProvider: Send + Sync {
46 fn get_credentials(&self) -> &Credentials;
48}
49
50#[derive(Clone)]
52pub struct StaticCredentials {
53 credentials: Credentials,
54}
55
56impl StaticCredentials {
57 pub fn new(api_key: impl Into<String>, api_secret: impl Into<String>) -> Self {
59 Self {
60 credentials: Credentials::new(api_key, api_secret),
61 }
62 }
63}
64
65impl CredentialsProvider for StaticCredentials {
66 fn get_credentials(&self) -> &Credentials {
67 &self.credentials
68 }
69}
70
71impl CredentialsProvider for Arc<StaticCredentials> {
72 fn get_credentials(&self) -> &Credentials {
73 &self.credentials
74 }
75}
76
77pub struct EnvCredentials {
81 credentials: Credentials,
82}
83
84impl EnvCredentials {
85 pub fn from_env() -> Self {
93 Self::from_env_vars("KRAKEN_API_KEY", "KRAKEN_API_SECRET")
94 }
95
96 pub fn from_env_vars(key_var: &str, secret_var: &str) -> Self {
102 let api_key = std::env::var(key_var)
103 .unwrap_or_else(|_| panic!("Environment variable {key_var} not set"));
104 let api_secret = std::env::var(secret_var)
105 .unwrap_or_else(|_| panic!("Environment variable {secret_var} not set"));
106
107 Self {
108 credentials: Credentials::new(api_key, api_secret),
109 }
110 }
111
112 pub fn try_from_env() -> Option<Self> {
116 Self::try_from_env_vars("KRAKEN_API_KEY", "KRAKEN_API_SECRET")
117 }
118
119 pub fn try_from_env_vars(key_var: &str, secret_var: &str) -> Option<Self> {
123 let api_key = std::env::var(key_var).ok()?;
124 let api_secret = std::env::var(secret_var).ok()?;
125
126 Some(Self {
127 credentials: Credentials::new(api_key, api_secret),
128 })
129 }
130}
131
132impl CredentialsProvider for EnvCredentials {
133 fn get_credentials(&self) -> &Credentials {
134 &self.credentials
135 }
136}
137
138#[cfg(test)]
139mod tests {
140 use super::*;
141
142 #[test]
143 fn test_credentials_debug_redacted() {
144 let creds = Credentials::new("my_key", "super_secret");
145 let debug_str = format!("{:?}", creds);
146 assert!(debug_str.contains("my_key"));
147 assert!(!debug_str.contains("super_secret"));
148 assert!(debug_str.contains("[REDACTED]"));
149 }
150
151 #[test]
152 fn test_static_credentials() {
153 let provider = StaticCredentials::new("key", "secret");
154 let creds = provider.get_credentials();
155 assert_eq!(creds.api_key, "key");
156 assert_eq!(creds.expose_secret(), "secret");
157 }
158}