Skip to content

Commit

Permalink
Fix rendering unauthorized instead of session page
Browse files Browse the repository at this point in the history
Remove redundancies
  • Loading branch information
dormant-user committed Feb 13, 2024
1 parent 1e72b38 commit e1ec493
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 52 deletions.
38 changes: 27 additions & 11 deletions src/routes/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -119,19 +120,9 @@ pub async fn logout(config: web::Data<Arc<squire::settings::Config>>,
pub async fn home(config: web::Data<Arc<squire::settings::Config>>,
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);

Expand Down Expand Up @@ -164,14 +155,39 @@ pub async fn home(config: web::Data<Arc<squire::settings::Config>>,
#[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)
.content_type("text/html; charset=utf-8")
.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()
}
25 changes: 14 additions & 11 deletions src/routes/authenticator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,11 @@ pub fn verify_token(request: &HttpRequest, config: &Data<Arc<squire::settings::C
// fixme: debate if this is useful, since unauthorized page will be rendered instead of session if server restarts
if SESSION_MAPPING.lock().unwrap().is_empty() {
log::warn!("No stored sessions, no point in validating further");
let ok = false;
let detail = "".to_string();
let username = "NA".to_string();
return AuthToken { ok, detail, username };
return AuthToken {
ok: false,
detail: "Server doesn't recognize your session".to_string(),
username: "NA".to_string()
};
}
if let Some(cookie) = request.cookie("session_token") {
if let Ok(decrypted) = constant::FERNET.decrypt(cookie.value()) {
Expand All @@ -156,19 +157,21 @@ pub fn verify_token(request: &HttpRequest, config: &Data<Arc<squire::settings::C
let current_time = Utc::now().timestamp();
// Max time and expiry for session token is set in the Cookie, but this is a fallback mechanism
if stored_key != *cookie_key {
return AuthToken { ok: false, detail: "Invalid session token".to_string(), username };
return AuthToken {
ok: false, detail: "Invalid session token".to_string(), username
};
}
if current_time - timestamp > 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()
}
}
2 changes: 1 addition & 1 deletion src/routes/images.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub async fn image_endpoint(request: HttpRequest, filename: web::Path<String>) -
});
}
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)
Expand Down
31 changes: 4 additions & 27 deletions src/routes/video.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)]
Expand Down Expand Up @@ -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
Expand All @@ -84,13 +60,14 @@ pub async fn track(config: web::Data<Arc<squire::settings::Config>>,
request: HttpRequest, track_path: web::Path<String>) -> 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")
Expand All @@ -117,7 +94,7 @@ pub async fn stream(config: web::Data<Arc<squire::settings::Config>>,
request: HttpRequest, video_path: web::Path<String>) -> 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);
Expand Down Expand Up @@ -224,7 +201,7 @@ pub async fn streaming_endpoint(config: web::Data<Arc<squire::settings::Config>>
request: HttpRequest, info: web::Query<Payload>) -> 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();
Expand Down
4 changes: 2 additions & 2 deletions src/templates/session.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ <h4>Click <a href="https://vigneshrao.com/contact">HERE</a> to reach out.</h4>
</body>
<script>
document.addEventListener("DOMContentLoaded", function() {
var image = document.getElementById("session_img");
var currentLocation = window.location.href;
let image = document.getElementById("session_img");
let currentLocation = window.location.origin;
image.src = currentLocation + "/images/session.gif";
});
</script>
Expand Down

0 comments on commit e1ec493

Please sign in to comment.