Исследование По Реализации Безопасности На Уровне Строк В Postgresql

В качестве дополнения к Способ реализации бизнес-логики на уровне хранимых функций PostgreSQL. И главным образом за подробный ответ на комментарий .

Теоретическая часть хорошо описана в документации.

PostgreSQL Политики защиты строк .

Ниже представлена практическая реализация небольшого конкретная бизнес-задача – сокрытие удаленных данных.

Этуд, посвященный реализации Ролевое моделирование с использованием RLS представлены отдельно.



Исследование по реализации безопасности на уровне строк в PostgreSQL

В статье нет ничего нового, нет скрытого смысла или тайных знаний.

Просто набросок о практической реализации теоретической идеи.

Если кому интересно, прочтите.

Если вам не интересно, не тратьте время.



Постановка задачи

Не углубляясь глубоко в предметную область, кратко проблему можно сформулировать следующим образом: Есть таблица, реализующая некую бизнес-сущность.

Строки в таблице можно удалить, но строки нельзя удалить физически; они должны быть скрыты.

Ибо сказано: «Ничего не удаляйте, просто переименуйте.

В интернет-магазинах ВСЁ» Попутно желательно не переписывать существующие хранимые функции, работающие с этой сущностью.

Для реализации этой концепции таблица имеет атрибут is_deleted .

Дальше все просто — нужно сделать так, чтобы клиент видел только те строки, в которых указан атрибут is_deleted false Для чего используется этот механизм? Безопасность на уровне строк.



Выполнение

Создайте отдельную роль и схему
  
  
  
  
  
  
  
   

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)

Именно это и требовалось в постановке задачи.



Нижняя граница

Если тема интересна, в следующем исследовании вы сможете показать пример реализации ролевой модели разделения доступа к данным с использованием Row Level Security. Теги: #Администрирование баз данных #postgresql #sql #rls #rls
Вместе с данным постом часто просматривают: