зеркало из https://github.com/Azure/AzureRMR.git
tests for tokens
This commit is contained in:
Родитель
8c10eab8e8
Коммит
a736649248
|
@ -7,6 +7,7 @@
|
||||||
#' - `refresh`: Refreshes the token. For expired Azure tokens using client credentials, refreshing really means requesting a new token.
|
#' - `refresh`: Refreshes the token. For expired Azure tokens using client credentials, refreshing really means requesting a new token.
|
||||||
#' - `validate`: Checks if the token is still valid. For Azure tokens using client credentials, this just checks if the current time is less than the token's expiry time.
|
#' - `validate`: Checks if the token is still valid. For Azure tokens using client credentials, this just checks if the current time is less than the token's expiry time.
|
||||||
#' - `hash`: Computes an MD5 hash on selected fields of the token. Used internally for identification purposes when caching.
|
#' - `hash`: Computes an MD5 hash on selected fields of the token. Used internally for identification purposes when caching.
|
||||||
|
#' - `cache`: Stores the token on disk for use in future sessions.
|
||||||
#'
|
#'
|
||||||
#' @seealso
|
#' @seealso
|
||||||
#' [get_azure_token], [httr::Token]
|
#' [get_azure_token], [httr::Token]
|
||||||
|
@ -239,7 +240,7 @@ private=list(
|
||||||
#' Similarly, since the authorization_code method opens a browser to load the AAD authorization page, your machine must have an Internet browser installed that can be run from inside R. In particular, if you are using a Linux [Data Science Virtual Machine](https://azure.microsoft.com/en-us/services/virtual-machines/data-science-virtual-machines/) in Azure, you may run into difficulties; use one of the other methods instead.
|
#' Similarly, since the authorization_code method opens a browser to load the AAD authorization page, your machine must have an Internet browser installed that can be run from inside R. In particular, if you are using a Linux [Data Science Virtual Machine](https://azure.microsoft.com/en-us/services/virtual-machines/data-science-virtual-machines/) in Azure, you may run into difficulties; use one of the other methods instead.
|
||||||
#'
|
#'
|
||||||
#' @section Caching:
|
#' @section Caching:
|
||||||
#' AzureRMR differs from httr in its handling of token caching in a number of ways. First, caching is based on all the inputs to `get_azure_token` as listed above. Second, it defines its own directory for cached tokens, using the rappdirs package. On recent Windows versions, this will usually be in the location `C:\\Users\\(username)\\AppData\\Local\\AzureR\\AzureRMR`. On Linux, it will be in `~/.config/AzureRMR`, and on MacOS, it will be in `~/Library/Application Support/AzureRMR`. Note that a single directory is used for all tokens, and the working directory is not touched (which eliminates the risk of accidentally introducing cached tokens into source control).
|
#' AzureRMR differs from httr in its handling of token caching in a number of ways. First, caching is based on all the inputs to `get_azure_token` as listed above. Second, it defines its own directory for cached tokens, using the rappdirs package. On recent Windows versions, this will usually be in the location `C:\\Users\\(username)\\AppData\\Local\\AzureR\\AzureRMR`. On Linux, it will be in `~/.config/AzureRMR`, and on MacOS, it will be in `~/Library/Application Support/AzureRMR`. Note that a single directory is used for all tokens, and the working directory is not touched (which significantly lessens the risk of accidentally introducing cached tokens into source control).
|
||||||
#'
|
#'
|
||||||
#' To list all cached tokens on disk, use `list_azure_tokens`. This returns a list of token objects, named according to their MD5 hashes.
|
#' To list all cached tokens on disk, use `list_azure_tokens`. This returns a list of token objects, named according to their MD5 hashes.
|
||||||
#'
|
#'
|
||||||
|
@ -424,7 +425,7 @@ delete_azure_token <- function(resource_host, tenant, app, password=NULL, userna
|
||||||
|
|
||||||
endp <- httr::oauth_endpoint(base_url=base_url,
|
endp <- httr::oauth_endpoint(base_url=base_url,
|
||||||
authorize="oauth2/authorize",
|
authorize="oauth2/authorize",
|
||||||
access=if(use_device) "oauth2/devicecode" else NULL)
|
access=if(use_device) "oauth2/devicecode" else "oauth2/token")
|
||||||
app <- httr::oauth_app("azure", app,
|
app <- httr::oauth_app("azure", app,
|
||||||
secret=if(client_credentials) password else NULL,
|
secret=if(client_credentials) password else NULL,
|
||||||
redirect_uri=if(client_credentials) NULL else httr::oauth_callback())
|
redirect_uri=if(client_credentials) NULL else httr::oauth_callback())
|
||||||
|
|
|
@ -1,14 +1,5 @@
|
||||||
context("AzureToken")
|
context("AzureToken")
|
||||||
|
|
||||||
tenant <- Sys.getenv("AZ_TEST_TENANT_ID")
|
|
||||||
app <- Sys.getenv("AZ_TEST_APP_ID")
|
|
||||||
password <- Sys.getenv("AZ_TEST_PASSWORD")
|
|
||||||
subscription <- Sys.getenv("AZ_TEST_SUBSCRIPTION")
|
|
||||||
|
|
||||||
if(tenant == "" || app == "" || password == "" || subscription == "")
|
|
||||||
skip("Authentication tests skipped: ARM credentials not set")
|
|
||||||
|
|
||||||
|
|
||||||
test_that("normalize_tenant, normalize_guid work",
|
test_that("normalize_tenant, normalize_guid work",
|
||||||
{
|
{
|
||||||
guid <- "abcdefab-1234-5678-9012-abcdefabcdef"
|
guid <- "abcdefab-1234-5678-9012-abcdefabcdef"
|
||||||
|
@ -22,6 +13,7 @@ test_that("normalize_tenant, normalize_guid work",
|
||||||
|
|
||||||
# improperly formatted GUID will be treated as a name
|
# improperly formatted GUID will be treated as a name
|
||||||
guid5 <- paste0("(", guid)
|
guid5 <- paste0("(", guid)
|
||||||
|
expect_false(is_guid(guid5))
|
||||||
expect_identical(normalize_tenant(guid5), paste0(guid5, ".onmicrosoft.com"))
|
expect_identical(normalize_tenant(guid5), paste0(guid5, ".onmicrosoft.com"))
|
||||||
|
|
||||||
expect_identical(normalize_tenant("common"), "common")
|
expect_identical(normalize_tenant("common"), "common")
|
||||||
|
@ -29,24 +21,71 @@ test_that("normalize_tenant, normalize_guid work",
|
||||||
expect_identical(normalize_tenant("mytenant.com"), "mytenant.com")
|
expect_identical(normalize_tenant("mytenant.com"), "mytenant.com")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
tenant <- Sys.getenv("AZ_TEST_TENANT_ID")
|
||||||
|
app <- Sys.getenv("AZ_TEST_APP_ID")
|
||||||
|
password <- Sys.getenv("AZ_TEST_PASSWORD")
|
||||||
|
subscription <- Sys.getenv("AZ_TEST_SUBSCRIPTION")
|
||||||
|
native_app <- Sys.getenv("AZ_TEST_NATIVE_APP_ID")
|
||||||
|
|
||||||
|
if(tenant == "" || app == "" || password == "" || subscription == "" || native_app == "")
|
||||||
|
skip("Authentication tests skipped: ARM credentials not set")
|
||||||
|
|
||||||
|
if(system.file(package="httpuv") == "")
|
||||||
|
skip("Authentication tests skipped: httpuv must be installed")
|
||||||
|
|
||||||
|
# not a perfect test: will fail to detect Linux DSVM issue
|
||||||
|
if(!interactive())
|
||||||
|
skip("Authentication tests skipped: must be an interactive session")
|
||||||
|
|
||||||
test_that("Authentication works",
|
test_that("Authentication works",
|
||||||
{
|
{
|
||||||
suppressWarnings(file.remove(dir(AzureRMR:::config_dir(), full.names=TRUE)))
|
suppressWarnings(file.remove(dir(AzureRMR:::config_dir(), full.names=TRUE)))
|
||||||
|
|
||||||
token <- get_azure_token("https://management.azure.com/", tenant, app, password)
|
res <- "https://management.azure.com/"
|
||||||
expect_true(is_azure_token(token))
|
|
||||||
|
|
||||||
toklist <- list_azure_tokens()
|
# obtain new tokens
|
||||||
hash <- AzureRMR:::token_hash(
|
aut_tok <- get_azure_token(res, tenant, native_app, auth_type="authorization_code")
|
||||||
"https://management.azure.com/", tenant, app, password, username=NULL,
|
expect_true(is_azure_token(aut_tok))
|
||||||
auth_type="client_credentials",
|
expect_identical(aut_tok$hash(), "b29ef592fa435a4fd92672daf8726bae")
|
||||||
aad_host="https://login.microsoftonline.com/")
|
|
||||||
expect_true(length(toklist) > 0)
|
|
||||||
expect_true(hash %in% names(toklist))
|
|
||||||
|
|
||||||
expect_true(is_azure_token(token$refresh()))
|
ccd_tok <- get_azure_token(res, tenant, app, password=password)
|
||||||
expect_null(delete_azure_token("https://management.azure.com/", tenant, app, password, confirm=FALSE))
|
expect_true(is_azure_token(ccd_tok))
|
||||||
|
expect_identical(ccd_tok$hash(), "c75c266d9c578af29e24d3f22013ebf6")
|
||||||
|
|
||||||
token <- get_azure_token("https://management.azure.com/", tenant, app, password)
|
dev_tok <- get_azure_token(res, tenant, native_app, auth_type="device_code")
|
||||||
expect_null(delete_azure_token(hash=hash, confirm=FALSE))
|
expect_true(is_azure_token(dev_tok))
|
||||||
|
expect_identical(dev_tok$hash(), "37cbd9fec7c15b5a47edc1ea6f2f2747")
|
||||||
|
|
||||||
|
aut_expire <- as.numeric(aut_tok$credentials$expires_on)
|
||||||
|
ccd_expire <- as.numeric(ccd_tok$credentials$expires_on)
|
||||||
|
dev_expire <- as.numeric(dev_tok$credentials$expires_on)
|
||||||
|
|
||||||
|
Sys.sleep(5)
|
||||||
|
|
||||||
|
# refresh/reauthenticate
|
||||||
|
aut_tok$refresh()
|
||||||
|
ccd_tok$refresh()
|
||||||
|
dev_tok$refresh()
|
||||||
|
|
||||||
|
expect_true(as.numeric(aut_tok$credentials$expires_on) > aut_expire)
|
||||||
|
expect_true(as.numeric(ccd_tok$credentials$expires_on) > ccd_expire)
|
||||||
|
expect_true(as.numeric(dev_tok$credentials$expires_on) > dev_expire)
|
||||||
|
|
||||||
|
# load cached tokens: should not get repeated login prompts/screens
|
||||||
|
aut_tok2 <- get_azure_token(res, tenant, native_app, auth_type="authorization_code")
|
||||||
|
expect_true(is_azure_token(aut_tok2))
|
||||||
|
expect_identical(aut_tok2$hash(), "b29ef592fa435a4fd92672daf8726bae")
|
||||||
|
|
||||||
|
ccd_tok2 <- get_azure_token(res, tenant, app, password=password)
|
||||||
|
expect_true(is_azure_token(ccd_tok2))
|
||||||
|
expect_identical(ccd_tok2$hash(), "c75c266d9c578af29e24d3f22013ebf6")
|
||||||
|
|
||||||
|
dev_tok2 <- get_azure_token(res, tenant, native_app, auth_type="device_code")
|
||||||
|
expect_true(is_azure_token(dev_tok2))
|
||||||
|
expect_identical(dev_tok2$hash(), "37cbd9fec7c15b5a47edc1ea6f2f2747")
|
||||||
|
|
||||||
|
expect_null(delete_azure_token(res, tenant, native_app, auth_type="authorization_code", confirm=FALSE))
|
||||||
|
expect_null(delete_azure_token(res, tenant, app, password=password, confirm=FALSE))
|
||||||
|
expect_null(delete_azure_token(res, tenant, native_app, auth_type="device_code", confirm=FALSE))
|
||||||
})
|
})
|
||||||
|
|
Загрузка…
Ссылка в новой задаче