เชฅเซเชฎ เชตเชฟเชเชพเชธ
เชเชชเชฏเซเชเชฎเชพเช เชฒเซเชตเชพเชคเซ เชตเซเชฏเซเชนเชฐเชเชจเชพ "เชกเซเชเชพเชฌเซเชเชฎเชพเช เชฌเชฟเชเชจเซเชธ เชฒเซเชเชฟเช" เชเซเชฏเชพเชฒเชจเซ เชเชชเชฏเซเช เชเชฐเซ เชเซ, เชเซเชจเซเช เช
เชนเซเช เชฅเซเชกเซ เชตเชงเซ เชตเชฟเชเชคเชฎเชพเช เชตเชฐเซเชฃเชจ เชเชฐเชตเชพเชฎเชพเช เชเชตเซเชฏเซเช เชเซ -
เชธเซเชฆเซเชงเชพเชเชคเชฟเช เชญเชพเช เชฆเชธเซเชคเชพเชตเซเชเซเชเชฐเชฃเชฎเชพเช เชธเชพเชฐเซ เชฐเซเชคเซ เชตเชฐเซเชฃเชตเซเชฒ เชเซ
เชฒเซเชเชฎเชพเช เชเชเช เชจเชตเซเช เชจเชฅเซ, เชเซเช เชเซเชชเชพเชฏเซเชฒ เช เชฐเซเชฅ เชเซ เชเซเชชเซเชค เชเซเชเชพเชจ เชจเชฅเซ. เชธเซเชฆเซเชงเชพเชเชคเชฟเช เชตเชฟเชเชพเชฐเชจเชพ เชตเซเชฏเชตเชนเชพเชฐเชฟเช เช เชฎเชฒเซเชเชฐเชฃ เชตเชฟเชถเซ เชฎเชพเชคเซเชฐ เชเช เชธเซเชเซเช. เชเซ เชเซเชเชจเซ เชฐเชธ เชนเซเชฏ เชคเซ เชตเชพเชเชเซ. เชเซ เชคเชฎเชจเซ เชฐเชธ เชจเชฅเซ, เชคเซ เชคเชฎเชพเชฐเซ เชธเชฎเชฏ เชฌเชเชพเชกเซ เชจเชนเซเช.
เชธเชฎเชธเซเชฏเชพเชจเซ เชฐเชเชจเชพ
เชเชชเซเชฒเชฟเชเซเชถเชจ เชตเชชเชฐเชพเชถเชเชฐเซเชคเชพเชจเซ เชญเซเชฎเชฟเชเชพ เช เชจเซเชธเชพเชฐ เชฆเชธเซเชคเชพเชตเซเช เชเซเชตเชพ/เชฆเชพเชเชฒ เชเชฐเชตเชพ/เชธเชเชถเซเชงเชฟเชค เชเชฐเชตเชพ/เชเชพเชขเซ เชจเชพเชเชตเชพเชจเซ เชเชเซเชธเซเชธเชจเซ เชชเซเชฐเชคเชฟเชฌเชเชงเชฟเชค เชเชฐเชตเซ เชเชฐเซเชฐเซ เชเซ. เชญเซเชฎเชฟเชเชพ เชเซเชทเซเชเชเชฎเชพเชเชจเซ เชเชจเซเชเซเชฐเซเชจเซ เชธเชเชฆเชฐเซเชญ เชเชชเซ เชเซ เชญเซเชฎเชฟเชเชพ เชเซเชฌเชฒ เชธเชพเชฅเซ เช เชจเซเช-เชฅเซ-เชเชฃเชพ เชธเชเชฌเชเชง เชธเชพเชฅเซ เชธเชเชเชณเชพเชฏเซเชฒ เชตเชชเชฐเชพเชถเชเชฐเซเชคเชพเช. เชเซเชทเซเชเชเซเชจเชพ เช เชฎเชฒเซเชเชฐเชฃเชจเซ เชตเชฟเชเชคเซ, เชคเซเชเซเชเชคเชพเชจเซ เชเชพเชฐเชฃเซ, เช เชตเชเชฃเชตเชพเชฎเชพเช เชเชตเซ เชเซ. เชตเชฟเชทเชฏ เชตเชฟเชธเซเชคเชพเชฐ เชธเชพเชฅเซ เชธเชเชฌเชเชงเชฟเชค เชเซเชเซเชเชธ เช เชฎเชฒเซเชเชฐเชฃ เชตเชฟเชเชคเซ เชชเชฃ เช เชตเชเชฃเชตเชพเชฎเชพเช เชเชตเซ เชเซ.
ะ ะตะฐะปะธะทะฐัะธั
เชญเซเชฎเชฟเชเชพเช, เชฏเซเชเชจเชพเช, เชเซเชทเซเชเชเซ เชฌเชจเชพเชตเซ
เชกเซเชเชพเชฌเซเช เชเชฌเซเชเซเชเซเชเซ เชฌเชจเชพเชตเซ เชฐเชนเซเชฏเชพ เชเซ
CREATE ROLE store;
CREATE SCHEMA store AUTHORIZATION store;
CREATE TABLE store.docs
(
id integer , --id ะดะพะบัะผะตะฝัะฐ
man_id integer , --id ะผะตะฝะตะดะถะตัะฐ ะดะพะบัะผะตะฝัะฐ
stat_id integer , --id ััะฐัััะฐ ะดะพะบัะผะตะฝัะฐ
...
is_del BOOLEAN DEFAULT FALSE
);
ALTER TABLE store.docs ADD CONSTRAINT doc_pk PRIMARY KEY (id);
ALTER TABLE store.docs OWNER TO store ;
RLS เชจเซ เช เชฎเชฒเชฎเชพเช เชฎเซเชเชตเชพ เชฎเชพเชเซ เชเชพเชฐเซเชฏเซ เชฌเชจเชพเชตเชตเชพ
SELECT เชชเชเชเซเชคเชฟเช เชเชฐเชตเชพเชจเซ เชเซเชทเชฎเชคเชพ เชคเชชเชพเชธเซ เชฐเชนเซเชฏเซเช เชเซ
เชเซเช_เชชเชธเชเชฆ เชเชฐเซ
CREATE OR REPLACE FUNCTION 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 ะธะผะตะตั ะดะพัััะฟ ะบะพ ะฒัะตะผ ะดะพะบัะผะตะฝัะฐะผ
IF SESSION_USER = 'curr_dba'
THEN
RETURN TRUE ;
END IF ;
--------------------------------
--ะัะปะธ ะดะพะบัะผะตะฝั ะธะผะตะตั ะผะตัะบั 'ัะดะฐะปะตะฝ' - ะฝะต ะฟะพะบะฐะทัะฒะฐัั ะฒ ะฒัะฑะพัะบะต
SELECT
is_del
INTO
result
FROM
store.docs
WHERE
id = current_id ;
IF result = TRUE
THEN
RETURN FALSE ;
END IF ;
--------------------------------
--ะะพะปััะธัั id ัะตะบััะตะณะพ ะฟะพะปัะทะพะฒะฐัะตะปั
SELECT
service_function.get_curr_pid ()
INTO
curr_pid ;
--------------------------------
--ะะพะปััะธัั id ะผะตะฝะตะดะถะตัะฐ ะดะพะบัะผะตะฝัะฐ
SELECT
man_id
INTO
doc_man_id
FROM
store.docs
WHERE
id = current_id ;
--------------------------------
--ะัะปะธ ะผะตะฝะตะดะถะตั ะดะพะบัะผะตะฝัะฐ ะฝะต ัะตะบััะธะน ะฟะพะปัะทะพะฒะฐัะตะปั ะธะปะธ ะผะตะฝะตะดะถะตั ะฝะต ะฝะฐะทะฝะฐัะตะฝ
--ะดะพะฑะฐะฒะธัั ะดะพะบัะผะตะฝั ะฒ ะฒัะฑะพัะบั
IF doc_man_id != curr_pid OR doc_man_id IS NULL
THEN
RETURN TRUE ;
ELSE
--ะะพะปััะธัั ัะตะบััะธะน ััะฐััั ะดะพะบัะผะตะฝัะฐ
SELECT
stat_id
INTO
curr_statid
FROM
store.docs
WHERE
id = current_id ;
--ะัะปะธ ััะฐััั ะฟะพะทะฒะพะปัะตั ะฟัะพัะผะพััะตัั ะดะพะบัะผะตะฝั - ะดะพะฑะฐะฒะธัั ะดะพะบัะผะตะฝั ะฒ ะฒัะฑะพัะบั
IF curr_statid = 4 OR curr_statid = 9
THEN
RETURN TRUE ;
ELSE
--ะะฝะฐัะต - ะธัะบะปััะธัั ะดะพะบัะผะตะฝั ะธะท ะฒัะฑะพัะบะธ
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;
เชชเชเชเซเชคเชฟเช เชฆเชพเชเชฒ เชเชฐเชตเชพเชจเซ เชเซเชทเชฎเชคเชพ เชคเชชเชพเชธเซ เชฐเชนเซเชฏเซเช เชเซ
check_insert
CREATE OR REPLACE FUNCTION store.check_insert ( current_id store.docs.id%TYPE ) RETURNS boolean AS $$
DECLARE
curr_role_id integer ;
BEGIN
--DBA ะผะพะถะตั ะดะพะฑะฐะฒะปััั ัััะพะบั ะฒ ะปัะฑะพะผ ัะปััะฐะต
IF SESSION_USER = 'curr_dba'
THEN
RETURN TRUE ;
END IF ;
--------------------------------
--ะะพะปััะธัั id ัะพะปะธ ัะตะบััะตะณะพ ะฟะพะปัะทะพะฒะฐัะตะปั
SELECT
service_functions.current_rid()
INTO
curr_role_id ;
--------------------------------
--ะัะปะธ ัะพะปั ะดะพะฟััะบะฐะตั ะฒะพะทะผะพะถะฝะพััั ัะพะทะดะฐะฝะธั ะฝะพะฒะพะณะพ ะดะพะบัะผะตะฝัะฐ
--ัะฐะทัะตัะธัั
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;
เชชเชเชเซเชคเชฟ เชเชพเชขเซ เชจเชพเชเชตเชพเชจเซ เชเซเชทเชฎเชคเชพ เชคเชชเชพเชธเซ เชฐเชนเซเชฏเซเช เชเซ
เชเซเช_เชกเชฟเชฒเซเช เชเชฐเซ
CREATE OR REPLACE FUNCTION store.check_delete ( current_id store.docs.id%TYPE )
RETURNS boolean AS $$
BEGIN
--ะขะพะปัะบะพ DBA ะผะพะถะตั ัะดะฐะปััั ัััะพะบั
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;
เชชเชเชเซเชคเชฟ เช เชชเชกเซเช เชเชฐเชตเชพเชจเซ เชเซเชทเชฎเชคเชพ เชคเชชเชพเชธเซ เชฐเชนเซเชฏเซเช เชเซ.
เช เชชเชกเซเช_เชเชชเชฏเซเช
CREATE OR REPLACE FUNCTION store.update_using ( current_id store.docs.id%TYPE , is_del boolean )
RETURNS boolean AS $$
BEGIN
--ะะพะบัะผะตะฝัั ะธะผะตััะธะต ััะฐััั 'ัะดะฐะปะตะฝ' - ะฝะต ัะตะดะฐะบัะธัััััั
IF is_del
THEN
RETURN FALSE ;
ELSE
RETURN TRUE ;
END IF ;
END
$$ LANGUAGE plpgsql SECURITY DEFINER;
ALTER FUNCTION store.update_using( store.docs.id%TYPE , boolean ) OWNER TO store ;
REVOKE EXECUTE ON FUNCTION store.update_using( store.docs.id%TYPE , boolean ) FROM public;
GRANT EXECUTE ON FUNCTION store.update_using( store.docs.id%TYPE ) TO service_functions;
เช เชชเชกเซเช_เชเซเช
CREATE OR REPLACE FUNCTION store.update_with_check ( current_id store.docs.id%TYPE , is_del boolean )
RETURNS boolean AS $$
DECLARE
current_rid integer ;
current_statid integer ;
BEGIN
--DBA ะผะพะถะตั ะฟัะพัะผะฐััะธะฒะฐัั ัััะพะบั
IF SESSION_USER = 'curr_dba'
THEN
RETURN TRUE ;
END IF ;
--------------------------------
--ะะพะปััะธัั id ัะพะปะธ ัะตะบััะตะณะพ ะฟะพะปัะทะพะฒะฐัะตะปั
SELECT
service_functions.current_rid()
INTO
curr_role_id ;
--------------------------------
--ะฃะดะฐะปะตะฝะธะต ะดะพะบัะผะตะฝัะฐ - ะธะทะผะตะฝะตะฝะธะต ะฟัะธะทะฝะฐะบะฐ
IF is_deleted
THEN
--ะัะปะธ ัะพะปั ะฟะพะปัะทะพะฒะฐัะตะปั ***
IF current_role_id = 3
THEN
SELECT
stat_id
INTO
curr_statid
FROM
store.docs
WHERE
id = current_id ;
--ะะพะบัะผะตะฝั ะฒ ััะฐัััะต *** ะฝะตะปัะทั ัะดะฐะปะธัั
IF current_status_id = 11
THEN
RETURN FALSE ;
ELSE
--ะะพะถะฝะพ ัะดะฐะปะธัั ะดะพะบัะผะตะฝั ะฒ ะดััะณะธั
ััะฐัััะฐั
RETURN TRUE ;
END IF ;
--ะะฝะฐัะต , ะตัะปะธ ัะพะปั ะฟะพะปัะทะพะฒะฐัะตะปั ***
ELSIF current_role_id = 5
THEN
--ะัะต ััะฐัััั ะดะพะบัะผะตะฝัะฐ
RETURN TRUE ;
ELSE
--ะััะณะธะต ะฟะพะปัะทะพะฒะฐัะตะปะธ ะฝะต ะผะพะณัั ัะดะฐะปััั ะดะพะบัะผะตะฝัั
RETURN FALSE ;
END IF ;
ELSE
--ะะฑะฝะพะฒะปะตะฝะธะต ะดะพะบัะผะตะฝัะฐ ัะฐะทัะตัะตะฝะพ
RETURN TRUE ;
END IF ;
RETURN FALSE ;
END
$$ LANGUAGE plpgsql SECURITY DEFINER;
ALTER FUNCTION store.update_with_check( storg.docs.id%TYPE , boolean ) OWNER TO store ;
REVOKE EXECUTE ON FUNCTION store.update_with_check( storg.docs.id%TYPE , boolean ) FROM public;
GRANT EXECUTE ON FUNCTION store.update_with_check( store.docs.id%TYPE ) TO service_functions;
เชเซเชฌเชฒ เชฎเชพเชเซ เชฐเซ เชฒเซเชตเชฒ เชธเซเชเซเชฏเซเชเชฐเซ เชชเซเชฒเชฟเชธเซเชจเซ เชธเชเซเชทเชฎ เชเชฐเซ.
เชชเชเชเซเชคเชฟ เชธเซเชคเชฐเชจเซ เชธเซเชฐเชเซเชทเชพเชจเซ เชธเชเซเชทเชฎ เชเชฐเซ
ALTER TABLE store.docs ENABLE ROW LEVEL SECURITY ;
CREATE POLICY doc_select ON store.docs FOR SELECT TO service_functions USING ( (SELECT store.check_select(id)) );
CREATE POLICY doc_insert ON store.docs FOR INSERT TO service_functions WITH CHECK ( (SELECT store.check_insert(id)) );
CREATE POLICY docs_delete ON store.docs FOR DELETE TO service_functions USING ( (SELECT store.check_delete(id)) );
CREATE POLICY doc_update_using ON store.docs FOR UPDATE TO service_functions USING ( (SELECT store.update_using(id , is_del )) );
CREATE POLICY doc_update_check ON store.docs FOR UPDATE TO service_functions WITH CHECK ( (SELECT store.update_with_check(id , is_del )) );
เชชเชฐเชฟเชฃเชพเชฎ
เชคเซ เชเชพเชฎ เชเชฐเซ เชเซ.
เชธเซเชเชฟเชค เชตเซเชฏเซเชนเชฐเชเชจเชพเชฅเซ เชฐเซเชฒ เชฎเซเชกเซเชฒเชจเชพ เช เชฎเชฒเซเชเชฐเชฃเชจเซ เชตเซเชฏเชตเชธเชพเชฏเชฟเช เชเชพเชฐเซเชฏเซเชจเชพ เชธเซเชคเชฐเชฅเซ เชกเซเชเชพ เชธเซเชเซเชฐเซเช เชธเซเชคเชฐ เชชเชฐ เชธเซเชฅเชพเชจเชพเชเชคเชฐเชฟเชค เชเชฐเชตเชพเชจเซเช เชถเชเซเชฏ เชฌเชจเซเชฏเซเช.
เชเซ เชตเซเชฏเชตเชธเชพเชฏเชฟเช เชเชตเชถเซเชฏเชเชคเชพเชเชจเซ เชคเซเชจเซ เชเชฐเซเชฐ เชนเซเชฏ เชคเซ เชตเชงเซ เช
เชคเซเชฏเชพเชงเซเชจเชฟเช เชกเซเชเชพ เชเซเชชเชพเชตเชตเชพเชจเชพ เชฎเซเชกเชฒเซเชธเชจเซ เช
เชฎเชฒเชฎเชพเช เชฎเซเชเชตเชพ เชฎเชพเชเซ เชซเชเชเซเชถเชจเชจเซ เชเชชเชฏเซเช เชเซเชฎเซเชชเชฒเซเช เชคเชฐเซเชเซ เชฅเช เชถเชเซ เชเซ.
เชธเซเชฐเซเชธ: www.habr.com