1
0
mirror of https://github.com/sasjs/core.git synced 2025-12-11 06:24:35 +00:00

Compare commits

...

23 Commits

Author SHA1 Message Date
Allan Bowe
54a24ced83 fix: using sasjs username in mf_getuser() 2022-06-17 15:54:30 +00:00
Allan Bowe
57ae2981f1 Merge pull request #256 from sasjs/allanbowe/mp-abort-fails-on-windows-254
fix: superq() for sysprocessname
2022-06-17 15:29:22 +02:00
Allan Bowe
a3043ac685 fix: superq() for sysprocessname 2022-06-17 13:28:51 +00:00
Allan Bowe
2bdb90b0be Merge pull request #255 from sasjs/allanbowe/mp-abort-fails-on-windows-254
fix: handling embedded speechmarks in SYSPROCESSNAME.  Closes #254
2022-06-17 14:32:02 +02:00
Allan Bowe
2cd846d504 fix: handling embedded speechmarks in SYSPROCESSNAME. Closes #254 2022-06-17 12:30:40 +00:00
Allan Bowe
f593c7bec9 fix: returning user list (single user) in desktop mode in ms_getusers() 2022-06-17 07:52:39 +00:00
Allan Bowe
c8805db0b5 feat: filter for groups by user id in ms_getgroups 2022-06-17 07:46:51 +00:00
Allan Bowe
1eb6d8cec9 feat: enabling user list by group id as well as name 2022-06-17 07:16:57 +00:00
Allan Bowe
ed19ee03af Merge pull request #253 from sasjs/servergroups
feat: enabling group macros on sasjs/server
2022-06-16 13:40:36 +02:00
Allan Bowe
a1c931b5e6 fix: tests with new APIs are now passing 2022-06-16 11:37:31 +00:00
Allan Bowe
cb553a31ab fix: failing test for filtering groups for a particular user (api isn't ready yet) 2022-06-14 19:37:06 +00:00
Allan Bowe
557df272ff fix: using new user/by/username api in sasjs/server 2022-06-14 19:24:41 +00:00
Allan Bowe
0cb3c96c15 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).
2022-06-14 13:40:05 +00:00
Allan Bowe
1cb39d4d61 Merge pull request #252 from sasjs/allanbowe/ms-getgroups-fails-in-251
fix: creating empty table in desktop mode (ms_getgroups)
2022-06-11 21:30:03 +02:00
Allan Bowe
934b7d4f8a fix: creating empty table in desktop mode (ms_getgroups) 2022-06-11 19:29:21 +00:00
Allan Bowe
24c50cde56 fix: use options nobomfile for sasjs server mp_abort, also doc update in mf_existvarlist 2022-06-09 22:16:34 +00:00
Allan Bowe
055e8d2f13 fix: setting header in mp_abort for sasjs server 2022-06-07 14:01:54 +00:00
Allan Bowe
abfe7fe339 fix: no json wrapper in SASjs mode in mp_abort.sas 2022-06-07 11:28:59 +00:00
Allan Bowe
16ed91f6a9 fix: mp_abort on windows m6+ 2022-06-06 11:28:37 +00:00
Allan Bowe
67ba2a5286 fix: mp_abort on m6 win needs endsas 2022-06-03 17:45:27 +00:00
Allan Bowe
3d7f9b71e1 fix: hard abort in mm_getstpcode when the stp does not exist 2022-06-02 17:50:50 +00:00
Allan Bowe
1d972fad11 fix: using outref instead of outloc in mm_getstpcode invocation from mx_getcode 2022-05-31 22:42:40 +00:00
Allan Bowe
e23bc461c4 fix: mx_getcode platform support 2022-05-31 22:00:58 +00:00
23 changed files with 833 additions and 229 deletions

455
all.sas
View File

