Etüüd Row Level Security rakendamisest PostgreSQL-is

Täienduseks Etüüd ärilogika rakendamisest PostgreSQL-i salvestatud funktsioonide tasemel ja peamiselt põhjalikku vastust jaoks järgnevaga kommentaar.

Teoreetiline osa on hästi kirjeldatud dokumentatsioonis Postgres ProRidade kaitse poliitikad. Allpool on käsitletud praktiline rakendus väikesest konkreetse äriprobleemi — kaugete andmete varjamise. Essee on pühendatud rakendusele rollimudeli kasutamisega RLS esitatud eraldi.

Etüüd Row Level Security rakendamisest PostgreSQL-is

Artiklis ei ole midagi uut, ei ole varjatud mõtet ega salajasi teadmisi. Lihtsalt joonistamine teoreetilise idee praktilisest elluviimisest. Kui kedagi huvitab — lugege. Kui ei huvita — ärge kulutage oma aega raisku.

Ülesande seadmine

Sügavale teemasse minemata võib lühidalt öelda, et ülesanne on järgmine: olemas on tabel, mis rakendab mingit ärilisi olemusi. Tabeli read võivad olla kustutatud, kuid füüsiliselt ridu kustutada ei tohi; neid tuleb varjata.

Sest öeldud on — „Mitte midagi ei kustuta, ainult nimetused muuda. Internet salvestab KÕIKE“

Samas on soovitav mitte kirjutada uuesti juba olemasolevaid salvestatud funktsioone, mis töötavad antud subjektiga.

Selle kontseptsiooni rakendamiseks on tabelil atribuudi is_deleted. Edasi on kõik lihtne — tuleb teha nii, et klient näeks ainult ridu, kus atribuudi is_deleted väärtus on vale. Selleks kasutatakse rea tasandi turvamehhanismi.

Rakendus

Loo eraldi roll ja skeem

CREATE ROLE repos;
CREATE SCHEMA repos;

Loo sihtmärk tabel

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

Luba rea tasandi turvalisus

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 ;

Teenusfunktsioon — rea kustutamine tabelis

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;

Ärifunktsioon — dokumendi kustutamine

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

Tulemused

Kliendikustutab dokumendi

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

Pärast kustutamist ei näe dokumendi klient

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

Aga andmebaasis dokument ei ole kustutatud, ainult atribuut on muudetud is_del

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

Just nagu tehtud ülesandes nõuti.

Kokkuvõte

Kui teema huvitab, siis järgmises eetüüd võib näidata näidet rollimudeli rakendamisest, kasutades Row Level Security.

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster