walker_common/sender/provider/
mod.rs

1//! Token provider functionality
2
3mod bearer_token;
4mod expires;
5mod inject;
6mod openid;
7
8pub use self::bearer_token::*;
9pub use self::expires::*;
10pub use self::inject::*;
11pub use self::openid::*;
12
13use crate::sender::Error;
14use async_trait::async_trait;
15use base64::{prelude::BASE64_STANDARD, write::EncoderStringWriter};
16use std::fmt::Debug;
17use std::io::Write;
18use std::sync::Arc;
19
20#[derive(Clone, Debug)]
21pub enum Credentials {
22    Bearer(String),
23    Basic(String, Option<String>),
24}
25
26impl Credentials {
27    /// Turn this into a value suitable for an `Authorization` header
28    pub fn to_authorization_value(&self) -> String {
29        match self {
30            Self::Bearer(token) => format!("Bearer {token}"),
31            Self::Basic(username, password) => {
32                let mut encoder = EncoderStringWriter::new(&BASE64_STANDARD);
33                let _ = write!(encoder, "{}:", username);
34                if let Some(password) = password {
35                    let _ = write!(encoder, "{}", password);
36                }
37                encoder.into_inner()
38            }
39        }
40    }
41}
42
43/// A provider for access credentials (mostly access tokens).
44#[async_trait]
45pub trait TokenProvider: Send + Sync {
46    async fn provide_access_token(&self) -> Result<Option<Credentials>, Error>;
47}
48
49#[async_trait]
50impl<T> TokenProvider for Arc<T>
51where
52    T: TokenProvider,
53{
54    async fn provide_access_token(&self) -> Result<Option<Credentials>, Error> {
55        self.as_ref().provide_access_token().await
56    }
57}
58
59#[async_trait]
60impl<T> TokenProvider for &Arc<T>
61where
62    T: TokenProvider,
63{
64    async fn provide_access_token(&self) -> Result<Option<Credentials>, Error> {
65        self.as_ref().provide_access_token().await
66    }
67}
68
69#[async_trait]
70impl TokenProvider for Arc<dyn TokenProvider> {
71    async fn provide_access_token(&self) -> Result<Option<Credentials>, Error> {
72        self.as_ref().provide_access_token().await
73    }
74}
75
76/// A token provider which does not provide tokens.
77#[derive(Debug, Clone, Copy)]
78pub struct NoTokenProvider;
79
80#[async_trait]
81impl TokenProvider for NoTokenProvider {
82    async fn provide_access_token(&self) -> Result<Option<Credentials>, Error> {
83        Ok(None)
84    }
85}
86
87#[async_trait]
88impl TokenProvider for () {
89    async fn provide_access_token(&self) -> Result<Option<Credentials>, Error> {
90        Ok(None)
91    }
92}
93
94#[async_trait]
95impl<T> TokenProvider for Option<T>
96where
97    T: TokenProvider + Sync,
98{
99    async fn provide_access_token(&self) -> Result<Option<Credentials>, Error> {
100        match self {
101            None => Ok(None),
102            Some(provider) => provider.provide_access_token().await,
103        }
104    }
105}
106
107#[async_trait]
108impl TokenProvider for String {
109    async fn provide_access_token(&self) -> Result<Option<Credentials>, Error> {
110        Ok(Some(Credentials::Bearer(self.clone())))
111    }
112}