diff --git a/crates/frontend/src/lib.rs b/crates/frontend/src/lib.rs index 16381f7..85b34b9 100644 --- a/crates/frontend/src/lib.rs +++ b/crates/frontend/src/lib.rs @@ -3,9 +3,11 @@ use actix_session::{ }; use actix_web::{ cookie::{Key, SameSite}, - http::Method, - web::{self, Data, Path}, - Responder, + dev::ServiceResponse, + http::{Method, StatusCode}, + middleware::{ErrorHandlerResponse, ErrorHandlers}, + web::{self, Data, Path, Redirect}, + HttpResponse, Responder, }; use askama::Template; use assets::{Assets, EmbedService}; @@ -60,6 +62,31 @@ async fn route_calendar( } } +fn unauthorized_handler(res: ServiceResponse) -> actix_web::Result> { + let (req, _) = res.into_parts(); + let login_url = req.url_for_static("frontend_login").unwrap().to_string(); + + // let response = Redirect::to(login_url).respond_to(&req); + let response = HttpResponse::Unauthorized().body(format!( + r#" + + + + + + Unauthorized, redirecting to login page + + + "# + )); + + let res = ServiceResponse::new(req, response) + .map_into_boxed_body() + .map_into_right_body(); + + Ok(ErrorHandlerResponse::Response(res)) +} + pub fn configure_frontend( cfg: &mut web::ServiceConfig, auth_provider: Arc, @@ -68,6 +95,7 @@ pub fn configure_frontend ) { cfg.service( web::scope("") + .wrap(ErrorHandlers::new().handler(StatusCode::UNAUTHORIZED, unauthorized_handler)) .wrap(AuthenticationMiddleware::new(auth_provider.clone())) .wrap( SessionMiddleware::builder( @@ -91,6 +119,7 @@ pub fn configure_frontend ) .service( web::resource("/login") + .name("frontend_login") .route(web::method(Method::GET).to(route_get_login)) .route(web::method(Method::POST).to(route_post_login::)), ), diff --git a/crates/store/src/auth/user.rs b/crates/store/src/auth/user.rs index ef86522..e9df3cc 100644 --- a/crates/store/src/auth/user.rs +++ b/crates/store/src/auth/user.rs @@ -1,8 +1,9 @@ use actix_web::{ + body::BoxBody, http::{header, StatusCode}, FromRequest, HttpMessage, HttpResponse, ResponseError, }; -use derive_more::Display; +use derive_more::{derive::Deref, Display}; use serde::{Deserialize, Serialize}; use std::future::{ready, Ready}; @@ -20,7 +21,7 @@ impl ResponseError for UnauthorizedError { fn status_code(&self) -> actix_web::http::StatusCode { StatusCode::UNAUTHORIZED } - fn error_response(&self) -> actix_web::HttpResponse { + fn error_response(&self) -> HttpResponse { HttpResponse::build(StatusCode::UNAUTHORIZED) .insert_header(( header::WWW_AUTHENTICATE, @@ -35,7 +36,6 @@ impl ResponseError for UnauthorizedError { } impl FromRequest for User { - // type Error = actix_web::Error; type Error = UnauthorizedError; type Future = Ready>; @@ -47,7 +47,6 @@ impl FromRequest for User { req.extensions() .get::() .cloned() - // .ok_or(ErrorUnauthorized("Not authenticated")), .ok_or(UnauthorizedError), ) }