The smoke boots the fake Secrets Manager in a container and drives the real binary from the host through a 0600 env file: login, listings, get by name and uuid, failure paths, and a redaction sweep over every captured output. README documents the implemented wire protocol, the library surface keyproxy will call, the verified quickstart, and the config table.
114 lines
4.5 KiB
Bash
Executable File
114 lines
4.5 KiB
Bash
Executable File
#!/bin/sh
|
|
# End-to-end smoke for bitwarden-go: builds the CLI in the Docker builder,
|
|
# boots the FAKE Secrets Manager in a container on 127.0.0.1:8600, drives
|
|
# the real binary from the host through a 0600 env file, and asserts the
|
|
# happy paths plus redaction. No real vault is ever contacted. Only exact
|
|
# container IDs / PIDs spawned here are killed.
|
|
set -e
|
|
|
|
cd "$(dirname "$0")/.."
|
|
|
|
IMAGE="golang@sha256:e8c859f5632dcfde7b32d2012b4351728f6437930887c2f6a91ea242459e5514"
|
|
PORT=8600
|
|
CID=""
|
|
|
|
cleanup() {
|
|
if [ -n "$CID" ]; then
|
|
docker rm -f "$CID" >/dev/null 2>&1 || true
|
|
fi
|
|
rm -rf .smoke
|
|
}
|
|
trap cleanup EXIT INT TERM
|
|
|
|
mkdir -p .smoke
|
|
umask 077
|
|
|
|
echo "--- build CLI (docker builder)"
|
|
docker run --rm -v "$PWD:/h" -w /h \
|
|
-u "$(id -u):$(id -g)" -e HOME=/tmp -e GOFLAGS=-buildvcs=false \
|
|
"$IMAGE" go build -o bin/bitwarden-go ./cmd/bitwarden-go
|
|
|
|
echo "--- boot fake Secrets Manager (container, port $PORT)"
|
|
CID=$(docker run -d --rm \
|
|
-v "$PWD:/h" -w /h \
|
|
-u "$(id -u):$(id -g)" -e HOME=/tmp -e GOFLAGS=-buildvcs=false \
|
|
-p 127.0.0.1:$PORT:8600 \
|
|
"$IMAGE" go run ./smoke/fakesm -addr :8600)
|
|
|
|
# wait for the fake to answer (any HTTP response, even 400, proves it is up)
|
|
i=0
|
|
until [ -n "$CID" ] && [ "$(docker inspect -f '{{.State.Running}}' "$CID" 2>/dev/null)" = "true" ] && \
|
|
printf 'grant_type=client_credentials&client_id=probe&client_secret=probe&scope=api.secrets' \
|
|
| python3 -c "
|
|
import sys, urllib.request, urllib.error
|
|
req = urllib.request.Request('http://127.0.0.1:$PORT/identity/connect/token',
|
|
data=sys.stdin.buffer.read(), headers={'Content-Type':'application/x-www-form-urlencoded'})
|
|
try:
|
|
urllib.request.urlopen(req, timeout=2)
|
|
except urllib.error.HTTPError:
|
|
sys.exit(0) # got an HTTP answer: server is up
|
|
except Exception:
|
|
sys.exit(1) # not yet
|
|
sys.exit(0)
|
|
"; do
|
|
i=$((i+1))
|
|
if [ "$i" -ge 60 ]; then
|
|
echo "smoke: fake server did not come up; logs:" >&2
|
|
docker logs "$CID" >&2 || true
|
|
exit 1
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
CRED='0.ec2c1d46-6a4b-4751-a310-af9601317f2d.C2IgxjjLF7qSshsbwe8JGcbM075YXw:X8vbvA0bduihIDe/qrzIQQ=='
|
|
printf 'BW_SERVER_URL=http://127.0.0.1:%s\nBW_ACCESS_TOKEN=%s\n' "$PORT" "$CRED" > .smoke/env
|
|
chmod 600 .smoke/env
|
|
|
|
export BITWARDENGO_CONFIG="$PWD/.smoke/env"
|
|
|
|
echo "--- login (credential check; prints summary only)"
|
|
./bin/bitwarden-go login | tee .smoke/login.out
|
|
grep -q "authenticated: account ec2c1d46-6a4b-4751-a310-af9601317f2d" .smoke/login.out
|
|
grep -q "expires" .smoke/login.out
|
|
|
|
echo "--- projects"
|
|
./bin/bitwarden-go projects > .smoke/projects.out
|
|
grep -q "ac1d0000-0000-4000-8000-000000000001 harness" .smoke/projects.out
|
|
|
|
echo "--- secrets list"
|
|
./bin/bitwarden-go secrets list > .smoke/secrets.out
|
|
grep -q "5ec1e700-0000-4000-8000-00000000000a smoke-redmine-key" .smoke/secrets.out
|
|
grep -q "5ec1e700-0000-4000-8000-00000000000b smoke-litellm-key" .smoke/secrets.out
|
|
|
|
echo "--- get (bare value, no newline)"
|
|
V="$(./bin/bitwarden-go get smoke-redmine-key)"
|
|
[ "$V" = "smoke-redmine-value-0123456789abcdef" ] || { echo "smoke: wrong value: $V" >&2; exit 1; }
|
|
|
|
echo "--- get by uuid"
|
|
V="$(./bin/bitwarden-go get 5ec1e700-0000-4000-8000-00000000000b)"
|
|
[ "$V" = "smoke-litellm-value-fedcba9876543210" ] || { echo "smoke: wrong value: $V" >&2; exit 1; }
|
|
|
|
echo "--- failure path: missing secret (exit code + redacted stderr)"
|
|
if ./bin/bitwarden-go get no-such-secret > .smoke/missing.out 2> .smoke/missing.err; then
|
|
echo "smoke: missing secret should fail" >&2; exit 1
|
|
fi
|
|
grep -q "secret not found" .smoke/missing.err
|
|
[ ! -s .smoke/missing.out ] || { echo "smoke: stdout not empty on failure" >&2; exit 1; }
|
|
|
|
echo "--- failure path: bad credential (exit code)"
|
|
printf 'BW_SERVER_URL=http://127.0.0.1:%s\nBW_ACCESS_TOKEN=0.ec2c1d46-6a4b-4751-a310-af9601317f2d.wrong-secret:X8vbvA0bduihIDe/qrzIQQ==\n' "$PORT" > .smoke/bad.env
|
|
chmod 600 .smoke/bad.env
|
|
if BITWARDENGO_CONFIG="$PWD/.smoke/bad.env" ./bin/bitwarden-go login 2> .smoke/bad.err; then
|
|
echo "smoke: bad credential should fail" >&2; exit 1
|
|
fi
|
|
grep -q "auth failed" .smoke/bad.err
|
|
|
|
echo "--- redaction: no material in any captured output"
|
|
for f in .smoke/login.out .smoke/projects.out .smoke/secrets.out .smoke/missing.err .smoke/bad.err; do
|
|
grep -qF 'C2IgxjjLF7qSshsbwe8JGcbM075YXw' "$f" && { echo "smoke: client secret leaked into $f" >&2; exit 1; }
|
|
grep -qF 'X8vbvA0bduihIDe/qrzIQQ==' "$f" && { echo "smoke: credential key leaked into $f" >&2; exit 1; }
|
|
done
|
|
grep -qF 'smoke-litellm-value' .smoke/secrets.out && { echo "smoke: secret value leaked into listing" >&2; exit 1; }
|
|
|
|
echo "smoke: OK"
|