Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Respect Sas token in conn string #8940

Merged
merged 4 commits into from
Dec 3, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 0 additions & 78 deletions sdk/storage/Azure.Storage.Blobs/tests/BlobBaseClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,84 +60,6 @@ public void Ctor_ConnectionString()
Assert.AreEqual("accountName", builder2.AccountName);
}

[Test]
public async Task Ctor_ConnectionString_Sas()
{
// Arrange
var sasBuilder = new AccountSasBuilder
{
ExpiresOn = Recording.UtcNow.AddHours(1),
Services = AccountSasServices.All,
ResourceTypes = AccountSasResourceTypes.All,
Protocol = SasProtocol.Https,
};
sasBuilder.SetPermissions(AccountSasPermissions.All);
var cred = new StorageSharedKeyCredential(TestConfigDefault.AccountName, TestConfigDefault.AccountKey);
string sasToken = sasBuilder.ToSasQueryParameters(cred).ToString();
var sasCred = new SharedAccessSignatureCredentials(sasToken);

(Uri, Uri) blobUri = StorageConnectionString.ConstructBlobEndpoint(
"https",
TestConfigDefault.AccountName,
default,
sasToken);

StorageConnectionString conn1 =
new StorageConnectionString(
sasCred,
blobUri,
(default, default),
(default, default));

BlobContainerClient containerClient1 = GetClient(conn1.ToString(exportSecrets: true));

// Also test with a connection string not containing the blob endpoint.
// This should still work provided account name and Sas credential are present.
StorageConnectionString conn2 = TestExtensions.CreateStorageConnectionString(
sasCred,
TestConfigDefault.AccountName);

BlobContainerClient containerClient2 = GetClient(conn2.ToString(exportSecrets: true));

BlobContainerClient GetClient(string connectionString) =>
InstrumentClient(
new BlobContainerClient(
connectionString,
GetNewContainerName(),
GetOptions()));

try
{
// Act
await containerClient1.CreateAsync();
BlobClient blob1 = InstrumentClient(containerClient1.GetBlobClient(GetNewBlobName()));

await containerClient2.CreateAsync();
BlobClient blob2 = InstrumentClient(containerClient2.GetBlobClient(GetNewBlobName()));

var data = GetRandomBuffer(Constants.KB);

Response<BlobContentInfo> info1 = await blob1.UploadAsync(
new MemoryStream(data),
true,
new CancellationToken());
Response<BlobContentInfo> info2 = await blob2.UploadAsync(
new MemoryStream(data),
true,
new CancellationToken());

// Assert
Assert.IsNotNull(info1.Value.ETag);
Assert.IsNotNull(info2.Value.ETag);
}
finally
{
// Clean up
await containerClient1.DeleteAsync();
await containerClient2.DeleteAsync();
}
}

[Test]
public void Ctor_Uri()
{
Expand Down
236 changes: 236 additions & 0 deletions sdk/storage/Azure.Storage.Blobs/tests/ContainerClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Azure.Core.Testing;
using Azure.Identity;
using Azure.Storage.Blobs.Models;
using Azure.Storage.Blobs.Specialized;
using Azure.Storage.Sas;
using Azure.Storage.Test;
using Azure.Storage.Test.Shared;
using Azure.Storage.Tests;
Expand Down Expand Up @@ -48,6 +50,240 @@ public void Ctor_ConnectionString()
Assert.AreEqual(accountName, builder.AccountName);
}

[Test]
public async Task Ctor_ConnectionString_Sas()
{
// Arrange
string sasToken = GetSasToken(AccountSasServices.All, AccountSasResourceTypes.All, AccountSasPermissions.All);
var sasCred = new SharedAccessSignatureCredentials(sasToken);

(Uri, Uri) blobUri = StorageConnectionString.ConstructBlobEndpoint(
Constants.Https,
TestConfigDefault.AccountName,
default,
default);

StorageConnectionString conn1 =
new StorageConnectionString(
sasCred,
blobUri,
(default, default),
(default, default));

BlobContainerClient containerClient1 = GetBlobContainerClient(conn1.ToString(exportSecrets: true));

// Also test with a connection string not containing the blob endpoint.
// This should still work provided account name and Sas credential are present.
StorageConnectionString conn2 = TestExtensions.CreateStorageConnectionString(
sasCred,
TestConfigDefault.AccountName);

BlobContainerClient containerClient2 = GetBlobContainerClient(conn2.ToString(exportSecrets: true));

try
{
// Act
await containerClient1.CreateAsync();
BlobClient blob1 = InstrumentClient(containerClient1.GetBlobClient(GetNewBlobName()));

await containerClient2.CreateAsync();
BlobClient blob2 = InstrumentClient(containerClient2.GetBlobClient(GetNewBlobName()));

var data = GetRandomBuffer(Constants.KB);

Response<BlobContentInfo> info1 = await blob1.UploadAsync(
new MemoryStream(data),
true,
new CancellationToken());
Response<BlobContentInfo> info2 = await blob2.UploadAsync(
new MemoryStream(data),
true,
new CancellationToken());

// Assert
Assert.IsNotNull(info1.Value.ETag);
Assert.IsNotNull(info2.Value.ETag);
}
finally
{
// Clean up
await containerClient1.DeleteAsync();
await containerClient2.DeleteAsync();
}
}

