Add API tokens support #9
@ -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 {
|
||||
|
@ -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::<Vec<_>>();
|
||||
let req_path_split = path.split('/').collect::<Vec<_>>();
|
||||
|
||||
'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"));
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user