From 1eb98b538e8da67a5e988f76da48516d4b5eaddb Mon Sep 17 00:00:00 2001 From: Hong Ooi Date: Mon, 2 Nov 2026 02:44:14 +1100 Subject: [PATCH 1/4] don't run examples --- R/sas.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/sas.R b/R/sas.R index b05b14c..e651d80 100644 --- a/R/sas.R +++ b/R/sas.R @@ -47,6 +47,8 @@ #' [Create a service SAS](https://learn.microsoft.com/en-us/rest/api/storageservices/create-service-sas) #' #' @examples +#' \dontrun{ +#' #' # account SAS valid for 7 days #' get_account_sas("mystorage", "access_key", start=Sys.Date(), expiry=Sys.Date() + 7) #' @@ -72,8 +74,6 @@ #' # read/write service SAS for a blob #' get_service_sas(endp, "containername/blobname", permissions="rw") #' -#' \dontrun{ -#' #' # user delegation key valid for 24 hours #' token <- AzureRMR::get_azure_token("https://storage.azure.com", "mytenant", "app_id") #' endp <- storage_endpoint("https://mystorage.blob.core.windows.net", token=token) From 81aa88e8b64df1e599723fbf8cd81b54d1d26bea Mon Sep 17 00:00:00 2001 From: Hong Ooi Date: Mon, 2 Nov 2026 17:13:18 +1100 Subject: [PATCH 2/4] reject any bad key --- DESCRIPTION | 2 +- NEWS.md | 4 ++++ R/storage_utils.R | 7 ++++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index a30750f..98ea011 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: AzureStor Title: Storage Management in 'Azure' -Version: 3.7.1 +Version: 3.7.2 Authors@R: c( person("Hong", "Ooi", , "hongooi73@gmail.com", role = c("aut", "cre")), person("Microsoft", role="cph") diff --git a/NEWS.md b/NEWS.md index 92d3907..2bc4a7c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,7 @@ +# AzureStor 3.7.2 + +- SAS generation will now always fail with a storage account key that is invalid Base64-encoded, rather than generating a bad SAS. Also fixes #147. + # AzureStor 3.7.1 - Update documentation links for CRAN diff --git a/R/storage_utils.R b/R/storage_utils.R index a3c5591..4ee2304 100644 --- a/R/storage_utils.R +++ b/R/storage_utils.R @@ -272,7 +272,12 @@ render_xml <- function(lst) sign_sha256 <- function(string, key) { - openssl::base64_encode(openssl::sha256(charToRaw(string), openssl::base64_decode(key))) + # throw error on all invalid keys (consistent with behaviour in openssl 2.5.0) + key_decoded <- try(openssl::base64_decode(key)) + if(inherits(key_decoded, "try-error") || length(key_decoded) == 0) + stop("Invalid storage account key, must be Base64 encoded", call.=FALSE) + + openssl::base64_encode(openssl::sha256(charToRaw(string), key_decoded)) } From 699304d67f86d8d458f8397211251666ed0cdf45 Mon Sep 17 00:00:00 2001 From: Hong Ooi Date: Mon, 2 Nov 2026 17:22:09 +1100 Subject: [PATCH 3/4] clarify --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 2bc4a7c..6b9d4f6 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,6 @@ # AzureStor 3.7.2 -- SAS generation will now always fail with a storage account key that is invalid Base64-encoded, rather than generating a bad SAS. Also fixes #147. +- Storage account key authentication and SAS generation will now always fail with a key that is invalid Base64-encoded, rather than generating a bad SAS. Also fixes #147. # AzureStor 3.7.1 From abf98276f901be47ba9cae2f2919c935a99a463d Mon Sep 17 00:00:00 2001 From: Hong Ooi Date: Mon, 2 Nov 2026 17:42:14 +1100 Subject: [PATCH 4/4] redocument --- DESCRIPTION | 2 +- NAMESPACE | 10 ++++++---- man/adls_filesystem.Rd | 2 +- man/blob_container.Rd | 2 +- man/sas.Rd | 4 ++-- man/storage_endpoint.Rd | 2 +- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 98ea011..11c5d5f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -31,4 +31,4 @@ Suggests: processx, uuid Roxygen: list(markdown=TRUE, r6=FALSE, old_usage=TRUE) -RoxygenNote: 7.3.2 +Config/roxygen2/version: 8.1.0 diff --git a/NAMESPACE b/NAMESPACE index e39ccb5..a23abb9 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -236,7 +236,9 @@ export(upload_azure_file) export(upload_blob) export(upload_to_url) import(AzureRMR) -importFrom(utils,URLencode) -importFrom(utils,glob2rx) -importFrom(utils,modifyList) -importFrom(utils,packageVersion) +importFrom(utils, + URLencode, + glob2rx, + modifyList, + packageVersion +) diff --git a/man/adls_filesystem.Rd b/man/adls_filesystem.Rd index f69ec86..0c57174 100644 --- a/man/adls_filesystem.Rd +++ b/man/adls_filesystem.Rd @@ -82,7 +82,7 @@ Get, list, create, or delete ADLSgen2 filesystems. \details{ You can call these functions in a couple of ways: by passing the full URL of the filesystem, or by passing the endpoint object and the name of the filesystem as a string. -If authenticating via AAD, you can supply the token either as a string, or as an object of class AzureToken, created via \link[AzureRMR:reexports]{AzureRMR::get_azure_token}. The latter is the recommended way of doing it, as it allows for automatic refreshing of expired tokens. +If authenticating via AAD, you can supply the token either as a string, or as an object of class AzureToken, created via \link[AzureRMR:get_azure_token]{AzureRMR::get_azure_token}. The latter is the recommended way of doing it, as it allows for automatic refreshing of expired tokens. } \examples{ \dontrun{ diff --git a/man/blob_container.Rd b/man/blob_container.Rd index 1a9e361..91421f0 100644 --- a/man/blob_container.Rd +++ b/man/blob_container.Rd @@ -87,7 +87,7 @@ Get, list, create, or delete blob containers. \details{ You can call these functions in a couple of ways: by passing the full URL of the share, or by passing the endpoint object and the name of the container as a string. -If authenticating via AAD, you can supply the token either as a string, or as an object of class AzureToken, created via \link[AzureRMR:reexports]{AzureRMR::get_azure_token}. The latter is the recommended way of doing it, as it allows for automatic refreshing of expired tokens. +If authenticating via AAD, you can supply the token either as a string, or as an object of class AzureToken, created via \link[AzureRMR:get_azure_token]{AzureRMR::get_azure_token}. The latter is the recommended way of doing it, as it allows for automatic refreshing of expired tokens. } \examples{ \dontrun{ diff --git a/man/sas.Rd b/man/sas.Rd index f1eb9b2..634e74f 100644 --- a/man/sas.Rd +++ b/man/sas.Rd @@ -131,6 +131,8 @@ To invalidate all user delegation keys, as well as the SAS's generated with them See the examples and Microsoft Docs pages below for how to specify arguments like the services, permissions, and resource types. Also, while not explicitly mentioned in the documentation, ADLSgen2 storage can use any SAS that is valid for blob storage. } \examples{ +\dontrun{ + # account SAS valid for 7 days get_account_sas("mystorage", "access_key", start=Sys.Date(), expiry=Sys.Date() + 7) @@ -156,8 +158,6 @@ get_service_sas(endp, "containername/dirname") # read/write service SAS for a blob get_service_sas(endp, "containername/blobname", permissions="rw") -\dontrun{ - # user delegation key valid for 24 hours token <- AzureRMR::get_azure_token("https://storage.azure.com", "mytenant", "app_id") endp <- storage_endpoint("https://mystorage.blob.core.windows.net", token=token) diff --git a/man/storage_endpoint.Rd b/man/storage_endpoint.Rd index 85bb45c..e27bac8 100644 --- a/man/storage_endpoint.Rd +++ b/man/storage_endpoint.Rd @@ -33,7 +33,7 @@ adls_endpoint(endpoint, key = NULL, token = NULL, sas = NULL, \item{key}{The access key for the storage account.} -\item{token}{An Azure Active Directory (AAD) authentication token. This can be either a string, or an object of class AzureToken created by \link[AzureRMR:reexports]{AzureRMR::get_azure_token}. The latter is the recommended way of doing it, as it allows for automatic refreshing of expired tokens.} +\item{token}{An Azure Active Directory (AAD) authentication token. This can be either a string, or an object of class AzureToken created by \link[AzureRMR:get_azure_token]{AzureRMR::get_azure_token}. The latter is the recommended way of doing it, as it allows for automatic refreshing of expired tokens.} \item{sas}{A shared access signature (SAS) for the account.}