create table PAYMENTS ( ID number, CNAME varchar2(64), /* */ REGION char(2), /* MO/NW */ AMOUNT number, /* */ ols_payments number(10), /* */ CONSTRAINT "PAYMENTS_PK" PRIMARY KEY ("ID") ) PARTITION BY RANGE (ols_payments) ( PARTITION SP VALUES LESS THAN (80000), PARTITION MP VALUES LESS THAN (90000), PARTITION BP VALUES LESS THAN (MAXVALUE) /* */ ); grant select on payments to public;
EXEC SA_SYSDBA.CREATE_POLICY ( policy_name => 'payments_pol', /* policy */ column_name => 'ols_payments', /* */ default_options => 'read_control'); /* */
BEGIN SA_COMPONENTS.CREATE_LEVEL ( policy_name => 'payments_pol', level_num => 90, /* */ short_name => 'B', /* */ long_name => 'BIG_PAYMENT'); /* */ SA_COMPONENTS.CREATE_LEVEL ( policy_name => 'payments_pol', level_num => 80, short_name => 'M', long_name => 'MEDIUM_PAYMENT'); SA_COMPONENTS.CREATE_LEVEL ( policy_name => 'payments_pol', level_num => 70, short_name => 'S', long_name => 'SMALL_PAYMENT'); END; /
BEGIN /* */ SA_COMPONENTS.CREATE_GROUP ( policy_name => 'payments_pol', group_num => 10, /* */ short_name => 'RG', /* */ long_name => 'REGIONS'); /* */ SA_COMPONENTS.CREATE_GROUP ( policy_name => 'payments_pol', group_num => 20, short_name => 'MO', long_name => 'MOSCOW_REGION', parent_name => 'RG'); /* */ SA_COMPONENTS.CREATE_GROUP ( policy_name => 'payments_pol', group_num => 30, short_name => 'NW', long_name => 'NW_REGION', parent_name => 'RG'); END; /
BEGIN -- RG labels SA_LABEL_ADMIN.CREATE_LABEL ( policy_name => 'payments_pol', label_tag => 90010, /* */ label_value => 'B::RG', /* */ data_label => TRUE); SA_LABEL_ADMIN.CREATE_LABEL ( policy_name => 'payments_pol', label_tag => 80010, label_value => 'M::RG', data_label => TRUE); SA_LABEL_ADMIN.CREATE_LABEL ( policy_name => 'payments_pol', label_tag => 70010, label_value => 'S::RG', data_label => TRUE); -- MO LABELS SA_LABEL_ADMIN.CREATE_LABEL ( policy_name => 'payments_pol', label_tag => 90020, label_value => 'B::MO', data_label => TRUE); SA_LABEL_ADMIN.CREATE_LABEL ( policy_name => 'payments_pol', label_tag => 80020, label_value => 'M::MO', data_label => TRUE); SA_LABEL_ADMIN.CREATE_LABEL ( policy_name => 'payments_pol', label_tag => 70020, label_value => 'S::MO', data_label => TRUE); -- NW LABELS SA_LABEL_ADMIN.CREATE_LABEL ( policy_name => 'payments_pol', label_tag => 90030, label_value => 'B::NW', data_label => TRUE); SA_LABEL_ADMIN.CREATE_LABEL ( policy_name => 'payments_pol', label_tag => 80030, label_value => 'M::NW', data_label => TRUE); SA_LABEL_ADMIN.CREATE_LABEL ( policy_name => 'payments_pol', label_tag => 70030, label_value => 'S::NW', data_label => TRUE); END; /
create or replace function payments_label(region varchar2, amount number) return LBACSYS.LBAC_LABEL as lvl varchar2(32); reg varchar2(32); rvalue number(10); begin case region when 'MO' then reg := 'MO'; when 'NW' then reg := 'NW'; else raise_application_error(-20000, 'invalid region.'); end case; case when amount >= 10000 then lvl := 'B'; when amount >= 5000 then lvl := 'M'; else lvl := 'S'; end case; return LBACSYS.to_lbac_label('PAYMENTS_POL', lvl || '::' || reg); end;
EXEC SA_POLICY_ADMIN.APPLY_TABLE_POLICY ( policy_name => 'payments_pol', schema_name => 'test', table_name => 'payments', table_options => 'READ_CONTROL,HIDE', /* , */ label_function => 'test.payments_label(:new.region,:new.amount)', /* , insert update. */ predicate => NULL);
$ sqlplus test/test insert into payments values(1, ' , ', 'MO', 100000); insert into payments values(2, ' , ', 'MO', 7000); insert into payments values(3, ' , ', 'MO', 100000); insert into payments values(4, ' , ', 'NW', 150000); insert into payments values(5, ' , ', 'NW', 3000);
-- big boss BEGIN SA_USER_ADMIN.SET_LEVELS ( policy_name => 'payments_pol', user_name => 'big_boss', max_level => 'B'); SA_USER_ADMIN.SET_GROUPS ( policy_name => 'payments_pol', user_name => 'big_boss', read_groups => 'RG'); -- medium boss SA_USER_ADMIN.SET_LEVELS ( policy_name => 'payments_pol', user_name => 'med_boss', max_level => 'M'); SA_USER_ADMIN.SET_GROUPS ( policy_name => 'payments_pol', user_name => 'med_boss', read_groups => 'RG'); -- big boss of MO region SA_USER_ADMIN.SET_LEVELS ( policy_name => 'payments_pol', user_name => 'mo_big_boss', max_level => 'B'); SA_USER_ADMIN.SET_GROUPS ( policy_name => 'payments_pol', user_name => 'mo_big_boss', read_groups => 'MO'); END; /
$ sqlplus big_boss/qw SQL> select label_to_char (ols_payments) label, id, cname, amount from test.payments; LABEL ID CNAME AMOUNT ---------- ---------- ------------------------------ ---------- S::MO 3 , 2000 S::NW 5 , 3000 M::MO 2 , 7000 B::MO 1 , 100000 B::NW 4 , 150000
sqlplus med_boss/qw SQL> select label_to_char (ols_payments) label, id, cname, amount from test.payments; LABEL ID CNAME AMOUNT ---------- ---------- ------------------------------ ---------- S::MO 3 , 2000 S::NW 5 , 3000 M::MO 2 , 7000
$ sqlplus mo_big_boss/qw SQL> select label_to_char (ols_payments) label, id, cname, amount from test.payments; LABEL ID CNAME AMOUNT ---------- ---------- ------------------------------ ---------- S::MO 3 , 2000 M::MO 2 , 7000 B::MO 1 , 100000
Source: https://habr.com/ru/post/185946/
All Articles