1# The private server serves a private repo's pages to its readers holding a2# token (Bearer, or basic auth with the token as password or user name),3# with Caddy's headers for pages but "private, no-cache". Anyone else gets4# the 404 a missing page gets, byte for byte: no token, a bad, expired or5# revoked one, a reader's token for another repo, a user whose keys are6# gone, a page or repo that isn't there.7. "$(dirname "$0")/../lib.sh"8for u in dami ana bob cat; do user "$u"; done9repo --private dami/secret "hidden thing"10repo --private dami/other11repo dami/open12for r in secret open; do13 clone dami "dami/$r" "$T/w/$r"14 at "$T/w/$r" commit "first"15 ok push_as dami "$T/w/$r" origin main16done17ok ssh_as dami readers dami/secret add ana18ok ssh_as dami readers dami/secret add bob19build20tok() { ssh_as "$@" 2>/dev/null; }21dami=$(tok dami token)22ana=$(tok ana token --repo dami/secret)23ana_other=$(tok ana token --repo dami/open)24bob=$(tok bob token)25cat=$(tok cat token)26short=$(tok dami token --ttl 1h)27gone=$(ssh_as dami token 2>"$T/err")28ok ssh_as dami tokens rm "$(sed -n 's/^token \([0-9a-f]*\) .*/\1/p' "$T/err")"29ok forge user rm bob30private_server31u=$PRIV/dami/secret/3233# Readers.34for t in "$dami" "$ana"; do35 eq "$(http -s -o /dev/null -w '%{http_code}' -H "Authorization: Bearer $t" "$u")" 20036done37eq "$(http -s -o /dev/null -w '%{http_code}' -u "ana:$ana" "$u")" 20038eq "$(http -s -o /dev/null -w '%{http_code}' -u "$ana:" "$u")" 20039response "$u" -H "Authorization: Bearer $dami" >"$T/page"40has "$T/page" '^HTTP/1.1 200 OK'41has "$T/page" '^Cache-Control: private, no-cache'42has "$T/page" '^Content-Type: text/html; charset=utf-8'43has "$T/page" '^ETag: "'44has "$T/page" '^Last-Modified: '45has "$T/page" 'hidden thing'46etag=$(sed -n 's/^ETag: //p' "$T/page" | tr -d '\r')47eq "$(http -s -o /dev/null -w '%{http_code}' -H "Authorization: Bearer $dami" -H "If-None-Match: $etag" "$u")" 30448eq "$(http -s -o /dev/null -w '%{http_code} %{redirect_url}' -H "Authorization: Bearer $dami" "$PRIV/dami/secret")" "308 $PRIV/dami/secret/"49eq "$(http -s -o /dev/null -w '%{http_code}' -H "Authorization: Bearer $dami" "$PRIV/dami/secret/search.json")" 2005051# Everyone and everything else: the same 404.52response "$PRIV/dami/nope/" >"$T/missing"53has "$T/missing" '^HTTP/1.1 404 Not Found'54has "$T/missing" '^Cache-Control: no-cache'55same() {56 response "$@" >"$T/got"57 cmp -s "$T/missing" "$T/got" || { diff "$T/missing" "$T/got" >&2 || true; fail "not the missing page's 404: $*"; }58}59same "$u"60same "$PRIV/dami/secret"61same "$u" -H "Authorization: Bearer $cat"62same "$u" -u "cat:$cat"63same "$u" -H "Authorization: Bearer $ana_other"64same "$u" -H "Authorization: Bearer $gone"65same "$u" -H "Authorization: Bearer $bob"66same "$u" -H "Authorization: Bearer forge_nope"67same "$u" -H "Authorization: Basic !!!"68same "$PRIV/dami/other/" -H "Authorization: Bearer $ana"69same "$PRIV/dami/secret/nope/" -H "Authorization: Bearer $dami"70same "$PRIV/dami/secret/..%2F..%2Fdami/open/" -H "Authorization: Bearer $dami"71same "$PRIV/dami/open/nope/"72same "$PRIV/dami/open/" -H "Authorization: Bearer $dami"73same "$PRIV/login.php"74same "$PRIV/dami/secret/" -X POST -H "Authorization: Bearer $dami"75# HEAD: the same headers, no body.76response "$PRIV/dami/nope/" -I >"$T/missing"77same "$u" -I7879# An hour and a bit later, the 1h token has expired; the 30-day ones80# haven't, and say when they were last used.81ok ssh_as dami tokens82eq "$(grep -c ' token$' "$T_LOG")" 283stop_servers84export FORGE_NOW=$((T_NOW + 3700))85private_server86same "$PRIV/dami/secret/" -H "Authorization: Bearer $short" -I87eq "$(http -s -o /dev/null -w '%{http_code}' -H "Authorization: Bearer $dami" "$PRIV/dami/secret/")" 20088ok ssh_as dami tokens89eq "$(grep -c ' token$' "$T_LOG")" 190has "$T_LOG" ' 2026-09-01 01:01 +token$'