ci / docker (push) Successful in 13s
Rust (axum + sqlx) API and worker sharing a Postgres-backed job queue (SKIP LOCKED, heartbeat, reaper, typed statuses), S3 storage with derived keys and a fully private bucket, OIDC photographer login with per-request allowlist checks, client share links with argon2 passwords and lockout, cookie-based image authorization with sliding expiry, hand-rolled spec-compliant streaming ZIP downloads with exact Content-Length, React + Vite gallery frontend, single Docker image, Helm chart for external S3 + Postgres, and Gitea CI. Co-Authored-By: Claude <noreply@anthropic.com>
30 lines
1.2 KiB
Rust
30 lines
1.2 KiB
Rust
//! Dev utility: mint a signed session cookie without going through OIDC.
|
|
//! Anyone holding SESSION_SECRET can forge sessions anyway; this just makes
|
|
//! local API testing possible before an IdP is wired up.
|
|
//!
|
|
//! Usage: SESSION_SECRET=... cargo run --example mint_session -- <user-uuid> <email>
|
|
|
|
use cookie::{Cookie, CookieJar, Key};
|
|
use sha2::{Digest, Sha512};
|
|
|
|
fn main() {
|
|
let mut args = std::env::args().skip(1);
|
|
let user_id = args.next().expect("usage: mint_session <user-uuid> <email>");
|
|
// Sessions are only honored for lowercased emails present in ALLOWED_EMAILS.
|
|
let email = args
|
|
.next()
|
|
.expect("usage: mint_session <user-uuid> <email>")
|
|
.to_lowercase();
|
|
let secret = std::env::var("SESSION_SECRET").expect("SESSION_SECRET must be set");
|
|
let key = Key::from(&Sha512::digest(secret.as_bytes()));
|
|
let exp = chrono::Utc::now().timestamp() + 86400;
|
|
let mut jar = CookieJar::new();
|
|
jar.signed_mut(&key).add(Cookie::new(
|
|
"photos_session",
|
|
format!("{user_id}|{exp}|{email}"),
|
|
));
|
|
// The plain jar now holds the signed on-wire value.
|
|
let cookie = jar.get("photos_session").unwrap();
|
|
println!("photos_session={}", cookie.value());
|
|
}
|