use async_trait::async_trait;
use drogue_client::user::v1::authn::{AuthenticationRequest, AuthenticationResponse};
use std::fmt::{Debug, Formatter};
use std::sync::Arc;
use crate::auth::AuthError;
pub use drogue_client::user::v1::authn::AuthenticationRequest as Request;
pub use drogue_client::user::v1::authn::AuthenticationResponse as Response;
pub use drogue_client::user::v1::authn::Outcome;
#[derive(Clone)]
pub struct Authenticator {
service: Arc<dyn Service>,
}
impl Debug for Authenticator {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Authenticator").finish()
}
}
impl Authenticator {
pub fn new<S>(service: S) -> Self
where
S: Service + 'static,
{
Self {
service: Arc::new(service),
}
}
}
impl Authenticator {
pub async fn authenticate(
&self,
request: AuthenticationRequest,
) -> Result<AuthenticationResponse, AuthError> {
self.service.authenticate(request).await
}
}
#[async_trait]
pub trait Service {
async fn authenticate(
&self,
request: AuthenticationRequest,
) -> Result<AuthenticationResponse, AuthError>;
}
#[async_trait]
impl Service for drogue_client::user::v1::Client {
async fn authenticate(&self, request: Request) -> Result<AuthenticationResponse, AuthError> {
Ok(self
.authenticate_access_token(request)
.await
.map_err(|err| AuthError::Internal(err.to_string()))?)
}
}