Studo pri efektivigado de Row Level Security en PostgreSQL

Kiel komplemento al Studo pri efektivigado de komerca logiko ĉe la nivelo de stokitaj funkcioj de PostgreSQL и ĉefe por detala respondo sur komento.

La teoria parto estas bone priskribita en la dokumentado PostgreSQL - Vicaj protektopolitikoj. Malsupre estas praktika efektivigo de malgranda specifa komerca tasko - kaŝi forigitajn datumojn. Skizo dediĉita al efektivigo Rolmodelado uzante RLS prezentita aparte.

Studo pri efektivigado de Row Level Security en PostgreSQL

Estas nenio nova en la artikolo, ne estas kaŝita signifo aŭ sekreta scio. Nur skizo pri la praktika efektivigo de teoria ideo. Se iu interesiĝas, legu ĝin. Se vi ne interesiĝas, ne malŝparu vian tempon.

Formulado de la problemo

Sen plonĝi profunde en la temon, mallonge, la problemo povas esti formulita jene: Estas tablo, kiu efektivigas certan komercan enton. Vicoj en la tabelo povas esti forigitaj, sed vicoj ne povas esti fizike forigitaj; ili devas esti kaŝitaj.

Ĉar estas dirite: "Ne forigu ion ajn, nur renomu ĝin. Interreto konservas ĈION"

Survoje, estas konsilinde ne reverki ekzistantajn konservitajn funkciojn, kiuj funkcias kun ĉi tiu ento.

Por efektivigi ĉi tiun koncepton, la tabelo havas la atributon estas_forigita. Tiam ĉio estas simpla - vi devas certigi, ke la kliento povas vidi nur la liniojn en kiuj la atributo estas_forigita malvera Por kio estas uzata la mekanismo? Vico Nivelo Sekureco.

Реализация

Kreu apartan rolon kaj skemon

CREATE ROLE repos;
CREATE SCHEMA repos;

Kreu la celtabelon

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

Ni inkluzivas Sekura Nivelo

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 ;

Serva funkcio — forigante vicon en la tabelo

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;

Komerca funkcio — forigi dokumenton

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

Результаты

La kliento forigas la dokumenton

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

Post forigo, la kliento ne vidas la dokumenton

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

Sed en la datumbazo la dokumento ne estas forigita, nur la atributo estas ŝanĝita is_del

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

Kio estas postulata en la problemo-deklaro.

La rezulto

Se la temo estas interesa, en la sekva studo vi povas montri ekzemplon pri efektivigo de rol-bazita modelo por apartigi datuman aliron uzante Row Level Security.

fonto: www.habr.com

Aldoni komenton