#!/usr/bin/env bash set -euo pipefail container=foundry-schema-$(openssl rand -hex 8) cleanup() { docker rm -f "$container" >/dev/null 2>&1 || true; } trap cleanup EXIT # No host port or shared network. The database is discarded after this check. docker run -d --name "$container" --network none \ -e POSTGRES_HOST_AUTH_METHOD=trust postgres:17-alpine >/dev/null for attempt in {1..30}; do if docker exec "$container" pg_isready -h 127.0.0.1 -U postgres >/dev/null 2>&1; then break; fi sleep 1 done psql() { docker exec -i "$container" psql -X -U postgres -v ON_ERROR_STOP=1; } psql < db/001-auth.sql psql <<'SQL' INSERT INTO project_accounts(project,id,google_subject,email) VALUES ('fixture','00000000-0000-0000-0000-000000000001','existing-google','existing@example.invalid'); INSERT INTO project_sessions VALUES ('existing-session','fixture','00000000-0000-0000-0000-000000000001',now()+interval '1 hour'); SQL psql <<'SQLROLE' CREATE ROLE foundry_fixture LOGIN; SQLROLE python3 deploy/migrate.py --container "$container" --database postgres --role foundry_fixture python3 deploy/migrate.py --container "$container" --database postgres --role foundry_fixture psql <<'SQL' DO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM project_sessions s JOIN project_accounts a ON (s.project,s.account_id)=(a.project,a.id) JOIN account_identities i ON (i.project,i.account_id)=(a.project,a.id) WHERE s.token_hash='existing-session' AND i.provider='google' AND i.subject='existing-google' ) THEN RAISE EXCEPTION 'Existing Google login was lost'; END IF; END $$; BEGIN; INSERT INTO project_accounts(project,id,email) VALUES ('fixture','00000000-0000-0000-0000-000000000002','email@example.invalid'); INSERT INTO email_credentials(project,email,account_id,password_hash) VALUES ('fixture','email@example.invalid','00000000-0000-0000-0000-000000000002','fixture-hash'); INSERT INTO workspaces(project,id,name,owner_id) VALUES ('fixture','00000000-0000-0000-0000-000000000010','Fixture','00000000-0000-0000-0000-000000000001'); INSERT INTO workspace_members(project,workspace_id,account_id,role) VALUES ('fixture','00000000-0000-0000-0000-000000000010','00000000-0000-0000-0000-000000000001','admin'); INSERT INTO materials(project,workspace_id,id,kind,title,created_by) VALUES ('fixture','00000000-0000-0000-0000-000000000010','00000000-0000-0000-0000-000000000020','article','Article','00000000-0000-0000-0000-000000000001'), ('fixture','00000000-0000-0000-0000-000000000010','00000000-0000-0000-0000-000000000021','board','Board','00000000-0000-0000-0000-000000000001'); INSERT INTO board_layouts(project,workspace_id,board_id,material_id,x,y,width,height) VALUES ('fixture','00000000-0000-0000-0000-000000000010','00000000-0000-0000-0000-000000000021','00000000-0000-0000-0000-000000000020',0,0,320,200); DO $$ BEGIN BEGIN INSERT INTO workspace_members(project,workspace_id,account_id,role) VALUES ('other','00000000-0000-0000-0000-000000000010','00000000-0000-0000-0000-000000000001','admin'); RAISE EXCEPTION 'Cross-project membership unexpectedly accepted'; EXCEPTION WHEN foreign_key_violation THEN NULL; END; END $$; ROLLBACK; SQL printf 'Migration preserved existing logins and enforced project isolation.\n' for package in platform auth; do CGO_ENABLED=0 go test -mod=readonly -c -o "bin/$package-tests" "./internal/$package" docker run --rm --network "container:$container" --user 1000:1000 \ --read-only --cap-drop ALL --security-opt no-new-privileges \ --mount "type=bind,source=$(pwd)/bin/$package-tests,target=/opt/integration-tests,readonly" \ -e PLATFORM_TEST_DATABASE_URL=postgres://foundry_fixture@127.0.0.1:5432/postgres?sslmode=disable \ --entrypoint /opt/integration-tests postgres:17-alpine -test.v done