1010# '
1111# ' If neither of these approaches has returned a token, it will try to retrieve
1212# ' a user token using the provided parameters, requiring the user to have
13- # ' authenticated using their device.
13+ # ' authenticated using their device. If `force_refresh` is set to `TRUE`, a
14+ # ' fresh web authentication process should be launched. Otherwise it will
15+ # ' attempt to use a cached token matching the given `resource` and `tenant`.
1416# '
1517# ' @param resource A string specifying the URL of the Azure resource for which
1618# ' the token is requested. Defaults to `"https://storage.azure.com"`.
2729# ' `resource` value as an existing token, but a different `tenant` or
2830# ' `auth_method`.
2931# ' @param ... Optional arguments (`token_args` or `use_cache`) to be passed on
30- # ' to [AzureAuth::get_managed_token].
32+ # ' to [AzureAuth::get_managed_token] or [AzureAuth::get_azure_token] .
3133# '
3234# ' @returns An Azure token object
3335# ' @examples
4749# ' @export
4850get_auth_token <- function (
4951 resource = " https://storage.azure.com" ,
50- tenant = " organizations " ,
52+ tenant = " common " ,
5153 client_id = NULL ,
5254 auth_method = " authorization_code" ,
5355 force_refresh = FALSE ,
@@ -56,44 +58,67 @@ get_auth_token <- function(
5658 possibly_get_token <- \(... ) purrr :: possibly(AzureAuth :: get_azure_token )(... )
5759 possibly_get_mtk <- \(... ) purrr :: possibly(AzureAuth :: get_managed_token )(... )
5860
59- # 1. use environment variables if all three are set
61+ dots <- rlang :: list2(... )
62+ # if the user specifies force_refresh = TRUE we turn off `use_cache`,
63+ # otherwise we leave `use_cache` as it is (or as `NULL`, its default value)
64+ use_cached <- ! force_refresh && (dots [[" use_cache" ]] %|| % TRUE )
65+ dots <- rlang :: dots_list(!!! dots , use_cache = use_cached , .homonyms = " last" )
66+
67+ # 1. Use environment variables if all three are set
6068 tenant_id_env <- Sys.getenv(" AZ_TENANT_ID" )
6169 client_id_env <- Sys.getenv(" AZ_CLIENT_ID" )
6270 client_secret <- Sys.getenv(" AZ_APP_SECRET" )
6371
6472 if (all(nzchar(c(tenant_id_env , client_id_env , client_secret )))) {
65- token <- possibly_get_token(
66- resource = resource ,
67- tenant = tenant_id_env ,
68- app = client_id_env ,
69- password = client_secret
73+ token <- rlang :: inject(
74+ possibly_get_token(
75+ resource = resource ,
76+ tenant = tenant_id_env ,
77+ app = client_id_env ,
78+ password = client_secret ,
79+ !!! dots
80+ )
7081 )
7182 } else {
72- # 2. try to get a managed token (for example on Azure VM, App Service)
73- token <- possibly_get_mtk(resource , ... )
83+ # 2. Try to get a managed token (for example on Azure VM, App Service)
84+ token <- rlang :: inject( possibly_get_mtk(resource , !!! dots ) )
7485 }
7586
76- # 3. if neither of those has worked, try to get an already stored user token
77- if (is.null(token )) {
78- # list tokens already locally stored
87+ # 3. If neither of those has worked, try to get an already stored user token
88+ # (unless `force_refresh` is on, in which case skip to option 4 anyway)
89+ if (is.null(token ) && ! force_refresh ) {
90+ # list tokens already locally cached
7991 local_tokens <- AzureAuth :: list_azure_tokens()
8092 if (length(local_tokens ) > 0 ) {
8193 resources <- purrr :: map(local_tokens , " resource" )
82- # if there are token(s) matching the `resource` argument then return one
83- token_index <- match(resource , resources )[1 ]
94+ scopes <- purrr :: map(local_tokens , list (" scope" , 1 ))
95+ resources <- purrr :: map2(resources , scopes , `%||%` )
96+ tenants <- purrr :: map(local_tokens , " tenant" )
97+ resource_index <- gregg(resources , " ^{resource}" )
98+ tenant_index <- tenant == tenants
99+ # if there are token(s) matching `resource` and `tenant` then return one
100+ token_index <- which(resource_index & tenant_index )[1 ]
84101 token <- if (! is.na(token_index )) local_tokens [[token_index ]] else NULL
102+ } else {
103+ token <- NULL
85104 }
86- # 4. If we still don't have a valid token, or if `force_refresh` is on,
87- # then we try to get one via user reauthentication.
88- if (is.null(token ) || force_refresh ) {
89- client_id <- client_id %|| % get_client_id()
90- token <- possibly_get_token(
105+ }
106+ # 4. If we still don't have a valid token, try to get a new one via user
107+ # reauthentication
108+ if (is.null(token )) {
109+ if (! force_refresh ) {
110+ cli :: cli_alert_info(" No matching cached token found: fetching new token" )
111+ }
112+ client_id <- client_id %|| % get_client_id()
113+ token <- rlang :: inject(
114+ possibly_get_token(
91115 resource = resource ,
92116 tenant = tenant ,
93117 app = client_id ,
94- auth_type = auth_method
118+ auth_type = auth_method ,
119+ !!! dots
95120 )
96- }
121+ )
97122 }
98123
99124 # Give some helpful feedback if process above has not worked
@@ -106,6 +131,7 @@ get_auth_token <- function(
106131 )
107132 invisible (NULL )
108133 } else {
134+ # check_that(token, AzureAuth::is_azure_token, "Invalid token returned")
109135 token
110136 }
111137}
0 commit comments