mirror of
https://github.com/sasjs/core.git
synced 2026-01-09 18:30:06 +00:00
Merge pull request #29 from sasjs/issue10
fix: adding checks for consul token access, and two tests to ensure t…
This commit is contained in:
65
all.sas
65
all.sas
@@ -16932,14 +16932,22 @@ run;
|
|||||||
%mend mv_jobwaitfor;/**
|
%mend mv_jobwaitfor;/**
|
||||||
@file mv_registerclient.sas
|
@file mv_registerclient.sas
|
||||||
@brief Register Client and Secret (admin task)
|
@brief Register Client and Secret (admin task)
|
||||||
@details When building apps on SAS Viya, an client id and secret is required.
|
@details When building apps on SAS Viya, an client id and secret are sometimes
|
||||||
This macro will obtain the Consul Token and use that to call the Web Service.
|
required. In order to generate them, filesystem access to the Consul Token
|
||||||
|
is needed (it is not enough to be in the SASAdministrator group in SAS
|
||||||
|
Environment Manager).
|
||||||
|
|
||||||
more info: https://developer.sas.com/reference/auth/#register
|
If you are registering a lot of clients / secrets, you may find it more
|
||||||
and:
|
convenient to use the [Viya Token Generator]
|
||||||
http://proc-x.com/2019/01/authentication-to-sas-viya-a-couple-of-approaches
|
(https://sasjs.io/apps/#viya-client-token-generator) (a SASjs Web App to
|
||||||
|
automate the generation of clients & secrets with various settings).
|
||||||
|
|
||||||
The default viyaroot location is /opt/sas/viya/config
|
For further information on clients / secrets, see;
|
||||||
|
@li https://developer.sas.com/reference/auth/#register
|
||||||
|
@li https://proc-x.com/2019/01/authentication-to-sas-viya-a-couple-of-approaches
|
||||||
|
@li https://cli.sasjs.io/faq/#how-can-i-obtain-a-viya-client-and-secret
|
||||||
|
|
||||||
|
The default viyaroot location is: `/opt/sas/viya/config`
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
@@ -16964,16 +16972,19 @@ run;
|
|||||||
)
|
)
|
||||||
|
|
||||||
@param client_id= The client name. Auto generated if blank.
|
@param client_id= The client name. Auto generated if blank.
|
||||||
@param client_secret= Client secret Auto generated if client is blank.
|
@param client_secret= Client secret. Auto generated if client is blank.
|
||||||
@param scopes= list of space-seperated unquoted scopes (default is openid)
|
@param scopes=(openid) List of space-seperated unquoted scopes
|
||||||
@param grant_type= valid values are "password" or "authorization_code"
|
@param grant_type=(authorization_code|refresh_token) Valid values are
|
||||||
(unquoted)
|
"password" or "authorization_code" (unquoted)
|
||||||
@param outds= the dataset to contain the registered client id and secret
|
@param outds=(mv_registerclient) The dataset to contain the registered client
|
||||||
@param access_token_validity= The duration of validity of the access token
|
id and secret
|
||||||
in seconds. A value of DEFAULT will omit the entry (and use system default)
|
@param access_token_validity=(DEFAULT) The duration of validity of the access
|
||||||
@param refresh_token_validity= The duration of validity of the refresh token
|
token in seconds. A value of DEFAULT will omit the entry (and use system
|
||||||
in seconds. A value of DEFAULT will omit the entry (and use system default)
|
default)
|
||||||
@param name= A human readable name for the client
|
@param refresh_token_validity=(DEFAULT) The duration of validity of the
|
||||||
|
refresh token in seconds. A value of DEFAULT will omit the entry (and use
|
||||||
|
system default)
|
||||||
|
@param name= An optional, human readable name for the client
|
||||||
@param required_user_groups= A list of group names. If a user does not belong
|
@param required_user_groups= A list of group names. If a user does not belong
|
||||||
to all the required groups, the user will not be authenticated and no tokens
|
to all the required groups, the user will not be authenticated and no tokens
|
||||||
are issued to this client for that user. If this field is not specified,
|
are issued to this client for that user. If this field is not specified,
|
||||||
@@ -16982,8 +16993,8 @@ run;
|
|||||||
apply. Setting this to true will autoapprove all the client scopes.
|
apply. Setting this to true will autoapprove all the client scopes.
|
||||||
@param use_session= If true, access tokens issued to this client will be
|
@param use_session= If true, access tokens issued to this client will be
|
||||||
associated with an HTTP session and revoked upon logout or time-out.
|
associated with an HTTP session and revoked upon logout or time-out.
|
||||||
@param outjson= A dataset containing the lines of JSON submitted. Useful
|
@param outjson= (_null_) A dataset containing the lines of JSON submitted.
|
||||||
for debugging. Default= _null_.
|
Useful for debugging.
|
||||||
|
|
||||||
@version VIYA V.03.04
|
@version VIYA V.03.04
|
||||||
@author Allan Bowe, source: https://github.com/sasjs/core
|
@author Allan Bowe, source: https://github.com/sasjs/core
|
||||||
@@ -17020,12 +17031,26 @@ run;
|
|||||||
options noquotelenmax;
|
options noquotelenmax;
|
||||||
/* first, get consul token needed to get client id / secret */
|
/* first, get consul token needed to get client id / secret */
|
||||||
%let tokloc=/etc/SASSecurityCertificateFramework/tokens/consul/default;
|
%let tokloc=/etc/SASSecurityCertificateFramework/tokens/consul/default;
|
||||||
|
%let tokloc=%mf_loc(VIYACONFIG)&tokloc/client.token;
|
||||||
|
|
||||||
|
|
||||||
|
%mp_abort(iftrue=(%sysfunc(fileexist(&tokloc))=0)
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(Unable to access the consul token at &tokloc)
|
||||||
|
)
|
||||||
|
|
||||||
|
%let consul_token=0;
|
||||||
data _null_;
|
data _null_;
|
||||||
infile "%mf_loc(VIYACONFIG)&tokloc/client.token";
|
infile "&tokloc";
|
||||||
input token:$64.;
|
input token:$64.;
|
||||||
call symputx('consul_token',token);
|
call symputx('consul_token',token);
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
%mp_abort(iftrue=("&consul_token"="0")
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(Unable to source the consul token from &tokloc)
|
||||||
|
)
|
||||||
|
|
||||||
%local base_uri; /* location of rest apis */
|
%local base_uri; /* location of rest apis */
|
||||||
%let base_uri=%mf_getplatform(VIYARESTAPI);
|
%let base_uri=%mf_getplatform(VIYARESTAPI);
|
||||||
|
|
||||||
@@ -17172,7 +17197,7 @@ filename &fname2 clear;
|
|||||||
filename &fname3 clear;
|
filename &fname3 clear;
|
||||||
libname &libref clear;
|
libname &libref clear;
|
||||||
|
|
||||||
%mend;
|
%mend mv_registerclient;
|
||||||
/**
|
/**
|
||||||
@file mv_tokenauth.sas
|
@file mv_tokenauth.sas
|
||||||
@brief Get initial Refresh and Access Tokens
|
@brief Get initial Refresh and Access Tokens
|
||||||
|
|||||||
36
tests/viya/mv_registerclient.test.1.sas
Normal file
36
tests/viya/mv_registerclient.test.1.sas
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
|
||||||
|
@file
|
||||||
|
@brief Testing mv_registerclient.sas macro
|
||||||
|
@details Tests for successful registration. For this to work, the test
|
||||||
|
account must be an admin.
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mf_getuniquename.sas
|
||||||
|
@li mp_assertcolvals.sas
|
||||||
|
@li mv_registerclient.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Case 1
|
||||||
|
*/
|
||||||
|
|
||||||
|
%let id=%mf_getuniquename();
|
||||||
|
%let sec=%mf_getuniquename();
|
||||||
|
%mv_registerclient(client_id=&id,client_secret=&sec, outds=testds)
|
||||||
|
|
||||||
|
data work.checkds;
|
||||||
|
id="&id";
|
||||||
|
sec="&sec";
|
||||||
|
run;
|
||||||
|
%mp_assertcolvals(work.testds.client_id,
|
||||||
|
checkvals=work.checkds.id,
|
||||||
|
desc=Checking client id was created
|
||||||
|
test=ALLVALS
|
||||||
|
)
|
||||||
|
%mp_assertcolvals(work.testds.client_secret,
|
||||||
|
checkvals=work.checkds.sec,
|
||||||
|
desc=Checking client secret was created
|
||||||
|
test=ALLVALS
|
||||||
|
)
|
||||||
43
tests/viya/mv_registerclient.test.2.sas
Normal file
43
tests/viya/mv_registerclient.test.2.sas
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/**
|
||||||
|
|
||||||
|
@file
|
||||||
|
@brief Testing mv_registerclient.sas macro
|
||||||
|
@details Tests for unsuccessful registration. To do this, overrides are
|
||||||
|
applied for the mf_loc.sas and mp_abort.sas macros.
|
||||||
|
|
||||||
|
<h4> SAS Macros </h4>
|
||||||
|
@li mp_assert.sas
|
||||||
|
@li mv_registerclient.sas
|
||||||
|
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Case
|
||||||
|
*/
|
||||||
|
|
||||||
|
%macro mf_loc(param);
|
||||||
|
/does/not/exist
|
||||||
|
%mend mf_loc;
|
||||||
|
|
||||||
|
%macro mp_abort(iftrue=,mac=mp_abort.sas, type=, msg=);
|
||||||
|
%if not(%eval(%unquote(&iftrue))) %then %return;
|
||||||
|
%put %substr(&msg,1,16);
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=("%substr(&msg,1,16)"="Unable to access"),
|
||||||
|
desc=Check that abort happens when consul token is unavailable
|
||||||
|
)
|
||||||
|
%webout(OPEN)
|
||||||
|
%webout(OBJ, TEST_RESULTS)
|
||||||
|
%webout(CLOSE)
|
||||||
|
%let syscc=0;
|
||||||
|
data _null_;
|
||||||
|
abort cancel nolist;
|
||||||
|
run;
|
||||||
|
%mend mp_abort;
|
||||||
|
|
||||||
|
%mv_registerclient( outds=testds)
|
||||||
|
|
||||||
|
%mp_assert(
|
||||||
|
iftrue=(0=1),
|
||||||
|
desc=Check that abort happens when consul token is unavailable
|
||||||
|
)
|
||||||
@@ -1,14 +1,22 @@
|
|||||||
/**
|
/**
|
||||||
@file mv_registerclient.sas
|
@file mv_registerclient.sas
|
||||||
@brief Register Client and Secret (admin task)
|
@brief Register Client and Secret (admin task)
|
||||||
@details When building apps on SAS Viya, an client id and secret is required.
|
@details When building apps on SAS Viya, an client id and secret are sometimes
|
||||||
This macro will obtain the Consul Token and use that to call the Web Service.
|
required. In order to generate them, filesystem access to the Consul Token
|
||||||
|
is needed (it is not enough to be in the SASAdministrator group in SAS
|
||||||
|
Environment Manager).
|
||||||
|
|
||||||
more info: https://developer.sas.com/reference/auth/#register
|
If you are registering a lot of clients / secrets, you may find it more
|
||||||
and:
|
convenient to use the [Viya Token Generator]
|
||||||
http://proc-x.com/2019/01/authentication-to-sas-viya-a-couple-of-approaches
|
(https://sasjs.io/apps/#viya-client-token-generator) (a SASjs Web App to
|
||||||
|
automate the generation of clients & secrets with various settings).
|
||||||
|
|
||||||
The default viyaroot location is /opt/sas/viya/config
|
For further information on clients / secrets, see;
|
||||||
|
@li https://developer.sas.com/reference/auth/#register
|
||||||
|
@li https://proc-x.com/2019/01/authentication-to-sas-viya-a-couple-of-approaches
|
||||||
|
@li https://cli.sasjs.io/faq/#how-can-i-obtain-a-viya-client-and-secret
|
||||||
|
|
||||||
|
The default viyaroot location is: `/opt/sas/viya/config`
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
@@ -33,16 +41,19 @@
|
|||||||
)
|
)
|
||||||
|
|
||||||
@param client_id= The client name. Auto generated if blank.
|
@param client_id= The client name. Auto generated if blank.
|
||||||
@param client_secret= Client secret Auto generated if client is blank.
|
@param client_secret= Client secret. Auto generated if client is blank.
|
||||||
@param scopes= list of space-seperated unquoted scopes (default is openid)
|
@param scopes=(openid) List of space-seperated unquoted scopes
|
||||||
@param grant_type= valid values are "password" or "authorization_code"
|
@param grant_type=(authorization_code|refresh_token) Valid values are
|
||||||
(unquoted)
|
"password" or "authorization_code" (unquoted)
|
||||||
@param outds= the dataset to contain the registered client id and secret
|
@param outds=(mv_registerclient) The dataset to contain the registered client
|
||||||
@param access_token_validity= The duration of validity of the access token
|
id and secret
|
||||||
in seconds. A value of DEFAULT will omit the entry (and use system default)
|
@param access_token_validity=(DEFAULT) The duration of validity of the access
|
||||||
@param refresh_token_validity= The duration of validity of the refresh token
|
token in seconds. A value of DEFAULT will omit the entry (and use system
|
||||||
in seconds. A value of DEFAULT will omit the entry (and use system default)
|
default)
|
||||||
@param name= A human readable name for the client
|
@param refresh_token_validity=(DEFAULT) The duration of validity of the
|
||||||
|
refresh token in seconds. A value of DEFAULT will omit the entry (and use
|
||||||
|
system default)
|
||||||
|
@param name= An optional, human readable name for the client
|
||||||
@param required_user_groups= A list of group names. If a user does not belong
|
@param required_user_groups= A list of group names. If a user does not belong
|
||||||
to all the required groups, the user will not be authenticated and no tokens
|
to all the required groups, the user will not be authenticated and no tokens
|
||||||
are issued to this client for that user. If this field is not specified,
|
are issued to this client for that user. If this field is not specified,
|
||||||
@@ -51,8 +62,8 @@
|
|||||||
apply. Setting this to true will autoapprove all the client scopes.
|
apply. Setting this to true will autoapprove all the client scopes.
|
||||||
@param use_session= If true, access tokens issued to this client will be
|
@param use_session= If true, access tokens issued to this client will be
|
||||||
associated with an HTTP session and revoked upon logout or time-out.
|
associated with an HTTP session and revoked upon logout or time-out.
|
||||||
@param outjson= A dataset containing the lines of JSON submitted. Useful
|
@param outjson= (_null_) A dataset containing the lines of JSON submitted.
|
||||||
for debugging. Default= _null_.
|
Useful for debugging.
|
||||||
|
|
||||||
@version VIYA V.03.04
|
@version VIYA V.03.04
|
||||||
@author Allan Bowe, source: https://github.com/sasjs/core
|
@author Allan Bowe, source: https://github.com/sasjs/core
|
||||||
@@ -89,12 +100,26 @@
|
|||||||
options noquotelenmax;
|
options noquotelenmax;
|
||||||
/* first, get consul token needed to get client id / secret */
|
/* first, get consul token needed to get client id / secret */
|
||||||
%let tokloc=/etc/SASSecurityCertificateFramework/tokens/consul/default;
|
%let tokloc=/etc/SASSecurityCertificateFramework/tokens/consul/default;
|
||||||
|
%let tokloc=%mf_loc(VIYACONFIG)&tokloc/client.token;
|
||||||
|
|
||||||
|
|
||||||
|
%mp_abort(iftrue=(%sysfunc(fileexist(&tokloc))=0)
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(Unable to access the consul token at &tokloc)
|
||||||
|
)
|
||||||
|
|
||||||
|
%let consul_token=0;
|
||||||
data _null_;
|
data _null_;
|
||||||
infile "%mf_loc(VIYACONFIG)&tokloc/client.token";
|
infile "&tokloc";
|
||||||
input token:$64.;
|
input token:$64.;
|
||||||
call symputx('consul_token',token);
|
call symputx('consul_token',token);
|
||||||
run;
|
run;
|
||||||
|
|
||||||
|
%mp_abort(iftrue=("&consul_token"="0")
|
||||||
|
,mac=&sysmacroname
|
||||||
|
,msg=%str(Unable to source the consul token from &tokloc)
|
||||||
|
)
|
||||||
|
|
||||||
%local base_uri; /* location of rest apis */
|
%local base_uri; /* location of rest apis */
|
||||||
%let base_uri=%mf_getplatform(VIYARESTAPI);
|
%let base_uri=%mf_getplatform(VIYARESTAPI);
|
||||||
|
|
||||||
@@ -241,4 +266,4 @@ filename &fname2 clear;
|
|||||||
filename &fname3 clear;
|
filename &fname3 clear;
|
||||||
libname &libref clear;
|
libname &libref clear;
|
||||||
|
|
||||||
%mend;
|
%mend mv_registerclient;
|
||||||
|
|||||||
Reference in New Issue
Block a user