[Test]
public async Task Ctor_ConnectionString_Sas_Resource_Types_Container()
{
// Arrange
string sasToken = GetSasToken(AccountSasServices.All, AccountSasResourceTypes.Container, AccountSasPermissions.All);
var sasCred = new SharedAccessSignatureCredentials(sasToken);

(Uri, Uri) blobUri = StorageConnectionString.ConstructBlobEndpoint(
Constants.Https,
TestConfigDefault.AccountName,
default,
default);

StorageConnectionString conn =
new StorageConnectionString(
sasCred,
blobUri,
(default, default),
(default, default));

BlobContainerClient containerClient = GetBlobContainerClient(conn.ToString(exportSecrets: true));

try
{
// Act
// This should succeed as we have Container resourceType permission
await containerClient.CreateAsync();

BlobClient blob = InstrumentClient(containerClient.GetBlobClient(GetNewBlobName()));

var data = GetRandomBuffer(Constants.KB);

// This should throw as we do not have Object permission
await TestHelper.AssertExpectedExceptionAsync<RequestFailedException>(
blob.UploadAsync(new MemoryStream(data)),
e => Assert.AreEqual("AuthorizationResourceTypeMismatch", e.ErrorCode));
}
finally
{
// Clean up
await containerClient.DeleteAsync();
}
}

[Test]
public async Task Ctor_ConnectionString_Sas_Resource_Types_Service()
{
// Arrange
string sasToken = GetSasToken(AccountSasServices.All, AccountSasResourceTypes.Service, AccountSasPermissions.All);
var sasCred = new SharedAccessSignatureCredentials(sasToken);

(Uri, Uri) blobUri = StorageConnectionString.ConstructBlobEndpoint(
Constants.Https,
TestConfigDefault.AccountName,
default,
default);

StorageConnectionString conn =
new StorageConnectionString(
sasCred,
blobUri,
(default, default),
(default, default));

BlobContainerClient containerClient = GetBlobContainerClient(conn.ToString(exportSecrets: true));

// This should throw as we do not have Container permission
await TestHelper.AssertExpectedExceptionAsync<RequestFailedException>(
containerClient.CreateAsync(),
e => Assert.AreEqual("AuthorizationResourceTypeMismatch", e.ErrorCode));
}

[Test]
public async Task Ctor_ConnectionString_Sas_Permissions_ReadOnly()
{
// Arrange
string sasToken = GetSasToken(AccountSasServices.All, AccountSasResourceTypes.All, AccountSasPermissions.Read);
var sasCred = new SharedAccessSignatureCredentials(sasToken);

(Uri, Uri) blobUri = StorageConnectionString.ConstructBlobEndpoint(
Constants.Https,
TestConfigDefault.AccountName,
default,
default);

StorageConnectionString conn =
new StorageConnectionString(
sasCred,
blobUri,
(default, default),
(default, default));

BlobContainerClient containerClient = GetBlobContainerClient(conn.ToString(exportSecrets: true));

// Act

var data = GetRandomBuffer(Constants.KB);

// This should throw as we only have read permission
await TestHelper.AssertExpectedExceptionAsync<RequestFailedException>(
containerClient.CreateAsync(),
e => Assert.AreEqual("AuthorizationPermissionMismatch", e.ErrorCode));
}

[Test]
public async Task Ctor_ConnectionString_Sas_Permissions_WriteOnly()
{
// Arrange
string sasToken = GetSasToken(
AccountSasServices.All,
AccountSasResourceTypes.All,
// include Delete so we can clean up the test
AccountSasPermissions.Write | AccountSasPermissions.Delete);
var sasCred = new SharedAccessSignatureCredentials(sasToken);

(Uri, Uri) blobUri = StorageConnectionString.ConstructBlobEndpoint(
Constants.Https,
TestConfigDefault.AccountName,
default,
default);

StorageConnectionString conn =
new StorageConnectionString(
sasCred,
blobUri,
(default, default),
(default, default));

BlobContainerClient containerClient = GetBlobContainerClient(conn.ToString(exportSecrets: true));

try
{
// Act
await containerClient.CreateAsync();

BlobClient blob = InstrumentClient(containerClient.GetBlobClient(GetNewBlobName()));

var data = GetRandomBuffer(Constants.KB);

// This should throw as we do not have read permission
await TestHelper.AssertExpectedExceptionAsync<RequestFailedException>(
blob.GetPropertiesAsync(),
e => Assert.AreEqual("AuthorizationPermissionMismatch", e.ErrorCode));
}
finally
{
// Clean up
await containerClient.DeleteAsync();
}
}

private BlobContainerClient GetBlobContainerClient(string connectionString) =>
InstrumentClient(
new BlobContainerClient(
connectionString,
GetNewContainerName(),
GetOptions()));

private string GetSasToken(AccountSasServices services, AccountSasResourceTypes resourceTypes, AccountSasPermissions permissions)
{
var sasBuilder = new AccountSasBuilder
{
ExpiresOn = Recording.UtcNow.AddHours(1),
Services = services,
ResourceTypes = resourceTypes,
Protocol = SasProtocol.Https,
};
sasBuilder.SetPermissions(permissions);
var cred = new StorageSharedKeyCredential(TestConfigDefault.AccountName, TestConfigDefault.AccountKey);
return sasBuilder.ToSasQueryParameters(cred).ToString();
}

[Test]
public void Ctor_Uri()
{
Expand Down
Loading