diff --git a/src/routes/auth.rs b/src/routes/auth.rs index 32e5616..097bed6 100644 --- a/src/routes/auth.rs +++ b/src/routes/auth.rs @@ -9,6 +9,7 @@ use minijinja::context; use serde::Serialize; use crate::{constant, routes, squire, template}; +use crate::routes::authenticator::AuthToken; /// Struct for representing a JSON Response with a redirect URL. #[derive(Serialize)] @@ -119,19 +120,9 @@ pub async fn logout(config: web::Data>, pub async fn home(config: web::Data>, request: HttpRequest) -> HttpResponse { let auth_response = routes::authenticator::verify_token(&request, &config); - if !auth_response.ok { - let mut response = HttpResponse::Found(); - - // Set to the lowest possible second since deletion is not an option - let age = Duration::new(0, 1); - let cookie = Cookie::build("detail", auth_response.detail) - .http_only(true).max_age(age).finish(); - response.cookie(cookie); - response.append_header(("Location", "/error")); - return response.finish(); + return failed_auth(auth_response); } - squire::logger::log_connection(&request); log::debug!("{}", auth_response.detail); @@ -164,6 +155,7 @@ pub async fn home(config: web::Data>, #[get("/error")] pub async fn error(request: HttpRequest) -> HttpResponse { if let Some(detail) = request.cookie("detail") { + log::info!("Error response for /error: {}", detail.value()); let template = constant::ENV.lock().unwrap(); let session = template.get_template("session").unwrap(); return HttpResponse::build(StatusCode::OK) @@ -171,7 +163,31 @@ pub async fn error(request: HttpRequest) -> HttpResponse { .body(session.render(context!(reason => detail.value())).unwrap()); } + log::info!("Sending unauthorized response for /error"); return HttpResponse::build(StatusCode::OK) .content_type("text/html; charset=utf-8") .body(template::UNAUTHORIZED); } + +/// Constructs an `HttpResponse` for failed `session_token` verification. +/// +/// # Arguments +/// +/// * `auth_response` - The authentication response containing details of the failure. +/// +/// # Returns +/// +/// Returns an `HttpResponse` with a redirect, setting a cookie with the failure detail. +pub fn failed_auth(auth_response: AuthToken) -> HttpResponse { + let mut response = HttpResponse::build(StatusCode::FOUND); + let detail = auth_response.detail; + let age = Duration::new(3, 0); + let cookie = Cookie::build("detail", detail) + .path("/error") + .http_only(true) + .max_age(age) + .finish(); + response.cookie(cookie); + response.append_header(("Location", "/error")); + response.finish() +} diff --git a/src/routes/authenticator.rs b/src/routes/authenticator.rs index 4493702..e139c1b 100644 --- a/src/routes/authenticator.rs +++ b/src/routes/authenticator.rs @@ -141,10 +141,11 @@ pub fn verify_token(request: &HttpRequest, config: &Data config.session_duration as i64 { return AuthToken { ok: false, detail: "Session Expired".to_string(), username }; } return AuthToken { - ok: true, detail: format!("Session valid for {}s", timestamp + - config.session_duration as i64 - current_time), username + ok: true, + detail: format!("Session valid for {}s", timestamp + config.session_duration as i64 - current_time), + username }; } } - let ok = false; - let detail = "Invalid session token".to_string(); - let username = "NA".to_string(); - AuthToken { ok, detail, username } + AuthToken { + ok: false, detail: "Session information not found".to_string(), username: "NA".to_string() + } } diff --git a/src/routes/images.rs b/src/routes/images.rs index 77adaea..e53c8c3 100644 --- a/src/routes/images.rs +++ b/src/routes/images.rs @@ -24,7 +24,7 @@ pub async fn image_endpoint(request: HttpRequest, filename: web::Path) - }); } let filepath = IMAGES.join(&filename.to_string()); - log::info!("File lookup: {}", &filepath.to_string_lossy()); + log::debug!("Image file lookup: {}", &filepath.to_string_lossy()); match web::block(|| std::fs::read(filepath)).await { Ok(image_content) => HttpResponse::Ok() .content_type(filetype) diff --git a/src/routes/video.rs b/src/routes/video.rs index 550f4df..b89caea 100644 --- a/src/routes/video.rs +++ b/src/routes/video.rs @@ -2,8 +2,6 @@ use std::path::PathBuf; use std::sync::Arc; use actix_web::{HttpRequest, HttpResponse, web}; -use actix_web::cookie::Cookie; -use actix_web::cookie::time::Duration; use actix_web::http::StatusCode; use itertools::Itertools; use minijinja::context; @@ -12,7 +10,6 @@ use url::form_urlencoded; use crate::{constant, squire}; use crate::routes; -use crate::routes::authenticator::AuthToken; /// Represents the payload structure for deserializing data from the request query parameters. #[derive(Deserialize)] @@ -47,27 +44,6 @@ fn subtitles(target: PathBuf, target_str: String) -> Subtitles { Subtitles { srt, vtt, vtt_file } } -/// Constructs an `HttpResponse` for failed `session_token` verification. -/// -/// # Arguments -/// -/// * `auth_response` - The authentication response containing details of the failure. -/// -/// # Returns -/// -/// Returns an `HttpResponse` with a redirect, setting a cookie with the failure detail. -fn failed_auth(auth_response: AuthToken) -> HttpResponse { - let mut response = HttpResponse::Found(); - // todo: session page never shows up, either due to low cookie lifetime or no cookie transfer - // Set to the lowest possible second since deletion is not an option - let age = Duration::new(1, 0); - let cookie = Cookie::build("detail", auth_response.detail) - .http_only(true).max_age(age).finish(); - response.cookie(cookie); - response.append_header(("Location", "/error")); - response.finish() -} - /// Handles requests for the '/track/{track_path:.*}' endpoint, serving track files. /// /// # Arguments @@ -84,13 +60,14 @@ pub async fn track(config: web::Data>, request: HttpRequest, track_path: web::Path) -> HttpResponse { let auth_response = routes::authenticator::verify_token(&request, &config); if !auth_response.ok { - return failed_auth(auth_response); + return routes::auth::failed_auth(auth_response); } squire::logger::log_connection(&request); log::debug!("{}", auth_response.detail); let track_file = track_path.to_string(); log::info!("Track requested: {}", &track_file); let filepath = PathBuf::new().join(&config.video_source).join(track_file); + log::debug!("Track file lookup: {}", &filepath.to_string_lossy()); match std::fs::read_to_string(&filepath) { Ok(content) => HttpResponse::Ok() .content_type("text/plain") @@ -117,7 +94,7 @@ pub async fn stream(config: web::Data>, request: HttpRequest, video_path: web::Path) -> HttpResponse { let auth_response = routes::authenticator::verify_token(&request, &config); if !auth_response.ok { - return failed_auth(auth_response); + return routes::auth::failed_auth(auth_response); } squire::logger::log_connection(&request); log::debug!("{}", auth_response.detail); @@ -224,7 +201,7 @@ pub async fn streaming_endpoint(config: web::Data> request: HttpRequest, info: web::Query) -> HttpResponse { let auth_response = routes::authenticator::verify_token(&request, &config); if !auth_response.ok { - return failed_auth(auth_response); + return routes::auth::failed_auth(auth_response); } squire::logger::log_connection(&request); let host = request.connection_info().host().to_owned(); diff --git a/src/templates/session.html b/src/templates/session.html index 19a2fb9..c50f3fc 100644 --- a/src/templates/session.html +++ b/src/templates/session.html @@ -63,8 +63,8 @@

Click HERE to reach out.