use super::*;
use crate::ServeError;
const TOKEN: &str = "sk-zzq-a-known-credential";
fn enforcing(token: &str) -> Credential {
let (cell, given) =
Credential::new(&TokenPolicy::Supplied(token.to_owned())).expect("a usable token");
assert_eq!(given.as_deref(), Some(token), "Supplied echoes its input");
cell
}
fn offers(cell: &Credential, value: Option<&str>) -> bool {
cell.admits(value.map(str::as_bytes))
}
#[test]
fn the_expected_header_is_accepted() {
let cell = enforcing(TOKEN);
assert!(offers(&cell, Some(&format!("Bearer {TOKEN}"))));
}
#[test]
fn serving_open_admits_everything_including_nothing() {
let (cell, token) = Credential::new(&TokenPolicy::InsecureNoAuth).expect("a usable policy");
assert_eq!(token, None, "there is no token to report");
assert!(offers(&cell, None));
assert!(offers(&cell, Some("Bearer anything")));
assert!(offers(&cell, Some("")));
}
#[test]
fn every_flavour_of_missing_or_wrong_credential_is_refused() {
let cell = enforcing(TOKEN);
let expected = format!("Bearer {TOKEN}");
let cases: Vec<(&str, Option<String>)> = vec![
("no Authorization header at all", None),
("an empty header", Some(String::new())),
("a different token", Some("Bearer sk-zzq-not-it".to_owned())),
(
"the right token under the wrong scheme",
Some(format!("Basic {TOKEN}")),
),
("the token with no scheme", Some(TOKEN.to_owned())),
(
"a prefix of the expected header",
Some(expected[..expected.len() - 1].to_owned()),
),
(
"the expected header plus a suffix",
Some(format!("{expected}x")),
),
("the scheme alone", Some("Bearer ".to_owned())),
(
"a scheme that only looks like the right one",
Some(format!("Bearerx {TOKEN}")),
),
(
"the right case, the wrong token",
Some("bearer sk-zzq-not-it".to_owned()),
),
(
"two spaces after the scheme",
Some(format!("Bearer {TOKEN}")),
),
("leading whitespace", Some(format!(" {expected}"))),
("trailing whitespace", Some(format!("{expected} "))),
];
for (description, offered) in cases {
assert!(
!offers(&cell, offered.as_deref()),
"{description} must be refused"
);
}
}
#[test]
fn a_prefix_never_passes() {
let cell = enforcing(TOKEN);
let expected = format!("Bearer {TOKEN}");
for cut in 1..expected.len() {
assert!(
!offers(&cell, Some(&expected[..cut])),
"a {cut}-byte prefix must not pass"
);
}
}
#[test]
fn set_refuses_the_old_credential_immediately() {
let cell = enforcing(TOKEN);
let old = format!("Bearer {TOKEN}");
assert!(offers(&cell, Some(&old)));
cell.set("sk-zzq-the-replacement".to_owned());
assert!(!offers(&cell, Some(&old)), "the old value is dead");
assert!(
offers(&cell, Some("Bearer sk-zzq-the-replacement")),
"and the new one works"
);
assert_eq!(cell.token().as_deref(), Some("sk-zzq-the-replacement"));
}
#[test]
fn there_is_no_window_where_both_credentials_pass() {
let cell = enforcing(TOKEN);
cell.set("sk-zzq-second".to_owned());
assert!(!offers(&cell, Some(&format!("Bearer {TOKEN}"))));
assert!(offers(&cell, Some("Bearer sk-zzq-second")));
}
#[test]
fn rotate_mints_a_fresh_token_and_enforces_it() {
let (cell, first) = Credential::new(&TokenPolicy::Generate).expect("a usable policy");
let first = first.expect("Generate produces a token");
assert!(offers(&cell, Some(&format!("Bearer {first}"))));
let second = cell.rotate();
assert_ne!(second, first, "rotation must actually change the value");
assert!(!offers(&cell, Some(&format!("Bearer {first}"))));
assert!(offers(&cell, Some(&format!("Bearer {second}"))));
assert_eq!(cell.token().as_deref(), Some(second.as_str()));
}
#[test]
fn set_turns_auth_on_when_serving_open() {
let (cell, _) = Credential::new(&TokenPolicy::InsecureNoAuth).expect("a usable policy");
assert!(offers(&cell, None), "open to begin with");
cell.set(TOKEN.to_owned());
assert!(!offers(&cell, None), "and closed afterwards");
assert!(offers(&cell, Some(&format!("Bearer {TOKEN}"))));
}
const CODE: &str = "483920";
const LONG: std::time::Duration = std::time::Duration::from_mins(1);
#[test]
fn a_grant_admits_one_request_and_then_is_a_wrong_token() {
let cell = enforcing(TOKEN);
assert!(
cell.grant(CODE.to_owned(), LONG),
"a presentable code takes"
);
let as_bearer = format!("Bearer {CODE}");
assert!(
offers(&cell, Some(&as_bearer)),
"the first presentation admits"
);
assert!(
!offers(&cell, Some(&as_bearer)),
"the second is refused like any wrong token"
);
}
#[test]
fn a_grant_leaves_the_enforced_token_untouched() {
let cell = enforcing(TOKEN);
cell.grant(CODE.to_owned(), LONG);
assert!(offers(&cell, Some(&format!("Bearer {TOKEN}"))));
assert_eq!(cell.token().as_deref(), Some(TOKEN));
assert!(
offers(&cell, Some(&format!("Bearer {CODE}"))),
"and the grant is still unspent — the token did not consume it"
);
}
#[test]
fn a_grant_is_presented_as_a_bearer_or_not_at_all() {
let cell = enforcing(TOKEN);
cell.grant(CODE.to_owned(), LONG);
assert!(!offers(&cell, Some(CODE)), "no scheme");
assert!(
!offers(&cell, Some(&format!("Basic {CODE}"))),
"wrong scheme"
);
assert!(
offers(&cell, Some(&format!("bearer {CODE}"))),
"the scheme is case-insensitive"
);
}
#[test]
fn an_unused_grant_expires() {
let cell = enforcing(TOKEN);
cell.grant(CODE.to_owned(), std::time::Duration::ZERO);
assert!(!offers(&cell, Some(&format!("Bearer {CODE}"))));
}
#[test]
fn rotating_the_token_does_not_disturb_a_live_grant() {
let cell = enforcing(TOKEN);
cell.grant(CODE.to_owned(), LONG);
cell.set("sk-zzq-the-replacement".to_owned());
assert!(offers(&cell, Some(&format!("Bearer {CODE}"))));
}
#[test]
fn an_unpresentable_grant_is_refused() {
let cell = enforcing(TOKEN);
for blank in ["", " ", "\t\n"] {
assert!(
!cell.grant(blank.to_owned(), LONG),
"{blank:?} must not become a grant"
);
}
}
#[test]
fn debug_counts_grants_and_never_shows_one() {
let cell = enforcing(TOKEN);
cell.grant(CODE.to_owned(), LONG);
let rendered = format!("{cell:?}");
assert!(!rendered.contains(CODE), "the grant leaked: {rendered}");
assert!(
rendered.contains("grants: 1"),
"but the count is legible: {rendered}"
);
}
#[test]
fn debug_reports_whether_a_credential_is_enforced_and_never_which() {
let enforced = enforcing(TOKEN);
let rendered = format!("{enforced:?}");
assert!(!rendered.contains(TOKEN), "the token leaked: {rendered}");
assert!(rendered.contains("enforced"), "but the state is legible");
let (open, _) = Credential::new(&TokenPolicy::InsecureNoAuth).expect("a usable policy");
assert!(format!("{open:?}").contains("open"));
}
#[test]
fn a_token_no_client_could_send_is_refused_rather_than_enforced() {
for empty in ["", " ", "\t", "\n", " \r\n "] {
assert!(
matches!(
Credential::new(&TokenPolicy::Supplied(empty.to_owned())),
Err(ServeError::InvalidToken)
),
"{empty:?} must not become a credential"
);
}
}
#[test]
fn an_unusual_but_presentable_token_is_still_accepted() {
for odd in ["x", " padded ", "sk-with spaces", "🔑"] {
let (cell, given) = Credential::new(&TokenPolicy::Supplied(odd.to_owned()))
.expect("presentable, however odd");
assert_eq!(given.as_deref(), Some(odd));
assert!(offers(&cell, Some(&format!("Bearer {odd}"))));
}
}
#[test]
fn setting_an_unpresentable_token_changes_nothing() {
let cell = enforcing(TOKEN);
assert!(
!cell.set(String::new()),
"the caller is told it did not take"
);
assert!(
offers(&cell, Some(&format!("Bearer {TOKEN}"))),
"the credential in force must survive a refused rotation"
);
}
#[test]
fn the_scheme_is_matched_without_regard_to_case() {
let cell = enforcing(TOKEN);
for scheme in ["Bearer", "bearer", "BEARER", "BeArEr", "bEARER"] {
assert!(
offers(&cell, Some(&format!("{scheme} {TOKEN}"))),
"{scheme} is the same scheme"
);
}
}
#[test]
fn the_token_is_still_matched_exactly() {
let cell = enforcing(TOKEN);
let flipped: String = TOKEN
.chars()
.map(|c| {
if c.is_ascii_lowercase() {
c.to_ascii_uppercase()
} else {
c.to_ascii_lowercase()
}
})
.collect();
assert_ne!(flipped, TOKEN, "the sentinel must have letters to flip");
assert!(
!offers(&cell, Some(&format!("Bearer {flipped}"))),
"the token is not a token comparison — case matters in the credential"
);
assert!(!offers(&cell, Some(&format!("bearer{TOKEN}"))));
assert!(!offers(&cell, Some(&format!("bearer\t{TOKEN}"))));
}
const NEXT: &str = "sk-zzq-the-replacement";
#[test]
fn the_key_a_graced_rotation_replaced_keeps_admitting() {
let cell = enforcing(TOKEN);
assert!(cell.set_with_grace(NEXT.to_owned(), LONG));
assert!(
offers(&cell, Some(&format!("Bearer {TOKEN}"))),
"the replaced key must go on admitting inside the window"
);
assert!(
offers(&cell, Some(&format!("Bearer {NEXT}"))),
"and so must the new one"
);
assert_eq!(
cell.token().as_deref(),
Some(NEXT),
"while the enforced token is unambiguously the new one"
);
}
#[test]
fn the_replaced_key_admits_every_machine_not_just_the_first() {
let cell = enforcing(TOKEN);
cell.set_with_grace(NEXT.to_owned(), LONG);
let as_bearer = format!("Bearer {TOKEN}");
for machine in 1..=4 {
assert!(
offers(&cell, Some(&as_bearer)),
"machine {machine} was refused; the window is being spent like a grant"
);
}
}
#[test]
fn the_replaced_key_stops_admitting_once_the_grace_passes() {
let cell = enforcing(TOKEN);
cell.set_with_grace(NEXT.to_owned(), std::time::Duration::from_millis(1));
std::thread::sleep(std::time::Duration::from_millis(20));
assert!(
!offers(&cell, Some(&format!("Bearer {TOKEN}"))),
"the window closed and the replaced key is still admitting"
);
assert!(offers(&cell, Some(&format!("Bearer {NEXT}"))));
}
#[test]
fn a_graced_rotation_with_no_grace_is_exactly_a_plain_one() {
let cell = enforcing(TOKEN);
cell.set_with_grace(NEXT.to_owned(), std::time::Duration::ZERO);
assert!(!offers(&cell, Some(&format!("Bearer {TOKEN}"))));
assert!(offers(&cell, Some(&format!("Bearer {NEXT}"))));
let rendered = format!("{cell:?}");
assert!(
rendered.contains("grace: false"),
"a zero window must not read as open: {rendered}"
);
}
#[test]
fn an_absurd_grace_does_not_panic_or_leave_a_standing_second_key() {
let cell = enforcing(TOKEN);
assert!(cell.set_with_grace(NEXT.to_owned(), std::time::Duration::MAX));
assert!(
!offers(&cell, Some(&format!("Bearer {TOKEN}"))),
"Duration::MAX must not become a permanent second credential"
);
assert!(
offers(&cell, Some(&format!("Bearer {NEXT}"))),
"and the rotation itself must still have happened"
);
assert_eq!(cell.token().as_deref(), Some(NEXT));
}
#[test]
fn a_plain_rotation_still_leaves_no_window() {
let cell = enforcing(TOKEN);
cell.set(NEXT.to_owned());
assert!(!offers(&cell, Some(&format!("Bearer {TOKEN}"))));
}
#[test]
fn a_plain_rotation_shuts_an_open_window() {
let cell = enforcing(TOKEN);
cell.set_with_grace(NEXT.to_owned(), LONG);
assert!(offers(&cell, Some(&format!("Bearer {TOKEN}"))));
cell.set("sk-zzq-the-third".to_owned());
assert!(
!offers(&cell, Some(&format!("Bearer {TOKEN}"))),
"the window was open and a plain rotation must close it"
);
assert!(
!offers(&cell, Some(&format!("Bearer {NEXT}"))),
"and the key it just replaced gets no window either"
);
assert!(offers(&cell, Some("Bearer sk-zzq-the-third")));
}
#[test]
fn a_second_graced_rotation_retires_the_first_replaced_key() {
let cell = enforcing(TOKEN);
cell.set_with_grace(NEXT.to_owned(), LONG);
cell.set_with_grace("sk-zzq-the-third".to_owned(), LONG);
assert!(
!offers(&cell, Some(&format!("Bearer {TOKEN}"))),
"a key two rotations behind must not survive on the strength of the first window"
);
assert!(
offers(&cell, Some(&format!("Bearer {NEXT}"))),
"the key the newest rotation replaced is the one that is held"
);
assert!(offers(&cell, Some("Bearer sk-zzq-the-third")));
}
#[test]
fn an_unpresentable_graced_rotation_changes_nothing() {
let cell = enforcing(TOKEN);
for blank in ["", " ", "\t\n"] {
assert!(
!cell.set_with_grace(blank.to_owned(), LONG),
"{blank:?} must not become the enforced token"
);
}
assert_eq!(cell.token().as_deref(), Some(TOKEN), "nothing was replaced");
assert!(offers(&cell, Some(&format!("Bearer {TOKEN}"))));
let rendered = format!("{cell:?}");
assert!(
rendered.contains("grace: false"),
"and no window was opened: {rendered}"
);
}
#[test]
fn a_refused_rotation_neither_shuts_nor_extends_an_open_window() {
let cell = enforcing(TOKEN);
cell.set_with_grace(NEXT.to_owned(), LONG);
assert!(offers(&cell, Some(&format!("Bearer {TOKEN}"))));
assert!(!cell.set_with_grace(String::new(), LONG), "refused");
assert!(
offers(&cell, Some(&format!("Bearer {TOKEN}"))),
"the window a refused call did not touch must still be open"
);
assert_eq!(cell.token().as_deref(), Some(NEXT), "and nothing rotated");
}
#[test]
fn a_graced_rotation_onto_an_open_listener_holds_nothing() {
let (cell, _) = Credential::new(&TokenPolicy::InsecureNoAuth).expect("a usable policy");
assert!(offers(&cell, None), "open to begin with");
assert!(cell.set_with_grace(TOKEN.to_owned(), LONG));
assert!(!offers(&cell, None), "and closed afterwards");
assert!(!offers(&cell, Some("Bearer anything")));
assert!(offers(&cell, Some(&format!("Bearer {TOKEN}"))));
}
#[test]
fn a_key_the_window_already_admits_does_not_spend_a_grant() {
let cell = enforcing(TOKEN);
assert!(
cell.grant(TOKEN.to_owned(), LONG),
"the same value, granted"
);
cell.set_with_grace(NEXT.to_owned(), LONG);
let as_bearer = format!("Bearer {TOKEN}");
assert!(offers(&cell, Some(&as_bearer)), "admitted by the window");
cell.set("sk-zzq-the-third".to_owned());
assert!(
offers(&cell, Some(&as_bearer)),
"the grant was spent by a request the window should have answered"
);
assert!(
!offers(&cell, Some(&as_bearer)),
"and now it really is spent"
);
}
#[test]
fn a_graced_rotation_does_not_disturb_a_live_grant() {
let cell = enforcing(TOKEN);
cell.grant(CODE.to_owned(), LONG);
cell.set_with_grace(NEXT.to_owned(), LONG);
assert!(offers(&cell, Some(&format!("Bearer {CODE}"))));
}
#[test]
fn debug_says_a_window_is_open_and_never_which_key() {
let cell = enforcing(TOKEN);
let shut = format!("{cell:?}");
assert!(shut.contains("grace: false"), "shut to begin with: {shut}");
cell.set_with_grace(NEXT.to_owned(), LONG);
let open = format!("{cell:?}");
assert!(
!open.contains(TOKEN),
"the superseded key leaked into Debug: {open}"
);
assert!(
open.contains("grace: true"),
"but the state is legible: {open}"
);
}