به عنوان مکمل
بخش تئوری به خوبی در مستندات توضیح داده شده است
هیچ چیز جدیدی در مقاله وجود ندارد، هیچ معنای پنهان یا دانش پنهانی وجود ندارد. فقط یک طرح در مورد اجرای عملی یک ایده نظری. اگر کسی علاقه مند است بخواند. اگر علاقه ای ندارید، وقت خود را تلف نکنید.
بیانیه مشکل
بدون غواصی عمیق در حوزه موضوعی، به طور خلاصه، مسئله را می توان به صورت زیر فرموله کرد: جدولی وجود دارد که یک نهاد تجاری خاص را پیاده سازی می کند. ردیفهای جدول را میتوان حذف کرد، اما ردیفها را نمیتوان به صورت فیزیکی حذف کرد، آنها باید پنهان شوند.
زیرا گفته می شود: «هیچ چیزی را حذف نکنید، فقط نام آن را تغییر دهید. اینترنت همه چیز را ذخیره می کند"
در طول مسیر، توصیه می شود توابع ذخیره شده موجود را که با این موجودیت کار می کنند، بازنویسی نکنید.
برای پیاده سازی این مفهوم، جدول دارای ویژگی است is_deleted است. سپس همه چیز ساده است - باید مطمئن شوید که مشتری می تواند فقط خطوطی را ببیند که در آن ویژگی وجود دارد is_deleted است نادرست مکانیسم مورد استفاده برای چیست؟ امنیت سطح ردیف
اجرا
یک نقش و طرح جداگانه ایجاد کنید
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 را نشان دهید.
منبع: www.habr.com