#!/usr/bin/env bash # Regression harness for secret-safe, identity-bound PR editing and explicit targets. set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" WORK_DIR="${MOSAIC_TEST_WORK_DIR:-$PWD/.mosaic-test-work/pr-edit}" REPO_DIR="$WORK_DIR/repo"; BIN_DIR="$WORK_DIR/bin"; HOME_DIR="$WORK_DIR/home" XDG_DIR="$WORK_DIR/xdg"; LOG_FILE="$WORK_DIR/calls.log" rm -rf "$WORK_DIR"; mkdir -p "$REPO_DIR" "$BIN_DIR" "$HOME_DIR" "$XDG_DIR/tea" git -C "$REPO_DIR" init -q git -C "$REPO_DIR" remote add origin https://git.uscllc.com/other/wrong-checkout.git git -C "$REPO_DIR" config mosaic.gitIdentity "" cat > "$XDG_DIR/tea/config.yml" <<'YAML' logins: - name: usc-coder3 url: https://git.uscllc.com token: fixture-usc-token - name: same-host-other url: https://git.uscllc.com token: fixture-other-token - name: mosaic-coder3 url: https://git.mosaicstack.dev token: fixture-mosaic-token YAML cat > "$BIN_DIR/tea" <<'SH' #!/usr/bin/env bash set -euo pipefail # Deliberately misleading duplicate-name response: the wrapper must never use # tea for identity validation because its name lookup is not host-bound. [[ "$*" == "api --login duplicate /user" ]] && { printf '{"login":"coder3"}\n'; exit 0; } exit 1 SH cat > "$BIN_DIR/curl" <<'SH' #!/usr/bin/env bash set -euo pipefail printf 'curl' >> "$MOSAIC_TEST_LOG"; printf ' <%s>' "$@" >> "$MOSAIC_TEST_LOG"; printf '\n' >> "$MOSAIC_TEST_LOG" if [[ "${*: -1}" == */user ]]; then printf '{"login":"%s"}\n' "${MOSAIC_STUB_AUTH_USER:-coder3}" elif [[ "${*: -1}" == */repos/* && " $* " != *" -X PATCH "* ]]; then [[ "${MOSAIC_STUB_SIGNAL:-}" == "TERM" ]] && { kill -TERM "$PPID"; sleep 1; } [[ "${MOSAIC_STUB_SIGNAL:-}" == "INT" ]] && { kill -INT "$PPID"; sleep 1; } printf '{"name":"repo"}\n' else printf '{"number":42,"draft":false}\n' fi SH cat > "$BIN_DIR/gh" <<'SH' #!/usr/bin/env bash set -euo pipefail printf 'gh' >> "$MOSAIC_TEST_LOG"; printf ' <%s>' "$@" >> "$MOSAIC_TEST_LOG"; printf '\n' >> "$MOSAIC_TEST_LOG" SH chmod +x "$BIN_DIR/tea" "$BIN_DIR/curl" "$BIN_DIR/gh" "$SCRIPT_DIR/pr-edit.sh" run_wrapper() { (cd "$REPO_DIR"; PATH="$BIN_DIR:$PATH" HOME="$HOME_DIR" XDG_CONFIG_HOME="$XDG_DIR" \ MOSAIC_TEST_LOG="$LOG_FILE" "$SCRIPT_DIR/pr-edit.sh" "$@") } assert_no_secret() { ! grep -q 'fixture-.*-token' "$LOG_FILE" || { echo "Credential leaked into curl argv/log" >&2; exit 1; } } # The explicit target differs from CWD origin and must govern BOTH host and slug. : > "$LOG_FILE" # shellcheck disable=SC2016 # literal backticks prove argument-array body safety. MOSAIC_GIT_IDENTITY=coder3 run_wrapper -n 42 --login mosaic-coder3 -r mosaicstack/stack \ -H git.mosaicstack.dev --title 'New title' --body 'Body with `literal` bytes' --base develop --draft >/dev/null python3 - "$LOG_FILE" <<'PY' import json, pathlib, sys lines = pathlib.Path(sys.argv[1]).read_text().splitlines() assert len(lines) == 3, lines assert "https://git.mosaicstack.dev/api/v1/user" in lines[0], lines assert "https://git.mosaicstack.dev/api/v1/repos/mosaicstack/stack" in lines[1], lines assert "https://git.mosaicstack.dev/api/v1/repos/mosaicstack/stack/pulls/42" in lines[2], lines assert all("--config" in line for line in lines), lines assert "Authorization:" not in "\n".join(lines), lines payload = lines[2].split(" <-d> <", 1)[1].split("> "$LOG_FILE" MOSAIC_GIT_IDENTITY=coder3 run_wrapper -n 42 --login usc-coder3 -r USC/uconnect -H git.uscllc.com --ready >/dev/null grep -q '"draft": false' "$LOG_FILE"; assert_no_secret # Identity is mandatory; no ambient/first-host login can write. : > "$LOG_FILE" if run_wrapper -n 42 --login usc-coder3 --draft >/dev/null 2>&1; then echo "Unset identity wrote" >&2; exit 1; fi [[ ! -s "$LOG_FILE" ]] || { echo "Unset identity reached curl" >&2; exit 1; } # Explicit and ambient same-host wrong principals both refuse after identity # lookup but before repo preflight/PATCH. The /user read is expected curl #1. for mode in explicit ambient; do : > "$LOG_FILE" if [[ "$mode" == explicit ]]; then cmd=(--login same-host-other) else cmd=(); export GITEA_LOGIN=same-host-other fi if MOSAIC_STUB_AUTH_USER=other MOSAIC_GIT_IDENTITY=coder3 run_wrapper -n 42 "${cmd[@]}" -r USC/uconnect -H git.uscllc.com --draft >/dev/null 2>&1; then echo "$mode wrong identity wrote" >&2; exit 1 fi unset GITEA_LOGIN [[ "$(wc -l < "$LOG_FILE")" -eq 1 ]] || { echo "$mode wrong identity passed identity lookup" >&2; exit 1; } ! grep -q '/repos/' "$LOG_FILE" || { echo "$mode wrong identity reached repo preflight/PATCH" >&2; exit 1; } done # Set identity with no explicit/ambient login refuses rather than selecting first host login. : > "$LOG_FILE" if MOSAIC_GIT_IDENTITY=coder3 run_wrapper -n 42 -r USC/uconnect -H git.uscllc.com --draft >/dev/null 2>&1; then echo "Missing login selected a principal" >&2; exit 1 fi [[ ! -s "$LOG_FILE" ]] || { echo "Missing login reached curl" >&2; exit 1; } # Split-credential probe for the duplicate-name cross-host seam: tea's # name-only /user would report coder3, while the selected host-bound curl token # reports other. The wrapper must trust only the latter handle used by PATCH. : > "$LOG_FILE" if MOSAIC_STUB_AUTH_USER=other MOSAIC_GIT_IDENTITY=coder3 run_wrapper -n 42 --login mosaic-coder3 \ -r mosaicstack/stack -H git.mosaicstack.dev --draft >/dev/null 2>&1; then echo "Duplicate-name split credential reached PATCH" >&2; exit 1 fi [[ "$(wc -l < "$LOG_FILE")" -eq 1 ]] || { echo "Duplicate-name identity mismatch passed /user" >&2; cat "$LOG_FILE" >&2; exit 1; } ! grep -q -- '-X> &2; exit 1; } # TERM and INT during repo preflight clean up, do not mutate, and return the # signal status rather than swallowing termination into success. for sig in TERM INT; do : > "$LOG_FILE" set +e MOSAIC_STUB_SIGNAL="$sig" MOSAIC_GIT_IDENTITY=coder3 run_wrapper -n 42 --login usc-coder3 \ -r USC/uconnect -H git.uscllc.com --draft >/dev/null 2>&1 rc=$? set -e [[ "$rc" -ne 0 ]] || { echo "$sig was swallowed into success" >&2; exit 1; } [[ "$rc" -eq 143 || "$rc" -eq 130 ]] || { echo "$sig returned unexpected status $rc" >&2; exit 1; } ! grep -q -- '-X> &2; exit 1; } assert_no_secret done # Cross-host credential fails before curl; explicit target preflight failure blocks PATCH. : > "$LOG_FILE" if MOSAIC_GIT_IDENTITY=coder3 run_wrapper -n 42 --login mosaic-coder3 -r USC/uconnect -H git.uscllc.com --draft >/dev/null 2>&1; then echo "Cross-host login wrote" >&2; exit 1 fi [[ ! -s "$LOG_FILE" ]] || { echo "Cross-host login reached curl" >&2; exit 1; } if run_wrapper -n 42 --draft --ready >/dev/null 2>&1; then echo "Accepted conflicting modes" >&2; exit 1; fi if run_wrapper -n 42 >/dev/null 2>&1; then echo "Accepted no-op edit" >&2; exit 1; fi run_wrapper --help 2>&1 | grep -q '^Usage:' # GitHub retains provider-native edit/readiness behavior. git -C "$REPO_DIR" remote set-url origin https://github.com/acme/widgets.git : > "$LOG_FILE"; run_wrapper -n 7 --title 'GitHub title' --draft >/dev/null grep -q 'gh <7> <--title> ' "$LOG_FILE" grep -q 'gh <7> <--undo>' "$LOG_FILE" echo "PR edit regression harness passed"