Etīde par Row Level Security ievieŔanu PostgreSQL

Kā papildinājumu Studija par biznesa loÄ£ikas realizāciju PostgreSQL uzglabāŔanas funkciju lÄ«menÄ« un galvenokārt detalizētai atbildei uz komentārs.

Teorētiskā daļa ir lieliski aprakstÄ«ta dokumentācijā Postgres Pro — Rindu aizsardzÄ«bas politikas. Zemāk tiks aplÅ«kota praktiskā maza konkrētā biznesa uzdevuma — dzēsto datu slēpÅ”anas. Studija, kas veltÄ«ta Lomu modeļa realizācijai, izmantojot RLS ir atseviŔķi izklāstÄ«ta.

Etīde par Row Level Security ievieŔanu PostgreSQL

Rakstā nav nekas jauns, nav slēpta jēga vai noslēpumu. Tā ir vienkārÅ”a piezÄ«me par praktiskās realizācijas teorētisko ideju. Ja kādu interesē — lasiet. Kam neinteresē — netērējiet savu laiku velti.

Uzdevuma formulēŔana

Nedziļinoties dziļi tēmā, Ä«si, uzdevumu var formulēt Ŕādi: ir tabula, kas realizē noteiktu biznesa entÄ«tiju. Rindas tabulā var tikt dzēstas, bet fiziski dzēst rindas nav atļauts, tās ir jāslēpj.

Jo ir teikts — ā€œNeko nemācÄ«ties, tikai pārdēvēt. Internets saglabā VISUā€

Ideāli vēlams nebÅ«t pārrakstÄ«t jau esoŔās glabāŔanas funkcijas, kas strādā ar Å”o entÄ«tiju.

Å Ä«s koncepcijas Ä«stenoÅ”anai tabulai ir atribÅ«ts is_deleted. Tālāk viss ir vienkārÅ”i — ir jāpanāk, lai klients redzētu tikai rindas, kurās atribÅ«ts is_deleted ir nepatiesi. Tāpēc tiek izmantots mehānisms Rindu lÄ«meņa droŔība.

Realizācija

Izveidojam atseviŔķu lomu un shēmu

CREATE ROLE repos;
CREATE SCHEMA repos;

Izveidojam mērķa tabulu

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

Ieslēdzam Rindu lÄ«meņa droŔību

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;

Servisa funkcija — rinda dzēŔana tabulā

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;

Biznesa funkcija — dokumenta dzēŔana

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

Rezultāti

Klients dzēŔ dokumentu

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

Pēc dzēŔanas klients dokumentu neredz

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

Bet datu bāzē dokuments netika dzēsts, tikai atribūts mainīts is_del

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

Kas arī bija prasītajā uzdevumā.

Rezultāts

Ja, ja ir interesanta tēma, nākamajā etÅ«dē varam parādÄ«t piekļuves datiem sadalīŔanas lomu modeļa Ä«stenoÅ”anas piemēru, izmantojot Rindu lÄ«meņa droŔību.

Avots: habr.com

Iegādājieties uzticamu tÄ«mekļa hostingu ar DDoS aizsardzÄ«bu, VPS VDS serveriem šŸ”„ Iegādājieties uzticamu tÄ«mekļa hostingu ar DDoS aizsardzÄ«bu, VPS VDS serveriem | ProHoster