Un estudi sobre la implementació de la seguretat a nivell de fila a PostgreSQL

Com a complement a Un estudi sobre la implementació de la lògica empresarial a nivell de funcions emmagatzemades PostgreSQL и principalment per a una resposta detallada en comentari.

La part teòrica està ben descrita a la documentació PostgreSQL - Polítiques de protecció de files. A continuació es mostra una implementació pràctica d'un petit tasca empresarial específica: amagar les dades suprimides. Croquis dedicat a la implementació Modelització de rols amb RLS presentat per separat.

Un estudi sobre la implementació de la seguretat a nivell de fila a PostgreSQL

No hi ha res de nou a l'article, no hi ha cap significat ocult ni coneixement secret. Només un esbós sobre la implementació pràctica d'una idea teòrica. Si algú està interessat, llegiu-lo. Si no t'interessa, no perdis el temps.

Declaració de problemes

Sense aprofundir en l'àrea temàtica, breument, el problema es pot formular de la següent manera: Hi ha una taula que implementa una determinada entitat empresarial. Les files de la taula es poden suprimir, però les files no es poden suprimir físicament; s'han d'amagar.

Perquè es diu: "No esborreu res, només canvieu el nom. Internet emmagatzema TOT"

Al llarg del camí, s'aconsella no reescriure les funcions emmagatzemades existents que funcionen amb aquesta entitat.

Per implementar aquest concepte, la taula té l'atribut està_suprimit. Aleshores, tot és senzill: heu d'assegurar-vos que el client només pot veure les línies en què l'atribut està_suprimit fals Per a què serveix el mecanisme? Seguretat a nivell de fila.

Implementació

Creeu un rol i un esquema separats

CREATE ROLE repos;
CREATE SCHEMA repos;

Creeu la taula de destinació

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

Incloem Seguretat de nivell de fila

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 ;

Funció de servei — suprimir una fila de la taula

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;

Funció empresarial - esborrar un 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;

Troballes

El client elimina el document

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

Després de la supressió, el client no veu el document

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

Però a la base de dades el document no s'elimina, només es canvia l'atribut is_del

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

Això és el que s'exigia a l'enunciat del problema.

Total

Si el tema és interessant, en el següent estudi podeu mostrar un exemple d'implementació d'un model basat en rols per separar l'accés a les dades mitjançant la seguretat a nivell de fila.

Font: www.habr.com

Afegeix comentari