@@ -324,9 +324,6 @@ https://github.com/yabwon/SAS_PACKAGES/blob/main/packages/baseplus.md#functionex
%put %mf_existVarList(sashelp.class, age sex name dummyvar);
<h4> SAS Macros </h4>
@li mf_abort.sas
@param libds 2 part dataset or view reference
@param varlist space separated variable names
@@ -1144,18 +1141,19 @@ or %index(&pgm,/tests/testteardown)
@author Allan Bowe
**/
%macro mf_getuser(type=META
%macro mf_getuser(
)/*/STORE SOURCE*/;
%local user metavar;
%if &type=OS %then %let metavar=_secureusername;
%else %let metavar=_metaperson;
%local user;
%if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %let user=&SYS_COMPUTE_SESSION_OWNER;
%else %if %symexist(&metavar) %then %do;
%if %length(&&&metavar)=0 %then %let user=&sysuserid;
%if %symexist(_sasjs_username) %then %let user=&_sasjs_username;
%else %if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %do;
%let user=&SYS_COMPUTE_SESSION_OWNER;
%end;
%else %if %symexist(_metaperson) %then %do;
%if %length(&_metaperson)=0 %then %let user=&sysuserid;
/* sometimes SAS will add @domain extension - remove for consistency */
/* but be sure to quote in case of usernames with commas */
%else %let user=%unquote(%scan(%quote(&&&metavar),1,@));
%else %let user=%unquote(%scan(%quote(&_metaperson),1,@));
%end;
%else %let user=&sysuserid;
@@ -2200,16 +2198,20 @@ Usage:
recognise this and fetch the log of the parent session instead)
@li STP environments must finish cleanly to avoid the log being sent to
_webout. To assist with this, we also run stpsrvset('program error', 0)
and set SYSCC=0. We take a unique "soft abort" approach - we open a macro
and set SYSCC=0.
Where possible, we take a unique "soft abort" approach - we open a macro
but don't close it! This works everywhere EXCEPT inside a \%include inside
a macro. For that, we recommend you use mp_include.sas to perform the
include, and then call \%mp_abort(mode=INCLUDE) from the source program (ie,
OUTSIDE of the top-parent macro).
The soft abort has also been found to be ineffective in 9.4m6 windows
environments and above, so in these cases, endsas is used.
@param mac= to contain the name of the calling macro
@param mac= (mp_abort.sas) To contain the name of the calling macro. Do not
use &sysmacroname as this will always resolve to MP_ABORT.
@param msg= message to be returned
@param iftrue= supply a condition under which the macro should be executed.
@param iftrue= (1=1) Supply a condition for which the macro should be executed
@param errds= (work.mp_abort_errds) There is no clean way to end a process
within a %include called within a macro. Furthermore, there is no way to
test if a macro is called within a %include. To handle this particular
@@ -2230,11 +2232,12 @@ Usage:
@li REGULAR (default)
@li INCLUDE
@version 9.4
@author Allan Bowe
<h4> Related Macros </h4>
@li mp_include.sas
@version 9.4
@author Allan Bowe
@cond
**/
@@ -2243,7 +2246,8 @@ Usage:
, mode=REGULAR
)/*/STORE SOURCE*/;
%global sysprocessmode sysprocessname;
%global sysprocessmode sysprocessname sasjs_stpsrv_header_loc;
%local fref fid i;
%if not(%eval(%unquote(&iftrue))) %then %return;
@@ -2253,7 +2257,7 @@ Usage:
%if %symexist(_SYSINCLUDEFILEDEVICE)
/* abort cancel FILE does not restart outside the INCLUDE on Viya 3.5 */
and "&SYSPROCESSNAME " ne "Compute Server "
and %superq(SYSPROCESSNAME) ne %str(Compute Server)
%then %do;
%if "*&_SYSINCLUDEFILEDEVICE*" ne "**" %then %do;
data &errds;
@@ -2271,7 +2275,7 @@ Usage:
/* Web App Context */
%if %symexist(_PROGRAM)
or "&SYSPROCESSNAME "="Compute Server "
or %superq(SYSPROCESSNAME) = %str(Compute Server)
or &mode=INCLUDE
%then %do;
options obs=max replace mprint;
@@ -2337,8 +2341,8 @@ Usage:
%end;
%if %symexist(SYS_JES_JOB_URI) %then %do;
/* setup webout */
OPTIONS NOBOMFILE;
/* setup webout for Viya */
options nobomfile;
%if "X&SYS_JES_JOB_URI.X"="XX" %then %do;
filename _webout temp lrecl=999999 mod;
%end;
@@ -2347,11 +2351,24 @@ Usage:
name="_webout.json" lrecl=999999 mod;
%end;
%end;
%else %if %sysfunc(filename(fref,&sasjs_stpsrv_header_loc))=0 %then %do;
options nobomfile;
/* set up http header for SASjs Server */
%let fid=%sysfunc(fopen(&fref,A));
%if &fid=0 %then %do;
%put %str(ERR)OR: %sysfunc(sysmsg());
%return;
%end;
%let rc=%sysfunc(fput(&fid,%str(Content-Type: application/json)));
%let rc=%sysfunc(fwrite(&fid));
%let rc=%sysfunc(fclose(&fid));
%let rc=%sysfunc(filename(&fref));
%end;
/* send response in SASjs JSON format */
data _null_;
file _webout mod lrecl=32000 encoding='utf-8';
length msg syswarningtext syserrortext $32767 ;
length msg syswarningtext syserrortext $32767 mode $10 ;
sasdatetime=datetime();
msg=symget('msg');
%if &logline>0 %then %do;
@@ -2367,7 +2384,8 @@ Usage:
msg=cats('"',msg,'"');
if symexist('_debug') then debug=quote(trim(symget('_debug')));
else debug='""';
put '>>weboutBEGIN<<';
if symget('sasjsprocessmode')='Stored Program' then mode='SASJS';
if mode ne 'SASJS' then put '>>weboutBEGIN<<';
put '{"SYSDATE" : "' "&SYSDATE" '"';
put ',"SYSTIME" : "' "&SYSTIME" '"';
put ',"sasjsAbort" : [{';
@@ -2399,8 +2417,8 @@ Usage:
syswarningtext=quote(trim(symget('syswarningtext')));
put ",""SYSWARNINGTEXT"" : " syswarningtext;
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
put "}" @;
put '>>weboutEND<<';
put "}" ;
if mode ne 'SASJS' then put '>>weboutEND<<';
run;
%put _all_;
@@ -2411,22 +2429,30 @@ Usage:
rc=stpsrvset('program error', 0);
call symputx("syscc",0,"g");
run;
/**
* endsas kills 9.4m3 deployments by orphaning multibridges.
* Abort variants are ungraceful (non zero return code)
* This approach lets SAS run silently until the end :-)
* Caution - fails when called within a %include within a macro
* Use mp_include() to handle this.
*/
filename skip temp;
data _null_;
file skip;
put '%macro skip();';
comment '%mend skip; -> fix lint ';
put '%macro skippy();';
comment '%mend skippy; -> fix lint ';
run;
%inc skip;
%if &sysscp=WIN
and "%substr(%str(&sysvlong ),1,8)"="9.04.01M"
and "%substr(%str(&sysvlong ),9,1)">"5" %then %do;
/* skip approach (below) does not work in windows m6+ envs */
endsas;
%end;
%else %do;
/**
* endsas kills 9.4m3 deployments by orphaning multibridges.
* Abort variants are ungraceful (non zero return code)
* This approach lets SAS run silently until the end :-)
* Caution - fails when called within a %include within a macro
* Use mp_include() to handle this.
*/
filename skip temp;
data _null_;
file skip;
put '%macro skip();';
comment '%mend skip; -> fix lint ';
put '%macro skippy();';
comment '%mend skippy; -> fix lint ';
run;
%inc skip;
%end;
%end;
%else %if "&sysprocessmode " = "SAS Compute Server " %then %do;
/* endsas kills the session making it harder to fetch results */
@@ -12990,7 +13016,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:
@@ -13000,10 +13029,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
<h4> Related Files </h4>
@li ms_adduser2group.sas
@version 9.3
@author Allan Bowe
@@ -15215,18 +15244,19 @@ data _null_;
put '%end; ';
put '%mend mp_jsonout; ';
put ' ';
put '%macro mf_getuser(type=META ';
put '%macro mf_getuser( ';
put ')/*/STORE SOURCE*/; ';
put ' %local user metavar; ';
put ' %if &type=OS %then %let metavar=_secureusername; ';
put ' %else %let metavar=_metaperson; ';
put ' %local user; ';
put ' ';
put ' %if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %let user=&SYS_COMPUTE_SESSION_OWNER; ';
put ' %else %if %symexist(&metavar) %then %do; ';
put ' %if %length(&&&metavar)=0 %then %let user=&sysuserid; ';
put ' %if %symexist(_sasjs_username) %then %let user=&_sasjs_username; ';
put ' %else %if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %do; ';
put ' %let user=&SYS_COMPUTE_SESSION_OWNER; ';
put ' %end; ';
put ' %else %if %symexist(_metaperson) %then %do; ';
put ' %if %length(&_metaperson)=0 %then %let user=&sysuserid; ';
put ' /* sometimes SAS will add @domain extension - remove for consistency */ ';
put ' /* but be sure to quote in case of usernames with commas */ ';
put ' %else %let user=%unquote(%scan(%quote(&&&metavar),1,@)); ';
put ' %else %let user=%unquote(%scan(%quote(&_metaperson),1,@)); ';
put ' %end; ';
put ' %else %let user=&sysuserid; ';
put ' ';
@@ -16214,17 +16244,15 @@ filename __outdoc clear;
Usage:
options ps=max nonotes nosource;
%mm_getfoldertree(root=/My/Meta/Path, outds=iwantthisdataset)
options notes source;
options ps=max nonotes nosource;
%mm_getfoldertree(root=/My/Meta/Path, outds=iwantthisdataset)
options notes source;
@param [in] root= the parent folder under which to return all contents
@param [out] outds= the dataset to create that contains the list of
directories
@param [in] mDebug= set to 1 to show debug messages in the log
<h4> SAS Macros </h4>
@version 9.4
@author Allan Bowe
@@ -17163,6 +17191,7 @@ filename __mc2 clear;
<h4> SAS Macros </h4>
@li mf_getuniquefileref.sas
@li mp_abort.sas
@author Allan Bowe
@@ -17212,11 +17241,10 @@ data _null_;
else put (_all_)(=);
run;
%if &tsuri=stopifempty %then %do;
%put %str(WARN)ING: &tree&name.(StoredProcess) not found!;
%return;
%end;
%mp_abort(iftrue= (&tsuri=stopifempty)
,mac=mm_getstpcode
,msg=%str(&tree&name.(StoredProcess) not found!)
)
/**
* Now we can extract the textstore
@@ -19078,6 +19106,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`|
<h4> SAS Macros </h4>
@li mf_getuniquefileref.sas
@li mf_getuniquelibref.sas
@li mp_abort.sas
<h4> Related Files </h4>
@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
@@ -19804,18 +19954,19 @@ data _null_;
put '%end; ';
put '%mend mp_jsonout; ';
put ' ';
put '%macro mf_getuser(type=META ';
put '%macro mf_getuser( ';
put ')/*/STORE SOURCE*/; ';
put ' %local user metavar; ';
put ' %if &type=OS %then %let metavar=_secureusername; ';
put ' %else %let metavar=_metaperson; ';
put ' %local user; ';
put ' ';
put ' %if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %let user=&SYS_COMPUTE_SESSION_OWNER; ';
put ' %else %if %symexist(&metavar) %then %do; ';
put ' %if %length(&&&metavar)=0 %then %let user=&sysuserid; ';
put ' %if %symexist(_sasjs_username) %then %let user=&_sasjs_username; ';
put ' %else %if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %do; ';
put ' %let user=&SYS_COMPUTE_SESSION_OWNER; ';
put ' %end; ';
put ' %else %if %symexist(_metaperson) %then %do; ';
put ' %if %length(&_metaperson)=0 %then %let user=&sysuserid; ';
put ' /* sometimes SAS will add @domain extension - remove for consistency */ ';
put ' /* but be sure to quote in case of usernames with commas */ ';
put ' %else %let user=%unquote(%scan(%quote(&&&metavar),1,@)); ';
put ' %else %let user=%unquote(%scan(%quote(&_metaperson),1,@)); ';
put ' %end; ';
put ' %else %let user=&sysuserid; ';
put ' ';
@@ -20123,13 +20274,24 @@ 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 on username:
%ms_getgroups(outds=userlist, user=James)
With filter on userid:
%ms_getgroups(outds=userlist, uid=1)
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
@param [in] user= (0) Provide the username on which to filter
@param [in] uid= (0) Provide the userid 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.|
@@ -20146,22 +20308,38 @@ filename &headref clear;
<h4> Related Files </h4>
@li ms_creategroup.sas
@li ms_getusers.test.sas
@li ms_getgroups.test.sas
**/
%macro ms_getgroups(
outds=work.ms_getgroups
,mdebug=0
);
user=0,
uid=0,
outds=work.ms_getgroups,
mdebug=0
);
%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 */
data &outds;
length NAME $32 DESCRIPTION $64. GROUPID 8;
name="&sysuserid";
description="&sysuserid (group - desktop mode)";
groupid=1;
output;
stop;
run;
%return;
%end;
%let fref0=%mf_getuniquefileref();
%let fref1=%mf_getuniquefileref();
%let libref=%mf_getuniquelibref();
@@ -20186,8 +20364,13 @@ run;
run;
%end;
%if "&user" ne "0" %then %let url=/SASjsApi/user/by/username/&user;
%else %if "&uid" ne "0" %then %let url=/SASjsApi/user/&uid;
%else %let url=/SASjsApi/group;
proc http method='GET' headerin=&fref0 out=&fref1
url="&_sasjs_apiserverurl/SASjsApi/group";
url="&_sasjs_apiserverurl.&url";
%if &mdebug=1 %then %do;
debug level=1;
%end;
@@ -20196,21 +20379,31 @@ 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" and "&uid"="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)
,mac=ms_getusers.sas
,mac=ms_getgroups.sas
,msg=%str(Issue reading response JSON)
)
@@ -20228,16 +20421,26 @@ 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 by group name:
%ms_getusers(outds=work.groupmembers, group=GROUPNAME)
Filtering for a group by group id:
%ms_getusers(outds=work.groupmembers, gid=1)
@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 [in] gid= (0) Set to a group id 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`|
@@ -20246,7 +20449,6 @@ options &optval;
|`New User `|`newuser `|`5`|
<h4> SAS Macros </h4>
@li mf_getuniquefileref.sas
@li mf_getuniquelibref.sas
@@ -20254,14 +20456,17 @@ options &optval;
<h4> Related Files </h4>
@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,
gid=0,
mdebug=0
);
%mp_abort(
iftrue=(&syscc ne 0)
@@ -20269,11 +20474,24 @@ 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();
%if %sysget(MODE)=desktop %then %do;
/* users api does not exist in desktop mode */
data &outds;
length DISPLAYNAME $60 USERNAME:$30 ID 8;
USERNAME="&sysuserid";
DISPLAYNAME="&sysuserid (desktop mode)";
ID=1;
output;
stop;
run;
%return;
%end;
/* avoid sending bom marker to API */
%let optval=%sysfunc(getoption(bomfile));
options nobomfile;
@@ -20294,26 +20512,40 @@ run;
run;
%end;
%if "&group" ne "0" %then %let url=/SASjsApi/group/by/groupname/&group;
%else %if "&gid" ne "0" %then %let url=/SASjsApi/group/&gid;
%else %let url=/SASjsApi/user;
proc http method='GET' headerin=&fref0 out=&fref1
url="&_sasjs_apiserverurl/SASjsApi/user";
url="&_sasjs_apiserverurl.&url";
%if &mdebug=1 %then %do;
debug level=1;
%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" and "&gid"="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;
%end;
%mp_abort(
iftrue=(&syscc ne 0)
@@ -22065,18 +22297,19 @@ data _null_;
put '%end; ';
put '%mend mp_jsonout; ';
put ' ';
put '%macro mf_getuser(type=META ';
put '%macro mf_getuser( ';
put ')/*/STORE SOURCE*/; ';
put ' %local user metavar; ';
put ' %if &type=OS %then %let metavar=_secureusername; ';
put ' %else %let metavar=_metaperson; ';
put ' %local user; ';
put ' ';
put ' %if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %let user=&SYS_COMPUTE_SESSION_OWNER; ';
put ' %else %if %symexist(&metavar) %then %do; ';
put ' %if %length(&&&metavar)=0 %then %let user=&sysuserid; ';
put ' %if %symexist(_sasjs_username) %then %let user=&_sasjs_username; ';
put ' %else %if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %do; ';
put ' %let user=&SYS_COMPUTE_SESSION_OWNER; ';
put ' %end; ';
put ' %else %if %symexist(_metaperson) %then %do; ';
put ' %if %length(&_metaperson)=0 %then %let user=&sysuserid; ';
put ' /* sometimes SAS will add @domain extension - remove for consistency */ ';
put ' /* but be sure to quote in case of usernames with commas */ ';
put ' %else %let user=%unquote(%scan(%quote(&&&metavar),1,@)); ';
put ' %else %let user=%unquote(%scan(%quote(&_metaperson),1,@)); ';
put ' %end; ';
put ' %else %let user=&sysuserid; ';
put ' ';
@@ -26979,8 +27212,8 @@ Usage:
%if &platform=SASJS %then %do;
%ms_getfile(&loc..sas, outref=&outref)
%end;
%else %if &platform=SAS9 %then %do;
%mm_getstpcode(tree=&loc,outloc=&outref)
%else %if &platform=SAS9 or &platform=SASMETA %then %do;
%mm_getstpcode(tree=&loc,outref=&outref)
%end;
%else %if &platform=SASVIYA %then %do;
/* extract name & path from &loc */

View File

@@ -6,9 +6,6 @@
%put %mf_existVarList(sashelp.class, age sex name dummyvar);
<h4> SAS Macros </h4>
@li mf_abort.sas
@param libds 2 part dataset or view reference
@param varlist space separated variable names

View File

@@ -23,18 +23,19 @@
@author Allan Bowe
**/
%macro mf_getuser(type=META
%macro mf_getuser(
)/*/STORE SOURCE*/;
%local user metavar;
%if &type=OS %then %let metavar=_secureusername;
%else %let metavar=_metaperson;
%local user;
%if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %let user=&SYS_COMPUTE_SESSION_OWNER;
%else %if %symexist(&metavar) %then %do;
%if %length(&&&metavar)=0 %then %let user=&sysuserid;
%if %symexist(_sasjs_username) %then %let user=&_sasjs_username;
%else %if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %do;
%let user=&SYS_COMPUTE_SESSION_OWNER;
%end;
%else %if %symexist(_metaperson) %then %do;
%if %length(&_metaperson)=0 %then %let user=&sysuserid;
/* sometimes SAS will add @domain extension - remove for consistency */
/* but be sure to quote in case of usernames with commas */
%else %let user=%unquote(%scan(%quote(&&&metavar),1,@));
%else %let user=%unquote(%scan(%quote(&_metaperson),1,@));
%end;
%else %let user=&sysuserid;

View File

@@ -15,16 +15,20 @@
recognise this and fetch the log of the parent session instead)
@li STP environments must finish cleanly to avoid the log being sent to
_webout. To assist with this, we also run stpsrvset('program error', 0)
and set SYSCC=0. We take a unique "soft abort" approach - we open a macro
and set SYSCC=0.
Where possible, we take a unique "soft abort" approach - we open a macro
but don't close it! This works everywhere EXCEPT inside a \%include inside
a macro. For that, we recommend you use mp_include.sas to perform the
include, and then call \%mp_abort(mode=INCLUDE) from the source program (ie,
OUTSIDE of the top-parent macro).
The soft abort has also been found to be ineffective in 9.4m6 windows
environments and above, so in these cases, endsas is used.
@param mac= to contain the name of the calling macro
@param mac= (mp_abort.sas) To contain the name of the calling macro. Do not
use &sysmacroname as this will always resolve to MP_ABORT.
@param msg= message to be returned
@param iftrue= supply a condition under which the macro should be executed.
@param iftrue= (1=1) Supply a condition for which the macro should be executed
@param errds= (work.mp_abort_errds) There is no clean way to end a process
within a %include called within a macro. Furthermore, there is no way to
test if a macro is called within a %include. To handle this particular
@@ -45,11 +49,12 @@
@li REGULAR (default)
@li INCLUDE
@version 9.4
@author Allan Bowe
<h4> Related Macros </h4>
@li mp_include.sas
@version 9.4
@author Allan Bowe
@cond
**/
@@ -58,7 +63,8 @@
, mode=REGULAR
)/*/STORE SOURCE*/;
%global sysprocessmode sysprocessname;
%global sysprocessmode sysprocessname sasjs_stpsrv_header_loc;
%local fref fid i;
%if not(%eval(%unquote(&iftrue))) %then %return;
@@ -68,7 +74,7 @@
%if %symexist(_SYSINCLUDEFILEDEVICE)
/* abort cancel FILE does not restart outside the INCLUDE on Viya 3.5 */
and "&SYSPROCESSNAME " ne "Compute Server "
and %superq(SYSPROCESSNAME) ne %str(Compute Server)
%then %do;
%if "*&_SYSINCLUDEFILEDEVICE*" ne "**" %then %do;
data &errds;
@@ -86,7 +92,7 @@
/* Web App Context */
%if %symexist(_PROGRAM)
or "&SYSPROCESSNAME "="Compute Server "
or %superq(SYSPROCESSNAME) = %str(Compute Server)
or &mode=INCLUDE
%then %do;
options obs=max replace mprint;
@@ -152,8 +158,8 @@
%end;
%if %symexist(SYS_JES_JOB_URI) %then %do;
/* setup webout */
OPTIONS NOBOMFILE;
/* setup webout for Viya */
options nobomfile;
%if "X&SYS_JES_JOB_URI.X"="XX" %then %do;
filename _webout temp lrecl=999999 mod;
%end;
@@ -162,11 +168,24 @@
name="_webout.json" lrecl=999999 mod;
%end;
%end;
%else %if %sysfunc(filename(fref,&sasjs_stpsrv_header_loc))=0 %then %do;
options nobomfile;
/* set up http header for SASjs Server */
%let fid=%sysfunc(fopen(&fref,A));
%if &fid=0 %then %do;
%put %str(ERR)OR: %sysfunc(sysmsg());
%return;
%end;
%let rc=%sysfunc(fput(&fid,%str(Content-Type: application/json)));
%let rc=%sysfunc(fwrite(&fid));
%let rc=%sysfunc(fclose(&fid));
%let rc=%sysfunc(filename(&fref));
%end;
/* send response in SASjs JSON format */
data _null_;
file _webout mod lrecl=32000 encoding='utf-8';
length msg syswarningtext syserrortext $32767 ;
length msg syswarningtext syserrortext $32767 mode $10 ;
sasdatetime=datetime();
msg=symget('msg');
%if &logline>0 %then %do;
@@ -182,7 +201,8 @@
msg=cats('"',msg,'"');
if symexist('_debug') then debug=quote(trim(symget('_debug')));
else debug='""';
put '>>weboutBEGIN<<';
if symget('sasjsprocessmode')='Stored Program' then mode='SASJS';
if mode ne 'SASJS' then put '>>weboutBEGIN<<';
put '{"SYSDATE" : "' "&SYSDATE" '"';
put ',"SYSTIME" : "' "&SYSTIME" '"';
put ',"sasjsAbort" : [{';
@@ -214,8 +234,8 @@
syswarningtext=quote(trim(symget('syswarningtext')));
put ",""SYSWARNINGTEXT"" : " syswarningtext;
put ',"END_DTTM" : "' "%sysfunc(datetime(),E8601DT26.6)" '" ';
put "}" @;
put '>>weboutEND<<';
put "}" ;
if mode ne 'SASJS' then put '>>weboutEND<<';
run;
%put _all_;
@@ -226,22 +246,30 @@
rc=stpsrvset('program error', 0);
call symputx("syscc",0,"g");
run;
/**
* endsas kills 9.4m3 deployments by orphaning multibridges.
* Abort variants are ungraceful (non zero return code)
* This approach lets SAS run silently until the end :-)
* Caution - fails when called within a %include within a macro
* Use mp_include() to handle this.
*/
filename skip temp;
data _null_;
file skip;
put '%macro skip();';
comment '%mend skip; -> fix lint ';
put '%macro skippy();';
comment '%mend skippy; -> fix lint ';
run;
%inc skip;
%if &sysscp=WIN
and "%substr(%str(&sysvlong ),1,8)"="9.04.01M"
and "%substr(%str(&sysvlong ),9,1)">"5" %then %do;
/* skip approach (below) does not work in windows m6+ envs */
endsas;
%end;
%else %do;
/**
* endsas kills 9.4m3 deployments by orphaning multibridges.
* Abort variants are ungraceful (non zero return code)
* This approach lets SAS run silently until the end :-)
* Caution - fails when called within a %include within a macro
* Use mp_include() to handle this.
*/
filename skip temp;
data _null_;
file skip;
put '%macro skip();';
comment '%mend skip; -> fix lint ';
put '%macro skippy();';
comment '%mend skippy; -> fix lint ';
run;
%inc skip;
%end;
%end;
%else %if "&sysprocessmode " = "SAS Compute Server " %then %do;
/* endsas kills the session making it harder to fetch results */

View File

@@ -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
<h4> Related Files </h4>
@li ms_adduser2group.sas
@version 9.3
@author Allan Bowe

View File

@@ -315,18 +315,19 @@ data _null_;
put '%end; ';
put '%mend mp_jsonout; ';
put ' ';
put '%macro mf_getuser(type=META ';
put '%macro mf_getuser( ';
put ')/*/STORE SOURCE*/; ';
put ' %local user metavar; ';
put ' %if &type=OS %then %let metavar=_secureusername; ';
put ' %else %let metavar=_metaperson; ';
put ' %local user; ';
put ' ';
put ' %if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %let user=&SYS_COMPUTE_SESSION_OWNER; ';
put ' %else %if %symexist(&metavar) %then %do; ';
put ' %if %length(&&&metavar)=0 %then %let user=&sysuserid; ';
put ' %if %symexist(_sasjs_username) %then %let user=&_sasjs_username; ';
put ' %else %if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %do; ';
put ' %let user=&SYS_COMPUTE_SESSION_OWNER; ';
put ' %end; ';
put ' %else %if %symexist(_metaperson) %then %do; ';
put ' %if %length(&_metaperson)=0 %then %let user=&sysuserid; ';
put ' /* sometimes SAS will add @domain extension - remove for consistency */ ';
put ' /* but be sure to quote in case of usernames with commas */ ';
put ' %else %let user=%unquote(%scan(%quote(&&&metavar),1,@)); ';
put ' %else %let user=%unquote(%scan(%quote(&_metaperson),1,@)); ';
put ' %end; ';
put ' %else %let user=&sysuserid; ';
put ' ';

View File

@@ -8,17 +8,15 @@
Usage:
options ps=max nonotes nosource;
%mm_getfoldertree(root=/My/Meta/Path, outds=iwantthisdataset)
options notes source;
options ps=max nonotes nosource;
%mm_getfoldertree(root=/My/Meta/Path, outds=iwantthisdataset)
options notes source;
@param [in] root= the parent folder under which to return all contents
@param [out] outds= the dataset to create that contains the list of
directories
@param [in] mDebug= set to 1 to show debug messages in the log
<h4> SAS Macros </h4>
@version 9.4
@author Allan Bowe

View File

@@ -21,6 +21,7 @@
<h4> SAS Macros </h4>
@li mf_getuniquefileref.sas
@li mp_abort.sas
@author Allan Bowe
@@ -70,11 +71,10 @@ data _null_;
else put (_all_)(=);
run;
%if &tsuri=stopifempty %then %do;
%put %str(WARN)ING: &tree&name.(StoredProcess) not found!;
%return;
%end;
%mp_abort(iftrue= (&tsuri=stopifempty)
,mac=mm_getstpcode
,msg=%str(&tree&name.(StoredProcess) not found!)
)
/**
* Now we can extract the textstore

View File

@@ -67,7 +67,7 @@
},
{
"name": "server",
"serverUrl": "https://sas.analytium.co.uk:5007",
"serverUrl": "https://sas.4gl.io",
"serverType": "SASJS",
"httpsAgentOptions": {
"allowInsecureRequests": false
@@ -107,4 +107,4 @@
"contextName": "SAS Job Execution compute context"
}
]
}
}

122
server/ms_adduser2group.sas Normal file
View File

@@ -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`|
<h4> SAS Macros </h4>
@li mf_getuniquefileref.sas
@li mf_getuniquelibref.sas
@li mp_abort.sas
<h4> Related Files </h4>
@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;

