#!/usr/bin/env bash
# Real demos for P060 "How to Fix a Security Leak: An API Key Pushed to Git". Runs on render01 (Docker).
# A private lab network on this machine only (192.168.41.0/24), deleted at the end:
#   git-server  stands in for GitHub: Ana pushes over SSH; anyone may clone read-only over git:// (a public repo)
#   laptop      Ana's laptop (192.168.41.10): her kettle shop's code and paylab, her payment account's tool
#   payments    a small payment service of our own (lab/pay_api.py), standing in for a real provider: it checks
#               API keys and logs every request with its key and the address it came from
#   stranger    a stranger's machine (192.168.41.66) that clones public repositories and scans them for keys
# Every terminal is a real interactive shell in a pty (demo_driver.py). The key is a lab key for our own lab
# service: it opens nothing outside this network. Ubuntu 26.04 for git-filter-repo 2.47 (--sensitive-data-removal).
set -euo pipefail
cd "$(dirname "$0")"
P=ce-p041
BOXES="git-server laptop payments stranger"
GITLEAKS=ghcr.io/gitleaks/gitleaks:v8.30.1
cleanup() {
  for b in $BOXES; do docker rm -f $P-$b >/dev/null 2>&1 || true; done
  docker network rm $P-net >/dev/null 2>&1 || true
}
cleanup
[ -n "${KEEP:-}" ] || trap cleanup EXIT
W=/tmp/$P && rm -rf $W && mkdir -p $W/img && cp lab/pay_api.py lab/paylab $W/img/

cat > $W/img/Dockerfile <<DOCKER
FROM $GITLEAKS AS gitleaks
FROM ubuntu:26.04
RUN apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends \
      git git-filter-repo openssh-client openssh-server ca-certificates curl python3 >/dev/null \
 && rm -rf /var/lib/apt/lists/* && (userdel -r ubuntu 2>/dev/null || true) \
 && useradd -m -s /usr/bin/git-shell git && useradd -m -s /bin/bash ana && useradd -m -s /bin/bash bot
COPY --from=gitleaks /usr/bin/gitleaks /usr/local/bin/gitleaks
COPY pay_api.py /srv/pay/pay_api.py
COPY paylab /usr/local/bin/paylab
DOCKER
docker build -q -t $P-img $W/img >/dev/null
docker network create --subnet 192.168.41.0/24 $P-net >/dev/null
declare -A IP=([git-server]=192.168.41.5 [laptop]=192.168.41.10 [payments]=192.168.41.20 [stranger]=192.168.41.66)
for b in $BOXES; do
  docker run -d --name $P-$b --hostname $b --network $P-net --ip ${IP[$b]} --network-alias $b $P-img sleep infinity >/dev/null
done
ex() { docker exec "$P-$1" bash -c "$2"; }
as() { docker exec -u "$2" -w "/home/$2" -e HOME="/home/$2" "$P-$1" bash -c "$3"; }

# The payment service, with Ana's one live key.
ex payments "python3 /srv/pay/pay_api.py init && (nohup python3 /srv/pay/pay_api.py >/dev/null 2>&1 &)"
# The Git server: SSH for Ana's pushes, git:// read-only for everyone (a public repository).
ex git-server "mkdir -p /run/sshd && /usr/sbin/sshd"
as git-server git "git init -q --bare -b main kettle-shop.git && touch kettle-shop.git/git-daemon-export-ok && mkdir -p -m 700 .ssh"
ex git-server "HOME=/home/git git daemon --base-path=/home/git --reuseaddr --detach --user=git /home/git"
sleep 2
as laptop ana "mkdir -p -m 700 .ssh && ssh-keygen -q -t ed25519 -N '' -f .ssh/id_ed25519 && ssh-keyscan git-server >> .ssh/known_hosts 2>/dev/null \
  && git config --global user.name Ana && git config --global user.email ana@example.com && git config --global init.defaultBranch main"
docker exec $P-laptop cat /home/ana/.ssh/id_ed25519.pub | docker exec -i -u git $P-git-server sh -c 'cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys'
# Ana's payment account login lives on her laptop only (her dashboard login, never in Git).
TOKEN=$(ex payments "python3 -c 'import json; print(json.load(open(\"/srv/pay/state.json\"))[\"account_token\"])'")
as laptop ana "mkdir -p -m 700 .config/paylab && echo $TOKEN > .config/paylab/token && chmod 600 .config/paylab/token"
as stranger bot "git config --global user.name bot && git config --global user.email bot@example.com"

# The shop so far: one commit, pushed.
as laptop ana "git clone -q git@git-server:kettle-shop.git 2>/dev/null && cd kettle-shop \
  && printf '<h1>Kettle shop</h1>\n' > index.html && git add index.html && git commit -qm 'Create the shop homepage' && git push -q origin main 2>/dev/null"
docker cp lab/payments.py $P-laptop:/home/ana/kettle-shop/payments.py
KEY=$(ex payments "python3 -c 'import json; print(json.load(open(\"/srv/pay/state.json\"))[\"keys\"][0][\"secret\"])'")
as laptop ana "echo PAYMENTS_API_KEY=$KEY > kettle-shop/.env"
ex laptop "chown ana: /home/ana/kettle-shop/payments.py"

python3 - "$P" < demo_driver.py
