@@ -212,24 +212,40 @@ namespace azure { namespace storage {
212
212
{
213
213
}
214
214
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
+
215
231
// / <summary>
216
232
// / Initializes a new instance of the <see cref="azure::storage::storage_credentials" /> class with the specified account name and key value.
217
233
// / </summary>
218
234
// / <param name="account_name">A string containing the name of the storage account.</param>
219
235
// / <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>())
222
237
{
238
+ m_account_key_credential->m_account_key = std::move (utility::conversions::from_base64 (account_key));
223
239
}
224
240
225
241
// / <summary>
226
242
// / Initializes a new instance of the <see cref="azure::storage::storage_credentials" /> class with the specified account name and key value.
227
243
// / </summary>
228
244
// / <param name="account_name">A string containing the name of the storage account.</param>
229
245
// / <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>())
232
247
{
248
+ m_account_key_credential->m_account_key = std::move (account_key);
233
249
}
234
250
235
251
class sas_credential
@@ -339,9 +355,10 @@ namespace azure { namespace storage {
339
355
m_sas_token = std::forward<T>(other).m_sas_token ;
340
356
m_sas_token_with_api_version = std::forward<T>(other).m_sas_token_with_api_version ;
341
357
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 ;
343
360
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 ;
345
362
}
346
363
return *this ;
347
364
}
@@ -387,7 +404,43 @@ namespace azure { namespace storage {
387
404
// / <returns>An array of bytes that contains the key.</returns>
388
405
const std::vector<uint8_t >& account_key () const
389
406
{
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);
391
444
}
392
445
393
446
// / <summary>
@@ -432,7 +485,7 @@ namespace azure { namespace storage {
432
485
// / <returns><c>true</c> if the credentials are for anonymous access; otherwise, <c>false</c>.</returns>
433
486
bool is_anonymous () const
434
487
{
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 ();
436
489
}
437
490
438
491
// / <summary>
@@ -441,7 +494,7 @@ namespace azure { namespace storage {
441
494
// / <returns><c>true</c> if the credentials are a shared access signature token; otherwise, <c>false</c>.</returns>
442
495
bool is_sas () const
443
496
{
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 ();
445
498
}
446
499
447
500
// / <summary>
@@ -450,7 +503,7 @@ namespace azure { namespace storage {
450
503
// / <returns><c>true</c> if the credentials are a shared key; otherwise, <c>false</c>.</returns>
451
504
bool is_shared_key () const
452
505
{
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 ();
454
507
}
455
508
456
509
// / <summary>
@@ -467,14 +520,28 @@ namespace azure { namespace storage {
467
520
return !token_ptr->m_bearer_token .empty ();
468
521
}
469
522
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
+
470
537
private:
471
538
472
539
utility::string_t m_sas_token;
473
540
utility::string_t m_sas_token_with_api_version;
474
541
utility::string_t m_account_name;
475
- std::vector<uint8_t > m_account_key;
476
542
// 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.
477
543
// These become deprecated since C++20, but still compile.
544
+ std::shared_ptr<account_key_credential> m_account_key_credential;
478
545
std::shared_ptr<bearer_token_credential> m_bearer_token_credential;
479
546
};
480
547
0 commit comments