author_axum/
user.rs

1use crate::session::Session;
2use author_web::user::UserSession;
3use axum::async_trait;
4use axum::extract::FromRequestParts;
5use axum::http::request::Parts;
6use axum::http::StatusCode;
7use std::marker::PhantomData;
8use tracing::trace;
9
10#[derive(Clone)]
11pub struct User<U: Clone, Sess>(pub U, pub PhantomData<Sess>);
12
13#[derive(Clone)]
14pub struct UserWithRole<U: Clone>(pub U);
15
16#[async_trait]
17impl<S, U, Sess> FromRequestParts<S> for User<U, Sess>
18where
19    Sess: UserSession<User = U> + Clone + Send + Sync + 'static,
20    U: Clone,
21{
22    type Rejection = (StatusCode, &'static str);
23
24    async fn from_request_parts(parts: &mut Parts, _state: &S) -> Result<Self, Self::Rejection> {
25        trace!("Loading user for request");
26
27        let Session(session) = parts
28            .extensions
29            .get::<Session<Sess>>()
30            .cloned()
31            .ok_or((StatusCode::FORBIDDEN, "Forbidden"))?;
32
33        trace!("Loaded session");
34
35        let user = session
36            .current_user()
37            .await
38            .map_err(|_| (StatusCode::FORBIDDEN, "Forbidden"))?
39            .ok_or((StatusCode::FORBIDDEN, "Forbidden"))?;
40
41        trace!("Loaded user");
42
43        Ok(User(user, PhantomData::default()))
44    }
45}