Štúdia o implementácii zabezpečenia na úrovni riadkov v PostgreSQL

Ako doplnok k Štúdia o implementácii obchodnej logiky na úrovni uložených funkcií PostgreSQL и hlavne za podrobnú odpoveď na komentár.

Teoretická časť je dobre popísaná v dokumentácii PostgreSQL - Zásady ochrany riadkov. Nižšie je praktická implementácia malého konkrétna obchodná úloha – skrytie vymazaných údajov. Náčrt venovaný implementácii Modelovanie rolí pomocou RLS prezentované samostatne.

Štúdia o implementácii zabezpečenia na úrovni riadkov v PostgreSQL

V článku nie je nič nové, nie je tam žiadny skrytý význam ani tajná znalosť. Len náčrt o praktickej realizácii teoretickej myšlienky. Ak to niekoho zaujíma, prečítajte si to. Ak nemáte záujem, nestrácajte čas.

Vyhlásenie o probléme

Bez toho, aby sme sa hlboko ponorili do predmetnej oblasti, stručne možno problém formulovať takto: Existuje tabuľka, ktorá implementuje určitý podnikateľský subjekt. Riadky v tabuľke je možné vymazať, ale riadky nie je možné vymazať fyzicky, musia byť skryté.

Hovorí sa totiž: „Nič nemažte, len premenujte. Internet ukladá VŠETKO"

Po ceste je vhodné neprepisovať existujúce uložené funkcie, ktoré s touto entitou pracujú.

Na implementáciu tohto konceptu má tabuľka atribút is_deleted. Potom je všetko jednoduché - musíte sa uistiť, že klient vidí iba riadky, v ktorých je atribút is_deleted falošný Na čo sa mechanizmus používa? Zabezpečenie na úrovni riadkov.

Реализация

Vytvorte samostatnú rolu a schému

CREATE ROLE repos;
CREATE SCHEMA repos;

Vytvorte cieľovú tabuľku

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

Zahŕňame Zabezpečenie na úrovni riadkov

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 ;

Servisná funkcia — vymazanie riadku v tabuľke

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;

Obchodná funkcia — vymazanie dokumentu

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

výsledky

Klient vymaže dokument

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

Po vymazaní klient dokument nevidí

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

Ale v databáze sa dokument nevymaže, zmení sa iba atribút is_del

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

Čo sa požadovalo vo vyhlásení o probléme.

Celkový

Ak je téma zaujímavá, v ďalšej štúdii môžete ukázať príklad implementácie modelu založeného na rolách na oddelenie prístupu k údajom pomocou zabezpečenia na úrovni riadkov.

Zdroj: hab.com

Pridať komentár