use async_trait::async_trait;
use crate::AuthenticationError;
use crate::core::AuthIdentity;
#[async_trait]
pub trait AuthBackend: Send + Sync {
async fn authenticate(
&self,
request: &reinhardt_http::Request,
) -> Result<Option<Box<dyn AuthIdentity>>, AuthenticationError>;
async fn get_user(
&self,
user_id: &str,
) -> Result<Option<Box<dyn AuthIdentity>>, AuthenticationError>;
}
pub struct CompositeAuthBackend {
backends: Vec<Box<dyn AuthBackend>>,
}
impl CompositeAuthBackend {
pub fn new() -> Self {
Self {
backends: Vec::new(),
}
}
pub fn add_backend(&mut self, backend: Box<dyn AuthBackend>) {
self.backends.push(backend);
}
}
impl Default for CompositeAuthBackend {
fn default() -> Self {
Self::new()
}
}
#[async_trait]
impl AuthBackend for CompositeAuthBackend {
async fn authenticate(
&self,
request: &reinhardt_http::Request,
) -> Result<Option<Box<dyn AuthIdentity>>, AuthenticationError> {
for backend in &self.backends {
if let Some(user) = backend.authenticate(request).await? {
return Ok(Some(user));
}
}
Ok(None)
}
async fn get_user(
&self,
user_id: &str,
) -> Result<Option<Box<dyn AuthIdentity>>, AuthenticationError> {
for backend in &self.backends {
if let Some(user) = backend.get_user(user_id).await? {
return Ok(Some(user));
}
}
Ok(None)
}
}