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_settings::constants;
8
9use crate::token;
10
11#[derive(Debug, Clone)]
12pub struct MaybeUser {
13 pub name: String,
14 pub is_admin: bool,
15 pub is_read_only: bool,
16}
17
18impl MaybeUser {
19 pub fn from_token(token: token::Token) -> Self {
20 Self {
21 name: token.user,
22 is_admin: token.is_admin,
23 is_read_only: token.is_read_only,
24 }
25 }
26
27 pub fn from_session(name: String, is_admin: bool) -> Self {
28 Self {
29 name,
30 is_admin,
31 is_read_only: false,
34 }
35 }
36}
37
38impl FromRequestParts<AppStateData> for MaybeUser {
39 type Rejection = StatusCode;
40
41 async fn from_request_parts(
42 parts: &mut Parts,
43 state: &AppStateData,
44 ) -> Result<Self, Self::Rejection> {
45 if let Ok(t) = token::Token::from_request_parts(parts, state).await {
47 return Ok(Self::from_token(t));
48 }
49
50 let jar: PrivateCookieJar = parts
52 .extract_with_state(state)
53 .await
54 .map_err(|_| StatusCode::UNAUTHORIZED)?;
55
56 let session_cookie = jar
57 .get(constants::COOKIE_SESSION_ID)
58 .ok_or(StatusCode::UNAUTHORIZED)?;
59
60 let (name, is_admin) = state
61 .db
62 .validate_session(session_cookie.value())
63 .await
64 .map_err(|_| StatusCode::UNAUTHORIZED)?;
65
66 Ok(Self::from_session(name, is_admin))
67 }
68}