@@ -212,24 +212,40 @@ namespace azure { namespace storage {
212212 {
213213 }
214214
215+ class account_key_credential
216+ {
217+ public:
218+ account_key_credential (std::vector<uint8_t > account_key = std::vector<uint8_t >()) : m_account_key(std::move(account_key))
219+ {
220+ }
221+
222+ public:
223+ std::vector<uint8_t > m_account_key;
224+
225+ private:
226+ pplx::extensibility::reader_writer_lock_t m_mutex;
227+
228+ friend class storage_credentials ;
229+ };
230+
215231 // / <summary>
216232 // / Initializes a new instance of the <see cref="azure::storage::storage_credentials" /> class with the specified account name and key value.
217233 // / </summary>
218234 // / <param name="account_name">A string containing the name of the storage account.</param>
219235 // / <param name="account_key">A string containing the Base64-encoded account access key.</param>
220- storage_credentials (utility::string_t account_name, const utility::string_t & account_key)
221- : m_account_name(std::move(account_name)), m_account_key(utility::conversions::from_base64(account_key))
236+ storage_credentials (utility::string_t account_name, const utility::string_t & account_key) : m_account_name(std::move(account_name)), m_account_key_credential(std::make_shared<account_key_credential>())
222237 {
238+ m_account_key_credential->m_account_key = std::move (utility::conversions::from_base64 (account_key));
223239 }
224240
225241 // / <summary>
226242 // / Initializes a new instance of the <see cref="azure::storage::storage_credentials" /> class with the specified account name and key value.
227243 // / </summary>
228244 // / <param name="account_name">A string containing the name of the storage account.</param>
229245 // / <param name="account_key">An array of bytes that represent the account access key.</param>
230- storage_credentials (utility::string_t account_name, std::vector<uint8_t > account_key)
231- : m_account_name(std::move(account_name)), m_account_key(std::move(account_key))
246+ storage_credentials (utility::string_t account_name, std::vector<uint8_t > account_key) : m_account_name(std::move(account_name)), m_account_key_credential(std::make_shared<account_key_credential>())
232247 {
248+ m_account_key_credential->m_account_key = std::move (account_key);
233249 }
234250
235251 class sas_credential
@@ -339,9 +355,10 @@ namespace azure { namespace storage {
339355 m_sas_token = std::forward<T>(other).m_sas_token ;
340356 m_sas_token_with_api_version = std::forward<T>(other).m_sas_token_with_api_version ;
341357 m_account_name = std::forward<T>(other).m_account_name ;
342- m_account_key = std::forward<T>(other).m_account_key ;
358+ std::atomic_store_explicit (&m_account_key_credential, std::atomic_load_explicit (&other.m_account_key_credential , std::memory_order_acquire), std::memory_order_release);
359+ auto key_ptr = std::forward<T>(other).m_account_key_credential ;
343360 std::atomic_store_explicit (&m_bearer_token_credential, std::atomic_load_explicit (&other.m_bearer_token_credential , std::memory_order_acquire), std::memory_order_release);
344- auto ptr = std::forward<T>(other).m_bearer_token_credential ;
361+ auto token_ptr = std::forward<T>(other).m_bearer_token_credential ;
345362 }
346363 return *this ;
347364 }
@@ -387,7 +404,43 @@ namespace azure { namespace storage {
387404 // / <returns>An array of bytes that contains the key.</returns>
388405 const std::vector<uint8_t >& account_key () const
389406 {
390- return m_account_key;
407+ auto account_key_ptr = std::atomic_load_explicit (&m_account_key_credential, std::memory_order_acquire);
408+ pplx::extensibility::scoped_read_lock_t guard (account_key_ptr->m_mutex );
409+ return account_key_ptr->m_account_key ;
410+ }
411+
412+ // / <summary>
413+ // / Sets the accounts for the credentials.
414+ // / </summary>
415+ // / <param name="account_key">A string containing the Base64-encoded account access key.</param>
416+ void set_account_key (const utility::string_t & account_key)
417+ {
418+ set_account_key (utility::conversions::from_base64 (account_key));
419+ }
420+
421+ // / <summary>
422+ // / Sets the accounts for the credentials.
423+ // / </summary>
424+ // / <param name="account_key">An array of bytes that represent the account access key.</param>
425+ void set_account_key (std::vector<uint8_t > account_key)
426+ {
427+ auto account_key_ptr = std::atomic_load_explicit (&m_account_key_credential, std::memory_order_acquire);
428+ if (!account_key_ptr)
429+ {
430+ auto new_credential = std::make_shared<account_key_credential>();
431+ new_credential->m_account_key = std::move (account_key);
432+ /* Compares m_account_key_credential and account_key_ptr(nullptr).
433+ * If they are equivalent, assigns new_credential into m_account_key_credential and returns true.
434+ * If they are not equivalent, assigns m_account_key_credential into m_account_key and returns false.
435+ */
436+ bool set = std::atomic_compare_exchange_strong_explicit (&m_account_key_credential, &account_key_ptr, new_credential, std::memory_order_release, std::memory_order_acquire);
437+ if (set) {
438+ return ;
439+ }
440+ account_key = std::move (new_credential->m_account_key );
441+ }
442+ pplx::extensibility::scoped_rw_lock_t guard (account_key_ptr->m_mutex );
443+ account_key_ptr->m_account_key = std::move (account_key);
391444 }
392445
393446 // / <summary>
@@ -432,7 +485,7 @@ namespace azure { namespace storage {
432485 // / <returns><c>true</c> if the credentials are for anonymous access; otherwise, <c>false</c>.</returns>
433486 bool is_anonymous () const
434487 {
435- return m_sas_token.empty () && m_account_key. empty () && !is_bearer_token ();
488+ return m_sas_token.empty () && ! is_account_key () && !is_bearer_token ();
436489 }
437490
438491 // / <summary>
@@ -441,7 +494,7 @@ namespace azure { namespace storage {
441494 // / <returns><c>true</c> if the credentials are a shared access signature token; otherwise, <c>false</c>.</returns>
442495 bool is_sas () const
443496 {
444- return !m_sas_token.empty () && m_account_key. empty () && !is_bearer_token ();
497+ return !m_sas_token.empty () && ! is_account_key () && !is_bearer_token ();
445498 }
446499
447500 // / <summary>
@@ -450,7 +503,7 @@ namespace azure { namespace storage {
450503 // / <returns><c>true</c> if the credentials are a shared key; otherwise, <c>false</c>.</returns>
451504 bool is_shared_key () const
452505 {
453- return m_sas_token.empty () && !m_account_key. empty () && !is_bearer_token ();
506+ return m_sas_token.empty () && is_account_key () && !is_bearer_token ();
454507 }
455508
456509 // / <summary>
@@ -467,14 +520,28 @@ namespace azure { namespace storage {
467520 return !token_ptr->m_bearer_token .empty ();
468521 }
469522
523+ // / <summary>
524+ // / Indicates whether the credentials are an account key.
525+ // / </summary>
526+ // / <returns><c>true</c> if the credentials are an account key; otherwise <c>false</c>.</returns>
527+ bool is_account_key () const {
528+ auto account_key_ptr = std::atomic_load_explicit (&m_account_key_credential, std::memory_order_acquire);
529+ if (!account_key_ptr)
530+ {
531+ return false ;
532+ }
533+ pplx::extensibility::scoped_read_lock_t guard (account_key_ptr->m_mutex );
534+ return !account_key_ptr->m_account_key .empty ();
535+ }
536+
470537 private:
471538
472539 utility::string_t m_sas_token;
473540 utility::string_t m_sas_token_with_api_version;
474541 utility::string_t m_account_name;
475- std::vector<uint8_t > m_account_key;
476542 // We use std::atomic_{load/store/...} functions specialized for std::shared_ptr<T> to access this member, since std::atomic<std::shared_ptr<T>> is not available until C++20.
477543 // These become deprecated since C++20, but still compile.
544+ std::shared_ptr<account_key_credential> m_account_key_credential;
478545 std::shared_ptr<bearer_token_credential> m_bearer_token_credential;
479546 };
480547
0 commit comments