diff --git a/virtweb_backend/examples/api_curl.rs b/virtweb_backend/examples/api_curl.rs index c401f8d..a13cd93 100644 --- a/virtweb_backend/examples/api_curl.rs +++ b/virtweb_backend/examples/api_curl.rs @@ -7,7 +7,7 @@ use virtweb_backend::api_tokens::TokenVerb; use virtweb_backend::extractors::api_auth_extractor::TokenClaims; use virtweb_backend::utils::time_utils::time; -/// curl wrapper to query Virtweb backend API +/// cURL wrapper to query Virtweb backend API #[derive(Parser, Debug)] #[command(version, about, long_about = None)] struct Args { diff --git a/virtweb_backend/src/api_tokens.rs b/virtweb_backend/src/api_tokens.rs index 1adaa76..61d4548 100644 --- a/virtweb_backend/src/api_tokens.rs +++ b/virtweb_backend/src/api_tokens.rs @@ -33,12 +33,16 @@ impl TokenRights { if !r.path.starts_with("/api/") { return Some("All API rights shall start with /api/"); } + + if r.path.len() > constants::API_TOKEN_PATH_MAX_LENGTH { + return Some("An API path shall not exceed maximum URL size!"); + } } None } pub fn contains(&self, verb: TokenVerb, path: &str) -> bool { - let path_split = path.split('/').collect::>(); + let req_path_split = path.split('/').collect::>(); 'root: for r in &self.0 { if r.verb != verb { @@ -47,11 +51,11 @@ impl TokenRights { let mut last_idx = 0; for (idx, part) in r.path.split('/').enumerate() { - if idx >= path_split.len() { + if idx >= req_path_split.len() { continue 'root; } - if part != "*" && part != path_split[idx] { + if part != "*" && part != req_path_split[idx] { continue 'root; } @@ -59,7 +63,7 @@ impl TokenRights { } // Check we visited the whole path - if last_idx + 1 == path_split.len() { + if last_idx + 1 == req_path_split.len() { return true; } } @@ -283,6 +287,7 @@ mod test { ]); assert!(rights.contains(TokenVerb::GET, "/api/vm/ab")); + assert!(!rights.contains(TokenVerb::GET, "/api/vm")); assert!(!rights.contains(TokenVerb::GET, "/api/vm/ab/c")); assert!(rights.contains(TokenVerb::PUT, "/api/vm/a")); assert!(!rights.contains(TokenVerb::PUT, "/api/vm/other")); diff --git a/virtweb_backend/src/constants.rs b/virtweb_backend/src/constants.rs index 6cfbe9b..b8de4eb 100644 --- a/virtweb_backend/src/constants.rs +++ b/virtweb_backend/src/constants.rs @@ -104,3 +104,6 @@ pub const API_TOKEN_DESCRIPTION_MIN_LENGTH: usize = 5; /// API token description max length pub const API_TOKEN_DESCRIPTION_MAX_LENGTH: usize = 30; + +/// API token path max length +pub const API_TOKEN_PATH_MAX_LENGTH: usize = 255; diff --git a/virtweb_backend/src/controllers/server_controller.rs b/virtweb_backend/src/controllers/server_controller.rs index 6a80039..76a1dd3 100644 --- a/virtweb_backend/src/controllers/server_controller.rs +++ b/virtweb_backend/src/controllers/server_controller.rs @@ -112,7 +112,10 @@ pub async fn static_config(local_auth: LocalAuthEnabled) -> impl Responder { max: constants::API_TOKEN_DESCRIPTION_MAX_LENGTH, }, - api_token_right_path_size: LenConstraints { min: 0, max: 255 }, + api_token_right_path_size: LenConstraints { + min: 0, + max: constants::API_TOKEN_PATH_MAX_LENGTH, + }, }, }) } diff --git a/virtweb_frontend/src/widgets/TimeWidget.tsx b/virtweb_frontend/src/widgets/TimeWidget.tsx index 5dcb76e..bc16825 100644 --- a/virtweb_frontend/src/widgets/TimeWidget.tsx +++ b/virtweb_frontend/src/widgets/TimeWidget.tsx @@ -1,5 +1,6 @@ import { Tooltip } from "@mui/material"; import date from "date-and-time"; +import { time } from "../utils/DateUtils"; export function formatDate(time: number): string { const t = new Date(); @@ -50,8 +51,8 @@ export function timeDiff(a: number, b: number): string { return `${diffYears} years`; } -export function timeDiffFromNow(time: number): string { - return timeDiff(time, Math.floor(new Date().getTime() / 1000)); +export function timeDiffFromNow(t: number): string { + return timeDiff(t, time()); } export function TimeWidget(p: { time?: number }): React.ReactElement {