drasi_lib/identity/
mod.rs1use anyhow::Result;
18use async_trait::async_trait;
19
20#[async_trait]
22pub trait IdentityProvider: Send + Sync {
23 async fn get_credentials(&self) -> Result<Credentials>;
25
26 fn clone_box(&self) -> Box<dyn IdentityProvider>;
28}
29
30impl Clone for Box<dyn IdentityProvider> {
31 fn clone(&self) -> Self {
32 self.clone_box()
33 }
34}
35
36#[derive(Clone, PartialEq, Eq)]
38pub enum Credentials {
39 UsernamePassword { username: String, password: String },
41 Token { username: String, token: String },
43 Certificate {
48 cert_pem: String,
50 key_pem: String,
52 username: Option<String>,
54 },
55}
56
57impl Credentials {
58 pub fn into_auth_pair(self) -> (String, String) {
64 match self {
65 Credentials::UsernamePassword { username, password } => (username, password),
66 Credentials::Token { username, token } => (username, token),
67 Credentials::Certificate { .. } => {
68 panic!("Certificate credentials cannot be converted to an auth pair. Use into_certificate() instead.")
69 }
70 }
71 }
72
73 pub fn into_certificate(self) -> (String, String, Option<String>) {
80 match self {
81 Credentials::Certificate {
82 cert_pem,
83 key_pem,
84 username,
85 } => (cert_pem, key_pem, username),
86 _ => panic!("Not certificate credentials. Use into_auth_pair() instead."),
87 }
88 }
89
90 pub fn is_certificate(&self) -> bool {
92 matches!(self, Credentials::Certificate { .. })
93 }
94}
95
96mod password;
97pub use password::PasswordIdentityProvider;
98
99#[cfg(feature = "azure-identity")]
100mod azure;
101#[cfg(feature = "azure-identity")]
102pub use azure::AzureIdentityProvider;
103
104#[cfg(feature = "aws-identity")]
105mod aws;
106#[cfg(feature = "aws-identity")]
107pub use aws::AwsIdentityProvider;
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112
113 #[tokio::test]
114 async fn test_password_provider() {
115 let provider = PasswordIdentityProvider::new("testuser", "testpass");
116 let credentials = provider.get_credentials().await.unwrap();
117
118 match credentials {
119 Credentials::UsernamePassword { username, password } => {
120 assert_eq!(username, "testuser");
121 assert_eq!(password, "testpass");
122 }
123 _ => panic!("Expected UsernamePassword credentials"),
124 }
125 }
126
127 #[tokio::test]
128 async fn test_provider_clone() {
129 let provider: Box<dyn IdentityProvider> =
130 Box::new(PasswordIdentityProvider::new("user", "pass"));
131 let cloned = provider.clone();
132
133 let credentials = cloned.get_credentials().await.unwrap();
134 assert!(matches!(credentials, Credentials::UsernamePassword { .. }));
135 }
136}