Files
minerops/scripts/test-agent-legacy-auth-retirement-migration.sh

165 lines
7.8 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "${repo_root}"
project_name="${MINEROPS_LEGACY_RETIREMENT_PROJECT:-minerops-legacy-retirement-$$}"
compose=(docker compose --project-name "${project_name}" --env-file .env.dev -f compose.dev.yaml)
cleanup() {
status=$?
if (( status != 0 )); then
"${compose[@]}" logs --no-color --tail 160 postgres || true
fi
"${compose[@]}" down --volumes --remove-orphans >/dev/null 2>&1 || true
exit "${status}"
}
trap cleanup EXIT
run_db_alembic() {
local database="$1"
shift
"${compose[@]}" run --rm --no-deps -e POSTGRES_DB="${database}" backend alembic "$@"
}
psql_named() {
local database="$1"
shift
"${compose[@]}" exec -T postgres sh -ec \
'database="$1"; shift; exec psql -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -d "$database" "$@"' \
sh "${database}" "$@"
}
create_database() {
"${compose[@]}" exec -T postgres sh -ec \
'exec createdb -U "$POSTGRES_USER" "$1"' sh "$1"
}
run_contract() {
local database="$1"
local case_name="$2"
local agent_id="$3"
"${compose[@]}" run --rm --no-deps \
--volume "${repo_root}/backend/tests:/app/tests:ro" \
--env POSTGRES_DB="${database}" \
--env MINEROPS_LEGACY_RETIREMENT_DISPOSABLE=1 \
--env MINEROPS_LEGACY_RETIREMENT_CASE="${case_name}" \
--env MINEROPS_AGENT_ID="${agent_id}" \
--env MINEROPS_AGENT_SHARED_SECRET=legacy-retirement-contract-secret \
backend python -m unittest -v \
tests.test_agent_legacy_auth_retirement_postgres
}
[[ -f .env.dev ]] || { echo "Missing .env.dev" >&2; exit 1; }
"${compose[@]}" up --detach postgres
for attempt in $(seq 1 60); do
"${compose[@]}" exec -T postgres sh -ec \
'pg_isready -U "$POSTGRES_USER" -d "$POSTGRES_DB"' >/dev/null 2>&1 && break
(( attempt < 60 )) || { echo "PostgreSQL did not become ready" >&2; exit 1; }
sleep 1
done
"${compose[@]}" build backend
expected_head="$(run_db_alembic postgres heads 2>/dev/null | awk 'NR == 1 { print $1 }')"
[[ "${expected_head}" == "0020_existing_agent_transition" ]]
echo "Testing selective 0019 backfill from the 0018 schema..."
create_database legacy_retirement_uncredentialed
run_db_alembic legacy_retirement_uncredentialed upgrade 0018_legacy_agent_routing
psql_named legacy_retirement_uncredentialed -c \
"INSERT INTO minerops_site_agents (agent_id, site_name) VALUES ('legacy-uncredentialed', 'Legacy')"
run_db_alembic legacy_retirement_uncredentialed upgrade head
[[ "$(psql_named legacy_retirement_uncredentialed -Atc "SELECT legacy_auth_disabled_at IS NULL FROM minerops_site_agents WHERE agent_id='legacy-uncredentialed'")" == "t" ]]
[[ "$(psql_named legacy_retirement_uncredentialed -Atc "SELECT count(*) FROM agent_legacy_auth_retirements WHERE agent_id='legacy-uncredentialed'")" == "0" ]]
create_database legacy_retirement_credentialed
run_db_alembic legacy_retirement_credentialed upgrade 0018_legacy_agent_routing
psql_named legacy_retirement_credentialed <<'SQL'
INSERT INTO minerops_site_agents (
agent_id, site_name, agent_secret_hash,
credential_created_at, credential_revoked_at
) VALUES (
'legacy-credentialed', 'Legacy', repeat('a', 64),
now() - interval '1 hour', now()
);
SQL
run_db_alembic legacy_retirement_credentialed upgrade head
[[ "$(psql_named legacy_retirement_credentialed -Atc "SELECT legacy_auth_disabled_at = credential_created_at FROM minerops_site_agents WHERE agent_id='legacy-credentialed'")" == "t" ]]
[[ "$(psql_named legacy_retirement_credentialed -Atc "SELECT retired_at = (SELECT credential_created_at FROM minerops_site_agents WHERE agent_id='legacy-credentialed') FROM agent_legacy_auth_retirements WHERE agent_id='legacy-credentialed'")" == "t" ]]
echo "Testing backfill from used enrollment history after credential clearing..."
create_database legacy_retirement_enrollment
run_db_alembic legacy_retirement_enrollment upgrade 0018_legacy_agent_routing
psql_named legacy_retirement_enrollment <<'SQL'
INSERT INTO sites (id, name)
VALUES ('00000000-0000-4000-8000-000000001901', 'Enrollment Evidence');
INSERT INTO agent_zones (id, site_id, name)
VALUES (
'00000000-0000-4000-8000-000000001902',
'00000000-0000-4000-8000-000000001901',
'Enrollment Evidence Zone'
);
INSERT INTO minerops_site_agents (
agent_id, site_name, site_id, agent_zone_id
) VALUES (
'enrollment-evidence-cleared',
'Enrollment Evidence',
'00000000-0000-4000-8000-000000001901',
'00000000-0000-4000-8000-000000001902'
);
INSERT INTO agent_enrollments (
token_hash, site_id, agent_zone_id, display_name,
created_at, expires_at, used_at, enrolled_agent_id
) VALUES (
repeat('c', 64),
'00000000-0000-4000-8000-000000001901',
'00000000-0000-4000-8000-000000001902',
'Enrollment Evidence Agent',
now() - interval '2 hours',
now() + interval '1 hour',
now() - interval '1 hour',
'enrollment-evidence-cleared'
);
SQL
run_db_alembic legacy_retirement_enrollment upgrade head
[[ "$(psql_named legacy_retirement_enrollment -Atc "SELECT count(*) FROM agent_legacy_auth_retirements WHERE agent_id='enrollment-evidence-cleared'")" == "1" ]]
[[ "$(psql_named legacy_retirement_enrollment -Atc "SELECT legacy_auth_disabled_at IS NOT NULL AND agent_secret_hash IS NULL AND credential_created_at IS NULL AND credential_revoked_at IS NULL FROM minerops_site_agents WHERE agent_id='enrollment-evidence-cleared'")" == "t" ]]
echo "Testing real PostgreSQL authentication before and after credential clearing..."
run_contract legacy_retirement_uncredentialed legacy legacy-uncredentialed
run_contract legacy_retirement_credentialed retired legacy-credentialed
echo "Testing database-enforced atomic retirement and ledger immutability..."
psql_named legacy_retirement_credentialed -c \
"INSERT INTO minerops_site_agents (agent_id, site_name, agent_secret_hash, credential_created_at) VALUES ('database-issued', 'Issued', repeat('b', 64), now())"
[[ "$(psql_named legacy_retirement_credentialed -Atc "SELECT count(*) FROM agent_legacy_auth_retirements WHERE agent_id='database-issued'")" == "1" ]]
[[ "$(psql_named legacy_retirement_credentialed -Atc "SELECT legacy_auth_disabled_at IS NOT NULL FROM minerops_site_agents WHERE agent_id='database-issued'")" == "t" ]]
if psql_named legacy_retirement_credentialed -c \
"UPDATE minerops_site_agents SET legacy_auth_disabled_at = NULL WHERE agent_id='legacy-credentialed'"; then
echo "Permanent retirement marker was unexpectedly cleared" >&2
exit 1
fi
if psql_named legacy_retirement_credentialed -c \
"UPDATE agent_legacy_auth_retirements SET retired_at = now() WHERE agent_id='legacy-credentialed'"; then
echo "Retirement history was unexpectedly updated" >&2
exit 1
fi
if psql_named legacy_retirement_credentialed -c \
"DELETE FROM agent_legacy_auth_retirements WHERE agent_id='legacy-credentialed'"; then
echo "Retirement history was unexpectedly deleted" >&2
exit 1
fi
if psql_named legacy_retirement_credentialed -c \
"TRUNCATE agent_legacy_auth_retirements"; then
echo "Retirement history was unexpectedly truncated" >&2
exit 1
fi
echo "Testing downgrade decision points..."
run_db_alembic legacy_retirement_uncredentialed downgrade 0018_legacy_agent_routing
[[ "$(psql_named legacy_retirement_uncredentialed -Atc 'SELECT version_num FROM alembic_version')" == "0018_legacy_agent_routing" ]]
if output="$(run_db_alembic legacy_retirement_credentialed downgrade 0018_legacy_agent_routing 2>&1)"; then
echo "0019 downgrade unexpectedly discarded retirement history" >&2
exit 1
fi
[[ "${output}" == *"durable identity-level legacy-auth retirement history exists"* ]]
[[ "$(psql_named legacy_retirement_credentialed -Atc 'SELECT version_num FROM alembic_version')" == "${expected_head}" ]]
echo "Durable legacy Agent authentication retirement checks passed."