fix(deploy): fail closed on postgres password mismatch
This commit is contained in:
1 parent
d140a47f23
commit
aea8cd7d60
8 files changed
+318
-21
No files matched your search
Executable
+100
@@ -0,0 +1,100 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
root=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
||||
fake_bin=$(mktemp -d /tmp/overcooked-installer-fakes.XXXXXX)
|
||||
test_root=$(mktemp -d /tmp/overcooked-installer-db-test.XXXXXX)
|
||||
trap 'rm -rf "$fake_bin" "$test_root"' EXIT
|
||||
cp "$root/test/fake-docker.sh" "$fake_bin/docker"
|
||||
cp "$root/test/fake-curl.sh" "$fake_bin/curl"
|
||||
chmod 755 "$fake_bin/docker" "$fake_bin/curl"
|
||||
|
||||
run_install() {
|
||||
mode=$1
|
||||
output=$2
|
||||
printf '%s\n' "$mode" > "$test_root/db-state"
|
||||
: > "$test_root/docker.log"
|
||||
set +e
|
||||
PATH="$fake_bin:$PATH" \
|
||||
FAKE_DOCKER_LOG="$test_root/docker.log" \
|
||||
FAKE_DB_STATE="$test_root/db-state" \
|
||||
OVERCOOKED_ROOT="$test_root/root" \
|
||||
OVERCOOKED_SERVER_IP=203.0.113.10 \
|
||||
OVERCOOKED_API_PORT=29880 \
|
||||
OVERCOOKED_WEB_PORT=29883 \
|
||||
OVERCOOKED_E_PORT=29896 \
|
||||
OVERCOOKED_AUTH_PUBLIC_KEYS='{"auth-1":"PUBLIC_KEY"}' \
|
||||
OVERCOOKED_ACTIVATION_CODE=TEST-CODE \
|
||||
"$root/install.sh" > "$output" 2>&1
|
||||
status=$?
|
||||
set -e
|
||||
if [ "$status" -ne 0 ]; then
|
||||
cat "$output" >&2
|
||||
fi
|
||||
return "$status"
|
||||
}
|
||||
|
||||
first_output=$test_root/first.out
|
||||
run_install ok "$first_output"
|
||||
first_e_password=$(sed -n 's/^PRODUCT_E_POSTGRES_PASSWORD=//p' "$test_root/root/production.env")
|
||||
first_s_password=$(sed -n 's/^S_POSTGRES_PASSWORD=//p' "$test_root/root/production.env")
|
||||
[ "${#first_e_password}" = 64 ]
|
||||
[ "${#first_s_password}" = 64 ]
|
||||
[ "$(stat -c '%a' "$test_root/root/production.env")" = 600 ]
|
||||
! rg -n 'volume rm|down .*-[^ ]*v' "$test_root/docker.log"
|
||||
|
||||
second_output=$test_root/second.out
|
||||
run_install ok "$second_output"
|
||||
second_e_password=$(sed -n 's/^PRODUCT_E_POSTGRES_PASSWORD=//p' "$test_root/root/production.env")
|
||||
second_s_password=$(sed -n 's/^S_POSTGRES_PASSWORD=//p' "$test_root/root/production.env")
|
||||
[ "$first_e_password" = "$second_e_password" ]
|
||||
[ "$first_s_password" = "$second_s_password" ]
|
||||
! rg -n 'volume rm|down .*-[^ ]*v' "$test_root/docker.log"
|
||||
echo "MALICIOUS=\$(touch $test_root/marker)" >> "$test_root/root/production.env"
|
||||
third_output=$test_root/third.out
|
||||
run_install ok "$third_output"
|
||||
[ ! -e "$test_root/marker" ]
|
||||
|
||||
mismatch_output=$test_root/mismatch.out
|
||||
if run_install mismatch "$mismatch_output"; then
|
||||
echo 'password mismatch unexpectedly succeeded' >&2
|
||||
exit 1
|
||||
fi
|
||||
rg -q 'DATABASE_PASSWORD_MISMATCH_NEEDS_MANUAL_RECOVERY' "$mismatch_output"
|
||||
! rg -n '^volume rm|down .*-[^ ]*v' "$test_root/docker.log"
|
||||
[ "$first_e_password" = "$(sed -n 's/^PRODUCT_E_POSTGRES_PASSWORD=//p' "$test_root/root/production.env")" ]
|
||||
|
||||
wrong_role_output=$test_root/wrong-role.out
|
||||
if run_install wrong-role "$wrong_role_output"; then
|
||||
echo 'wrong database role unexpectedly succeeded' >&2
|
||||
exit 1
|
||||
fi
|
||||
rg -q 'DATABASE_PASSWORD_MISMATCH_NEEDS_MANUAL_RECOVERY' "$wrong_role_output"
|
||||
! rg -n '^volume rm|down .*-[^ ]*v' "$test_root/docker.log"
|
||||
|
||||
s_mismatch_output=$test_root/s-mismatch.out
|
||||
if run_install s-mismatch "$s_mismatch_output"; then
|
||||
echo 'S password mismatch unexpectedly succeeded' >&2
|
||||
exit 1
|
||||
fi
|
||||
rg -q 'DATABASE_PASSWORD_MISMATCH_NEEDS_MANUAL_RECOVERY' "$s_mismatch_output"
|
||||
! rg -n '^volume rm|down .*-[^ ]*v' "$test_root/docker.log"
|
||||
|
||||
reset_output=$test_root/reset.out
|
||||
printf 'reset-once\n' > "$test_root/db-state"
|
||||
PATH="$fake_bin:$PATH" \
|
||||
FAKE_DOCKER_LOG="$test_root/docker.log" \
|
||||
FAKE_DB_STATE="$test_root/db-state" \
|
||||
OVERCOOKED_ROOT="$test_root/root" \
|
||||
OVERCOOKED_SERVER_IP=203.0.113.10 \
|
||||
OVERCOOKED_API_PORT=29880 \
|
||||
OVERCOOKED_WEB_PORT=29883 \
|
||||
OVERCOOKED_E_PORT=29896 \
|
||||
OVERCOOKED_AUTH_PUBLIC_KEYS='{"auth-1":"PUBLIC_KEY"}' \
|
||||
OVERCOOKED_ACTIVATION_CODE=TEST-CODE \
|
||||
OVERCOOKED_RESET_FAILED_INSTALL=1 \
|
||||
OVERCOOKED_CONFIRM_NO_BUSINESS_DATA=YES \
|
||||
"$root/install.sh" > "$reset_output" 2>&1
|
||||
rg -q '已收到显式无业务数据确认' "$reset_output"
|
||||
rg -q '^volume rm fake-e-postgres$' "$test_root/docker.log"
|
||||
echo 'database credential retry/reset tests passed'
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
exit 0
|
||||
Executable
+81
@@ -0,0 +1,81 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
: "${FAKE_DOCKER_LOG:?}"
|
||||
: "${FAKE_DB_STATE:?}"
|
||||
printf '%s\n' "$*" >> "$FAKE_DOCKER_LOG"
|
||||
|
||||
if [ "${1:-}" = compose ]; then
|
||||
shift
|
||||
args=$*
|
||||
case "$args" in
|
||||
*' version'*) exit 0 ;;
|
||||
*' ps -q postgres'*) printf 'fake-postgres\n'; exit 0 ;;
|
||||
*' ps -q control-proxy'*) printf 'fake-control-proxy\n'; exit 0 ;;
|
||||
*' exec '*product_e*)
|
||||
if [ "$(cat "$FAKE_DB_STATE")" = mismatch ]; then
|
||||
printf 'FATAL: password authentication failed for user product_e\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
if [ "$(cat "$FAKE_DB_STATE")" = reset-once ]; then
|
||||
printf 'FATAL: password authentication failed for user product_e\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
if [ "$(cat "$FAKE_DB_STATE")" = wrong-role ]; then
|
||||
printf 'product_s\n'
|
||||
exit 0
|
||||
fi
|
||||
printf 'product_e\n'; exit 0 ;;
|
||||
*' exec '*product_s*)
|
||||
if [ "$(cat "$FAKE_DB_STATE")" = wrong-role ]; then
|
||||
printf 'product_e\n'
|
||||
exit 0
|
||||
fi
|
||||
if [ "$(cat "$FAKE_DB_STATE")" = s-mismatch ]; then
|
||||
printf 'FATAL: password authentication failed for user product_s\n' >&2
|
||||
exit 2
|
||||
fi
|
||||
printf 'product_s\n'; exit 0 ;;
|
||||
*) exit 0 ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
case "${1:-}" in
|
||||
network|pull|image) exit 0 ;;
|
||||
save)
|
||||
output=''
|
||||
previous=''
|
||||
for argument do
|
||||
if [ "$previous" = -o ]; then output=$argument; fi
|
||||
previous=$argument
|
||||
done
|
||||
[ -n "$output" ] && : > "$output"
|
||||
exit 0
|
||||
;;
|
||||
inspect)
|
||||
format=${3:-}
|
||||
case "$format" in
|
||||
*State.Health.Status*) printf 'healthy\n' ;;
|
||||
*var/lib/postgresql/data*) printf 'fake-e-postgres\n' ;;
|
||||
*) printf '\n' ;;
|
||||
esac
|
||||
exit 0
|
||||
;;
|
||||
volume)
|
||||
case "${2:-}" in
|
||||
inspect)
|
||||
case "${4:-}" in
|
||||
*com.docker.compose.project*) printf 'overcooked-e\n' ;;
|
||||
*com.docker.compose.volume*) printf 'e-postgres\n' ;;
|
||||
esac
|
||||
exit 0
|
||||
;;
|
||||
rm)
|
||||
printf 'ok\n' > "$FAKE_DB_STATE"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
@@ -16,11 +16,15 @@ test -f compose/s.yml
|
||||
test -f compose/e.yml
|
||||
test -f config/e-server.production.yaml
|
||||
test -f s-migrations.tar.gz
|
||||
test "$(find s-migrations -type f -name '*.up.sql' | wc -l)" -gt 0
|
||||
test "$(tar -tzf s-migrations.tar.gz | awk '/\.up\.sql$/ { count++ } END { print count + 0 }')" -gt 0
|
||||
test -x test/database-credentials.sh
|
||||
sha256sum -c SHA256SUMS >/dev/null
|
||||
! rg -n '^([[:space:]]*)build:' compose
|
||||
! rg -n 'overcooked-auth|overcooked-auth-webui' compose install.sh
|
||||
! rg -n 'S_TURNSTILE_(SITE|SECRET)_KEY: .*\\?required' compose
|
||||
! rg -n 'S_INTERNAL_TLS_(ADDR|CERT_FILE|KEY_FILE|CLIENT_CA_FILE)' compose install.sh
|
||||
! rg -n 'psql[[:space:]]+-U[[:space:]]+postgres|(^|[^[:alnum:]_])eval([[:space:]]|$)' install.sh
|
||||
rg -n 'psql[[:space:]]+-U[[:space:]]+product_e|psql[[:space:]]+-U[[:space:]]+product_s' install.sh >/dev/null
|
||||
rg -n 'control-proxy|PRODUCT_E_CONTROL_PLANE_TLS_' compose install.sh >/dev/null
|
||||
./test/database-credentials.sh
|
||||
echo 'static customer installer checks passed'
|
||||
Reference in new issue
Block a user