Студија за спроведување на безбедност на ниво на ред во PostgreSQL

Како дополнување на Студија за имплементација на деловна логика на ниво на складирани функции PostgreSQL и главно за детален одговор на коментар.

Теоретскиот дел е добро опишан во документацијата PostgreSQL - Политики за заштита на редови. Подолу е практична имплементација на мала специфична деловна задача - криење на избришани податоци. Скица посветена на имплементација Моделирање на улоги со користење на RLS презентирани одделно.

Студија за спроведување на безбедност на ниво на ред во PostgreSQL

Нема ништо ново во статијата, нема скриено значење или тајно знаење. Само скица за практичната имплементација на теоретска идеја. Ако некој го интересира нека прочита. Ако не сте заинтересирани, не трошете го вашето време.

Проблем изјава

Без длабоко навлегување во предметната област, накратко, проблемот може да се формулира на следниов начин: Има табела која имплементира одреден деловен субјект. Редовите во табелата може да се избришат, но редовите не можат физички да се избришат; тие мора да бидат скриени.

Зашто се вели: „Не бришете ништо, само преименувајте го. Интернетот складира СЕ“

На патот, препорачливо е да не се препишуваат постоечките зачувани функции што работат со овој ентитет.

За да се имплементира овој концепт, табелата го има атрибутот е_избришан. Тогаш сè е едноставно - треба да бидете сигурни дека клиентот може да ги види само линиите во кои атрибутот е_избришан лажни За што се користи механизмот? Безбедност на ниво на ред.

Реализация

Направете посебна улога и шема

CREATE ROLE repos;
CREATE SCHEMA repos;

Направете целна табела

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

Вклучуваме Безбедност на ниво на редови

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 ;

Сервисна функција — бришење ред во табелата

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;

Деловна функција — бришење документ

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

Наоди

Клиентот го брише документот

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

По бришењето, клиентот не го гледа документот

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

Но, во базата на податоци документот не се брише, само се менува атрибутот is_del

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

Што се бараше во изјавата за проблемот.

Вкупно

Ако темата е интересна, во следната студија можете да покажете пример за имплементација на модел заснован на улоги за одвојување на пристапот до податоци користејќи безбедност на ниво на ред.

Извор: www.habr.com

Додадете коментар