Skip to content

Commit

Permalink
Merge pull request #310 from JinmingHu-MSFT/dev
Browse files Browse the repository at this point in the history
Release 7.1.0
  • Loading branch information
vinjiang authored Jan 10, 2020
2 parents a86cce3 + ebe0945 commit 0a0c96b
Show file tree
Hide file tree
Showing 40 changed files with 920 additions and 268 deletions.
7 changes: 7 additions & 0 deletions Changelog.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Azure Storage Client Library for C++
History of Changes

Changes in v7.1.0
- New feature: User delegation SAS.
- Fixed a bug in snapshot SAS.
- Fixed some unittest failures.
- Fixed some crash issues.
- Added an API with which user can custom HTTP connection settings.

Changes in v7.0.0
- Default REST API version is 2019-02-02.
- Upgraded CPPRest to latest version 2.10.14.
Expand Down
2 changes: 1 addition & 1 deletion Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ PROJECT_NAME = "Microsoft Azure Storage Client Library for C++"
# could be handy for archiving the generated documentation or if some version
# control system is used.

PROJECT_NUMBER = 7.0.0
PROJECT_NUMBER = 7.1.0

# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
Expand Down
2 changes: 1 addition & 1 deletion Microsoft.WindowsAzure.Storage/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ set(AZURESTORAGE_LIBRARIES ${AZURESTORAGE_LIBRARY} ${CASABLANCA_LIBRARY} ${Boost

# Set version numbers centralized
set (AZURESTORAGE_VERSION_MAJOR 7)
set (AZURESTORAGE_VERSION_MINOR 0)
set (AZURESTORAGE_VERSION_MINOR 1)
set (AZURESTORAGE_VERSION_REVISION 0)

# Set output directories.
Expand Down
4 changes: 3 additions & 1 deletion Microsoft.WindowsAzure.Storage/includes/was/auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ namespace azure { namespace storage {
class cloud_blob_shared_access_headers;
class cloud_file_shared_access_headers;
class account_shared_access_policy;
struct user_delegation_key;

}} // namespace azure::storage

namespace azure { namespace storage { namespace protocol {

utility::string_t calculate_hmac_sha256_hash(const utility::string_t& string_to_hash, const storage_credentials& credentials);
utility::string_t calculate_hmac_sha256_hash(const utility::string_t& string_to_hash, const std::vector<uint8_t>& key);

const utility::string_t auth_name_shared_key(_XPLATSTR("SharedKey"));
const utility::string_t auth_name_shared_key_lite(_XPLATSTR("SharedKeyLite"));
Expand Down Expand Up @@ -474,6 +475,7 @@ namespace azure { namespace storage { namespace protocol {
utility::string_t get_queue_sas_token(const utility::string_t& identifier, const shared_access_policy& policy, const utility::string_t& resource, const storage_credentials& credentials);
utility::string_t get_table_sas_token(const utility::string_t& identifier, const shared_access_policy& policy, const utility::string_t& table_name, const utility::string_t& start_partition_key, const utility::string_t& start_row_key, const utility::string_t& end_partition_key, const utility::string_t& end_row_key, const utility::string_t& resource, const storage_credentials& credentials);
utility::string_t get_file_sas_token(const utility::string_t& identifier, const shared_access_policy& policy, const cloud_file_shared_access_headers& headers, const utility::string_t& resource_type, const utility::string_t& resource, const storage_credentials& credentials);
utility::string_t get_blob_user_delegation_sas_token(const shared_access_policy& policy, const cloud_blob_shared_access_headers& headers, const utility::string_t& resource_type, const utility::string_t& resource, const utility::string_t& snapshot_time, const user_delegation_key& key);
storage_credentials parse_query(const web::http::uri& uri, bool require_signed_resource);

#pragma endregion
Expand Down
73 changes: 73 additions & 0 deletions Microsoft.WindowsAzure.Storage/includes/was/blob.h
Original file line number Diff line number Diff line change
Expand Up @@ -2516,6 +2516,17 @@ namespace azure { namespace storage {
friend class protocol::list_containers_reader;
};

struct user_delegation_key
{
utility::string_t signed_oid;
utility::string_t signed_tid;
utility::datetime signed_start;
utility::datetime signed_expiry;
utility::string_t signed_service;
utility::string_t signed_version;
utility::string_t key;
};

/// <summary>
/// Provides a client-side logical representation of the Windows Azure Blob Service. This client is used to configure and execute requests against the Blob Service.
/// </summary>
Expand Down Expand Up @@ -3064,6 +3075,39 @@ namespace azure { namespace storage {
m_directory_delimiter = std::move(value);
}

/// <summary>
/// Gets a key that can be used to sign a user delegation SAS (shared access signature).
/// </summary>
/// <param name="start">The start time for the user delegation key.</param>
/// <param name="expiry">The expiry time for the user delegation key.</param>
/// <returns>A string containing user delegation key.</returns>
user_delegation_key get_user_delegation_key(const utility::datetime& start, const utility::datetime& expiry)
{
return get_user_delegation_key_async(start, expiry).get();
}

/// <summary>
/// Initiates an asynchronous operation to get a key that can be used to sign a user delegation SAS (shared access signature).
/// </summary>
/// <param name="start">The start time for the user delegation key.</param>
/// <param name="expiry">The expiry time for the user delegation key.</param>
/// <returns>A <see cref="pplx::task" /> object of string that contains user delegation key.</returns>
pplx::task<user_delegation_key> get_user_delegation_key_async(const utility::datetime& start, const utility::datetime& expiry)
{
return get_user_delegation_key_async(start, expiry, blob_request_options(), operation_context(), pplx::cancellation_token::none());
}

/// <summary>
/// Initiates an asynchronous operation to get a key that can be used to sign a user delegation SAS (shared access signature).
/// </summary>
/// <param name="start">The start time for the user delegation key.</param>
/// <param name="expiry">The expiry time for the user delegation key.</param>
/// <param name="options">An <see cref="azure::storage::blob_request_options" /> object that specifies additional options for the request.</param>
/// <param name="context">An <see cref="azure::storage::operation_context" /> object that represents the context for the current operation.</param>
/// <param name="cancellation_token">An <see cref="pplx::cancellation_token" /> object that is used to cancel the current operation.</param>
/// <returns>A <see cref="pplx::task" /> object of string that contains user delegation key.</returns>
WASTORAGE_API pplx::task<user_delegation_key> get_user_delegation_key_async(const utility::datetime& start, const utility::datetime& expiry, const request_options& modified_options, operation_context context, const pplx::cancellation_token& cancellation_token);

private:
pplx::task<account_properties> download_account_properties_base_async(const storage_uri& uri, const request_options& modified_options, operation_context context, const pplx::cancellation_token& cancellation_token) const;

Expand Down Expand Up @@ -3175,6 +3219,14 @@ namespace azure { namespace storage {
/// <returns>A string containing a shared access signature.</returns>
WASTORAGE_API utility::string_t get_shared_access_signature(const blob_shared_access_policy& policy, const utility::string_t& stored_policy_identifier) const;

/// <summary>
/// Returns a user delegation SAS for the container.
/// </summary>
/// <param name="key">User delegation key used to sign this SAS.</param>
/// <param name="policy">The access policy for the shared access signature.</param>
/// <returns>A string containing a shared access signature.</returns>
WASTORAGE_API utility::string_t get_user_delegation_sas(const user_delegation_key& key, const blob_shared_access_policy& policy) const;

/// <summary>
/// Gets a reference to a blob in this container.
/// </summary>
Expand Down Expand Up @@ -4612,6 +4664,27 @@ namespace azure { namespace storage {
/// <returns>A string containing a shared access signature.</returns>
WASTORAGE_API utility::string_t get_shared_access_signature(const blob_shared_access_policy& policy, const utility::string_t& stored_policy_identifier, const cloud_blob_shared_access_headers& headers) const;


/// <summary>
/// Returns a user delegation SAS for the blob.
/// </summary>
/// <param name="key">User delegation key used to sign this SAS.</param>
/// <param name="policy">The access policy for the shared access signature.</param>
/// <returns>A string containing a shared access signature.</returns>
utility::string_t get_user_delegation_sas(const user_delegation_key& key, const blob_shared_access_policy& policy) const
{
return get_user_delegation_sas(key, policy, cloud_blob_shared_access_headers());
}

/// <summary>
/// Returns a user delegation SAS for the blob.
/// </summary>
/// <param name="key">User delegation key used to sign this SAS.</param>
/// <param name="policy">The access policy for the shared access signature.</param>
/// <param name="headers">The optional header values to set for a blob returned with this SAS.</param>
/// <returns>A string containing a shared access signature.</returns>
WASTORAGE_API utility::string_t get_user_delegation_sas(const user_delegation_key& key, const blob_shared_access_policy& policy, const cloud_blob_shared_access_headers& headers) const;

/// <summary>
/// Opens a stream for reading from the blob.
/// </summary>
Expand Down
35 changes: 35 additions & 0 deletions Microsoft.WindowsAzure.Storage/includes/was/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -1728,6 +1728,23 @@ namespace azure { namespace storage {
}
#endif

/// <summary>
/// Sets a callback to enable custom setting of platform specific options.
/// </summary>
/// <param name="callback">A user callback allowing for customization of the session.</param>
void set_native_session_handle_options_callback(const std::function<void(web::http::client::native_handle)>& callback)
{
m_native_session_handle_options_callback = callback;
}

/// <summary>
/// Gets the user's callback to custom setting of platform specific options.
/// </summary>
const std::function<void(web::http::client::native_handle)>& get_native_session_handle_options_callback() const
{
return m_native_session_handle_options_callback;
}

private:

std::function<void(web::http::http_request &, operation_context)> m_sending_request;
Expand All @@ -1744,6 +1761,7 @@ namespace azure { namespace storage {
boost::log::sources::severity_logger<boost::log::trivial::severity_level> m_logger;
std::function<void(boost::asio::ssl::context&)> m_ssl_context_callback; //No need to initialize as CPPRest does not initialize it.
#endif
std::function<void(web::http::client::native_handle)> m_native_session_handle_options_callback;
};

/// <summary>
Expand Down Expand Up @@ -1991,6 +2009,23 @@ namespace azure { namespace storage {
}
#endif

/// <summary>
/// Sets a callback to enable custom setting of platform specific options.
/// </summary>
/// <param name="callback">A user callback allowing for customization of the session.</param>
void set_native_session_handle_options_callback(const std::function<void(web::http::client::native_handle)>& callback)
{
m_impl->set_native_session_handle_options_callback(callback);
}

/// <summary>
/// Gets the user's callback to custom setting of platform specific options.
/// </summary>
const std::function<void(web::http::client::native_handle)>& get_native_session_handle_options_callback() const
{
return m_impl->get_native_session_handle_options_callback();
}

std::shared_ptr<_operation_context> _get_impl() const
{
return m_impl;
Expand Down
47 changes: 40 additions & 7 deletions Microsoft.WindowsAzure.Storage/includes/was/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,22 +232,45 @@ namespace azure { namespace storage {
{
}

class sas_credential
{
public:
explicit sas_credential(utility::string_t sas_token) : m_sas_token(std::move(sas_token))
{
}

private:
utility::string_t m_sas_token;

friend class storage_credentials;
};

/// <summary>
/// Initializes a new instance of the <see cref="azure::storage::storage_credentials" /> class with the specified shared access signature token.
/// </summary>
/// <param name="sas_token">A string containing the shared access signature token.</param>
explicit storage_credentials(utility::string_t sas_token)
: m_sas_token(std::move(sas_token))
: storage_credentials(utility::string_t(), sas_credential{sas_token})
{
}

/// <summary>
/// Initializes a new instance of the <see cref="azure::storage::storage_credentials" /> class with the specified account name and shared access signature token.
/// </summary>
/// <param name="account_name">A string containing the name of the storage account.</param>
/// <param name="sas_token">An <see cref="azure::storage::sas_credential" /> containing shared access signature token.</param>
storage_credentials(utility::string_t account_name, sas_credential sas_token)
: m_account_name(std::move(account_name)), m_sas_token(std::move(sas_token.m_sas_token))
{
if (m_sas_token.size() >= 1 && m_sas_token.at(0) == _XPLATSTR('?'))
{
m_sas_token = m_sas_token.substr(1);
}

auto splitted_query = web::uri::split_query(m_sas_token);
if (!splitted_query.empty())
{
splitted_query[protocol::uri_query_sas_api_version] = protocol::header_value_storage_version;
splitted_query[protocol::uri_query_sas_api_version] = protocol::header_value_storage_version;
web::uri_builder builder;
for (const auto& kv : splitted_query)
{
Expand Down Expand Up @@ -278,7 +301,17 @@ namespace azure { namespace storage {
/// </summary>
/// <param name="token">A <see cref="azure::storage::storage_credentials::bearer_token_credential" /> class containing bearer token.</param>
template<class T, typename std::enable_if<std::is_same<typename std::decay<T>::type, bearer_token_credential>::value>::type* = nullptr>
explicit storage_credentials(T&& token) : m_bearer_token_credential(std::make_shared<bearer_token_credential>())
explicit storage_credentials(T&& token) : storage_credentials(utility::string_t(), std::forward<T>(token))
{
}

/// <summary>
/// Initializes a new instance of the <see cref="azure::storage::storage_credentials" /> class with the specified account name and bearer token.
/// </summary>
/// <param name="account_name">A string containing the name of the storage account.</param>
/// <param name="token">A <see cref="azure::storage::storage_credentials::bearer_token_credential" /> class containing bearer token.</param>
template<class T, typename std::enable_if<std::is_same<typename std::decay<T>::type, bearer_token_credential>::value>::type* = nullptr>
storage_credentials(utility::string_t account_name, T&& token) : m_account_name(std::move(account_name)), m_bearer_token_credential(std::make_shared<bearer_token_credential>())
{
m_bearer_token_credential->m_bearer_token = std::forward<T>(token).m_bearer_token;
}
Expand Down Expand Up @@ -399,7 +432,7 @@ namespace azure { namespace storage {
/// <returns><c>true</c> if the credentials are for anonymous access; otherwise, <c>false</c>.</returns>
bool is_anonymous() const
{
return m_sas_token.empty() && m_account_name.empty() && !is_bearer_token();
return m_sas_token.empty() && m_account_key.empty() && !is_bearer_token();
}

/// <summary>
Expand All @@ -408,7 +441,7 @@ namespace azure { namespace storage {
/// <returns><c>true</c> if the credentials are a shared access signature token; otherwise, <c>false</c>.</returns>
bool is_sas() const
{
return !m_sas_token.empty() && m_account_name.empty() && !is_bearer_token();
return !m_sas_token.empty() && m_account_key.empty() && !is_bearer_token();
}

/// <summary>
Expand All @@ -417,7 +450,7 @@ namespace azure { namespace storage {
/// <returns><c>true</c> if the credentials are a shared key; otherwise, <c>false</c>.</returns>
bool is_shared_key() const
{
return m_sas_token.empty() && !m_account_name.empty() && !is_bearer_token();
return m_sas_token.empty() && !m_account_key.empty() && !is_bearer_token();
}

/// <summary>
Expand Down
Loading

0 comments on commit 0a0c96b

Please # to comment.