Skip to content

Commit 0705d70

Browse files
Merge pull request #64 from The-Strategy-Unit/francisbarton/issue62
Rejig logic of get_auth_token when force_refresh is turned on
2 parents f59df0b + e81d071 commit 0705d70

File tree

2 files changed

+54
-26
lines changed

2 files changed

+54
-26
lines changed

R/get_auth_token.R

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
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"`.
@@ -27,7 +29,7 @@
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
@@ -47,7 +49,7 @@
4749
#' @export
4850
get_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
}

man/get_auth_token.Rd

Lines changed: 5 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)