frontend: Add redirect to login page for unauthorized requests

This commit is contained in:
Lennart
2024-11-03 16:23:37 +01:00
parent aead176cdb
commit 31c7143dd8
2 changed files with 35 additions and 7 deletions

View File

@@ -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<C: CalendarStore + ?Sized>(
}
}
fn unauthorized_handler<B>(res: ServiceResponse<B>) -> actix_web::Result<ErrorHandlerResponse<B>> {
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#"<!Doctype html>
<html>
<head>
<meta http-equiv="refresh" content="2; url={login_url}" />
</head>
<body>
Unauthorized, redirecting to <a href="{login_url}">login page</a>
</body>
<html>
"#
));
let res = ServiceResponse::new(req, response)
.map_into_boxed_body()
.map_into_right_body();
Ok(ErrorHandlerResponse::Response(res))
}
pub fn configure_frontend<AP: AuthenticationProvider, C: CalendarStore + ?Sized>(
cfg: &mut web::ServiceConfig,
auth_provider: Arc<AP>,
@@ -68,6 +95,7 @@ pub fn configure_frontend<AP: AuthenticationProvider, C: CalendarStore + ?Sized>
) {
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<AP: AuthenticationProvider, C: CalendarStore + ?Sized>
)
.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::<AP>)),
),

View File

@@ -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<actix_web::body::BoxBody> {
fn error_response(&self) -> HttpResponse<BoxBody> {
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<Result<Self, Self::Error>>;
@@ -47,7 +47,6 @@ impl FromRequest for User {
req.extensions()
.get::<Self>()
.cloned()
// .ok_or(ErrorUnauthorized("Not authenticated")),
.ok_or(UnauthorizedError),
)
}