Како дополнување на
Теоретскиот дел е добро опишан во документацијата
Нема ништо ново во статијата, нема скриено значење или тајно знаење. Само скица за практичната имплементација на теоретска идеја. Ако некој го интересира нека прочита. Ако не сте заинтересирани, не трошете го вашето време.
Проблем изјава
Без длабоко навлегување во предметната област, накратко, проблемот може да се формулира на следниов начин: Има табела која имплементира одреден деловен субјект. Редовите во табелата може да се избришат, но редовите не можат физички да се избришат; тие мора да бидат скриени.
Зашто се вели: „Не бришете ништо, само преименувајте го. Интернетот складира СЕ“
На патот, препорачливо е да не се препишуваат постоечките зачувани функции што работат со овој ентитет.
За да се имплементира овој концепт, табелата го има атрибутот е_избришан. Тогаш сè е едноставно - треба да бидете сигурни дека клиентот може да ги види само линиите во кои атрибутот е_избришан лажни За што се користи механизмот? Безбедност на ниво на ред.
Реализация
Направете посебна улога и шема
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