haematite-cli 0.21.8

The haematite command: serve a store, its door and Studio, answer MCP, query with jq, and host the store's assistant seat
Documentation
use super::{Door, SIGN_IN_FOR};
use super::{Issuer, SignedIn, Started};
use lys_pass::Error;
use std::sync::atomic::{AtomicUsize, Ordering};
struct Lys(AtomicUsize);
impl Lys {
    const fn new() -> Self {
        Self(AtomicUsize::new(0))
    }
}
impl Issuer for Lys {
    fn start(&self) -> Result<Started, Error> {
        let n = self.0.fetch_add(1, Ordering::Relaxed) + 1;
        Ok(Started {
            url: "https://lys.example".into(),
            state: format!("s{n}"),
            verifier: "v1".into(),
            browser: "b1".into(),
        })
    }
    fn finish(
        &self,
        _code: &str,
        _state: &str,
        _browser: &str,
        _started: &Started,
    ) -> Result<SignedIn, Error> {
        Ok(SignedIn {
            token: "fixture".into(),
            holder: "fixture".into(),
            expires_at: 1600,
            refresh: None,
        })
    }
    fn refresh(&self, _refresh: &str) -> Result<SignedIn, Error> {
        Err(Error::CannotAsk("fixture"))
    }
}
type TestResult = Result<(), Box<dyn std::error::Error>>;

#[test]
fn expired_pending_signins_are_removed_on_access() -> TestResult {
    let door = Door::new(Lys::new());
    door.begin(1_000)?;
    let refused = door
        .pass("unknown", 1_000 + SIGN_IN_FOR + 1)
        .err()
        .ok_or("unknown session was accepted")?;
    assert_eq!(refused.code, "session_unknown");
    assert!(
        super::lock(&door.sessions.pending)?.is_empty(),
        "expired pending sign-in retained on access"
    );
    Ok(())
}

#[test]
fn expired_sessions_are_removed_on_insert() -> TestResult {
    let door = Door::new(Lys::new());
    door.begin(1_000)?;
    let session = door.callback("code", "s1", "b1", 1_000)?;
    door.begin(1_000 + 12 * 60 * 60 + 1)?;
    assert!(
        !super::lock(&door.sessions.live)?.contains_key(&session),
        "expired session retained on insert"
    );
    Ok(())
}

#[test]
fn pending_signins_are_bounded_before_asking_the_issuer() -> TestResult {
    let door = Door::new(Lys::new());
    let mut refused = None;
    for _ in 0..513 {
        if let Err(failure) = door.begin(1_000) {
            refused = Some(failure);
            break;
        }
    }
    let refusal = refused.ok_or("pending sign-ins grew past the default bound of 512")?;
    assert_eq!(refusal.code, "busy_pending_signins");
    assert_eq!(
        door.issuer().0.load(Ordering::Relaxed),
        512,
        "full pending map still asked the issuer"
    );
    Ok(())
}

struct LastRefresh(Lys);

impl Issuer for LastRefresh {
    fn start(&self) -> Result<Started, Error> {
        self.0.start()
    }

    fn finish(
        &self,
        code: &str,
        state: &str,
        browser: &str,
        started: &Started,
    ) -> Result<SignedIn, Error> {
        let mut signed_in = self.0.finish(code, state, browser, started)?;
        signed_in.refresh = Some("last-refresh".to_owned());
        Ok(signed_in)
    }

    fn refresh(&self, _refresh: &str) -> Result<SignedIn, Error> {
        Ok(SignedIn {
            token: "fresh".to_owned(),
            holder: "fixture".to_owned(),
            expires_at: 1700,
            refresh: None,
        })
    }
}

#[test]
fn a_session_without_a_new_refresh_token_expires_with_its_fresh_pass() -> TestResult {
    let door = Door::new(LastRefresh(Lys::new()));
    door.begin(1000)?;
    let id = door.callback("code", "s1", "b1", 1000)?;
    assert_eq!(door.pass(&id, 1590)?, "fresh");
    door.begin(1701)?;
    assert!(
        !super::lock(&door.sessions.live)?.contains_key(&id),
        "expired refreshed session survived the next access"
    );
    Ok(())
}