Files
BetterDesk/scripts/test-postgresql-hba.sh
T
UNITRONIX abc00b8804 feat(guest): enforce scoped guest access lifecycle
Bind guest WebSocket sessions to a single target peer, enforce grant lifecycle and atomic usage, add the guest issuer scope, and document the password-less security boundary.\n\nRefs #440\n\nThanks: INSOLVE (Honorary); Marco Jakobs (@jacotec); MyNameisStitch (@MyNameisStitch); Redspin (@playerumpknow)
2026-10-03 10:22:20 +02:00

130 lines
3.5 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
INSTALLER="$REPO_ROOT/betterdesk.sh"
TEST_ROOT="$(mktemp -d)"
FUNCTIONS_FILE="$TEST_ROOT/betterdesk-functions.sh"
FAKE_BIN="$TEST_ROOT/bin"
HBA_FILE="$TEST_ROOT/pg_hba.conf"
STATE_DIR="$TEST_ROOT/state"
mkdir -p "$FAKE_BIN" "$STATE_DIR"
trap 'rm -rf "$TEST_ROOT"' EXIT
# The installer has a direct-execution guard, so source the complete file
# instead of deleting an assumed final line.
cp "$INSTALLER" "$FUNCTIONS_FILE"
cat > "$FAKE_BIN/sudo" <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
if [ "${1:-}" = "-u" ] && [ "${2:-}" = "postgres" ]; then
shift 2
fi
exec "$@"
EOF
cat > "$FAKE_BIN/psql" <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
case "$*" in
*"SHOW hba_file;"*)
printf '%s\n' "$BETTERDESK_TEST_HBA"
;;
*)
exit 0
;;
esac
EOF
cat > "$FAKE_BIN/systemctl" <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
if [ "${1:-}" = "reload" ] && [ "${2:-}" = "postgresql" ]; then
touch "$BETTERDESK_TEST_RELOADED"
fi
EOF
cat > "$FAKE_BIN/service" <<'EOF'
#!/usr/bin/env bash
exit 1
EOF
chmod +x "$FAKE_BIN"/*
count_exact_line() {
local expected="$1"
awk -v expected="$expected" '$0 == expected { count++ } END { print count + 0 }' "$HBA_FILE"
}
run_hba_setup() {
local host="$1"
PATH="$FAKE_BIN:$PATH" \
AUTO_MODE=true \
POSTGRESQL_HOST="$host" \
POSTGRESQL_DB=betterdesk \
POSTGRESQL_USER=betterdesk \
BETTERDESK_TEST_HBA="$HBA_FILE" \
BETTERDESK_TEST_RELOADED="$STATE_DIR/reloaded" \
bash -c 'script="$1"; shift; source "$script" --auto; ensure_postgresql_local_hba_rules' \
-- "$FUNCTIONS_FILE"
}
cat > "$HBA_FILE" <<'EOF'
# PostgreSQL client authentication configuration file.
local all postgres peer
host all all 127.0.0.1/32 md5
host all all ::1/128 md5
EOF
run_hba_setup localhost
ipv4_rule='host betterdesk betterdesk 127.0.0.1/32 scram-sha-256'
ipv6_rule='host betterdesk betterdesk ::1/128 scram-sha-256'
if [ "$(count_exact_line "$ipv4_rule")" -ne 1 ] ||
[ "$(count_exact_line "$ipv6_rule")" -ne 1 ]; then
printf 'Expected both BetterDesk localhost HBA rules exactly once.\n' >&2
exit 1
fi
if ! [ -f "$STATE_DIR/reloaded" ]; then
printf 'Expected PostgreSQL reload after changing pg_hba.conf.\n' >&2
exit 1
fi
rule_line="$(awk -v expected="$ipv4_rule" '$0 == expected { print NR; exit }' "$HBA_FILE")"
broad_rule_line="$(awk '$1 == "host" && $2 == "all" && $3 == "all" && $4 == "127.0.0.1/32" { print NR; exit }' "$HBA_FILE")"
if [ "$rule_line" -ge "$broad_rule_line" ]; then
printf 'Expected the scoped IPv4 rule before the broad localhost rule.\n' >&2
exit 1
fi
before="$(sha256sum "$HBA_FILE")"
run_hba_setup localhost
after="$(sha256sum "$HBA_FILE")"
if [ "$before" != "$after" ]; then
printf 'Expected a second HBA setup to be idempotent.\n' >&2
exit 1
fi
cat > "$HBA_FILE" <<'EOF'
local all postgres peer
EOF
rm -f "$STATE_DIR/reloaded"
run_hba_setup db.example.test
if [ -s "$HBA_FILE" ] && [ "$(wc -l < "$HBA_FILE")" -ne 1 ]; then
printf 'Expected remote PostgreSQL setup to leave pg_hba.conf unchanged.\n' >&2
exit 1
fi
if [ -f "$STATE_DIR/reloaded" ]; then
printf 'Expected remote PostgreSQL setup to skip reload.\n' >&2
exit 1
fi
printf '%s\n' "PostgreSQL pg_hba.conf regression checks passed."