diff --git a/paws.common/DESCRIPTION b/paws.common/DESCRIPTION index dd4c127db..aef1315a2 100644 --- a/paws.common/DESCRIPTION +++ b/paws.common/DESCRIPTION @@ -1,7 +1,7 @@ Package: paws.common Type: Package Title: Paws Low-Level Amazon Web Services API -Version: 0.7.6 +Version: 0.7.6.9000 Authors@R: c( person("David", "Kretch", email = "david.kretch@gmail.com", role = "aut"), person("Adam", "Banker", email = "adam.banker39@gmail.com", role = "aut"), diff --git a/paws.common/NEWS.md b/paws.common/NEWS.md index c0e35b8f3..72c3ed56b 100644 --- a/paws.common/NEWS.md +++ b/paws.common/NEWS.md @@ -1,3 +1,8 @@ +# paws.common 0.7.7 +* fix unix time expiration check +* remove redundant caching method +* ensure all calls has paws user-agent string attached + # paws.common 0.7.6 * fix `handle_copy_source_param` encoding redirected calls. * fix `handle_copy_source_param` removing attributes diff --git a/paws.common/R/cache.R b/paws.common/R/cache.R index 35e427628..8c3bca28c 100644 --- a/paws.common/R/cache.R +++ b/paws.common/R/cache.R @@ -4,8 +4,6 @@ ini_cache <- new.env(parent = emptyenv()) os_env_cache <- new.env(parent = emptyenv()) -cred_refresh_cache <- new.env(parent = emptyenv()) - set_os_env_cache <- function() { env_vars <- system("printenv", intern = TRUE) diff --git a/paws.common/R/config.R b/paws.common/R/config.R index 0c526e371..6ee3fcb48 100644 --- a/paws.common/R/config.R +++ b/paws.common/R/config.R @@ -203,7 +203,6 @@ get_instance_metadata <- function(query_path = "") { timeout = 1, header = c("X-aws-ec2-metadata-token-ttl-seconds" = token_ttl) ) - metadata_token_response <- tryCatch( { issue(metadata_token_request) @@ -229,7 +228,11 @@ get_instance_metadata <- function(query_path = "") { header = c("X-aws-ec2-metadata-token" = token) ) } else { - metadata_request <- new_http_request("GET", metadata_url, timeout = 1) + metadata_request <- new_http_request( + "GET", + metadata_url, + timeout = 1 + ) } metadata_response <- tryCatch( { diff --git a/paws.common/R/credential_providers.R b/paws.common/R/credential_providers.R index a453c6f1b..46e99b811 100644 --- a/paws.common/R/credential_providers.R +++ b/paws.common/R/credential_providers.R @@ -240,10 +240,6 @@ sso_credential_process <- function(sso_session, sso_account_id, sso_region, sso_role_name) { - if (!check_if_cred_needs_refresh(sso_role_name)) { - return(cred_refresh_cache[[sso_role_name]]) - } - input_str <- sso_session %||% sso_start_url cache_key <- digest::digest(enc2utf8(input_str), algo = "sha1", serialize = FALSE) json_file <- paste0(cache_key, ".json") @@ -283,29 +279,12 @@ sso_credential_process <- function(sso_session, return(NULL) } - creds <- Creds( + return(Creds( access_key_id = resp$roleCredentials$accessKeyId, secret_access_key = resp$roleCredentials$secretAccessKey, session_token = resp$roleCredentials$sessionToken, expiration = resp$roleCredentials$expiration - ) - cred_refresh_cache[[sso_role_name]] <- creds - return(cred_refresh_cache[[sso_role_name]]) -} - -check_if_cred_needs_refresh <- function(sso_role_name) { - if (!is.null(cred <- cred_refresh_cache[[sso_role_name]])) { - if (!length(expire <- cred$expiration)) { - return(TRUE) - } - if (is.infinite(expire)) { - return(TRUE) - } - expiration <- expire / 1000 - now <- as.numeric(Sys.time()) - return(now > expiration) - } - return(TRUE) + )) } # Get STS temporary credentials for the role with ARN `role_arn` using @@ -391,7 +370,6 @@ get_assume_role_with_web_identity_creds <- function(role_arn, role_session_name, container_credentials_provider <- function() { # Initialize to NULL credentials_response <- NULL - container_credentials_uri <- get_env("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI") container_credentials_full_uri <- get_env("AWS_CONTAINER_CREDENTIALS_FULL_URI") container_credentials_token <- get_env("AWS_WEB_IDENTITY_TOKEN_FILE") @@ -460,45 +438,44 @@ get_container_credentials <- function(credentials_uri, credentials_full_uri) { credentials_response_body <- jsonlite::fromJSON(raw_to_utf8(metadata_response$body)) - credentials_list <- list( - access_key_id = credentials_response_body$AccessKeyId, - secret_access_key = credentials_response_body$SecretAccessKey, - session_token = credentials_response_body$Token, - expiration = as_timestamp(credentials_response_body$Expiration, "iso8601") + return( + list( + access_key_id = credentials_response_body$AccessKeyId, + secret_access_key = credentials_response_body$SecretAccessKey, + session_token = credentials_response_body$Token, + expiration = as_timestamp(credentials_response_body$Expiration, "iso8601") + ) ) - - return(credentials_list) } # Developed from: # https://github.com/boto/botocore/blob/ba7da3497853ac83e9b8552f41de83cb27932fe9/botocore/credentials.py#L1945-L1955C22 set_container_credentails_headers <- function() { - auth_token <- NULL + auth_token <- list() ENV_VAR_AUTH_TOKEN <- get_env("AWS_CONTAINER_AUTHORIZATION_TOKEN") ENV_VAR_AUTH_TOKEN_FILE <- get_env("AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE") if (ENV_VAR_AUTH_TOKEN_FILE != "") { - auth_token <- readLines("token_file", encoding = "utf-8", warn = FALSE) + auth_token[["Authorization"]] <- readLines(ENV_VAR_AUTH_TOKEN_FILE, encoding = "utf-8", warn = FALSE) } else if (ENV_VAR_AUTH_TOKEN != "") { - auth_token <- ENV_VAR_AUTH_TOKEN + auth_token[["Authorization"]] <- ENV_VAR_AUTH_TOKEN } # validate auth token - if (!is.null(auth_token)) { - if (grepl("\r|\n", auth_token)) { + if (!is.null(auth_token[["Authorization"]])) { + if (grepl("\r|\n", auth_token[["Authorization"]])) { stop("Auth token value is not a legal header value") } - names(auth_token) <- "Authorization" } return(auth_token) } get_container_credentials_eks <- function() { - credentials_list <- get_assume_role_with_web_identity_creds( - role_arn = get_role_arn(), - role_session_name = get_role_session_name(), - web_identity_token = get_web_identity_token() + return( + get_assume_role_with_web_identity_creds( + role_arn = get_role_arn(), + role_session_name = get_role_session_name(), + web_identity_token = get_web_identity_token() + ) ) - - return(credentials_list) } # Retrieve credentials for EC2 IAM Role diff --git a/paws.common/R/credentials.R b/paws.common/R/credentials.R index 2371e34ea..ccfd0aa40 100644 --- a/paws.common/R/credentials.R +++ b/paws.common/R/credentials.R @@ -69,8 +69,15 @@ is_credentials_provided <- function(creds, window = 5 * 60) { if (is.null(creds$secret_access_key) || creds$secret_access_key == "") { return(FALSE) } - if (length(creds$expiration) == 1 && is.finite(creds$expiration) && Sys.time() > creds$expiration - window) { + if (check_if_cred_needs_refresh(creds, window)) { return(FALSE) } return(TRUE) } + +check_if_cred_needs_refresh <- function(creds, window) { + if (is.numeric(expire <- creds$expiration)) { + expire <- expire / 1000 + } + return(length(expire) == 1 && is.finite(expire) && Sys.time() > expire - window) +} diff --git a/paws.common/R/handlers_core.R b/paws.common/R/handlers_core.R index a9931d356..19f03b933 100644 --- a/paws.common/R/handlers_core.R +++ b/paws.common/R/handlers_core.R @@ -2,17 +2,6 @@ #' @include util.R -# Add the name/version to the User-Agent request header. -sdk_version_user_agent_handler <- function(request) { - paws_version <- .__NAMESPACE__.[["spec"]]["version"] %||% packageVersion("paws.common") - user_agent <- sprintf( - "paws/%s (R%s; %s; %s)", - paws_version, getRversion(), R.version$os, R.version$arch - ) - request$http_request$header["User-Agent"] <- user_agent - return(request) -} - # Add the execution environment to the User-Agent request header. # TODO: Implement. add_host_exec_env_user_agent_handler <- function(request) { diff --git a/paws.common/R/net.R b/paws.common/R/net.R index 82d0423a8..aec6625dd 100644 --- a/paws.common/R/net.R +++ b/paws.common/R/net.R @@ -66,6 +66,7 @@ new_http_request <- function(method, url, body = NULL, close = FALSE, connect_ti if (!valid_method(method)) { stopf("invalid method: %s", method) } + header["User-Agent"] <- PAWS_USER_AGENT u <- parse_url(url) req <- HttpRequest( method = method, diff --git a/paws.common/R/onLoad.R b/paws.common/R/onLoad.R index d943055d7..5257562a4 100644 --- a/paws.common/R/onLoad.R +++ b/paws.common/R/onLoad.R @@ -4,6 +4,7 @@ .onLoad <- function(libname, pkgname) { init_log_config() init_log_styles() + set_user_agent(pkgname) # Cache UNIX OS environment variables if (.Platform$OS.type == "unix") { diff --git a/paws.common/R/service.R b/paws.common/R/service.R index c95e5f0ca..4636a3e3a 100644 --- a/paws.common/R/service.R +++ b/paws.common/R/service.R @@ -23,7 +23,6 @@ new_handlers <- function(protocol, signer) { validate_parameters_handler ), build = HandlerList( - sdk_version_user_agent_handler, add_host_exec_env_user_agent_handler, handler(protocol, "build") ), diff --git a/paws.common/R/util.R b/paws.common/R/util.R index fe28699eb..8e244e97a 100644 --- a/paws.common/R/util.R +++ b/paws.common/R/util.R @@ -242,3 +242,12 @@ parse_in_half <- function(x, char = "=") { substr(x, right_start, right_end) ) } + +set_user_agent <- function(pkgname) { + paws_version <- .__NAMESPACE__.[["spec"]]["version"] %||% packageVersion(pkgname) + user_agent <- sprintf( + "paws/%s (R%s; %s; %s)", + paws_version, getRversion(), R.version$os, R.version$arch + ) + assign("PAWS_USER_AGENT", user_agent, envir = getNamespace(pkgname)) +} diff --git a/paws.common/tests/testthat/test_credential_providers.R b/paws.common/tests/testthat/test_credential_providers.R index 79464ce67..19bc64111 100644 --- a/paws.common/tests/testthat/test_credential_providers.R +++ b/paws.common/tests/testthat/test_credential_providers.R @@ -124,24 +124,3 @@ test_that("config_file_provider", { )) }) }) - -test_that("check if refreshed credentials need refreshing", { - rm(list = names(cred_refresh_cache), envir = cred_refresh_cache) - # if profile not found: true - expect_true(check_if_cred_needs_refresh("profile")) - - # old time: true - time <- as.numeric(Sys.time()) * 1000 - 1000 - cred_refresh_cache$profile <- list(expiration = time) - expect_true(check_if_cred_needs_refresh("profile")) - - # unexpected expiration: true - time <- integer() - cred_refresh_cache$profile <- list(expiration = time) - expect_true(check_if_cred_needs_refresh("profile")) - - # future time: false - time <- as.numeric(Sys.time()) * 1000 + 10000 - cred_refresh_cache$profile <- list(expiration = time) - expect_false(check_if_cred_needs_refresh("profile")) -}) diff --git a/paws.common/tests/testthat/test_credentials.R b/paws.common/tests/testthat/test_credentials.R index 503235fca..14331e588 100644 --- a/paws.common/tests/testthat/test_credentials.R +++ b/paws.common/tests/testthat/test_credentials.R @@ -35,14 +35,30 @@ test_that("credentials not provided", { }) test_that("credentials expired", { - creds <- Creds( + creds <- paws.common:::Creds( + access_key_id = "foo", + secret_access_key = "bar", + expiration = 1000 + ) + + expect_false(is_credentials_provided(creds)) + + creds <- paws.common:::Creds( access_key_id = "foo", secret_access_key = "bar", - expiration = 0 + expiration = Sys.time() - 5*60 ) expect_false(is_credentials_provided(creds)) + creds <- Creds( + access_key_id = "foo", + secret_access_key = "bar", + expiration = Sys.time() + 30*60 + ) + + expect_true(is_credentials_provided(creds)) + creds <- Creds( access_key_id = "foo", secret_access_key = "bar", diff --git a/paws.common/tests/testthat/test_handlers_core.R b/paws.common/tests/testthat/test_handlers_core.R index 30f32f453..24296faac 100644 --- a/paws.common/tests/testthat/test_handlers_core.R +++ b/paws.common/tests/testthat/test_handlers_core.R @@ -71,13 +71,14 @@ expect_user_agent <- function(request) { "paws/%s (R%s; %s; %s)", paws_version, r_version, r_os, r_arch ) - request$http_request$header["User-Agent"] <- user_agent - return(request) + return(user_agent) } test_that("check if user agent string is built correctly", { - request <- list(http_request = list(header = list())) - actual <- sdk_version_user_agent_handler(request) - expected <- expect_user_agent(request) + mock_assign <- mock2() + mockery::stub(set_user_agent, "assign", mock_assign) + set_user_agent("paws.common") + expected <- expect_user_agent() + actual <- mockery::mock_args(mock_assign)[[1]][[2]] expect_equal(actual, expected) })