View File

@@ -317,18 +317,19 @@ data _null_;
put '%end; ';
put '%mend mp_jsonout; ';
put ' ';
put '%macro mf_getuser(type=META ';
put '%macro mf_getuser( ';
put ')/*/STORE SOURCE*/; ';
put ' %local user metavar; ';
put ' %if &type=OS %then %let metavar=_secureusername; ';
put ' %else %let metavar=_metaperson; ';
put ' %local user; ';
put ' ';
put ' %if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %let user=&SYS_COMPUTE_SESSION_OWNER; ';
put ' %else %if %symexist(&metavar) %then %do; ';
put ' %if %length(&&&metavar)=0 %then %let user=&sysuserid; ';
put ' %if %symexist(_sasjs_username) %then %let user=&_sasjs_username; ';
put ' %else %if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %do; ';
put ' %let user=&SYS_COMPUTE_SESSION_OWNER; ';
put ' %end; ';
put ' %else %if %symexist(_metaperson) %then %do; ';
put ' %if %length(&_metaperson)=0 %then %let user=&sysuserid; ';
put ' /* sometimes SAS will add @domain extension - remove for consistency */ ';
put ' /* but be sure to quote in case of usernames with commas */ ';
put ' %else %let user=%unquote(%scan(%quote(&&&metavar),1,@)); ';
put ' %else %let user=%unquote(%scan(%quote(&_metaperson),1,@)); ';
put ' %end; ';
put ' %else %let user=&sysuserid; ';
put ' ';

