irmin serve: Tw_html DSL + GitHub OAuth with allowlist
HTML is now composed from tw.html's typed DSL (no raw strings, no
CDN scripts); /tw.css is generated at startup from a sample page.
Upload form is a plain <form action method POST enctype multipart>
that the browser submits natively.
GitHub OAuth wired via ocaml-auth:
- enabled when IRMIN_AUTH_CLIENT_ID/_SECRET/_BASE_URL/_COOKIE_SECRET
are all set; otherwise uploads are unauthenticated (dev mode).
- Auth.routes mounted under /auth/github*, /auth/signout.
- Auth DB at .irmin/auth.db (SQLite, single-process).
- Each page renders a header strip: "Sign in with GitHub" with no
session, "<email> [Sign out]" when signed in, nothing when off.
Upload allowlist lives inside the store at refs/meta/config,
file admin.toml (Gerrit convention). Format:
[[allow]]
email = "you@example.com"
Re-read on every upload, so editing and committing admin.toml
takes effect without restarting. Missing or empty allowlist means
no one is allowed (safe default).
Dependencies added: tw, tw.html, auth, oauth, requests, tomlt.