Files
loft/backend/src/web/mw_auth.rs

55 lines
1.4 KiB
Rust

use axum::{
extract::{FromRequestParts, Request, State},
middleware::Next,
response::Response,
};
use tower_cookies::Cookies;
use crate::{
ctx::Ctx,
error::{LoftError, Result},
model::UserRepository,
web::AUTH_TOKEN,
};
pub async fn mw_require_auth(ctx: Result<Ctx>, req: Request, next: Next) -> Result<Response> {
ctx?;
Ok(next.run(req).await)
}
pub async fn mw_ctx_resolver(
State(user_repository): State<UserRepository>,
cookies: Cookies,
mut req: Request,
next: Next,
) -> Result<Response> {
let auth_token = cookies.get(AUTH_TOKEN).map(|c| c.value().to_string());
let result_ctx = match auth_token {
Some(token) => user_repository
.get_session(&token)
.await
.and_then(|s| s.ok_or(LoftError::AuthFailSessionNotFound))
.map(|s| Ctx::new(s.user_id)),
None => Err(LoftError::AuthFailNoAuthTokenCookie),
};
req.extensions_mut().insert(result_ctx);
Ok(next.run(req).await)
}
impl<S: Send + Sync> FromRequestParts<S> for Ctx {
type Rejection = LoftError;
async fn from_request_parts(
parts: &mut axum::http::request::Parts,
_: &S,
) -> Result<Self, Self::Rejection> {
parts
.extensions
.get::<Result<Ctx>>()
.ok_or(LoftError::AuthFailCtxNotInRequestExt)?
.clone()
}
}