Ως συμπλήρωμα του
Το θεωρητικό μέρος περιγράφεται καλά στην τεκμηρίωση
Δεν υπάρχει τίποτα νέο στο άρθρο, δεν υπάρχει κρυφό νόημα ή μυστική γνώση. Απλά ένα σκίτσο για την πρακτική εφαρμογή μιας θεωρητικής ιδέας. Αν κάποιος ενδιαφέρεται ας το διαβάσει. Αν δεν σας ενδιαφέρει, μην χάνετε το χρόνο σας.
Δήλωση προβλήματος
Χωρίς να βουτήξουμε βαθιά στη θεματική περιοχή, εν συντομία, το πρόβλημα μπορεί να διατυπωθεί ως εξής: Υπάρχει ένας πίνακας που υλοποιεί μια συγκεκριμένη επιχειρηματική οντότητα. Οι σειρές στον πίνακα μπορούν να διαγραφούν, αλλά οι σειρές δεν μπορούν να διαγραφούν φυσικά, πρέπει να είναι κρυφές.
Διότι λέγεται: «Μην διαγράψετε τίποτα, απλώς μετονομάστε το. Το Διαδίκτυο αποθηκεύει ΤΑ ΠΑΝΤΑ»
Στην πορεία, συνιστάται να μην ξαναγράψετε υπάρχουσες αποθηκευμένες συναρτήσεις που λειτουργούν με αυτήν την οντότητα.
Για την υλοποίηση αυτής της έννοιας, ο πίνακας έχει το χαρακτηριστικό 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)
Αυτό που απαιτούνταν στη δήλωση προβλήματος.
Σύνολο
Εάν το θέμα είναι ενδιαφέρον, στην επόμενη μελέτη μπορείτε να δείξετε ένα παράδειγμα εφαρμογής ενός μοντέλου βασισμένου σε ρόλους για τον διαχωρισμό της πρόσβασης δεδομένων χρησιμοποιώντας την ασφάλεια επιπέδου γραμμής.
Πηγή: www.habr.com