test: a guest JWT is capped by the instance allowance; pin ee-repo-ref

The guest policy moved (parent merge): guests are free up to the instance
allowance, then metered on Enterprise and hard-capped elsewhere. The JWT arm now
calls guest_admission inside the transaction that records guest_activity (the
advisory lock spans the count check and the row), and the door re-reads
guest_session_stands (switch, instance switch, no account) for every guest
request, so the JWT arm needs nothing extra for those. The plan gate on the key
config is gone (guests are free on any plan).

Adds an allowance test: with the window full on a capped instance, a stranger's
JWT is refused (401) and a returning guest's is admitted.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VF3v6LA9399gNphmZaHYG3
This commit is contained in:
Ruben Fiszel
2026-09-03 22:18:11 +02:00
co-authored by Claude Opus 4.8
parent 60ae85419c
commit 2907a531b2
2 changed files with 99 additions and 1 deletions
+1 -1
View File
@@ -1 +1 @@
a7dbde8c0df6da63dfa389c14c08bf4fd3169d5e
b01177583aa21be2086b124025313967c6357879
+98
View File
@@ -145,3 +145,101 @@ async fn the_allowance_caps_strangers_and_meters_an_enterprise_plan(
Ok(())
}
// --- The same allowance, reached through a guest JWT (`jwt_guest_`) ---
const JWT_PUB: &str = "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEzAfqyCh34iYOCW0vg4ejq/zzJlzL\nSZScjnVyPjLGTapEwo4gc6/y1Yudd/v54wKh0OdfTfzAKMPWx/2NWx/ugg==\n-----END PUBLIC KEY-----\n";
const JWT_PRIV: &str = "-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgu27S2DbSwUh8BmQb\n/i4/VhNdoXV7PJekhnoceMULYLihRANCAATMB+rIKHfiJg4JbS+Dh6Or/PMmXMtJ\nlJyOdXI+MsZNqkTCjiBzr/LVi513+/njAqHQ519N/MAow9bH/Y1bH+6C\n-----END PRIVATE KEY-----\n";
fn guest_jwt(email: &str) -> String {
use jsonwebtoken::{encode, Algorithm, EncodingKey, Header};
let exp = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs()
+ 3600;
let claims = json!({
"email": email,
"workspace_id": "test-workspace",
"app_path": APP_PATH,
"exp": exp,
});
let jwt = encode(
&Header::new(Algorithm::ES256),
&claims,
&EncodingKey::from_ec_pem(JWT_PRIV.as_bytes()).unwrap(),
)
.unwrap();
format!("jwt_guest_{jwt}")
}
/// A JWT guest is subject to the same allowance as a signed-in one. Past the cap on a
/// capped instance, a stranger's JWT is refused (the auth arm returns 401; the visitor
/// message is only logged, since the arm cannot carry it), while a guest already in the
/// window is let back in.
#[sqlx::test(fixtures("base"))]
async fn a_guest_jwt_is_capped_like_a_signed_in_guest(db: Pool<Postgres>) -> anyhow::Result<()> {
initialize_tracing().await;
let server = ApiServer::start(db.clone()).await?;
let port = server.addr.port();
let ws = format!("http://localhost:{port}/api/w/test-workspace");
authed(
client().post(format!("{ws}/workspaces/edit_guest_access")),
ADMIN_TOKEN,
)
.json(&json!({ "guest_access_enabled": true }))
.send()
.await?;
let resp = authed(
client().post(format!("{ws}/workspaces/edit_guest_jwt_key")),
ADMIN_TOKEN,
)
.json(&json!({ "public_key": JWT_PUB }))
.send()
.await?;
assert_eq!(resp.status(), 200, "{}", resp.text().await?);
let resp = authed(client().post(format!("{ws}/apps/create")), ADMIN_TOKEN)
.json(&json!({
"path": APP_PATH,
"summary": "Guest app",
"value": {},
"policy": { "execution_mode": "guest", "triggerables_v2": {} }
}))
.send()
.await?;
assert_eq!(resp.status(), 201, "{}", resp.text().await?);
// The whole allowance, used today (g1..gN).
sqlx::query(
"INSERT INTO guest_activity (email, workspace_id, day)
SELECT 'g' || i || '@example.com', 'test-workspace', CURRENT_DATE
FROM generate_series(1, $1) AS i",
)
.bind(FREE_GUESTS_PER_WINDOW)
.execute(&db)
.await?;
set_plan(true);
let resp = authed(
client().get(format!("{ws}/users/whoami")),
&guest_jwt("stranger@example.com"),
)
.send()
.await?;
assert_eq!(resp.status(), 401, "a stranger's JWT is refused past the cap");
let resp = authed(
client().get(format!("{ws}/users/whoami")),
&guest_jwt("g1@example.com"),
)
.send()
.await?;
assert_eq!(
resp.status(),
200,
"a returning guest's JWT is admitted: {}",
resp.text().await?
);
Ok(())
}