Teema arendamine ja laiendatud vastuse jaoks . Tundub, et
Kasutatud strateegia eeldab kontseptsiooni "Ăriloogika andmebaasis", mida on veidi lĂ€hemalt kirjeldatud siin â
Teoreetiline osa on dokumentatsioonis suurepĂ€raselt kirjeldatud â . Allpool kĂ€sitletakse konkreetse rakendamise praktikat konkreetse Ă€riĂŒlesande â andmete juurdepÀÀsu rollimudeli.

Artiklis ei ole midagi uut, pole peidetud tÀhendust ega saladusi. Lihtsalt visand teoreetilise idee praktilisest rakendamisest. Kui see huvitab, lugege. Kui ei, siis Àrge raisake oma aega.
Ălesande seadmine
On vajalik piirata juurdepÀÀsu dokumendi vaatamiseks/sisestamiseks/muutmiseks/kustutamiseks vastavalt rakenduse kasutaja rollile. Rolli all mĂ”istetakse kirjet tabelis roles paljusid-mitme suhetega tabeliga users. Tabelite rakenduse ĂŒksikasjad, lihtsuse tĂ”ttu, jĂ€etakse vĂ€lja. Samuti jĂ€etakse vĂ€lja spetsiifilised rakenduse detailid, mis on seotud ainevaldkonnaga.
Rakendamine
Loome rollid, skeemid, tabeli
Andmebaasi objektide loomine
CREATE ROLE store;
CREATE SCHEMA store AUTHORIZATION store;
CREATE TABLE store.docs
(
id integer , --dokumendi id
man_id integer , --dokumendi halduri id
stat_id integer , --dokumendi staatuse id
...
is_del BOOLEAN DEFAULT FALSE
);
ALTER TABLE store.docs ADD CONSTRAINT doc_pk PRIMARY KEY (id);
ALTER TABLE store.docs OWNER TO store ;
Loome funktsioonid RLS rakendamiseks
Kontrolli, kas saab SELECT rida teostada
check_select
Loo ja asenda funktsioon store.check_select ( current_id store.docs.id%TYPE ) RETURNS boolean AS $$
DECLARE
result boolean ;
curr_pid integer ;
curr_stat_id integer ;
doc_man_id integer ;
BEGIN
-- DBA-l on juurdepÀÀs kÔigile dokumentidele
IF SESSION_USER = 'curr_dba'
THEN
RETURN TRUE ;
END IF ;
--------------------------------
-- Kui dokument on mÀrgistatud 'kustutatud', siis ei nÀidata seda valikus
SELECT
is_del
INTO
result
FROM
store.docs
WHERE
id = current_id ;
IF result = TRUE
THEN
RETURN FALSE ;
END IF ;
--------------------------------
-- Saada praeguse kasutaja id
SELECT
service_function.get_curr_pid ()
INTO
curr_pid ;
--------------------------------
-- Saada dokumendi halduri id
SELECT
man_id
INTO
doc_man_id
FROM
store.docs
WHERE
id = current_id ;
--------------------------------
-- Kui dokumendi haldur ei ole praegune kasutaja vÔi haldurit ei ole mÀÀratud
-- lisa dokument valikusse
IF doc_man_id != curr_pid OR doc_man_id IS NULL
THEN
RETURN TRUE ;
ELSE
-- Saada dokumendi praegune staatus
SELECT
stat_id
INTO
curr_statid
FROM
store.docs
WHERE
id = current_id ;
-- Kui staatus lubab dokumenti vaadata - lisa dokument valikusse
IF curr_statid = 4 OR curr_statid = 9
THEN
RETURN TRUE ;
ELSE
-- Muidu - vÀlista dokument valikust
RETURN FALSE ;
END IF ;
END IF ;
--------------------------------
RETURN FALSE ;
END
$$ LANGUAGE plpgsql SECURITY DEFINER;
ALTER FUNCTION store.check_select( store.docs.id%TYPE ) OWNER TO store ;
REVOKE EXECUTE ON FUNCTION store.check_select( store.docs.id%TYPE ) FROM public;
GRANT EXECUTE ON FUNCTION store.check_select( store.docs.id%TYPE ) TO service_functions;
Kontrolli, kas rida on vÔimalik sisestada
check_insert
Loo ja asenda funktsioon store.check_insert ( current_id store.docs.id%TYPE ) RETURNS boolean AS $$
DECLARE
curr_role_id integer ;
BEGIN
-- DBA vÔib rida igal juhul lisada
IF SESSION_USER = 'curr_dba'
THEN
RETURN TRUE ;
END IF ;
--------------------------------
-- Saada praeguse kasutaja rolli id
SELECT
service_functions.current_rid()
INTO
curr_role_id ;
--------------------------------
-- Kui roll vÔimaldab uue dokumendi loomist
-- luba
IF curr_role_id = 3 OR curr_role_id = 5
THEN
RETURN TRUE ;
END IF ;
--------------------------------
RETURN FALSE ;
END
$$ LANGUAGE plpgsql SECURITY DEFINER;
ALTER FUNCTION store.check_insert( store.docs.id%TYPE ) OWNER TO store ;
REVOKE EXECUTE ON FUNCTION store.check_insert( store.docs.id%TYPE ) FROM public;
GRANT EXECUTE ON FUNCTION store.check_insert( store.docs.id%TYPE ) TO service_functions;
Kontrolli, kas rida on vÔimalik kustutada
check_delete
Loo ja asenda funktsioon store.check_delete ( current_id store.docs.id%TYPE )
RETURNS boolean AS $$
BEGIN
-- Ainult DBA vÔib rida kustutada
IF SESSION_USER = 'curr_dba'
THEN
RETURN TRUE ;
END IF ;
--------------------------------
RETURN FALSE ;
END
$$ LANGUAGE plpgsql
SECURITY DEFINER;
ALTER FUNCTION store.check_delete( store.docs.id%TYPE ) OWNER TO store ;
REVOKE EXECUTE ON FUNCTION store.check_delete( store.docs.id%TYPE ) FROM public;Kontrolli, kas rida on vÔimalik uuendada.
update_using
Looja vÔi asenda funktsioon store.update_using ( current_id store.docs.id%TYPE , is_del boolean )
TULEMUSED boolean NAGU $$
ALUSTA
--Dokumendid, millel on olek 'kustutatud' - ei redigeerita
KUI is_del
SEE
TAGASTA FALSE ;
MUU
TAGASTA TRUE ;
LĂPETA
LĂPETA
$$ KEEL plpgsql SECURITY DEFINER;
MUUDA FUNKTSIOON store.update_using( store.docs.id%TYPE , boolean ) OMANIK KAUPO ;
TĂHISTA EXECUTE FUNKTSIOONIL store.update_using( store.docs.id%TYPE , boolean ) PUBLIC;
ANDA EXECUTE FUNKTSIOONILE store.update_using( store.docs.id%TYPE ) SERVICE_FUNCTIONS;update_check
Looja vÔi asenda funktsioon store.update_with_check ( current_id store.docs.id%TYPE , is_del boolean )
TULEMUSED boolean NAGU $$
DECLARE
current_rid integer ;
current_statid integer ;
ALUSTA
--DBA saab vaadata rida
KUI SESSION_USER = 'curr_dba'
SEE
TAGASTA TRUE ;
LĂPETA
--------------------------------
--Hangi praegune kasutaja rolli id
VALI
service_functions.current_rid()
INTO
curr_role_id ;
--------------------------------
--Dokumendi kustutamine - seisundi muutmine
KUI is_deleted
SEE
--Kui kasutaja roll ***
KUI current_role_id = 3
SEE
VALI
stat_id
INTO
curr_statid
FROM
store.docs
KUS
id = current_id ;
--Dokument olekus *** ei saa kustutada
KUI current_status_id = 11
SEE
TAGASTA FALSE ;
MUU
--Dokumente saab kustutada teistes olekutes
TAGASTA TRUE ;
LĂPETA
--Vastasel juhul, kui kasutaja roll ***
ELSIF current_role_id = 5
SEE
--KÔik dokumentide olekud
TAGASTA TRUE ;
MUU
--Teised kasutajad ei saa dokumente kustutada
TAGASTA FALSE ;
LĂPETA
ELSE
--Dokumendi uuendamine on lubatud
TAGASTA TRUE ;
LĂPETA
TAGASTA FALSE ;
LĂPETA
$$ KEEL plpgsql SECURITY DEFINER;
MUUDA FUNKTSIOON store.update_with_check( storg.docs.id%TYPE , boolean ) OMANIK KAUPO ;
TĂHISTA EXECUTE FUNKTSIOONIL store.update_with_check( storg.docs.id%TYPE , boolean ) PUBLIC;
ANDA EXECUTE FUNKTSIOONILE store.update_with_check( store.docs.id%TYPE ) SERVICE_FUNCTIONS;Ridade tasandi turbe poliitika sisselĂŒlitamine tabelis.
LUBA RIDADE TASANDI TURVE
MUUDA TABELIT store.docs LUBA RIDADE TASANDI TURVE ;
LOO POLIITIKA doc_select STORE.docs VALIKU KAUPO service_functions KASUTADES ( (VALI store.check_select(id)) );
LOO POLIITIKA doc_insert STORE.docs INSERT KAUPO service_functions KONTROLLIDE ( (VALI store.check_insert(id)) );
LOO POLIITIKA docs_delete STORE.docs KUSTUTAMINE KAUPO service_functions KASUTADES ( (VALI store.check_delete(id)) );
LOO POLIITIKA doc_update_using STORE.docs UUENDAMINE KAUPO service_functions KASUTADES ( (VALI store.update_using(id , is_del )) );
LOO POLIITIKA doc_update_check STORE.docs UUENDAMINE KAUPO service_functions KONTROLLIDE ( (VALI store.update_with_check(id , is_del )) );KokkuvÔte
See töötab.
Ettepanekute strateegia vÔimaldas edastada rollimudeli teostamise tasemelt Àrifunktsioonide tasemele andmehÔive tasemele.
Funktsioone saab kasutada ƥabloonina keerukamate andmete varjamise mudelite rakendamiseks, kui Àri nÔuded seda nÔuavad.
Allikas: habr.com
