From 0463714882173ff71461c07700692c80d134ef80 Mon Sep 17 00:00:00 2001 From: Ethan Girouard Date: Sun, 28 Jun 2026 11:56:18 -0400 Subject: [PATCH] Add middleware to require authentication for some routes --- src/server/main.rs | 11 +++++-- src/server/mod.rs | 1 + src/server/require_auth_mw.rs | 58 +++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 src/server/require_auth_mw.rs diff --git a/src/server/main.rs b/src/server/main.rs index 1b2230b..0fd0f6f 100644 --- a/src/server/main.rs +++ b/src/server/main.rs @@ -1,7 +1,13 @@ -use dioxus::{fullstack::axum::Router, server::axum::Extension}; +use dioxus::{ + fullstack::axum::{Router, middleware::from_fn}, + server::axum::Extension, +}; use crate::App; -use crate::server::{auth::build_auth_layer, config, database, key_val_store}; +use crate::server::{ + auth::build_auth_layer, config, database, key_val_store, + require_auth_mw::require_auth_middleware, +}; use crate::util::error::{Contextualize, Error, Result}; pub fn main() -> Result { @@ -31,6 +37,7 @@ async fn router_setup() -> Result { let auth_layer = build_auth_layer(db_pool.clone(), key_val_pool); let router = dioxus::server::router(App) + .layer(from_fn(require_auth_middleware)) .layer(Extension(config)) .layer(Extension(db_pool)) .layer(auth_layer); diff --git a/src/server/mod.rs b/src/server/mod.rs index 7246556..e534ab3 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -3,5 +3,6 @@ pub mod config; pub mod database; pub mod key_val_store; pub mod main; +pub mod require_auth_mw; pub use main::main; diff --git a/src/server/require_auth_mw.rs b/src/server/require_auth_mw.rs new file mode 100644 index 0000000..db5cc51 --- /dev/null +++ b/src/server/require_auth_mw.rs @@ -0,0 +1,58 @@ +use dioxus::fullstack::{ + axum::{body::Body, extract::Request, middleware::Next}, + extract::FromRequestParts, + http::Response, +}; +use dioxus::prelude::*; + +use crate::server::auth::AuthSession; + +const ALLOWED_PATH_PREFIX: [&str; 1] = ["/assets/"]; + +const ALLOWED_PATHS: [&str; 5] = [ + "/login", + "/signup", + "/api/v1/auth/login", + "/api/v1/auth/signup", + "/favicon.ico", +]; + +/// Axum middleware to redirect an unauthenticated request to /login unless it matches one of the allowed paths +pub async fn require_auth_middleware( + req: Request, + next: Next, +) -> Result, (StatusCode, &'static str)> { + let path = req.uri().path(); + + if ALLOWED_PATH_PREFIX + .iter() + .any(|prefix| path.starts_with(prefix)) + || ALLOWED_PATHS.contains(&path) + { + let response = next.run(req).await; + return Ok(response); + } + + let (mut parts, body) = req.into_parts(); + + let auth_session = AuthSession::from_request_parts(&mut parts, &()).await?; + + if auth_session.user.is_none() { + let response = Response::builder() + .status(StatusCode::TEMPORARY_REDIRECT) + .header("Location", "/login") + .body(Body::empty()) + .map_err(|_| { + ( + StatusCode::INTERNAL_SERVER_ERROR, + "Failed to build response", + ) + })?; + + return Ok(response); + } + + let req = Request::from_parts(parts, body); + let response = next.run(req).await; + Ok(response) +}