-- ===================================================================== -- TeeCup — isolasjonstest (oppførsel, ikke bare skjema) -- ===================================================================== -- Beviser at RLS faktisk hindrer én organisasjon i å se en annens data, -- sett fra runtime-rollen teecup_app (som IKKE er superuser/BYPASSRLS). -- -- Kjør som admin/superbruker mot en scratch- eller test-database der -- 001_initial_schema.sql og 002_roles_and_grants.sql allerede er kjørt: -- psql -d teecup_scratch -f test_isolation.sql -- -- Alt kjøres i én transaksjon som RULLES TILBAKE til slutt — ingen testdata -- blir liggende igjen. Skriptet stopper med feil hvis isolasjonen svikter. -- ===================================================================== \set ON_ERROR_STOP on BEGIN; -- --- Seed to organisasjoner + én turnering hver (som privilegert rolle) --- -- (Superbruker omgår RLS, så innsettingen går uhindret her — det er meningen.) INSERT INTO organization (id, name) VALUES ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'Org A'), ('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'Org B'); INSERT INTO tournament (organization_id, name) VALUES ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'A-Cup'), ('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'B-Cup'); -- --- Bytt til runtime-rollen: nå SKAL RLS gjelde --------------------- SET ROLE teecup_app; SELECT set_config('app.current_org', 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', false); -- Test 1: Ser bare Org A sine turneringer (1, ikke 2). DO $$ DECLARE n int; BEGIN SELECT count(*) INTO n FROM tournament; IF n <> 1 THEN RAISE EXCEPTION 'ISOLASJON FEILET (lesing): ser % turneringer, forventet 1', n; END IF; RAISE NOTICE 'OK Test 1: ser kun egen organisasjons turneringer (%).', n; END $$; -- Test 2: Ser bare sin egen organisasjonsrad. DO $$ DECLARE n int; BEGIN SELECT count(*) INTO n FROM organization; IF n <> 1 THEN RAISE EXCEPTION 'ISOLASJON FEILET (organization): ser % rader, forventet 1', n; END IF; RAISE NOTICE 'OK Test 2: ser kun egen organisasjonsrad (%).', n; END $$; -- Test 3: Kan IKKE sette inn data merket med en annen organisasjon. -- WITH CHECK skal blokkere det (SQLSTATE 42501). DO $$ BEGIN BEGIN INSERT INTO tournament (organization_id, name) VALUES ('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'kryss-org-forsøk'); -- Kommer vi hit, ble det tillatt -> isolasjonen er brutt. RAISE EXCEPTION 'ISOLASJON FEILET (skriving): fikk sette inn data for annen org'; EXCEPTION WHEN insufficient_privilege THEN RAISE NOTICE 'OK Test 3: WITH CHECK blokkerte kryss-org innsetting.'; END; END $$; -- Test 4: Kontrollprøve — bytter kontekst til Org B og ser Bs turnering isteden. SELECT set_config('app.current_org', 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', false); DO $$ DECLARE nm text; BEGIN SELECT name INTO nm FROM tournament; IF nm <> 'B-Cup' THEN RAISE EXCEPTION 'ISOLASJON FEILET (kontekstbytte): forventet B-Cup, fikk %', nm; END IF; RAISE NOTICE 'OK Test 4: kontekstbytte gir riktig organisasjons data (%).', nm; END $$; RESET ROLE; RESET app.current_org; ROLLBACK; -- ingen testdata blir liggende igjen \echo '============================================' \echo ' Alle isolasjonstester bestått (se OK-linjer)' \echo '============================================'