Tak, całkowicie możliwe.
1. Generalnie nie zezwalaj na UPDATE
do A
Działałbym z uprawnieniami:
REVOKE ALL ON TABLE A FROM public; -- and from anybody else who might have it
Pozostają superużytkownicy, tacy jak postgres
którzy ignorują te skromne ograniczenia. Złap te wewnątrz funkcji wyzwalacza na A
z pg_has_role()
:
IF pg_has_role('postgres', 'member') THEN
RETURN NULL;
END IF;
Gdzie postgres
jest prawdziwym superużytkownikiem. Uwaga:obejmuje to również innych superużytkowników, ponieważ są oni członkami każdej roli, nawet innych superużytkowników.
Możesz złapać użytkowników niebędących superużytkownikami w podobny sposób (alternatywa do REVOKE
podejście).
2. Zezwól na AKTUALIZACJĘ
dla roli demona
Utwórz rolę bez logowania, która może aktualizować A
:
CREATE ROLE a_update NOLOGIN;
-- GRANT USAGE ON SCHEMA xyz TO a_update; -- may be needed, too
GRANT UPDATE ON TABLE A TO a_update;
Utwórz funkcje wyzwalacza w tabelach B
i C
, własność przez tę rolę demona i SECURITY DEFINER
. Szczegóły:
Dodaj do funkcji wyzwalacza w A
:
IF pg_has_role('postgres', 'member') THEN
RETURN NULL;
ELSIF pg_has_role('a_update', 'member') THEN
RETURN NEW;
END IF;
W przypadku prostych zależności 1:1 możesz również pracować z ograniczenia kluczy obcych (dodatkowo) przy użyciu ON UPDATE CASCADE
.