Ca o completare a
Partea teoretică este bine descrisă în documentație
Nu există nimic nou în articol, nu există niciun sens ascuns sau cunoștințe secrete. Doar o schiță despre implementarea practică a unei idei teoretice. Daca e cineva interesat, citeste-l. Dacă nu ești interesat, nu-ți pierde timpul.
Declarație de problemă
Fără să ne scufundăm adânc în domeniul subiectului, pe scurt, problema poate fi formulată după cum urmează: Există un tabel care implementează o anumită entitate de afaceri. Rândurile din tabel pot fi șterse, dar rândurile nu pot fi șterse fizic; ele trebuie ascunse.
Căci se spune: „Nu șterge nimic, ci doar redenumiți. Internetul stochează TOTUL”
Pe parcurs, este recomandabil să nu rescrieți funcțiile stocate existente care funcționează cu această entitate.
Pentru a implementa acest concept, tabelul are atributul este_ștersă. Apoi totul este simplu - trebuie să vă asigurați că clientul poate vedea numai liniile în care atributul este_ștersă fals Pentru ce este folosit mecanismul? Securitate la nivel de rând.
punerea în aplicare
Creați un rol și o schemă separate
CREATE ROLE repos;
CREATE SCHEMA repos;
Creați tabelul țintă
CREATE TABLE repos.file
(
...
is_del BOOLEAN DEFAULT FALSE
);
CREATE SCHEMA repos
Includem Securitate la nivel de rând
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 ;
Funcția de service — ștergerea unui rând din tabel
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;
Funcția de afaceri — ștergerea unui document
CREATE OR REPLACE business_functions.deleteDoc( doc_for_delete JSON )
RETURNS JSON AS $$
BEGIN
...
PERFORM repos.delete( doc_id ) ;
...
END
$$ LANGUAGE plpgsql SECURITY DEFINER;
Constatări
Clientul șterge documentul
SELECT business_functions.delCFile( (SELECT json_build_object( 'CId', 3 )) );
După ștergere, clientul nu vede documentul
SELECT business_functions.getCFile"( (SELECT json_build_object( 'CId', 3 )) ) ;
-----------------
(0 rows)
Dar în baza de date documentul nu este șters, se schimbă doar atributul is_del
psql -d my_db
SELECT id, name , is_del FROM repos.file ;
id | name | is_del
--+---------+------------
1 | test_1 | t
(1 row)
Ceea ce a fost cerut în declarația problemei.
Total
Dacă subiectul este interesant, în următorul studiu puteți arăta un exemplu de implementare a unui model bazat pe roluri pentru separarea accesului la date folosind Row Level Security.
Sursa: www.habr.com