Establish project-scoped account and collaboration schema
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
#!/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 -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 < db/002-platform.sql
|
||||
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'
|
||||
Reference in New Issue
Block a user