clone

a personal forge on plain git: static pages, stacked-diff reviews, signed local ci, repo sites and releases

main
forge / test / scenarios / private-web-clone.sh
private-web-clone.sh 4.4K
1# HTTPS clones of a private repo with a token: Caddy asks the private server2# (forward_auth) about any repo without git-daemon-export-ok, and only what3# it lets through reaches git http-backend with GIT_HTTP_EXPORT_ALL. Without4# a token, a private repo and a missing one both ask for credentials (401);5# with a token that may not read it, both are a 404. Public repos clone as6# before. With caddy installed, a real git clones through a real Caddy;7# test/git-cgi.ts stands in for fcgiwrap.8. "$(dirname "$0")/../lib.sh"9user dami10user ana11user cat12repo --private dami/secret13repo dami/open14for r in secret open; do15 clone dami "dami/$r" "$T/w/$r"16 at "$T/w/$r" commit "first $r"17 ok push_as dami "$T/w/$r" origin main18done19ok ssh_as dami readers dami/secret add ana2021mkdir "$T/bin"22printf '#!/bin/sh\n' >"$T/bin/fcgiwrap"23chmod +x "$T/bin/fcgiwrap"24PATH="$T/bin:$PATH" forge server caddyfile git.test >"$T/Caddyfile" 2>"$T_LOG" || fail "caddyfile"25# The flag that makes http-backend serve any repo is set once, after forward_auth.26eq "$(grep -c 'GIT_HTTP_EXPORT_ALL' "$T/Caddyfile")" 127awk '/forward_auth/ { a = NR } /GIT_HTTP_EXPORT_ALL/ { e = NR } END { exit !(a && e > a) }' "$T/Caddyfile" || fail "GIT_HTTP_EXPORT_ALL before forward_auth"28has "$T/Caddyfile" 'try_files /\{re\.git\.1\}/\{re\.git\.2\}\.git/git-daemon-export-ok'29has "$T/Caddyfile" 'header_up X-Forge-Repo \{re\.git\.1\}/\{re\.git\.2\}'30command -v caddy >/dev/null 2>&1 || { note "caddy is not installed: skipped cloning through it"; exit 0; }31ok caddy adapt --config "$T/Caddyfile" --adapter caddyfile3233cport=$(free_port)34gport=$(free_port)35private_server36node "$T_HOME/test/git-cgi.ts" "$gport" >"$T/cgi.log" 2>&1 &37T_PIDS="$T_PIDS $!"38{39 printf '{\n\tadmin off\n\tauto_https off\n\tpersist_config off\n}\n\n'40 PATH="$T/bin:$PATH" FORGE_PRIVATE_PORT=$PRIV_PORT "$FORGE" server caddyfile "http://127.0.0.1:$cport"41} | awk -v up="127.0.0.1:$gport" '42 /reverse_proxy unix\/\/run\/fcgiwrap\.socket/ { sub(/unix\/\/run\/fcgiwrap\.socket/, up); print; next }43 /transport fastcgi \{/ { fc = 1; next }44 fc && /^[ \t]*\}$/ { fc = 0; next }45 fc { sub(/env /, "header_up X-Cgi-"); print; next }46 { print }' >"$T/Caddyfile.run"47XDG_DATA_HOME=$T/xdg XDG_CONFIG_HOME=$T/xdg caddy run --config "$T/Caddyfile.run" --adapter caddyfile >"$T/caddy.log" 2>&1 &48T_PIDS="$T_PIDS $!"49c=http://127.0.0.1:$cport50wait_http "$c/"51wait_http "http://127.0.0.1:$gport/"52ana=$(ssh_as ana token --repo dami/secret 2>/dev/null)53ana_all=$(ssh_as ana token 2>/dev/null)54ana_open=$(ssh_as ana token --repo dami/open 2>/dev/null)55cat=$(ssh_as cat token 2>/dev/null)56revoked=$(ssh_as ana token 2>"$T/err")57ok ssh_as ana tokens rm "$(sed -n 's/^token \([0-9a-f]*\) .*/\1/p' "$T/err")"58export GIT_TERMINAL_PROMPT=059hclone() { git clone -q "$@"; }6061ok hclone "$c/dami/open.git" "$T/c/open"62eq "$(git -C "$T/c/open" log -1 --format=%s)" "first open"63ok hclone "http://ana:$ana@127.0.0.1:$cport/dami/secret.git" "$T/c/one"64eq "$(git -C "$T/c/one" log -1 --format=%s)" "first secret"65ok hclone "http://ana:$ana_all@127.0.0.1:$cport/dami/secret.git" "$T/c/all"66# The token alone, as the user name.67ok hclone "http://$ana@127.0.0.1:$cport/dami/secret.git" "$T/c/user"68# A credential helper, as git would keep the token.69ok git -c credential.helper= -c "credential.helper=!f() { echo username=ana; echo password=$ana; }; f" clone -q "$c/dami/secret.git" "$T/c/helper"70ok git -C "$T/c/one" fetch -q71fails hclone "$c/dami/secret.git" "$T/c/anon"72fails hclone "http://cat:$cat@127.0.0.1:$cport/dami/secret.git" "$T/c/cat"73fails hclone "http://ana:$ana_open@127.0.0.1:$cport/dami/secret.git" "$T/c/scope"74fails hclone "http://ana:$revoked@127.0.0.1:$cport/dami/secret.git" "$T/c/revoked"75missing "$T/c/anon"7677# What the client sees: the same for a private repo and a missing one.78refs=/info/refs?service=git-upload-pack79same() {80 response "$c/dami/nope.git$refs" "$@" >"$T/missing"81 response "$c/dami/secret.git$refs" "$@" >"$T/got"82 cmp -s "$T/missing" "$T/got" || { diff "$T/missing" "$T/got" >&2 || true; fail "dami/secret and dami/nope differ: $*"; }83}84same85has "$T/got" '^HTTP/1.1 401'86has "$T/got" '^Www-Authenticate: Basic realm="forge"'87same -u "cat:$cat"88has "$T/got" '^HTTP/1.1 404'89same -u "ana:$ana_open"90same -u "ana:$revoked"91has "$T/got" '^HTTP/1.1 401'92# Nothing else in a private repo is served, token or not.93eq "$(http -s -o /dev/null -w '%{http_code}' -u "ana:$ana" "$c/dami/secret.git/config")" 40494eq "$(http -s -o /dev/null -w '%{http_code}' -u "ana:$ana" "$c/dami/secret.git/git-receive-pack")" 404