forked from Azure/azure-sdk-for-net
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add AzureSasCredential (Azure#17636)
* Add AzureSasCredential * corner case. * api. * doc update. * less allocations. * call base last. * Revert "less allocations." This reverts commit 6375606. * validation feedback. * policy rename. * another attempt to reduce allocations. * Revert "another attempt to reduce allocations." This reverts commit 89cc867. * changelog.
- Loading branch information
1 parent
24d372f
commit 4ff3601
Showing
9 changed files
with
205 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
using System.ComponentModel; | ||
using System.Threading; | ||
using Azure.Core; | ||
|
||
namespace Azure | ||
{ | ||
/// <summary> | ||
/// Shared access signature credential used to authenticate to an Azure Service. | ||
/// It provides the ability to update the shared access signature without creating a new client. | ||
/// </summary> | ||
public class AzureSasCredential | ||
{ | ||
private string _signature; | ||
|
||
/// <summary> | ||
/// Shared access signature used to authenticate to an Azure service. | ||
/// </summary> | ||
[EditorBrowsable(EditorBrowsableState.Never)] | ||
public string Signature | ||
{ | ||
get => Volatile.Read(ref _signature); | ||
private set => Volatile.Write(ref _signature, value); | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="AzureSasCredential"/> class. | ||
/// </summary> | ||
/// <param name="signature">Shared access signature to use to authenticate with the Azure service.</param> | ||
/// <exception cref="System.ArgumentNullException"> | ||
/// Thrown when the <paramref name="signature"/> is null. | ||
/// </exception> | ||
/// <exception cref="System.ArgumentException"> | ||
/// Thrown when the <paramref name="signature"/> is empty. | ||
/// </exception> | ||
#pragma warning disable CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable. | ||
public AzureSasCredential(string signature) => Update(signature); | ||
#pragma warning restore CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable. | ||
|
||
/// <summary> | ||
/// Updates the shared access signature. | ||
/// This is intended to be used when you've regenerated your shared access signature | ||
/// and want to update long lived clients. | ||
/// </summary> | ||
/// <param name="signature">Shared access signature to authenticate the service against.</param> | ||
/// <exception cref="System.ArgumentNullException"> | ||
/// Thrown when the <paramref name="signature"/> is null. | ||
/// </exception> | ||
/// <exception cref="System.ArgumentException"> | ||
/// Thrown when the <paramref name="signature"/> is empty. | ||
/// </exception> | ||
public void Update(string signature) | ||
{ | ||
Argument.AssertNotNullOrWhiteSpace(signature, nameof(signature)); | ||
Signature = signature; | ||
} | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
sdk/core/Azure.Core/src/Shared/AzureSasCredentialSynchronousPolicy.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
using System; | ||
using Azure.Core.Pipeline; | ||
|
||
namespace Azure.Core | ||
{ | ||
internal class AzureSasCredentialSynchronousPolicy : HttpPipelineSynchronousPolicy | ||
{ | ||
private readonly AzureSasCredential _credential; | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="AzureSasCredentialSynchronousPolicy"/> class. | ||
/// </summary> | ||
/// <param name="credential">The <see cref="AzureSasCredentialSynchronousPolicy"/> used to authenticate requests.</param> | ||
public AzureSasCredentialSynchronousPolicy(AzureSasCredential credential) | ||
{ | ||
Argument.AssertNotNull(credential, nameof(credential)); | ||
_credential = credential; | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override void OnSendingRequest(HttpMessage message) | ||
{ | ||
string query = message.Request.Uri.Query; | ||
string signature = _credential.Signature; | ||
if (signature.StartsWith("?", StringComparison.InvariantCulture)) | ||
{ | ||
signature = signature.Substring(1); | ||
} | ||
if (!query.Contains(signature)) | ||
{ | ||
query = string.IsNullOrEmpty(query) ? '?' + signature : query + '&' + signature; | ||
message.Request.Uri.Query = query; | ||
} | ||
|
||
base.OnSendingRequest(message); | ||
} | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
sdk/core/Azure.Core/tests/AzureSasCredentialSynchronousPolicyTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Azure.Core.Pipeline; | ||
using Azure.Core.TestFramework; | ||
using NUnit.Framework; | ||
|
||
namespace Azure.Core.Tests | ||
{ | ||
public class AzureSasCredentialSynchronousPolicyTests : PolicyTestBase | ||
{ | ||
[TestCase("sig=test_signature_value")] | ||
[TestCase("?sig=test_signature_value")] | ||
public async Task SetsSignatureEmptyQuery(string signatureValue) | ||
{ | ||
var transport = new MockTransport(new MockResponse(200)); | ||
var sasPolicy = new AzureSasCredentialSynchronousPolicy(new AzureSasCredential(signatureValue)); | ||
|
||
await SendGetRequest(transport, sasPolicy); | ||
|
||
Assert.AreEqual("?sig=test_signature_value", transport.SingleRequest.Uri.Query); | ||
} | ||
|
||
[TestCase("sig=test_signature_value")] | ||
[TestCase("?sig=test_signature_value")] | ||
public async Task SetsSignatureNonEmptyQuery(string signatureValue) | ||
{ | ||
var transport = new MockTransport(new MockResponse(200)); | ||
var sasPolicy = new AzureSasCredentialSynchronousPolicy(new AzureSasCredential(signatureValue)); | ||
string query = "?foo=bar"; | ||
|
||
await SendGetRequest(transport, sasPolicy, query: query); | ||
|
||
Assert.AreEqual($"?foo=bar&sig=test_signature_value", transport.SingleRequest.Uri.Query); | ||
} | ||
|
||
[TestCase("sig=test_signature_value")] | ||
[TestCase("?sig=test_signature_value")] | ||
public async Task VerifyRetryEmptyQuery(string signatureValue) | ||
{ | ||
var transport = new MockTransport(new MockResponse(200), new MockResponse(200)); | ||
var sasPolicy = new AzureSasCredentialSynchronousPolicy(new AzureSasCredential(signatureValue)); | ||
|
||
using (Request request = transport.CreateRequest()) | ||
{ | ||
request.Method = RequestMethod.Get; | ||
var pipeline = new HttpPipeline(transport, new[] { sasPolicy }); | ||
await pipeline.SendRequestAsync(request, CancellationToken.None); | ||
await pipeline.SendRequestAsync(request, CancellationToken.None); | ||
} | ||
|
||
Assert.AreEqual("?sig=test_signature_value", transport.Requests[0].Uri.Query); | ||
} | ||
|
||
[TestCase("sig=test_signature_value")] | ||
[TestCase("?sig=test_signature_value")] | ||
public async Task VerifyRetryNonEmptyQuery(string signatureValue) | ||
{ | ||
var transport = new MockTransport(new MockResponse(200), new MockResponse(200)); | ||
var sasPolicy = new AzureSasCredentialSynchronousPolicy(new AzureSasCredential(signatureValue)); | ||
string query = "?foo=bar"; | ||
|
||
using (Request request = transport.CreateRequest()) | ||
{ | ||
request.Method = RequestMethod.Get; | ||
request.Uri.Query = query; | ||
var pipeline = new HttpPipeline(transport, new[] { sasPolicy }); | ||
await pipeline.SendRequestAsync(request, CancellationToken.None); | ||
await pipeline.SendRequestAsync(request, CancellationToken.None); | ||
} | ||
|
||
Assert.AreEqual("?foo=bar&sig=test_signature_value", transport.Requests[0].Uri.Query); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters