From 0cb3c96c1527c02f0f0db9d97aacf12a8d4af212 Mon Sep 17 00:00:00 2001 From: Allan Bowe Date: Tue, 14 Jun 2022 13:40:05 +0000 Subject: [PATCH 1/4] feat: enabling group macros on sasjs/server This PR updates ms_getgroups with a user filter, and ms_getusers with a group filter. ms_adduser2group was also created to faciliate the necessary test(s). --- all.sas | 256 ++++++++++++++++++--- meta/mm_adduser2group.sas | 11 +- sasjs/sasjsconfig.json | 4 +- server/ms_adduser2group.sas | 122 ++++++++++ server/ms_getgroups.sas | 53 ++++- server/ms_getusers.sas | 70 ++++-- tests/serveronly/ms_adduser2group.test.sas | 52 +++++ tests/serveronly/ms_createuser.test.sas | 4 +- tests/serveronly/ms_getusers.test.sas | 35 +++ tests/serveronly/ms_runstp.test.sas | 2 +- tests/serveronly/ms_testservice.test.sas | 8 +- tests/serveronly/ms_webout.test.sas | 2 +- 12 files changed, 553 insertions(+), 66 deletions(-) create mode 100644 server/ms_adduser2group.sas create mode 100644 tests/serveronly/ms_adduser2group.test.sas diff --git a/all.sas b/all.sas index 1c046c7..d91b20e 100644 --- a/all.sas +++ b/all.sas @@ -13015,7 +13015,10 @@ create table &libds( @file mm_adduser2group.sas @brief Adds a user to a group @details Adds a user to a metadata group. The macro first checks whether the - user is in that group, and if not, the user is added. + user is in that group, and if not, the user is added. + + Note that the macro does not check inherited group memberships - it looks at + direct members only. Usage: @@ -13025,10 +13028,10 @@ create table &libds( @param user= the user name (not displayname) @param group= the group to which to add the user - @param mdebug= set to 1 to show debug info in log + @param mdebug= (0) set to 1 to show debug info in log - @warning the macro does not check inherited group memberships - it looks at - direct members only +

Related Files

+ @li ms_adduser2group.sas @version 9.3 @author Allan Bowe @@ -19101,6 +19104,128 @@ run; %let rc=%sysfunc(filename(&fref)); %mend mfs_httpheader; +/** + @file + @brief Adds a user to a group on SASjs Server + @details Adds a user to a group based on userid and groupid. Both user and + group must already exist. + + Examples: + + %ms_adduser2group(uid=1,gid=1) + + + @param [in] uid= (0) The User ID to be added + @param [in] gid= (0) The Group ID to contain the new user + @param [in] mdebug= (0) Set to 1 to enable DEBUG messages + @param [out] outds= (work.ms_adduser2group) This output dataset will contain + the new list of group members, eg: +|DISPLAYNAME:$18.|USERNAME:$10.|ID:best.| +|---|---|---| +|`Super Admin `|`secretuser `|`1`| +|`Sabir Hassan`|`sabir`|`2`| +|`Mihajlo Medjedovic `|`mihajlo `|`3`| +|`Ivor Townsend `|`ivor `|`4`| +|`New User `|`newuser `|`5`| + + + +

SAS Macros

+ @li mf_getuniquefileref.sas + @li mf_getuniquelibref.sas + @li mp_abort.sas + +

Related Files

+ @li ms_creategroup.sas + @li ms_createuser.sas + +**/ + +%macro ms_adduser2group(uid=0 + ,gid=0 + ,outds=work.ms_adduser2group + ,mdebug=0 + ); + +%mp_abort( + iftrue=(&syscc ne 0) + ,mac=ms_adduser2group.sas + ,msg=%str(syscc=&syscc on macro entry) +) + +%local fref0 fref1 fref2 libref optval rc msg; +%let fref0=%mf_getuniquefileref(); +%let fref1=%mf_getuniquefileref(); +%let libref=%mf_getuniquelibref(); + +/* avoid sending bom marker to API */ +%let optval=%sysfunc(getoption(bomfile)); +options nobomfile; + +data _null_; + file &fref0 lrecl=1000; + infile "&_sasjs_tokenfile" lrecl=1000; + input; + if _n_=1 then put "accept: application/json"; + put _infile_; +run; + +%if &mdebug=1 %then %do; + %put _local_; + data _null_; + infile &fref0; + input; + put _infile_; + run; +%end; + +proc http method='POST' headerin=&fref0 out=&fref1 + url="&_sasjs_apiserverurl/SASjsApi/group/&gid/&uid"; +%if &mdebug=1 %then %do; + debug level=1; +%end; +run; + +%mp_abort( + iftrue=(&syscc ne 0) + ,mac=ms_adduser2group.sas + ,msg=%str(Issue submitting query to SASjsApi/group) +) + +libname &libref JSON fileref=&fref1; + +data &outds; + set &libref..users; + drop ordinal_root ordinal_users; +%if &mdebug=1 %then %do; + putlog _all_; +%end; +run; + + +%mp_abort( + iftrue=(&syscc ne 0) + ,mac=ms_creategroup.sas + ,msg=%str(Issue reading response JSON) +) + +/* reset options */ +options &optval; + +%if &mdebug=0 %then %do; + filename &fref0 clear; + filename &fref1 clear; + libname &libref clear; +%end; +%else %do; + data _null_; + infile &fref1; + input; + putlog _infile_; + run; +%end; + +%mend ms_adduser2group; /** @file @brief Creates a file on SASjs Drive @@ -20146,13 +20271,19 @@ filename &headref clear; @file @brief Fetches the list of groups from SASjs Server @details Fetches the list of groups from SASjs Server and writes them to an - output dataset. + output dataset. Provide a username to filter for the groups for a particular + user. Example: %ms_getgroups(outds=userlist) + With filter: + + %ms_getgroups(outds=userlist, user=James) + @param [in] mdebug= (0) Set to 1 to enable DEBUG messages + @param [in] user= (0) Provide the username on which to filter @param [out] outds= (work.ms_getgroups) This output dataset will contain the list of groups. Format: |NAME:$32.|DESCRIPTION:$64.|GROUPID:best.| @@ -20174,9 +20305,10 @@ filename &headref clear; **/ %macro ms_getgroups( - outds=work.ms_getgroups - ,mdebug=0 - ); + user=0, + outds=work.ms_getgroups, + mdebug=0 +); %mp_abort( iftrue=(&syscc ne 0) @@ -20190,7 +20322,10 @@ filename &headref clear; /* groups api does not exist in desktop mode */ data &outds; length NAME $32 DESCRIPTION $64. GROUPID 8; - call missing (of _all_); + name="&sysuserid"; + description="&sysuserid (group - desktop mode)"; + groupid=1; + output; stop; run; %return; @@ -20220,12 +20355,35 @@ run; run; %end; -proc http method='GET' headerin=&fref0 out=&fref1 - url="&_sasjs_apiserverurl/SASjsApi/group"; -%if &mdebug=1 %then %do; - debug level=1; +%if "&user"="0" %then %do; + proc http method='GET' headerin=&fref0 out=&fref1 + url="&_sasjs_apiserverurl/SASjsApi/group"; + %if &mdebug=1 %then %do; + debug level=1; + %end; + run; +%end; +%else %do; + /* + first get the userid - cannot do this directly until the following ticket + is closed: https://github.com/sasjs/server/issues/188 + */ + data;run; + %local ds1 uid; + %let ds1=&syslast; + %ms_getusers(outds=&ds1) + %let uid=0; + data _null_; + set &ds1; + if username="&user" then call symputx('uid',id,'l'); + run; + proc http method='GET' headerin=&fref0 out=&fref1 + url="&_sasjs_apiserverurl/SASjsApi/group"; + %if &mdebug=1 %then %do; + debug level=1; + %end; + run; %end; -run; %mp_abort( iftrue=(&syscc ne 0) @@ -20262,13 +20420,18 @@ options &optval; @file @brief Fetches the list of users from SASjs Server @details Fetches the list of users from SASjs Server and writes them to an - output dataset. + output dataset. Can also be filtered, for a particular group. Example: %ms_getusers(outds=userlist) + Filtering for a group: + + %ms_getusers(outds=work.groupmembers, group=GROUPNAME) + @param [in] mdebug= (0) Set to 1 to enable DEBUG messages + @param [in] group= (0) Set to a group name to filter members for that group @param [out] outds= (work.ms_getusers) This output dataset will contain the list of user accounts. Format: |DISPLAYNAME:$18.|USERNAME:$10.|ID:best.| @@ -20284,18 +20447,22 @@ options &optval;

SAS Macros

@li mf_getuniquefileref.sas @li mf_getuniquelibref.sas + @li mf_getuniquename.sas @li mp_abort.sas + @li ms_getgroups.sas

Related Files

@li ms_createuser.sas + @li ms_getgroups.sas @li ms_getusers.test.sas **/ %macro ms_getusers( - outds=work.ms_getusers - ,mdebug=0 - ); + outds=work.ms_getusers, + group=0, + mdebug=0 +); %mp_abort( iftrue=(&syscc ne 0) @@ -20327,27 +20494,56 @@ run; put _infile_; run; %end; - -proc http method='GET' headerin=&fref0 out=&fref1 - url="&_sasjs_apiserverurl/SASjsApi/user"; -%if &mdebug=1 %then %do; - debug level=1; +%if "&group"="0" %then %do; + proc http method='GET' headerin=&fref0 out=&fref1 + url="&_sasjs_apiserverurl/SASjsApi/user"; + %if &mdebug=1 %then %do; + debug level=1; + %end; + run; +%end; +%else %do; + /* currently we only have an API to fetch by group ID */ + /* so first fetch all the groups, and grab the id */ + %local groupid ds1; + %let ds1=%mf_getuniquename(prefix=groups); + %ms_getgroups(outds=&ds1) + data _null_; + set &ds1; + where name="&group"; + call symputx('groupid',groupid,'l'); + run; + + proc http method='GET' headerin=&fref0 out=&fref1 + url="&_sasjs_apiserverurl/SASjsApi/group/&groupid"; + %if &mdebug=1 %then %do; + debug level=1; + %put &=groupid; + %end; + run; + %end; -run; %mp_abort( iftrue=(&syscc ne 0) ,mac=ms_getusers.sas - ,msg=%str(Issue submitting GET query to SASjsApi/user) + ,msg=%str(Issue submitting API query) ) libname &libref JSON fileref=&fref1; -data &outds; - set &libref..root; - drop ordinal_root; -run; - +%if "&group"="0" %then %do; + data &outds; + set &libref..root; + drop ordinal_root; + run; +%end; +%else %do; + data &outds; + set &libref..users; + drop ordinal_root ordinal_users; + run; +%end; %mp_abort( iftrue=(&syscc ne 0) diff --git a/meta/mm_adduser2group.sas b/meta/mm_adduser2group.sas index 6b5ce81..5b61053 100644 --- a/meta/mm_adduser2group.sas +++ b/meta/mm_adduser2group.sas @@ -2,7 +2,10 @@ @file mm_adduser2group.sas @brief Adds a user to a group @details Adds a user to a metadata group. The macro first checks whether the - user is in that group, and if not, the user is added. + user is in that group, and if not, the user is added. + + Note that the macro does not check inherited group memberships - it looks at + direct members only. Usage: @@ -12,10 +15,10 @@ @param user= the user name (not displayname) @param group= the group to which to add the user - @param mdebug= set to 1 to show debug info in log + @param mdebug= (0) set to 1 to show debug info in log - @warning the macro does not check inherited group memberships - it looks at - direct members only +

Related Files

+ @li ms_adduser2group.sas @version 9.3 @author Allan Bowe diff --git a/sasjs/sasjsconfig.json b/sasjs/sasjsconfig.json index 34da685..de6d74a 100644 --- a/sasjs/sasjsconfig.json +++ b/sasjs/sasjsconfig.json @@ -67,7 +67,7 @@ }, { "name": "server", - "serverUrl": "https://sas.analytium.co.uk:5007", + "serverUrl": "https://sas.4gl.io:5001", "serverType": "SASJS", "httpsAgentOptions": { "allowInsecureRequests": false @@ -107,4 +107,4 @@ "contextName": "SAS Job Execution compute context" } ] -} +} \ No newline at end of file diff --git a/server/ms_adduser2group.sas b/server/ms_adduser2group.sas new file mode 100644 index 0000000..07c75be --- /dev/null +++ b/server/ms_adduser2group.sas @@ -0,0 +1,122 @@ +/** + @file + @brief Adds a user to a group on SASjs Server + @details Adds a user to a group based on userid and groupid. Both user and + group must already exist. + + Examples: + + %ms_adduser2group(uid=1,gid=1) + + + @param [in] uid= (0) The User ID to be added + @param [in] gid= (0) The Group ID to contain the new user + @param [in] mdebug= (0) Set to 1 to enable DEBUG messages + @param [out] outds= (work.ms_adduser2group) This output dataset will contain + the new list of group members, eg: +|DISPLAYNAME:$18.|USERNAME:$10.|ID:best.| +|---|---|---| +|`Super Admin `|`secretuser `|`1`| +|`Sabir Hassan`|`sabir`|`2`| +|`Mihajlo Medjedovic `|`mihajlo `|`3`| +|`Ivor Townsend `|`ivor `|`4`| +|`New User `|`newuser `|`5`| + + + +

SAS Macros

+ @li mf_getuniquefileref.sas + @li mf_getuniquelibref.sas + @li mp_abort.sas + +

Related Files

+ @li ms_creategroup.sas + @li ms_createuser.sas + +**/ + +%macro ms_adduser2group(uid=0 + ,gid=0 + ,outds=work.ms_adduser2group + ,mdebug=0 + ); + +%mp_abort( + iftrue=(&syscc ne 0) + ,mac=ms_adduser2group.sas + ,msg=%str(syscc=&syscc on macro entry) +) + +%local fref0 fref1 fref2 libref optval rc msg; +%let fref0=%mf_getuniquefileref(); +%let fref1=%mf_getuniquefileref(); +%let libref=%mf_getuniquelibref(); + +/* avoid sending bom marker to API */ +%let optval=%sysfunc(getoption(bomfile)); +options nobomfile; + +data _null_; + file &fref0 lrecl=1000; + infile "&_sasjs_tokenfile" lrecl=1000; + input; + if _n_=1 then put "accept: application/json"; + put _infile_; +run; + +%if &mdebug=1 %then %do; + %put _local_; + data _null_; + infile &fref0; + input; + put _infile_; + run; +%end; + +proc http method='POST' headerin=&fref0 out=&fref1 + url="&_sasjs_apiserverurl/SASjsApi/group/&gid/&uid"; +%if &mdebug=1 %then %do; + debug level=1; +%end; +run; + +%mp_abort( + iftrue=(&syscc ne 0) + ,mac=ms_adduser2group.sas + ,msg=%str(Issue submitting query to SASjsApi/group) +) + +libname &libref JSON fileref=&fref1; + +data &outds; + set &libref..users; + drop ordinal_root ordinal_users; +%if &mdebug=1 %then %do; + putlog _all_; +%end; +run; + + +%mp_abort( + iftrue=(&syscc ne 0) + ,mac=ms_creategroup.sas + ,msg=%str(Issue reading response JSON) +) + +/* reset options */ +options &optval; + +%if &mdebug=0 %then %do; + filename &fref0 clear; + filename &fref1 clear; + libname &libref clear; +%end; +%else %do; + data _null_; + infile &fref1; + input; + putlog _infile_; + run; +%end; + +%mend ms_adduser2group; diff --git a/server/ms_getgroups.sas b/server/ms_getgroups.sas index bb96b23..524e454 100644 --- a/server/ms_getgroups.sas +++ b/server/ms_getgroups.sas @@ -2,13 +2,19 @@ @file @brief Fetches the list of groups from SASjs Server @details Fetches the list of groups from SASjs Server and writes them to an - output dataset. + output dataset. Provide a username to filter for the groups for a particular + user. Example: %ms_getgroups(outds=userlist) + With filter: + + %ms_getgroups(outds=userlist, user=James) + @param [in] mdebug= (0) Set to 1 to enable DEBUG messages + @param [in] user= (0) Provide the username on which to filter @param [out] outds= (work.ms_getgroups) This output dataset will contain the list of groups. Format: |NAME:$32.|DESCRIPTION:$64.|GROUPID:best.| @@ -30,9 +36,10 @@ **/ %macro ms_getgroups( - outds=work.ms_getgroups - ,mdebug=0 - ); + user=0, + outds=work.ms_getgroups, + mdebug=0 +); %mp_abort( iftrue=(&syscc ne 0) @@ -46,7 +53,10 @@ /* groups api does not exist in desktop mode */ data &outds; length NAME $32 DESCRIPTION $64. GROUPID 8; - call missing (of _all_); + name="&sysuserid"; + description="&sysuserid (group - desktop mode)"; + groupid=1; + output; stop; run; %return; @@ -76,12 +86,35 @@ run; run; %end; -proc http method='GET' headerin=&fref0 out=&fref1 - url="&_sasjs_apiserverurl/SASjsApi/group"; -%if &mdebug=1 %then %do; - debug level=1; +%if "&user"="0" %then %do; + proc http method='GET' headerin=&fref0 out=&fref1 + url="&_sasjs_apiserverurl/SASjsApi/group"; + %if &mdebug=1 %then %do; + debug level=1; + %end; + run; +%end; +%else %do; + /* + first get the userid - cannot do this directly until the following ticket + is closed: https://github.com/sasjs/server/issues/188 + */ + data;run; + %local ds1 uid; + %let ds1=&syslast; + %ms_getusers(outds=&ds1) + %let uid=0; + data _null_; + set &ds1; + if username="&user" then call symputx('uid',id,'l'); + run; + proc http method='GET' headerin=&fref0 out=&fref1 + url="&_sasjs_apiserverurl/SASjsApi/group"; + %if &mdebug=1 %then %do; + debug level=1; + %end; + run; %end; -run; %mp_abort( iftrue=(&syscc ne 0) diff --git a/server/ms_getusers.sas b/server/ms_getusers.sas index 5228736..a93e98c 100644 --- a/server/ms_getusers.sas +++ b/server/ms_getusers.sas @@ -2,13 +2,18 @@ @file @brief Fetches the list of users from SASjs Server @details Fetches the list of users from SASjs Server and writes them to an - output dataset. + output dataset. Can also be filtered, for a particular group. Example: %ms_getusers(outds=userlist) + Filtering for a group: + + %ms_getusers(outds=work.groupmembers, group=GROUPNAME) + @param [in] mdebug= (0) Set to 1 to enable DEBUG messages + @param [in] group= (0) Set to a group name to filter members for that group @param [out] outds= (work.ms_getusers) This output dataset will contain the list of user accounts. Format: |DISPLAYNAME:$18.|USERNAME:$10.|ID:best.| @@ -24,18 +29,22 @@

SAS Macros

@li mf_getuniquefileref.sas @li mf_getuniquelibref.sas + @li mf_getuniquename.sas @li mp_abort.sas + @li ms_getgroups.sas

Related Files

@li ms_createuser.sas + @li ms_getgroups.sas @li ms_getusers.test.sas **/ %macro ms_getusers( - outds=work.ms_getusers - ,mdebug=0 - ); + outds=work.ms_getusers, + group=0, + mdebug=0 +); %mp_abort( iftrue=(&syscc ne 0) @@ -67,27 +76,56 @@ run; put _infile_; run; %end; - -proc http method='GET' headerin=&fref0 out=&fref1 - url="&_sasjs_apiserverurl/SASjsApi/user"; -%if &mdebug=1 %then %do; - debug level=1; +%if "&group"="0" %then %do; + proc http method='GET' headerin=&fref0 out=&fref1 + url="&_sasjs_apiserverurl/SASjsApi/user"; + %if &mdebug=1 %then %do; + debug level=1; + %end; + run; +%end; +%else %do; + /* currently we only have an API to fetch by group ID */ + /* so first fetch all the groups, and grab the id */ + %local groupid ds1; + %let ds1=%mf_getuniquename(prefix=groups); + %ms_getgroups(outds=&ds1) + data _null_; + set &ds1; + where name="&group"; + call symputx('groupid',groupid,'l'); + run; + + proc http method='GET' headerin=&fref0 out=&fref1 + url="&_sasjs_apiserverurl/SASjsApi/group/&groupid"; + %if &mdebug=1 %then %do; + debug level=1; + %put &=groupid; + %end; + run; + %end; -run; %mp_abort( iftrue=(&syscc ne 0) ,mac=ms_getusers.sas - ,msg=%str(Issue submitting GET query to SASjsApi/user) + ,msg=%str(Issue submitting API query) ) libname &libref JSON fileref=&fref1; -data &outds; - set &libref..root; - drop ordinal_root; -run; - +%if "&group"="0" %then %do; + data &outds; + set &libref..root; + drop ordinal_root; + run; +%end; +%else %do; + data &outds; + set &libref..users; + drop ordinal_root ordinal_users; + run; +%end; %mp_abort( iftrue=(&syscc ne 0) diff --git a/tests/serveronly/ms_adduser2group.test.sas b/tests/serveronly/ms_adduser2group.test.sas new file mode 100644 index 0000000..177e089 --- /dev/null +++ b/tests/serveronly/ms_adduser2group.test.sas @@ -0,0 +1,52 @@ +/** + @file + @brief Testing ms_adduser2group.sas macro + +

SAS Macros

+ @li mf_getuniquename.sas + @li mp_assert.sas + @li mp_assertscope.sas + @li ms_adduser2group.sas + @li ms_creategroup.sas + +**/ + +/* first, create an empty group */ +%let group=%substr(%mf_getuniquename(),1,8); +%ms_creategroup(&group, desc=The description,mdebug=&sasjs_mdebug,outds=test1a) +%let groupid=0; +data _null_; + set work.test1a; + call symputx('groupid',groupid); +run; +%mp_assert( + iftrue=(&groupid>0), + desc=Checking that group was created with an ID, + outds=work.test_results +) + +/* now add a user (user 1 always exists) */ + + +%mp_assertscope(SNAPSHOT) +%ms_adduser2group(uid=1,gid=&groupid,mdebug=&sasjs_mdebug,outds=test1) +%mp_assertscope(COMPARE + ,ignorelist=MCLIB0_JADP1LEN MCLIB0_JADPNUM MCLIB0_JADVLEN +) + +/* check the user is in the output list */ +%let checkid=0; +data _null_; + set work.test1; + if id=1 then call symputx('checkid',1); +run; +%mp_assert( + iftrue=(&checkid=1), + desc=Checking that user was created in the new group, + outds=work.test_results +) + + + + + diff --git a/tests/serveronly/ms_createuser.test.sas b/tests/serveronly/ms_createuser.test.sas index 1479ab8..6749066 100644 --- a/tests/serveronly/ms_createuser.test.sas +++ b/tests/serveronly/ms_createuser.test.sas @@ -23,6 +23,7 @@ data _null_; set work.test1; call symputx('id',id); + putlog (_all_)(=); run; %mp_assert( iftrue=(&id>0), @@ -35,7 +36,8 @@ run; %let checkid=0; data _null_; set work.test2; - where username="&user"; + if _n_<20 then putlog (_all_)(=); + if username="&user"; call symputx('checkid',id); run; %mp_assert( diff --git a/tests/serveronly/ms_getusers.test.sas b/tests/serveronly/ms_getusers.test.sas index addc778..307c6c8 100644 --- a/tests/serveronly/ms_getusers.test.sas +++ b/tests/serveronly/ms_getusers.test.sas @@ -3,6 +3,8 @@ @brief Testing ms_getusers.sas macro

SAS Macros

+ @li ms_creategroup.sas + @li ms_adduser2group.sas @li ms_getusers.sas @li mp_assertdsobs.sas @li mp_assertscope.sas @@ -18,6 +20,39 @@ %mp_assertdsobs(work.test1,test=ATLEAST 1) +/** + * test the extraction of group members + */ + +/* create a group */ +%let group=%substr(%mf_getuniquename(),1,8); +%ms_creategroup(&group, desc=some desc,mdebug=&sasjs_mdebug,outds=work.group) +%let gid=0; +data _null_; + set work.group; + call symputx('gid',groupid); +run; + +/* add a member */ +%ms_adduser2group(uid=1,gid=&gid) + +/* extract the members */ +%ms_getusers(group=&group,outds=test2) + +/* check the user is in the output list */ +%let checkid=0; +data _null_; + set work.test2; + if id=1 then call symputx('checkid',1); +run; +%mp_assert( + iftrue=(&checkid=1), + desc=Checking that admin user was created in the new group, + outds=work.test_results +) + + + diff --git a/tests/serveronly/ms_runstp.test.sas b/tests/serveronly/ms_runstp.test.sas index 00fc38f..457688b 100644 --- a/tests/serveronly/ms_runstp.test.sas +++ b/tests/serveronly/ms_runstp.test.sas @@ -34,7 +34,7 @@ options mprint; ) %mp_assertscope(COMPARE) -libname webeen json (weboot); +libname webeen json fileref=weboot; data _null_; infile weboot; diff --git a/tests/serveronly/ms_testservice.test.sas b/tests/serveronly/ms_testservice.test.sas index e61f7dc..34c892c 100644 --- a/tests/serveronly/ms_testservice.test.sas +++ b/tests/serveronly/ms_testservice.test.sas @@ -10,7 +10,12 @@ **/ filename ft15f001 temp; -parmcards4; +data _null_; + file ft15f001; + infile cards; + input; + put _infile_; +cards4; %put Initialising sendObj: ; %put _all_; %webout(FETCH) @@ -27,6 +32,7 @@ parmcards4; %mend x; %x() %webout(CLOSE) ;;;; +run; %put creating web service: &mcTestAppLoc/services; %ms_createwebservice( path=&mcTestAppLoc/services, diff --git a/tests/serveronly/ms_webout.test.sas b/tests/serveronly/ms_webout.test.sas index 34dc868..bd68244 100644 --- a/tests/serveronly/ms_webout.test.sas +++ b/tests/serveronly/ms_webout.test.sas @@ -20,7 +20,7 @@ run; %ms_webout(OBJ,datasets,fref=&fref) %ms_webout(CLOSE,fref=&fref) -libname test JSON (&fref); +libname test JSON fileref=&fref; data root; set test.root; call symputx('checkval',sysvlong); From 557df272ff5d367ab63cd2284899ea328fbf0aeb Mon Sep 17 00:00:00 2001 From: Allan Bowe Date: Tue, 14 Jun 2022 19:24:41 +0000 Subject: [PATCH 2/4] fix: using new user/by/username api in sasjs/server --- all.sas | 66 +++++++++++++++++------------------------ server/ms_getgroups.sas | 66 +++++++++++++++++------------------------ 2 files changed, 56 insertions(+), 76 deletions(-) diff --git a/all.sas b/all.sas index d91b20e..656be03 100644 --- a/all.sas +++ b/all.sas @@ -20300,7 +20300,7 @@ filename &headref clear;

Related Files

@li ms_creategroup.sas - @li ms_getusers.test.sas + @li ms_getgroups.test.sas **/ @@ -20312,11 +20312,11 @@ filename &headref clear; %mp_abort( iftrue=(&syscc ne 0) - ,mac=ms_getusers.sas + ,mac=ms_getgroups.sas ,msg=%str(syscc=&syscc on macro entry) ) -%local fref0 fref1 libref optval rc msg; +%local fref0 fref1 libref optval rc msg url; %if %sysget(MODE)=desktop %then %do; /* groups api does not exist in desktop mode */ @@ -20355,50 +20355,40 @@ run; run; %end; -%if "&user"="0" %then %do; - proc http method='GET' headerin=&fref0 out=&fref1 - url="&_sasjs_apiserverurl/SASjsApi/group"; - %if &mdebug=1 %then %do; - debug level=1; - %end; - run; -%end; -%else %do; - /* - first get the userid - cannot do this directly until the following ticket - is closed: https://github.com/sasjs/server/issues/188 - */ - data;run; - %local ds1 uid; - %let ds1=&syslast; - %ms_getusers(outds=&ds1) - %let uid=0; - data _null_; - set &ds1; - if username="&user" then call symputx('uid',id,'l'); - run; - proc http method='GET' headerin=&fref0 out=&fref1 - url="&_sasjs_apiserverurl/SASjsApi/group"; - %if &mdebug=1 %then %do; - debug level=1; - %end; - run; +%if "&user"="0" %then %let url=/SASjsApi/group; +%else %let url=/SASjsApi/user/by/username/&user; + +proc http method='GET' headerin=&fref0 out=&fref1 + url="&_sasjs_apiserverurl.&url"; +%if &mdebug=1 %then %do; + debug level=1; %end; +run; %mp_abort( iftrue=(&syscc ne 0) ,mac=ms_getgroups.sas - ,msg=%str(Issue submitting GET query to SASjsApi/group) + ,msg=%str(Issue submitting GET query to SASjsApi) ) libname &libref JSON fileref=&fref1; -data &outds; - length NAME $32 DESCRIPTION $64. GROUPID 8; - if _n_=1 then call missing(of _all_); - set &libref..root; - drop ordinal_root; -run; +%if "&user"="0" %then %do; + data &outds; + length NAME $32 DESCRIPTION $64. GROUPID 8; + if _n_=1 then call missing(of _all_); + set &libref..root; + drop ordinal_root; + run; +%end; +%else %do; + data &outds; + length NAME $32 DESCRIPTION $64. GROUPID 8; + if _n_=1 then call missing(of _all_); + set &libref..groups; + drop ordinal_:; + run; +%end; %mp_abort( iftrue=(&syscc ne 0) diff --git a/server/ms_getgroups.sas b/server/ms_getgroups.sas index 524e454..597f9fb 100644 --- a/server/ms_getgroups.sas +++ b/server/ms_getgroups.sas @@ -31,7 +31,7 @@

Related Files

@li ms_creategroup.sas - @li ms_getusers.test.sas + @li ms_getgroups.test.sas **/ @@ -43,11 +43,11 @@ %mp_abort( iftrue=(&syscc ne 0) - ,mac=ms_getusers.sas + ,mac=ms_getgroups.sas ,msg=%str(syscc=&syscc on macro entry) ) -%local fref0 fref1 libref optval rc msg; +%local fref0 fref1 libref optval rc msg url; %if %sysget(MODE)=desktop %then %do; /* groups api does not exist in desktop mode */ @@ -86,50 +86,40 @@ run; run; %end; -%if "&user"="0" %then %do; - proc http method='GET' headerin=&fref0 out=&fref1 - url="&_sasjs_apiserverurl/SASjsApi/group"; - %if &mdebug=1 %then %do; - debug level=1; - %end; - run; -%end; -%else %do; - /* - first get the userid - cannot do this directly until the following ticket - is closed: https://github.com/sasjs/server/issues/188 - */ - data;run; - %local ds1 uid; - %let ds1=&syslast; - %ms_getusers(outds=&ds1) - %let uid=0; - data _null_; - set &ds1; - if username="&user" then call symputx('uid',id,'l'); - run; - proc http method='GET' headerin=&fref0 out=&fref1 - url="&_sasjs_apiserverurl/SASjsApi/group"; - %if &mdebug=1 %then %do; - debug level=1; - %end; - run; +%if "&user"="0" %then %let url=/SASjsApi/group; +%else %let url=/SASjsApi/user/by/username/&user; + +proc http method='GET' headerin=&fref0 out=&fref1 + url="&_sasjs_apiserverurl.&url"; +%if &mdebug=1 %then %do; + debug level=1; %end; +run; %mp_abort( iftrue=(&syscc ne 0) ,mac=ms_getgroups.sas - ,msg=%str(Issue submitting GET query to SASjsApi/group) + ,msg=%str(Issue submitting GET query to SASjsApi) ) libname &libref JSON fileref=&fref1; -data &outds; - length NAME $32 DESCRIPTION $64. GROUPID 8; - if _n_=1 then call missing(of _all_); - set &libref..root; - drop ordinal_root; -run; +%if "&user"="0" %then %do; + data &outds; + length NAME $32 DESCRIPTION $64. GROUPID 8; + if _n_=1 then call missing(of _all_); + set &libref..root; + drop ordinal_root; + run; +%end; +%else %do; + data &outds; + length NAME $32 DESCRIPTION $64. GROUPID 8; + if _n_=1 then call missing(of _all_); + set &libref..groups; + drop ordinal_:; + run; +%end; %mp_abort( iftrue=(&syscc ne 0) From cb553a31ab9b89b658bc61fe6a68755d36e98953 Mon Sep 17 00:00:00 2001 From: Allan Bowe Date: Tue, 14 Jun 2022 19:37:06 +0000 Subject: [PATCH 3/4] fix: failing test for filtering groups for a particular user (api isn't ready yet) --- tests/serveronly/ms_getgroups.test.sas | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/serveronly/ms_getgroups.test.sas b/tests/serveronly/ms_getgroups.test.sas index b0eebcf..e95c4db 100644 --- a/tests/serveronly/ms_getgroups.test.sas +++ b/tests/serveronly/ms_getgroups.test.sas @@ -3,21 +3,61 @@ @brief Testing ms_getgroups.sas macro

SAS Macros

+ @li mf_getuniquename.sas + @li ms_adduser2group.sas + @li ms_creategroup.sas @li ms_getgroups.sas + @li mp_assert.sas @li mp_assertdsobs.sas @li mp_assertscope.sas **/ +/* create a group */ +%let group=%substr(%mf_getuniquename(),1,8); +%ms_creategroup(&group, desc=The description,mdebug=&sasjs_mdebug,outds=test1) +/* get groups */ %mp_assertscope(SNAPSHOT) %ms_getgroups(outds=work.test1,mdebug=&sasjs_mdebug) %mp_assertscope(COMPARE ,ignorelist=MCLIB0_JADP1LEN MCLIB0_JADPNUM MCLIB0_JADVLEN ) +/* check the group was created */ %mp_assertdsobs(work.test1,test=ATLEAST 1) +%let test2=0; +data _null_; + set work.test1; + if groupname="&group" then do; + call symputx('test2',1); + call symputx('gid',groupid); /* used in next test */ + end; +run; + +%mp_assert( + iftrue=("&test2"="1"), + desc=Checking group was created, + outds=work.test_results +) +/* now check if the filter for the groups for a user works */ +/* add a member */ +%ms_adduser2group(uid=1,gid=&gid) + +%ms_getgroups(user=secretuser,outds=work.test3) + +%let test3=0; +data _null_; + set work.test3; + if groupid=&gid then call symputx('test3',1); +run; + +%mp_assert( + iftrue=("&test3"="1"), + desc=Checking group list was returned for a user, + outds=work.test_results +) From a1c931b5e61cbe9ab6750a2dafdfce97d6d0661f Mon Sep 17 00:00:00 2001 From: Allan Bowe Date: Thu, 16 Jun 2022 11:37:31 +0000 Subject: [PATCH 4/4] fix: tests with new APIs are now passing --- all.sas | 43 +++++++----------------- sasjs/sasjsconfig.json | 2 +- server/ms_getusers.sas | 43 +++++++----------------- tests/serveronly/ms_creategroup.test.sas | 2 +- tests/serveronly/ms_createuser.test.sas | 2 +- tests/serveronly/ms_getgroups.test.sas | 5 ++- 6 files changed, 33 insertions(+), 64 deletions(-) diff --git a/all.sas b/all.sas index 656be03..10109be 100644 --- a/all.sas +++ b/all.sas @@ -20424,7 +20424,7 @@ options &optval; @param [in] group= (0) Set to a group name to filter members for that group @param [out] outds= (work.ms_getusers) This output dataset will contain the list of user accounts. Format: -|DISPLAYNAME:$18.|USERNAME:$10.|ID:best.| +|DISPLAYNAME:$60.|USERNAME:$30.|ID:best.| |---|---|---| |`Super Admin `|`secretuser `|`1`| |`Sabir Hassan`|`sabir`|`2`| @@ -20437,9 +20437,7 @@ options &optval;

SAS Macros

@li mf_getuniquefileref.sas @li mf_getuniquelibref.sas - @li mf_getuniquename.sas @li mp_abort.sas - @li ms_getgroups.sas

Related Files

@li ms_createuser.sas @@ -20460,7 +20458,7 @@ options &optval; ,msg=%str(syscc=&syscc on macro entry) ) -%local fref0 fref1 libref optval rc msg; +%local fref0 fref1 libref optval rc msg url; %let fref0=%mf_getuniquefileref(); %let fref1=%mf_getuniquefileref(); %let libref=%mf_getuniquelibref(); @@ -20484,35 +20482,18 @@ run; put _infile_; run; %end; -%if "&group"="0" %then %do; - proc http method='GET' headerin=&fref0 out=&fref1 - url="&_sasjs_apiserverurl/SASjsApi/user"; - %if &mdebug=1 %then %do; - debug level=1; - %end; - run; -%end; -%else %do; - /* currently we only have an API to fetch by group ID */ - /* so first fetch all the groups, and grab the id */ - %local groupid ds1; - %let ds1=%mf_getuniquename(prefix=groups); - %ms_getgroups(outds=&ds1) - data _null_; - set &ds1; - where name="&group"; - call symputx('groupid',groupid,'l'); - run; - proc http method='GET' headerin=&fref0 out=&fref1 - url="&_sasjs_apiserverurl/SASjsApi/group/&groupid"; - %if &mdebug=1 %then %do; - debug level=1; - %put &=groupid; - %end; - run; +%if "&group"="0" %then %let url=/SASjsApi/user; +%else %let url=/SASjsApi/group/by/groupname/&group; + +proc http method='GET' headerin=&fref0 out=&fref1 + url="&_sasjs_apiserverurl.&url"; +%if &mdebug=1 %then %do; + debug level=1; %end; +run; + %mp_abort( iftrue=(&syscc ne 0) @@ -20524,12 +20505,14 @@ libname &libref JSON fileref=&fref1; %if "&group"="0" %then %do; data &outds; + length DISPLAYNAME $60 USERNAME:$30 ID 8; set &libref..root; drop ordinal_root; run; %end; %else %do; data &outds; + length DISPLAYNAME $60 USERNAME:$30 ID 8; set &libref..users; drop ordinal_root ordinal_users; run; diff --git a/sasjs/sasjsconfig.json b/sasjs/sasjsconfig.json index de6d74a..ae89c0e 100644 --- a/sasjs/sasjsconfig.json +++ b/sasjs/sasjsconfig.json @@ -67,7 +67,7 @@ }, { "name": "server", - "serverUrl": "https://sas.4gl.io:5001", + "serverUrl": "https://sas.4gl.io", "serverType": "SASJS", "httpsAgentOptions": { "allowInsecureRequests": false diff --git a/server/ms_getusers.sas b/server/ms_getusers.sas index a93e98c..17e5f86 100644 --- a/server/ms_getusers.sas +++ b/server/ms_getusers.sas @@ -16,7 +16,7 @@ @param [in] group= (0) Set to a group name to filter members for that group @param [out] outds= (work.ms_getusers) This output dataset will contain the list of user accounts. Format: -|DISPLAYNAME:$18.|USERNAME:$10.|ID:best.| +|DISPLAYNAME:$60.|USERNAME:$30.|ID:best.| |---|---|---| |`Super Admin `|`secretuser `|`1`| |`Sabir Hassan`|`sabir`|`2`| @@ -29,9 +29,7 @@

SAS Macros

@li mf_getuniquefileref.sas @li mf_getuniquelibref.sas - @li mf_getuniquename.sas @li mp_abort.sas - @li ms_getgroups.sas

Related Files

@li ms_createuser.sas @@ -52,7 +50,7 @@ ,msg=%str(syscc=&syscc on macro entry) ) -%local fref0 fref1 libref optval rc msg; +%local fref0 fref1 libref optval rc msg url; %let fref0=%mf_getuniquefileref(); %let fref1=%mf_getuniquefileref(); %let libref=%mf_getuniquelibref(); @@ -76,35 +74,18 @@ run; put _infile_; run; %end; -%if "&group"="0" %then %do; - proc http method='GET' headerin=&fref0 out=&fref1 - url="&_sasjs_apiserverurl/SASjsApi/user"; - %if &mdebug=1 %then %do; - debug level=1; - %end; - run; -%end; -%else %do; - /* currently we only have an API to fetch by group ID */ - /* so first fetch all the groups, and grab the id */ - %local groupid ds1; - %let ds1=%mf_getuniquename(prefix=groups); - %ms_getgroups(outds=&ds1) - data _null_; - set &ds1; - where name="&group"; - call symputx('groupid',groupid,'l'); - run; - proc http method='GET' headerin=&fref0 out=&fref1 - url="&_sasjs_apiserverurl/SASjsApi/group/&groupid"; - %if &mdebug=1 %then %do; - debug level=1; - %put &=groupid; - %end; - run; +%if "&group"="0" %then %let url=/SASjsApi/user; +%else %let url=/SASjsApi/group/by/groupname/&group; + +proc http method='GET' headerin=&fref0 out=&fref1 + url="&_sasjs_apiserverurl.&url"; +%if &mdebug=1 %then %do; + debug level=1; %end; +run; + %mp_abort( iftrue=(&syscc ne 0) @@ -116,12 +97,14 @@ libname &libref JSON fileref=&fref1; %if "&group"="0" %then %do; data &outds; + length DISPLAYNAME $60 USERNAME:$30 ID 8; set &libref..root; drop ordinal_root; run; %end; %else %do; data &outds; + length DISPLAYNAME $60 USERNAME:$30 ID 8; set &libref..users; drop ordinal_root ordinal_users; run; diff --git a/tests/serveronly/ms_creategroup.test.sas b/tests/serveronly/ms_creategroup.test.sas index cda4f7f..1fb778b 100644 --- a/tests/serveronly/ms_creategroup.test.sas +++ b/tests/serveronly/ms_creategroup.test.sas @@ -35,7 +35,7 @@ run; %let checkid=0; data _null_; set work.test2; - where name="&group"; + where upcase(name)="%upcase(&group)"; call symputx('checkid',groupid); run; %mp_assert( diff --git a/tests/serveronly/ms_createuser.test.sas b/tests/serveronly/ms_createuser.test.sas index 6749066..1cc1286 100644 --- a/tests/serveronly/ms_createuser.test.sas +++ b/tests/serveronly/ms_createuser.test.sas @@ -37,7 +37,7 @@ run; data _null_; set work.test2; if _n_<20 then putlog (_all_)(=); - if username="&user"; + if upcase(username)="%upcase(&user)"; call symputx('checkid',id); run; %mp_assert( diff --git a/tests/serveronly/ms_getgroups.test.sas b/tests/serveronly/ms_getgroups.test.sas index e95c4db..8c87d63 100644 --- a/tests/serveronly/ms_getgroups.test.sas +++ b/tests/serveronly/ms_getgroups.test.sas @@ -28,9 +28,12 @@ %mp_assertdsobs(work.test1,test=ATLEAST 1) %let test2=0; +%put &=group; data _null_; set work.test1; - if groupname="&group" then do; + putlog (_all_)(=); + if upcase(name)="%upcase(&group)" then do; + putlog "&group found!"; call symputx('test2',1); call symputx('gid',groupid); /* used in next test */ end;