use async_trait::async_trait;
use super::super::auth_strategy::{AuthConfig, AuthStrategy, Credentials};
use super::super::errors::AuthError;
#[derive(Debug, Default)]
pub struct PatAuthStrategy;
#[async_trait]
impl AuthStrategy for PatAuthStrategy {
async fn authenticate(&self, config: &AuthConfig) -> anyhow::Result<Credentials> {
let token = config
.get("token")
.ok_or_else(|| AuthError::MissingCredentials("token".to_string()))?;
let mut credentials = Credentials::new();
credentials.insert("token".to_string(), token.clone());
credentials.insert(
"authorization_header".to_string(),
format!("Bearer {token}"),
);
Ok(credentials)
}
fn validate_credentials(&self, credentials: &Credentials) -> bool {
credentials
.get("token")
.is_some_and(|token| !token.is_empty())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn wraps_the_token_in_a_bearer_authorization_header() {
let strategy = PatAuthStrategy;
let config = AuthConfig::from([("token".to_string(), "abc123".to_string())]);
let credentials = strategy.authenticate(&config).await.unwrap();
assert_eq!(
credentials.get("authorization_header").unwrap(),
"Bearer abc123"
);
}
#[tokio::test]
async fn rejects_a_config_missing_the_token() {
let strategy = PatAuthStrategy;
assert!(strategy.authenticate(&AuthConfig::new()).await.is_err());
}
}