#!/usr/bin/env bash # Hermetic regression for load_credentials gitea seat-slot resolution. # Sandbox brain home + sandbox credentials.json; no real credential is read. # # Pins: # G1 MOSAIC_GIT_IDENTITY naming a seat with a populated slot → GITEA_TOKEN # comes from the SLOT, URL from credentials.json. # G2 seat with an EMPTY slot → rc 1, refusal names the identity and the # slot path, and NO fallback to the service store occurred (the token # must not equal the service-store value). # G3 no identity → service store, unchanged behavior (token from # credentials.json). # G4 identity that is NOT a seat (no directory) → service store (same as # G3; the identity is irrelevant on a non-fleet path). # G5 other services are untouched: woodpecker resolution works the same # with and without MOSAIC_GIT_IDENTITY set. # G6 pre-existing GITEA_TOKEN env is never overridden by the seat path. set -uo pipefail W="${TMPDIR:-/tmp}/creds-seat-test-$$" BRAIN="$W/brain"; CREDS="$W/credentials.json" mkdir -p "$BRAIN/fleet/agents/live-seat/secrets" "$BRAIN/fleet/agents/empty-seat" printf 'seat-token-value-abc123\n' > "$BRAIN/fleet/agents/live-seat/secrets/gitea-mosaicstack-live-seat.token" cat > "$CREDS" <<'EOF' {"gitea":{"mosaicstack":{"url":"https://gitea.example.test","token":"service-token-value-xyz789"}}, "woodpecker":{"default":"mosaic","mosaic":{"url":"https://ci.example.test","token":"wp-token-1"}}} EOF SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck source=/dev/null source "$SCRIPT_DIR/credentials.sh" fail() { echo "FAIL: $*" >&2; exit 1; } load_env() { # $1=service, $2=env-setup; clean subshell; echoes rc then token local svc="$1" setup="$2" ( eval "$setup" unset GITEA_TOKEN GITEA_URL export MOSAIC_CREDENTIALS_FILE="$CREDS" MOSAIC_BRAIN_HOME="$BRAIN" load_credentials "$svc" >/dev/null 2>"$W/err" rc=$? printf '%s\n%s\n' "$rc" "${GITEA_TOKEN:-}" ) } # G1: seat with populated slot out=$(load_env gitea-mosaicstack 'export MOSAIC_GIT_IDENTITY=live-seat') rc=$(printf '%s' "$out" | sed -n 1p); tok=$(printf '%s' "$out" | sed -n 2p) [ "$rc" = 0 ] || fail "G1: rc=$rc err=$(cat "$W/err")" [ "$tok" = "seat-token-value-abc123" ] || fail "G1: token not from slot: ${tok:0:20}" # G2: seat with empty slot refuses, no fallback out=$(load_env gitea-mosaicstack 'export MOSAIC_GIT_IDENTITY=empty-seat') rc=$(printf '%s' "$out" | sed -n 1p); tok=$(printf '%s' "$out" | sed -n 2p) [ "$rc" = 1 ] || fail "G2: expected rc=1 refusal, got rc=$rc tok=${tok:0:20}" [ "$tok" != "service-token-value-xyz789" ] || fail "G2: FELL BACK to service store on seat-miss" grep -q "empty-seat" "$W/err" || fail "G2: refusal does not name the identity" grep -q "fleet/agents/empty-seat" "$W/err" || fail "G2: refusal does not name the slot path" # G3: no identity → service store out=$(load_env gitea-mosaicstack 'unset MOSAIC_GIT_IDENTITY') rc=$(printf '%s' "$out" | sed -n 1p); tok=$(printf '%s' "$out" | sed -n 2p) [ "$rc" = 0 ] || fail "G3: rc=$rc err=$(cat "$W/err")" [ "$tok" = "service-token-value-xyz789" ] || fail "G3: service-store token not loaded" # G4: identity that is not a seat → service store out=$(load_env gitea-mosaicstack 'export MOSAIC_GIT_IDENTITY=nobody') rc=$(printf '%s' "$out" | sed -n 1p); tok=$(printf '%s' "$out" | sed -n 2p) [ "$rc" = 0 ] || fail "G4: rc=$rc err=$(cat "$W/err")" [ "$tok" = "service-token-value-xyz789" ] || fail "G4: non-seat identity broke the service path" # G5: woodpecker ignores MOSAIC_GIT_IDENTITY entirely ( export MOSAIC_CREDENTIALS_FILE="$CREDS" export MOSAIC_GIT_IDENTITY=live-seat unset WOODPECKER_URL WOODPECKER_TOKEN load_credentials woodpecker >/dev/null 2>&1 || fail "G5: woodpecker load failed with identity set" [ "$WOODPECKER_TOKEN" = "wp-token-1" ] || fail "G5: woodpecker token wrong" [ "$WOODPECKER_URL" = "https://ci.example.test" ] || fail "G5: woodpecker url wrong" ) # G6: pre-set GITEA_TOKEN env is preserved (both arms) ( export MOSAIC_CREDENTIALS_FILE="$CREDS" MOSAIC_BRAIN_HOME="$BRAIN" export MOSAIC_GIT_IDENTITY=live-seat GITEA_TOKEN=already-set-env load_credentials gitea-mosaicstack >/dev/null 2>&1 || fail "G6: load failed" [ "$GITEA_TOKEN" = "already-set-env" ] || fail "G6: seat path overrode existing GITEA_TOKEN" ) rm -rf "$W" echo "credentials seat-slot regression passed"