1use crate::auth::AdminAuth;
2use axum::{
3 extract::Request,
4 http::{header::LOCATION, StatusCode},
5 middleware::Next,
6 response::{IntoResponse, Response},
7 Extension,
8};
9use std::sync::Arc;
10use tower_cookies::Cookies;
11
12pub const SESSION_COOKIE: &str = "axum_admin_session";
13
14pub async fn require_auth(
15 cookies: Cookies,
16 Extension(auth): Extension<Arc<dyn AdminAuth>>,
17 mut req: Request,
18 next: Next,
19) -> Response {
20 let session_id = cookies.get(SESSION_COOKIE).map(|c| c.value().to_string());
21
22 if let Some(sid) = session_id {
23 if let Ok(Some(user)) = auth.get_session(&sid).await {
24 req.extensions_mut().insert(user);
25 return next.run(req).await;
26 }
27 }
28
29 let path = req.uri().path_and_query().map(|p| p.as_str()).unwrap_or("/admin/");
30 let encoded: String = form_urlencoded::Serializer::new(String::new())
31 .append_pair("next", path)
32 .finish();
33 let login_url = format!("/admin/login?{}", encoded);
34 (StatusCode::FOUND, [(LOCATION, login_url)]).into_response()
35}