View File

@@ -2,13 +2,24 @@
@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 on username:
%ms_getgroups(outds=userlist, user=James)
With filter on userid:
%ms_getgroups(outds=userlist, uid=1)
@param [in] mdebug= (0) Set to 1 to enable DEBUG messages
@param [in] user= (0) Provide the username on which to filter
@param [in] uid= (0) Provide the userid 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.|
@@ -25,22 +36,38 @@
<h4> Related Files </h4>
@li ms_creategroup.sas
@li ms_getusers.test.sas
@li ms_getgroups.test.sas
**/
%macro ms_getgroups(
outds=work.ms_getgroups
,mdebug=0
);
user=0,
uid=0,
outds=work.ms_getgroups,
mdebug=0
);
%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 */
data &outds;
length NAME $32 DESCRIPTION $64. GROUPID 8;
name="&sysuserid";
description="&sysuserid (group - desktop mode)";
groupid=1;
output;
stop;
run;
%return;
%end;
%let fref0=%mf_getuniquefileref();
%let fref1=%mf_getuniquefileref();
%let libref=%mf_getuniquelibref();
@@ -65,8 +92,13 @@ run;
run;
%end;
%if "&user" ne "0" %then %let url=/SASjsApi/user/by/username/&user;
%else %if "&uid" ne "0" %then %let url=/SASjsApi/user/&uid;
%else %let url=/SASjsApi/group;
proc http method='GET' headerin=&fref0 out=&fref1
url="&_sasjs_apiserverurl/SASjsApi/group";
url="&_sasjs_apiserverurl.&url";
%if &mdebug=1 %then %do;
debug level=1;
%end;
@@ -75,21 +107,31 @@ 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" and "&uid"="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)
,mac=ms_getusers.sas
,mac=ms_getgroups.sas
,msg=%str(Issue reading response JSON)
)

