Compare commits

...

10 Commits

Author SHA1 Message Date
150c19b1b0 Merge pull request 'development' (#41) from development into main
Some checks failed
Release / release (push) Failing after 2m15s
Reviewed-on: #41
2023-10-08 16:46:19 +00:00
f04c51ee4e Merge pull request 'fix: closes #39 upcase issue in MPE_SECURITY' (#40) from issue39 into development
Some checks reported warnings
Build / Build-and-ng-test (pull_request) Has been cancelled
Reviewed-on: #40
2023-10-08 16:45:23 +00:00
c4338bf957 chore: updating tests, post edit hook, and access check macro. #39
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 1m22s
2023-10-08 17:42:26 +01:00
5b06f4ede8 chore: improving docs for mpe_accesscheck and adding a test for mpe_accesscheck
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 1m27s
2023-10-07 22:46:32 +01:00
e7ab2cc956 chore: adding mpe_security_postedit hook link in MPE_TABLES on deploy. #39
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 1m28s
2023-10-07 18:28:36 +01:00
5ebf8a66f7 chore: error message source file fix
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 1m19s
2023-10-07 00:16:05 +01:00
3d4e886b9b chore: adding missing dependency
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 1m22s
2023-10-07 00:13:48 +01:00
a00d31caf3 fix: closes #39 upcase issue in MPE_SECURITY
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 1m23s
adding frontend validation rule, backend upcase enforcement rule, and modification to service code to ensure values are upcased before comparison
2023-10-07 00:11:38 +01:00
40fe707287 Merge pull request 'maincopy' (#38) from maincopy into development
Reviewed-on: #38
2023-09-26 07:40:05 +00:00
8296be01ba chore: cleanup of items in changelog for v6.2.1
All checks were successful
Build / Build-and-ng-test (pull_request) Successful in 1m19s
2023-09-26 08:38:40 +01:00
5 changed files with 179 additions and 54 deletions

View File

@ -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)

View File

@ -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;

View 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
)

View File

@ -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"

View 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)
)