use axum::extract::Request;
use axum::middleware::Next;
use axum::response::{IntoResponse, Redirect, Response};
use larust_http::session::Session;
use crate::guard;
use crate::Authenticatable;
pub async fn require_auth(session: Session, request: Request, next: Next) -> Response {
match guard::check(&session).await {
Ok(true) => next.run(request).await,
Ok(false) => Redirect::to(&login_path()).into_response(),
Err(error) => {
tracing::warn!(%error, "require_auth: failed to read session; denying access");
Redirect::to(&login_path()).into_response()
}
}
}
pub async fn require_auth_for<U: Authenticatable>(
session: Session,
request: Request,
next: Next,
) -> Response {
match guard::check_for::<U>(&session).await {
Ok(true) => next.run(request).await,
Ok(false) => Redirect::to(&guard_login_path(U::GUARD)).into_response(),
Err(error) => {
tracing::warn!(%error, "require_auth_for: failed to read session; denying access");
Redirect::to(&guard_login_path(U::GUARD)).into_response()
}
}
}
pub async fn redirect_authenticated(session: Session, request: Request, next: Next) -> Response {
match guard::check(&session).await {
Ok(true) => Redirect::to("/").into_response(),
Ok(false) => next.run(request).await,
Err(error) => {
tracing::warn!(%error, "redirect_authenticated: failed to read session; allowing access");
next.run(request).await
}
}
}
pub async fn redirect_authenticated_for<U: Authenticatable>(
session: Session,
request: Request,
next: Next,
) -> Response {
match guard::check_for::<U>(&session).await {
Ok(true) => Redirect::to("/").into_response(),
Ok(false) => next.run(request).await,
Err(error) => {
tracing::warn!(%error, "redirect_authenticated_for: failed to read session; allowing access");
next.run(request).await
}
}
}
fn login_path() -> String {
larust_http::resolve_route_name("login").unwrap_or_else(|| {
tracing::warn!(
"require_auth: no route named `login` is registered; falling back to /login"
);
"/login".to_string()
})
}
fn guard_login_path(guard: &str) -> String {
let guard_specific_name = format!("{guard}.login");
larust_http::resolve_route_name(&guard_specific_name).unwrap_or_else(|| {
tracing::warn!(
"require_auth_for::<{guard}>: no route named `{guard_specific_name}` is \
registered; falling back to the default `login` route"
);
login_path()
})
}