View File

@@ -2,16 +2,26 @@
@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 by group name:
%ms_getusers(outds=work.groupmembers, group=GROUPNAME)
Filtering for a group by group id:
%ms_getusers(outds=work.groupmembers, gid=1)
@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 [in] gid= (0) Set to a group id 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`|
@@ -20,7 +30,6 @@
|`New User `|`newuser `|`5`|
<h4> SAS Macros </h4>
@li mf_getuniquefileref.sas
@li mf_getuniquelibref.sas
@@ -28,14 +37,17 @@
<h4> Related Files </h4>
@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,
gid=0,
mdebug=0
);
%mp_abort(
iftrue=(&syscc ne 0)
@@ -43,11 +55,24 @@
,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();
%if %sysget(MODE)=desktop %then %do;
/* users api does not exist in desktop mode */
data &outds;
length DISPLAYNAME $60 USERNAME:$30 ID 8;
USERNAME="&sysuserid";
DISPLAYNAME="&sysuserid (desktop mode)";
ID=1;
output;
stop;
run;
%return;
%end;
/* avoid sending bom marker to API */
%let optval=%sysfunc(getoption(bomfile));
options nobomfile;
@@ -68,26 +93,40 @@ run;
run;
%end;
%if "&group" ne "0" %then %let url=/SASjsApi/group/by/groupname/&group;
%else %if "&gid" ne "0" %then %let url=/SASjsApi/group/&gid;
%else %let url=/SASjsApi/user;
proc http method='GET' headerin=&fref0 out=&fref1
url="&_sasjs_apiserverurl/SASjsApi/user";
url="&_sasjs_apiserverurl.&url";
%if &mdebug=1 %then %do;
debug level=1;
%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" and "&gid"="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;
%end;
%mp_abort(
iftrue=(&syscc ne 0)

View File

@@ -0,0 +1,52 @@
/**
@file
@brief Testing ms_adduser2group.sas macro
<h4> SAS Macros </h4>
@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
)

View File

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

View File

@@ -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 upcase(username)="%upcase(&user)";
call symputx('checkid',id);
run;
%mp_assert(

View File

@@ -3,21 +3,64 @@
@brief Testing ms_getgroups.sas macro
<h4> SAS Macros </h4>
@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;
%put &=group;
data _null_;
set work.test1;
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;
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
)

View File

@@ -3,6 +3,8 @@
@brief Testing ms_getusers.sas macro
<h4> SAS Macros </h4>
@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
)

View File

@@ -34,7 +34,7 @@ options mprint;
)
%mp_assertscope(COMPARE)
libname webeen json (weboot);
libname webeen json fileref=weboot;
data _null_;
infile weboot;

View File

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

View File

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

View File

@@ -459,18 +459,19 @@ data _null_;
put '%end; ';
put '%mend mp_jsonout; ';
put ' ';
put '%macro mf_getuser(type=META ';
put '%macro mf_getuser( ';
put ')/*/STORE SOURCE*/; ';
put ' %local user metavar; ';
put ' %if &type=OS %then %let metavar=_secureusername; ';
put ' %else %let metavar=_metaperson; ';
put ' %local user; ';
put ' ';
put ' %if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %let user=&SYS_COMPUTE_SESSION_OWNER; ';
put ' %else %if %symexist(&metavar) %then %do; ';
put ' %if %length(&&&metavar)=0 %then %let user=&sysuserid; ';
put ' %if %symexist(_sasjs_username) %then %let user=&_sasjs_username; ';
put ' %else %if %symexist(SYS_COMPUTE_SESSION_OWNER) %then %do; ';
put ' %let user=&SYS_COMPUTE_SESSION_OWNER; ';
put ' %end; ';
put ' %else %if %symexist(_metaperson) %then %do; ';
put ' %if %length(&_metaperson)=0 %then %let user=&sysuserid; ';
put ' /* sometimes SAS will add @domain extension - remove for consistency */ ';
put ' /* but be sure to quote in case of usernames with commas */ ';
put ' %else %let user=%unquote(%scan(%quote(&&&metavar),1,@)); ';
put ' %else %let user=%unquote(%scan(%quote(&_metaperson),1,@)); ';
put ' %end; ';
put ' %else %let user=&sysuserid; ';
put ' ';

View File

@@ -34,8 +34,8 @@
%if &platform=SASJS %then %do;
%ms_getfile(&loc..sas, outref=&outref)
%end;
%else %if &platform=SAS9 %then %do;
%mm_getstpcode(tree=&loc,outloc=&outref)
%else %if &platform=SAS9 or &platform=SASMETA %then %do;
%mm_getstpcode(tree=&loc,outref=&outref)
%end;
%else %if &platform=SASVIYA %then %do;
/* extract name & path from &loc */