Mercurial > hg > orthanc-object-storage
diff Azure/AzureBlobStoragePlugin.cpp @ 47:1691da4ae9c3
merge patch-azure: 'create container if not exists' option
author | Alain Mazy <am@osimis.io> |
---|---|
date | Fri, 02 Apr 2021 09:30:52 +0200 |
parents | 50d0be413c42 3b8fab63313d |
children | ff113c3561c5 |
line wrap: on
line diff
--- a/Azure/AzureBlobStoragePlugin.cpp Fri Mar 19 17:40:12 2021 +0100 +++ b/Azure/AzureBlobStoragePlugin.cpp Fri Apr 02 09:30:52 2021 +0200 @@ -23,6 +23,7 @@ #include <boost/lexical_cast.hpp> #include <boost/algorithm/string.hpp> #include "cpprest/rawptrstream.h" +#include "cpprest/details/basic_types.h" // Create aliases to make the code easier to read. @@ -161,11 +162,32 @@ return "Azure Blob Storage"; } +bool isSasTokenAccountLevel(utility::string_t sasToken) +{ + // Use cpprestsdk's utility::string_t here since the expected argument is the return value of + // as::storage_credentials::sas_token(), which is type utility::string_t + size_t newIdx = 0; + size_t prevIdx = 0; + while ((newIdx = sasToken.find('&', prevIdx)) != utility::string_t::npos) + { + utility::string_t kvpair = sasToken.substr(prevIdx, newIdx-prevIdx); + prevIdx = newIdx + 1; // start next time from char after '&' + + size_t equalsIdx = kvpair.find('='); + utility::string_t key = kvpair.substr(0, equalsIdx); + if (key == "srt") // only account SAS has this parameter + return true; + } + + return false; +} + IStoragePlugin* AzureBlobStoragePluginFactory::CreateStoragePlugin(const OrthancPlugins::OrthancConfiguration& orthancConfig) { std::string connectionString; std::string containerName; bool enableLegacyStorageStructure; + bool createContainerIfNotExists; if (orthancConfig.IsSection(PLUGIN_SECTION)) { @@ -191,6 +213,8 @@ boost::trim(connectionString); // without that, if there's an EOL in the string, it fails with "provided uri is invalid" boost::trim(containerName); + + createContainerIfNotExists = pluginSection.GetBooleanValue("CreateContainerIfNotExists", true); } else if (orthancConfig.IsSection("BlobStorage")) // backward compatibility with the old plugin: { @@ -223,6 +247,8 @@ std::ostringstream connectionStringBuilder; connectionStringBuilder << "DefaultEndpointsProtocol=https;AccountName=" << accountName << ";AccountKey=" << accountKey; connectionString = connectionStringBuilder.str(); + + createContainerIfNotExists = pluginSection.GetBooleanValue("CreateContainerIfNotExists", true); } else { @@ -243,12 +269,21 @@ as::cloud_blob_container blobContainer = blobClient.get_container_reference(utility::conversions::to_string_t(containerName)); OrthancPlugins::LogInfo("Accessing blob container"); - // Return value is true if the container did not exist and was successfully created. - bool containerCreated = blobContainer.create_if_not_exists(); + // blobContainer.create_if_not_exists() throws an error if a service SAS (for a blob container) + // was used in the connectionString. + // Only allow the use of this function when using storage account-level credentials, whether + // through accountName/accountKey combo or account SAS. + if ((storageAccount.credentials().is_account_key() || + (storageAccount.credentials().is_sas() && isSasTokenAccountLevel(storageAccount.credentials().sas_token()))) + && createContainerIfNotExists) + { + // Return value is true if the container did not exist and was successfully created. + bool containerCreated = blobContainer.create_if_not_exists(); - if (containerCreated) - { - OrthancPlugins::LogWarning("Blob Storage Area container has been created. **** check in the Azure console that your container is private ****"); + if (containerCreated) + { + OrthancPlugins::LogWarning("Blob Storage Area container has been created. **** check in the Azure console that your container is private ****"); + } } OrthancPlugins::LogInfo("Blob storage initialized");