1use axum::extract::FromRequestParts;
4use axum::http::request::Parts;
5use axum_login::{AuthSession, AuthnBackend};
6use purwa_core::PurwaError;
7
8#[derive(Debug, Clone)]
12pub struct CurrentUser<B>(pub B::User)
13where
14 B: AuthnBackend + Clone + Send + Sync + 'static,
15 B::User: std::fmt::Debug + Clone + Send + Sync + 'static;
16
17impl<S, B> FromRequestParts<S> for CurrentUser<B>
18where
19 B: AuthnBackend + Clone + Send + Sync + 'static,
20 B::User: std::fmt::Debug + Clone + Send + Sync + 'static,
21 S: Send + Sync,
22{
23 type Rejection = PurwaError;
24
25 async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
26 let auth = AuthSession::<B>::from_request_parts(parts, state)
27 .await
28 .map_err(|_| PurwaError::internal("auth session unavailable"))?;
29
30 let Some(user) = auth.user.clone() else {
31 return Err(PurwaError::unauthorized("login required"));
32 };
33
34 Ok(CurrentUser(user))
35 }
36}