Eine Studie zur Implementierung von Row Level Security in PostgreSQL

Als Ergänzung zu Eine Studie zur Implementierung von Geschäftslogik auf der Ebene gespeicherter PostgreSQL-Funktionen и Hauptsächlich wegen einer ausführlichen Antwort auf Kommentar.

Der theoretische Teil ist in der Dokumentation gut beschrieben PostgreSQL - Zeilenschutzrichtlinien. Nachfolgend finden Sie eine praktische Umsetzung eines kleinen spezifische Geschäftsaufgabe – Ausblenden gelöschter Daten. Skizze zur Umsetzung gewidmet Rollenmodellierung mit RLS gesondert dargestellt.

Eine Studie zur Implementierung von Row Level Security in PostgreSQL

Der Artikel enthält nichts Neues, keine versteckte Bedeutung oder geheimes Wissen. Nur eine Skizze zur praktischen Umsetzung einer theoretischen Idee. Wenn es jemanden interessiert, lesen Sie es. Wenn Sie kein Interesse haben, verschwenden Sie keine Zeit.

Formulierung des Problems

Ohne tief in die Materie einzutauchen, lässt sich das Problem kurz wie folgt formulieren: Es gibt eine Tabelle, die eine bestimmte Geschäftseinheit implementiert. Zeilen in der Tabelle können gelöscht werden, Zeilen können jedoch nicht physisch gelöscht werden; sie müssen ausgeblendet werden.

Denn es heißt: „Löschen Sie nichts, sondern benennen Sie es um.“ Das Internet speichert ALLES“

Unterwegs ist es ratsam, vorhandene gespeicherte Funktionen, die mit dieser Entität arbeiten, nicht neu zu schreiben.

Um dieses Konzept umzusetzen, verfügt die Tabelle über das Attribut ist gelöscht. Dann ist alles ganz einfach – Sie müssen sicherstellen, dass der Client nur die Zeilen sehen kann, in denen das Attribut steht ist gelöscht FALSCH Wozu dient der Mechanismus? Sicherheit auf Zeilenebene.

Implementierung

Erstellen Sie eine separate Rolle und ein separates Schema

CREATE ROLE repos;
CREATE SCHEMA repos;

Erstellen Sie die Zieltabelle

CREATE TABLE repos.file
(
...
is_del BOOLEAN DEFAULT FALSE
);
CREATE SCHEMA repos

Einschalten Sicherheit auf Zeilenebene

ALTER TABLE repos.file  ENABLE ROW LEVEL SECURITY ;
CREATE POLICY file_invisible_deleted  ON repos.file FOR ALL TO dba_role USING ( NOT is_deleted );
GRANT ALL ON TABLE repos.file to dba_role ;
GRANT USAGE ON SCHEMA repos TO dba_role ;

Servicefunktion – Löschen einer Zeile in der Tabelle

CREATE OR REPLACE repos.delete( curr_id repos.file.id%TYPE)
RETURNS integer AS $$
BEGIN
...
UPDATE repos.file
SET is_del = TRUE 
WHERE id = curr_id ; 
...
END
$$ LANGUAGE plpgsql SECURITY DEFINER;

Geschäftsfunktion — Löschen eines Dokuments

CREATE OR REPLACE business_functions.deleteDoc( doc_for_delete JSON )
RETURNS JSON AS $$
BEGIN
...
PERFORM  repos.delete( doc_id ) ;
...
END
$$ LANGUAGE plpgsql SECURITY DEFINER;

Ergebnisse

Der Client löscht das Dokument

SELECT business_functions.delCFile( (SELECT json_build_object( 'CId', 3 )) );

Nach dem Löschen sieht der Kunde das Dokument nicht

SELECT business_functions.getCFile"( (SELECT json_build_object( 'CId', 3 )) ) ;
-----------------
(0 rows)

In der Datenbank wird das Dokument jedoch nicht gelöscht, sondern nur das Attribut geändert is_del

psql -d my_db
SELECT  id, name , is_del FROM repos.file ;
id |  name  | is_del
--+---------+------------
 1 |  test_1 | t
(1 row)

Das war es, was in der Problemstellung gefordert wurde.

Ergebnis

Wenn das Thema interessant ist, können Sie in der nächsten Studie ein Beispiel für die Implementierung eines rollenbasierten Modells zur Trennung des Datenzugriffs mithilfe von Row Level Security zeigen.

Source: habr.com

Kommentar hinzufügen