use crate::http::{HttpResponse, Response};
use crate::middleware::{Middleware, Next};
use crate::Request;
use async_trait::async_trait;
use super::guard::Auth;
pub struct AuthMiddleware {
redirect_to: Option<String>,
}
impl AuthMiddleware {
pub fn new() -> Self {
Self { redirect_to: None }
}
pub fn redirect_to(path: impl Into<String>) -> Self {
Self {
redirect_to: Some(path.into()),
}
}
}
impl Default for AuthMiddleware {
fn default() -> Self {
Self::new()
}
}
#[async_trait]
impl Middleware for AuthMiddleware {
async fn handle(&self, request: Request, next: Next) -> Response {
if Auth::check() {
return next(request).await;
}
match &self.redirect_to {
Some(path) => {
if request.is_inertia() {
Err(HttpResponse::text("")
.status(409)
.header("X-Inertia-Location", path.clone()))
} else {
Err(HttpResponse::new()
.status(302)
.header("Location", path.clone()))
}
}
None => {
Err(HttpResponse::json(serde_json::json!({
"message": "Unauthenticated."
}))
.status(401))
}
}
}
}
pub struct GuestMiddleware {
redirect_to: String,
}
impl GuestMiddleware {
pub fn redirect_to(path: impl Into<String>) -> Self {
Self {
redirect_to: path.into(),
}
}
pub fn new() -> Self {
Self::redirect_to("/")
}
}
impl Default for GuestMiddleware {
fn default() -> Self {
Self::new()
}
}
#[async_trait]
impl Middleware for GuestMiddleware {
async fn handle(&self, request: Request, next: Next) -> Response {
if Auth::guest() {
return next(request).await;
}
if request.is_inertia() {
Err(HttpResponse::text("")
.status(409)
.header("X-Inertia-Location", &self.redirect_to))
} else {
Err(HttpResponse::new()
.status(302)
.header("Location", &self.redirect_to))
}
}
}