87 lines
3.1 KiB
Bash
Executable File
87 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Apply migration 007 (user_roles.admin_from_email_policy) to an EXISTING Postgres.
|
|
# initdb scripts in docker-entrypoint-initdb.d run only on first volume creation.
|
|
#
|
|
# Default (full SQL file): adds column, runs one-time policy DELETE/UPDATE (see
|
|
# be0/migrations/007_user_roles_email_policy_admin.sql before running on prod).
|
|
#
|
|
# Usage (from anywhere):
|
|
# ./be0/scripts/apply-migration-007.sh
|
|
# ./be0/scripts/apply-migration-007.sh --schema-only # only ADD COLUMN (safest repeat)
|
|
#
|
|
# On a remote host (SSH to be0/docker host, repo or copy of migrations present):
|
|
# export POSTGRES_CONTAINER=initiative-postgres POSTGRES_USER=initiative POSTGRES_DB=initiatives
|
|
# ./be0/scripts/apply-migration-007.sh
|
|
#
|
|
# From repo root (wrapper):
|
|
# ./scripts/apply-migration-007-postgres.sh
|
|
set -euo pipefail
|
|
|
|
SCHEMA_ONLY=0
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
--schema-only) SCHEMA_ONLY=1 ;;
|
|
-h|--help)
|
|
sed -n '2,20p' "$0"
|
|
exit 0
|
|
;;
|
|
esac
|
|
done
|
|
|
|
BE0_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
SQL_FULL="$BE0_ROOT/migrations/007_user_roles_email_policy_admin.sql"
|
|
CONTAINER="${POSTGRES_CONTAINER:-initiative-postgres}"
|
|
PGUSER="${POSTGRES_USER:-initiative}"
|
|
PGDATABASE="${POSTGRES_DB:-initiatives}"
|
|
|
|
if ! docker info >/dev/null 2>&1; then
|
|
echo "error: Docker is not reachable (is the daemon running?)" >&2
|
|
exit 1
|
|
fi
|
|
if ! docker inspect "$CONTAINER" >/dev/null 2>&1; then
|
|
echo "error: container not found: $CONTAINER (set POSTGRES_CONTAINER)" >&2
|
|
exit 1
|
|
fi
|
|
if [[ "$(docker inspect -f '{{.State.Running}}' "$CONTAINER" 2>/dev/null || echo false)" != "true" ]]; then
|
|
echo "error: container is not running: $CONTAINER" >&2
|
|
exit 1
|
|
fi
|
|
|
|
apply_schema_only() {
|
|
docker exec -i "$CONTAINER" psql -U "$PGUSER" -d "$PGDATABASE" -v ON_ERROR_STOP=1 <<'SQL'
|
|
ALTER TABLE user_roles ADD COLUMN IF NOT EXISTS admin_from_email_policy BOOLEAN NOT NULL DEFAULT FALSE;
|
|
|
|
COMMENT ON COLUMN user_roles.admin_from_email_policy IS
|
|
'TRUE when admin was granted by email allow-list (AUTH_ADMIN_EMAILS). Reconciliation may DELETE this row if the user email is no longer in the list. FALSE preserves manually granted admin (future / exceptional).';
|
|
SQL
|
|
}
|
|
|
|
apply_full() {
|
|
if [[ ! -f "$SQL_FULL" ]]; then
|
|
echo "error: missing migration file: $SQL_FULL" >&2
|
|
exit 1
|
|
fi
|
|
docker exec -i "$CONTAINER" psql -U "$PGUSER" -d "$PGDATABASE" -v ON_ERROR_STOP=1 <"$SQL_FULL"
|
|
}
|
|
|
|
verify_column() {
|
|
local out
|
|
out="$(docker exec "$CONTAINER" psql -U "$PGUSER" -d "$PGDATABASE" -tAc \
|
|
"SELECT 1 FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'user_roles' AND column_name = 'admin_from_email_policy'")"
|
|
if [[ "${out//$'\r'/}" != "1" ]]; then
|
|
echo "error: verification failed: column admin_from_email_policy missing on public.user_roles" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
if (( SCHEMA_ONLY )); then
|
|
echo "Applying schema only (ADD COLUMN + COMMENT) → $CONTAINER / $PGDATABASE"
|
|
apply_schema_only
|
|
else
|
|
echo "Applying full 007_user_roles_email_policy_admin.sql → $CONTAINER / $PGDATABASE"
|
|
apply_full
|
|
fi
|
|
|
|
verify_column
|
|
echo "ok: user_roles.admin_from_email_policy is present; admin register/login should work with current be0."
|