kellnr_auth/
maybe_user.rs1use axum::RequestPartsExt;
2use axum::extract::FromRequestParts;
3use axum::http::StatusCode;
4use axum::http::request::Parts;
5use axum_extra::extract::PrivateCookieJar;
6use kellnr_appstate::AppStateData;
7use kellnr_db::SessionInfo;
8use kellnr_settings::constants;
9
10use crate::token;
11
12#[derive(Debug, Clone)]
13pub struct MaybeUser {
14 pub name: String,
15 pub is_admin: bool,
16 pub is_read_only: bool,
17}
18
19impl MaybeUser {
20 pub fn from_token(token: token::Token) -> Self {
21 Self {
22 name: token.user,
23 is_admin: token.is_admin,
24 is_read_only: token.is_read_only,
25 }
26 }
27
28 pub fn from_session(session: SessionInfo) -> Self {
29 Self {
30 name: session.name,
31 is_admin: session.is_admin,
32 is_read_only: session.is_read_only,
33 }
34 }
35}
36
37impl FromRequestParts<AppStateData> for MaybeUser {
38 type Rejection = StatusCode;
39
40 async fn from_request_parts(
41 parts: &mut Parts,
42 state: &AppStateData,
43 ) -> Result<Self, Self::Rejection> {
44 if let Ok(t) = token::Token::from_request_parts(parts, state).await {
46 return Ok(Self::from_token(t));
47 }
48
49 let jar: PrivateCookieJar = parts
51 .extract_with_state(state)
52 .await
53 .map_err(|_| StatusCode::UNAUTHORIZED)?;
54
55 let session_cookie = jar
56 .get(constants::COOKIE_SESSION_ID)
57 .ok_or(StatusCode::UNAUTHORIZED)?;
58
59 let session = state
60 .db
61 .validate_session(session_cookie.value())
62 .await
63 .map_err(|_| StatusCode::UNAUTHORIZED)?;
64
65 Ok(Self::from_session(session))
66 }
67}