use crate::error::AkribesError;
pub fn assert_token_safe_in_url(token: &str) -> Result<(), AkribesError> {
if token.starts_with("akribes_tk_") || token.starts_with("aura_tk_") {
return Ok(());
}
Err(AkribesError::Other(
"Refusing to put a non-scoped token in the URL query string. \
Scoped tokens (akribes_tk_…) may be passed in ?token= because \
they are short-lived and revokable; service tokens (the secret \
half of AKRIBES_SERVICE_TOKEN_<NAME>=*:secret) MUST use header \
bearer auth and never appear in URLs that hit access logs."
.to_string(),
))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn scoped_token_accepted() {
assert!(assert_token_safe_in_url("akribes_tk_abc123").is_ok());
assert!(assert_token_safe_in_url("aura_tk_legacyhex").is_ok());
}
#[test]
fn service_token_secret_rejected() {
let err = assert_token_safe_in_url("puto-secret-padded-to-thirtytwo-bytes-aaaa")
.expect_err("service-token secret must be rejected");
assert!(format!("{err:?}").contains("Refusing"));
}
#[test]
fn opaque_bearer_rejected() {
assert!(assert_token_safe_in_url("eyJhbGciOi...JWT-shape").is_err());
assert!(assert_token_safe_in_url("").is_err());
}
}