Compare commits
10 Commits
dbeb003292
...
150c19b1b0
Author | SHA1 | Date | |
---|---|---|---|
150c19b1b0 | |||
f04c51ee4e | |||
c4338bf957 | |||
5b06f4ede8 | |||
e7ab2cc956 | |||
5ebf8a66f7 | |||
3d4e886b9b | |||
a00d31caf3 | |||
40fe707287 | |||
8296be01ba |
@ -10,13 +10,6 @@
|
|||||||
* updating editors/stagedata to address issues in particular viya configurations as described in issue [#33](https://git.datacontroller.io/dc/dc/issues/33) ([94ab949](https://git.datacontroller.io/dc/dc/commit/94ab949df8c75072525751a2156b7a32c2e641dc))
|
* updating editors/stagedata to address issues in particular viya configurations as described in issue [#33](https://git.datacontroller.io/dc/dc/issues/33) ([94ab949](https://git.datacontroller.io/dc/dc/commit/94ab949df8c75072525751a2156b7a32c2e641dc))
|
||||||
* updating logic for REPLACE loadtype ([1f2ce55](https://git.datacontroller.io/dc/dc/commit/1f2ce55f249f4af56f0cacdec47e69246cd47431))
|
* updating logic for REPLACE loadtype ([1f2ce55](https://git.datacontroller.io/dc/dc/commit/1f2ce55f249f4af56f0cacdec47e69246cd47431))
|
||||||
|
|
||||||
## [6.2.1](https://git.datacontroller.io/dc/dc/compare/v6.2.0...v6.2.1) (2023-08-25)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* approve, history and submit pages grouped in review module ([e056ece](https://git.datacontroller.io/dc/dc/commit/e056ece2234ef6aab050f6a5b1f8de633b163d91))
|
|
||||||
* updating logic for REPLACE loadtype ([1f2ce55](https://git.datacontroller.io/dc/dc/commit/1f2ce55f249f4af56f0cacdec47e69246cd47431))
|
|
||||||
|
|
||||||
# [6.2.0](https://git.datacontroller.io/dc/dc/compare/v6.1.0...v6.2.0) (2023-08-24)
|
# [6.2.0](https://git.datacontroller.io/dc/dc/compare/v6.1.0...v6.2.0) (2023-08-24)
|
||||||
|
|
||||||
|
@ -1,21 +1,33 @@
|
|||||||
/**
|
/**
|
||||||
@file
|
@file
|
||||||
@brief Checks the level of access a user has to the MP Editor
|
@brief Checks group access level for a table or library
|
||||||
@details In order for a user to be able to EDIT or APPROVE a table they must
|
@details In order for a user to be able to EDIT or APPROVE a table they must
|
||||||
be in a metadata group that has been granted access to that table in the
|
be in a group that has been granted access to that table in the
|
||||||
&mpelib..mpe_security table. Alternatively, they may be in the
|
MPE_SECURITY table. Alternatively, they may be in the &mpeadmins
|
||||||
&mpeadmins group (has overall access).
|
group (which has full access to everything).
|
||||||
|
|
||||||
|
@param [in] base_table The base table to check for
|
||||||
|
@param [in] user= The user for which the access level should be returned. If
|
||||||
|
not provided, the mf_user() result is used instead.
|
||||||
|
@param [in] access_level= (APPROVE) access_level (per MPE_SECURITY) reqd.
|
||||||
|
Valid values:
|
||||||
|
@li EDIT
|
||||||
|
@li APPROVE
|
||||||
|
@li VIEW
|
||||||
|
@param [in] cntl_lib_var= (MPELIB) The name of a global macro variable that
|
||||||
|
contains the libref in which the MPE_SECURITY table is stored
|
||||||
|
@param [out] outds= (MED_ACCESSCHECK) Output WORK table containing all the
|
||||||
|
groups for which the user is granted the particular ACCESS_LEVEL.
|
||||||
|
|
||||||
<h4> SAS Macros </h4>
|
<h4> SAS Macros </h4>
|
||||||
@li mp_abort.sas
|
@li mp_abort.sas
|
||||||
|
@li mf_getuniquename.sas
|
||||||
|
@li mf_getuser.sas
|
||||||
@li mf_verifymacvars.sas
|
@li mf_verifymacvars.sas
|
||||||
@li mpe_getgroups.sas
|
@li mpe_getgroups.sas
|
||||||
@li mp_dropmembers.sas
|
|
||||||
|
|
||||||
@param [in] access_level= access_level (per &mpelib..mp_editor_security) reqd
|
<h4> Related Macros </h4>
|
||||||
|
@li mpe_accesscheck.test.sas
|
||||||
@returns outds A table containing all the groups that user is a member of,
|
|
||||||
which are granted the access_level requested.
|
|
||||||
|
|
||||||
@version 9.2
|
@version 9.2
|
||||||
@author 4GL Apps Ltd
|
@author 4GL Apps Ltd
|
||||||
@ -25,65 +37,64 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
%macro mpe_accesscheck(
|
%macro mpe_accesscheck(
|
||||||
base_table /* base table to check for */
|
base_table
|
||||||
,outds=med_accesscheck /* WORK table to contain access details */
|
,outds=med_accesscheck /* WORK table to contain access details */
|
||||||
,user= /* metadata user to check for */
|
,user= /* metadata user to check for */
|
||||||
,access_level=APPROVE
|
,access_level=APPROVE
|
||||||
|
,cntl_lib_var=MPELIB
|
||||||
);
|
);
|
||||||
|
|
||||||
%if &user= %then %let user=%mf_getuser();
|
%if &user= %then %let user=%mf_getuser();
|
||||||
|
|
||||||
%if %index(&outds,.) %then %do;
|
%mp_abort(
|
||||||
%local lib ds;
|
iftrue=(%index(&outds,.)>0 and %upcase(%scan(&outds,1,.)) ne WORK)
|
||||||
%let lib=%scan(&outds,1,.);
|
,mac=mpe_accesscheck
|
||||||
%let ds=%scan(&outds,2,.);
|
,msg=%str(outds should be a WORK table)
|
||||||
%if %upcase(&lib) ne WORK %then %do;
|
)
|
||||||
%mp_abort(msg=outds should be a WORK table
|
|
||||||
,mac=mpe_accesscheck);
|
|
||||||
%end;
|
|
||||||
%end;
|
|
||||||
%else %let ds=&outds;
|
|
||||||
|
|
||||||
%mp_abort(
|
%mp_abort(
|
||||||
iftrue=(%mf_verifymacvars(base_table user access_level)=0)
|
iftrue=(%mf_verifymacvars(base_table user access_level)=0)
|
||||||
,mac=bitemporal_dataloader
|
,mac=mpe_accesscheck
|
||||||
,msg=%str(Missing base_table/user access_level)
|
,msg=%str(Missing base_table/user access_level variables)
|
||||||
)
|
)
|
||||||
|
|
||||||
/* ensure any existing table is dropped */
|
/* make unique temp table vars */
|
||||||
%mp_dropmembers(&ds)
|
%local tempds1 tempds2;
|
||||||
|
%let tempds1=%mf_getuniquename(prefix=usergroups);
|
||||||
|
%let tempds2=%mf_getuniquename(prefix=tablegroups);
|
||||||
|
|
||||||
/* create a new table for temp use */
|
/* get list of user groups */
|
||||||
data; run;
|
%mpe_getgroups(user=&user,outds=&tempds1)
|
||||||
%local tempds; %let tempds=&syslast;
|
|
||||||
|
|
||||||
/* overwrite with the list of groups */
|
|
||||||
%mpe_getgroups(user=&user,outds=&tempds);
|
|
||||||
|
|
||||||
|
/* get list of groups with access for that table */
|
||||||
|
proc sql;
|
||||||
|
create table &tempds2 as
|
||||||
|
select distinct sas_group
|
||||||
|
from &&&cntl_lib_var...mpe_security
|
||||||
|
where &dc_dttmtfmt. lt tx_to
|
||||||
|
and access_level="&access_level"
|
||||||
|
and (
|
||||||
|
(libref="%scan(&base_table,1,.)" and upcase(dsn)="%scan(&base_table,2,.)")
|
||||||
|
or (libref="%scan(&base_table,1,.)" and dsn="*ALL*")
|
||||||
|
or (libref="*ALL*")
|
||||||
|
);
|
||||||
%if &_debug ge 131 %then %do;
|
%if &_debug ge 131 %then %do;
|
||||||
data _null_;
|
data _null_;
|
||||||
set &tempds;
|
set &tempds1;
|
||||||
|
putlog (_all_)(=);
|
||||||
|
run;
|
||||||
|
data _null_;
|
||||||
|
set &tempds2;
|
||||||
putlog (_all_)(=);
|
putlog (_all_)(=);
|
||||||
run;
|
run;
|
||||||
%end;
|
%end;
|
||||||
|
|
||||||
proc sql;
|
proc sql;
|
||||||
create table &outds as
|
create table &outds as
|
||||||
select * from &tempds
|
select * from &tempds1
|
||||||
where groupname="&mpeadmins"
|
where groupname="&mpeadmins"
|
||||||
or groupname in
|
or groupname in (select * from &tempds2);
|
||||||
(select sas_group from &mpelib..mpe_security
|
|
||||||
where &dc_dttmtfmt. lt tx_to
|
|
||||||
and access_level="&access_level"
|
|
||||||
& (
|
|
||||||
(libref="%scan(&base_table,1,.)" and dsn="%scan(&base_table,2,.)")
|
|
||||||
or (libref="%scan(&base_table,1,.)" and dsn="*ALL*")
|
|
||||||
or (libref="*ALL*")
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
%put base_table=&base_table;
|
%put &sysmacroname: base_table=&base_table;
|
||||||
%put libref=%scan(&base_table,1,.);
|
%put &sysmacroname: access_level=&access_level;
|
||||||
%put dsn=%scan(&base_table,2,.);
|
|
||||||
%put access_level=&access_level;
|
|
||||||
%mend mpe_accesscheck;
|
%mend mpe_accesscheck;
|
||||||
|
68
sas/sasjs/macros/mpe_accesscheck.test.sas
Normal file
68
sas/sasjs/macros/mpe_accesscheck.test.sas
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Testing mpe_accesscheck macro
|
||||||
|
@details Checking functionality of mpe_accesscheck.sas macro
|
||||||
|
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getuniquename.sas
|
||||||
|
@li mf_getuser.sas
|
||||||
|
@li mp_assertdsobs.sas
|
||||||
|
@li mpe_getgroups.sas
|
||||||
|
@li mpe_accesscheck.sas
|
||||||
|
|
||||||
|
|
||||||
|
@author 4GL Apps Ltd
|
||||||
|
@copyright 4GL Apps Ltd. This code may only be used within Data Controller
|
||||||
|
and may not be re-distributed or re-sold without the express permission of
|
||||||
|
4GL Apps Ltd.
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
/* get the groups this user is actually a member of */
|
||||||
|
%mpe_getgroups(user=%mf_getuser(),outds=work.groups)
|
||||||
|
|
||||||
|
data _null_;
|
||||||
|
set work.groups;
|
||||||
|
call symputx('groupname',groupname);
|
||||||
|
run;
|
||||||
|
|
||||||
|
/* create demo MPE_SECURITY table */
|
||||||
|
data work.mpe_security;
|
||||||
|
if 0 then set &dc_libref..mpe_security;
|
||||||
|
do access_level='EDIT','APPROVE','VIEW','SIGNOFF','AUDIT';
|
||||||
|
LIBREF='SOMELIB';
|
||||||
|
DSN='SOMEDS';
|
||||||
|
sas_group="&groupname";
|
||||||
|
tx_from=0;
|
||||||
|
tx_to='31dec4999:23:59:59'dt;
|
||||||
|
output;
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%let WRK=WORK;
|
||||||
|
|
||||||
|
%mpe_accesscheck(
|
||||||
|
SOMELIB.SOMEDS
|
||||||
|
,outds=work.test1
|
||||||
|
,access_level=APPROVE
|
||||||
|
,cntl_lib_var=WRK
|
||||||
|
)
|
||||||
|
%mp_assertdsobs(work.test1,
|
||||||
|
desc=Test 1 - One record returned,
|
||||||
|
test=EQUALS 1,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
||||||
|
%mpe_accesscheck(
|
||||||
|
SOMELIB.INVALID
|
||||||
|
,outds=work.test2
|
||||||
|
,access_level=APPROVE
|
||||||
|
,cntl_lib_var=WRK
|
||||||
|
)
|
||||||
|
%mp_assertdsobs(work.test2,
|
||||||
|
desc=Test 12 - 0 records returned,
|
||||||
|
test=EQUALS 0,
|
||||||
|
outds=work.test_results
|
||||||
|
)
|
||||||
|
|
@ -1014,7 +1014,8 @@ insert into &lib..mpe_selectbox set
|
|||||||
,buskey='LIBREF DSN ACCESS_LEVEL SAS_GROUP'
|
,buskey='LIBREF DSN ACCESS_LEVEL SAS_GROUP'
|
||||||
,var_txfrom='TX_FROM'
|
,var_txfrom='TX_FROM'
|
||||||
,var_txto='TX_TO'
|
,var_txto='TX_TO'
|
||||||
,notes='Shows which metadata groups can edit which tables'
|
,notes='Determines which groups can view/edit/approve which tables'
|
||||||
|
,post_edit_hook='services/hooks/mpe_security_postedit'
|
||||||
;
|
;
|
||||||
insert into &lib..mpe_tables
|
insert into &lib..mpe_tables
|
||||||
set tx_from=0
|
set tx_from=0
|
||||||
@ -1351,6 +1352,15 @@ insert into &lib..MPE_VALIDATIONS set
|
|||||||
,rule_value='UPCASE'
|
,rule_value='UPCASE'
|
||||||
,rule_active=1
|
,rule_active=1
|
||||||
,tx_to='31DEC5999:23:59:59'dt;
|
,tx_to='31DEC5999:23:59:59'dt;
|
||||||
|
insert into &lib..MPE_VALIDATIONS set
|
||||||
|
tx_from=0
|
||||||
|
,base_lib="&lib"
|
||||||
|
,base_ds="MPE_SECURITY"
|
||||||
|
,base_col="LIBREF"
|
||||||
|
,rule_type='CASE'
|
||||||
|
,rule_value="UPCASE"
|
||||||
|
,rule_active=1
|
||||||
|
,tx_to='31DEC5999:23:59:59'dt;
|
||||||
insert into &lib..MPE_VALIDATIONS set
|
insert into &lib..MPE_VALIDATIONS set
|
||||||
tx_from=0
|
tx_from=0
|
||||||
,base_lib="&lib"
|
,base_lib="&lib"
|
||||||
@ -1369,6 +1379,15 @@ insert into &lib..MPE_VALIDATIONS set
|
|||||||
,rule_value="&lib..MPE_TABLES.LIBREF"
|
,rule_value="&lib..MPE_TABLES.LIBREF"
|
||||||
,rule_active=1
|
,rule_active=1
|
||||||
,tx_to='31DEC5999:23:59:59'dt;
|
,tx_to='31DEC5999:23:59:59'dt;
|
||||||
|
insert into &lib..MPE_VALIDATIONS set
|
||||||
|
tx_from=0
|
||||||
|
,base_lib="&lib"
|
||||||
|
,base_ds="MPE_SECURITY"
|
||||||
|
,base_col="DSN"
|
||||||
|
,rule_type='CASE'
|
||||||
|
,rule_value="UPCASE"
|
||||||
|
,rule_active=1
|
||||||
|
,tx_to='31DEC5999:23:59:59'dt;
|
||||||
insert into &lib..MPE_VALIDATIONS set
|
insert into &lib..MPE_VALIDATIONS set
|
||||||
tx_from=0
|
tx_from=0
|
||||||
,base_lib="&lib"
|
,base_lib="&lib"
|
||||||
|
34
sas/sasjs/services/hooks/mpe_security_postedit.sas
Normal file
34
sas/sasjs/services/hooks/mpe_security_postedit.sas
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
@file
|
||||||
|
@brief Post Edit Hook script for the MPE_SECURITY table
|
||||||
|
@details Post edit hooks provide additional backend validation against
|
||||||
|
user-sourced data. The incoming dataset is always `work.staging_ds` and this
|
||||||
|
file is included from the mpe_loader.sas macro.
|
||||||
|
|
||||||
|
Available (at runtime) macro variables:
|
||||||
|
@li DC_LIBREF - The DC control library for your site
|
||||||
|
@li LIBREF - The library of the dataset being edited (is assigned)
|
||||||
|
@li DS - The dataset being edited
|
||||||
|
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
/* ensure upcase and check access level values*/
|
||||||
|
%let errval=0;
|
||||||
|
%let errmsg=;
|
||||||
|
data work.staging_ds;
|
||||||
|
set work.staging_ds;
|
||||||
|
LIBREF=upcase(LIBREF);
|
||||||
|
DSN=upcase(DSN);
|
||||||
|
ACCESS_LEVEL=upcase(ACCESS_LEVEL);
|
||||||
|
if ACCESS_LEVEL not in ('EDIT','APPROVE','VIEW','SIGNOFF','AUDIT') then do;
|
||||||
|
putlog "ERR" +(-1) "OR: invalid ACCESS_LEVEL - " access_level;
|
||||||
|
call symputx('errval',1);
|
||||||
|
call symputx('errmsg',"Invalid ACCESS_LEVEL: "!!access_level);
|
||||||
|
end;
|
||||||
|
run;
|
||||||
|
|
||||||
|
%mp_abort(iftrue=(&errval=1)
|
||||||
|
,mac=mpe_security_postedit.sas
|
||||||
|
,msg=%str(&errmsg)
|
||||||
|
)
|
Loading…
x
Reference in New Issue
Block a user