azure-sdk-for-cpp/sdk/storage/test/blobs/blob_sas_test.cpp
2020-07-29 16:11:21 +08:00

465 lines
18 KiB
C++

// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
#include "blob_container_client_test.hpp"
#include "blobs/blob_sas_builder.hpp"
namespace Azure { namespace Storage { namespace Test {
TEST_F(BlobContainerClientTest, BlobSasTest)
{
AccountSasBuilder accountSasBuilder;
accountSasBuilder.Protocol = SasProtocol::HttpsAndHtttp;
accountSasBuilder.StartsOn
= ToISO8601(std::chrono::system_clock::now() - std::chrono::minutes(5));
accountSasBuilder.ExpiresOn
= ToISO8601(std::chrono::system_clock::now() + std::chrono::minutes(60));
accountSasBuilder.Services = AccountSasServices::Blobs;
accountSasBuilder.ResourceTypes = AccountSasResource::Object | AccountSasResource::Container;
std::string blobName = RandomString();
Blobs::BlobSasBuilder blobSasBuilder;
blobSasBuilder.Protocol = SasProtocol::HttpsAndHtttp;
blobSasBuilder.StartsOn = ToISO8601(std::chrono::system_clock::now() - std::chrono::minutes(5));
blobSasBuilder.ExpiresOn
= ToISO8601(std::chrono::system_clock::now() + std::chrono::minutes(60));
blobSasBuilder.ContainerName = m_containerName;
blobSasBuilder.BlobName = blobName;
blobSasBuilder.Resource = Blobs::BlobSasResource::Blob;
Blobs::BlobSasBuilder containerSasBuilder = blobSasBuilder;
containerSasBuilder.BlobName.clear();
containerSasBuilder.Resource = Blobs::BlobSasResource::Container;
auto keyCredential
= Details::ParseConnectionString(StandardStorageConnectionString()).KeyCredential;
auto accountName = keyCredential->AccountName;
auto blobServiceClient0
= Blobs::BlobServiceClient::CreateFromConnectionString(StandardStorageConnectionString());
auto blobContainerClient0 = blobServiceClient0.GetBlobContainerClient(m_containerName);
auto blobClient0 = blobContainerClient0.GetAppendBlobClient(blobName);
auto serviceUri = blobServiceClient0.GetUri();
auto containerUri = blobContainerClient0.GetUri();
auto blobUri = blobClient0.GetUri();
auto blobServiceClient1 = Blobs::BlobServiceClient(
serviceUri,
std::make_shared<Azure::Core::Credentials::ClientSecretCredential>(
AadTenantId(), AadClientId(), AadClientSecret()));
auto userDelegationKey = *blobServiceClient1.GetUserDelegationKey(
ToISO8601(std::chrono::system_clock::now() - std::chrono::minutes(5)),
ToISO8601(std::chrono::system_clock::now() + std::chrono::minutes(60)));
auto verify_blob_read = [&](const std::string& sas) {
EXPECT_NO_THROW(blobClient0.Create());
auto blobClient = Blobs::AppendBlobClient(blobUri + sas);
auto downloadedContent = blobClient.Download();
EXPECT_TRUE(ReadBodyStream(downloadedContent->BodyStream).empty());
};
auto verify_blob_write = [&](const std::string& sas) {
auto blobClient = Blobs::AppendBlobClient(blobUri + sas);
EXPECT_NO_THROW(blobClient.Create());
};
auto verify_blob_delete = [&](const std::string& sas) {
blobClient0.Create();
auto blobClient = Blobs::AppendBlobClient(blobUri + sas);
EXPECT_NO_THROW(blobClient.Delete());
};
auto verify_blob_add = [&](const std::string& sas) {
blobClient0.Create();
std::string content = "Hello world";
auto blockContent = Azure::Core::Http::MemoryBodyStream(
reinterpret_cast<const uint8_t*>(content.data()), content.size());
auto blobClient = Blobs::AppendBlobClient(blobUri + sas);
EXPECT_NO_THROW(blobClient.AppendBlock(&blockContent));
};
auto verify_blob_list = [&](const std::string& sas) {
auto blobContainerClient = Blobs::BlobContainerClient(containerUri + sas);
EXPECT_NO_THROW(blobContainerClient.ListBlobsFlat());
};
auto verify_blob_create = [&](const std::string& sas) {
try
{
blobClient0.Delete();
}
catch (StorageError&)
{
}
auto blobClient = Blobs::AppendBlobClient(blobUri + sas);
blobClient.Create();
blobClient.CreateSnapshot();
Blobs::DeleteBlobOptions options;
options.DeleteSnapshots = Blobs::DeleteSnapshotsOption::IncludeSnapshots;
blobClient0.Delete(options);
};
auto verify_blob_tags = [&](const std::string& sas) {
unused(sas);
// TODO: Add test for blob tags
};
auto verify_blob_filter = [&](const std::string& sas) {
unused(sas);
// TODO: Add test for blob tags
};
auto verify_blob_delete_version = [&](const std::string& sas) {
unused(sas);
// TODO: Add test for versions
};
for (auto permissions : {
AccountSasPermissions::All,
AccountSasPermissions::Read,
AccountSasPermissions::Write,
AccountSasPermissions::Delete,
AccountSasPermissions::DeleteVersion,
AccountSasPermissions::List,
AccountSasPermissions::Add,
AccountSasPermissions::Create,
AccountSasPermissions::Tags,
AccountSasPermissions::Filter,
})
{
accountSasBuilder.SetPermissions(permissions);
auto sasToken = accountSasBuilder.ToSasQueryParameters(*keyCredential);
if ((permissions & AccountSasPermissions::Read) == AccountSasPermissions::Read)
{
verify_blob_read(sasToken);
}
if ((permissions & AccountSasPermissions::Write) == AccountSasPermissions::Write)
{
verify_blob_write(sasToken);
}
if ((permissions & AccountSasPermissions::Delete) == AccountSasPermissions::Delete)
{
verify_blob_delete(sasToken);
}
if ((permissions & AccountSasPermissions::DeleteVersion)
== AccountSasPermissions::DeleteVersion)
{
verify_blob_delete_version(sasToken);
}
if ((permissions & AccountSasPermissions::List) == AccountSasPermissions::List)
{
verify_blob_list(sasToken);
}
if ((permissions & AccountSasPermissions::Add) == AccountSasPermissions::Add)
{
verify_blob_add(sasToken);
}
if ((permissions & AccountSasPermissions::Create) == AccountSasPermissions::Create)
{
verify_blob_create(sasToken);
}
if ((permissions & AccountSasPermissions::Tags) == AccountSasPermissions::Tags)
{
verify_blob_tags(sasToken);
}
if ((permissions & AccountSasPermissions::Filter) == AccountSasPermissions::Filter)
{
verify_blob_filter(sasToken);
}
}
for (auto permissions :
{Blobs::BlobSasPermissions::All,
Blobs::BlobSasPermissions::Read,
Blobs::BlobSasPermissions::Write,
Blobs::BlobSasPermissions::Delete,
Blobs::BlobSasPermissions::Add,
Blobs::BlobSasPermissions::Create,
Blobs::BlobSasPermissions::Tags,
Blobs::BlobSasPermissions::DeleteVersion})
{
blobSasBuilder.SetPermissions(permissions);
auto sasToken = blobSasBuilder.ToSasQueryParameters(*keyCredential);
auto sasToken2 = blobSasBuilder.ToSasQueryParameters(userDelegationKey, accountName);
if ((permissions & Blobs::BlobSasPermissions::Read) == Blobs::BlobSasPermissions::Read)
{
verify_blob_read(sasToken);
verify_blob_read(sasToken2);
}
if ((permissions & Blobs::BlobSasPermissions::Write) == Blobs::BlobSasPermissions::Write)
{
verify_blob_write(sasToken);
verify_blob_write(sasToken2);
}
if ((permissions & Blobs::BlobSasPermissions::Delete) == Blobs::BlobSasPermissions::Delete)
{
verify_blob_delete(sasToken);
verify_blob_delete(sasToken2);
}
if ((permissions & Blobs::BlobSasPermissions::Add) == Blobs::BlobSasPermissions::Add)
{
verify_blob_add(sasToken);
verify_blob_add(sasToken2);
}
if ((permissions & Blobs::BlobSasPermissions::Create) == Blobs::BlobSasPermissions::Create)
{
verify_blob_create(sasToken);
verify_blob_create(sasToken2);
}
if ((permissions & Blobs::BlobSasPermissions::Tags) == Blobs::BlobSasPermissions::Tags)
{
verify_blob_tags(sasToken);
verify_blob_tags(sasToken2);
}
if ((permissions & Blobs::BlobSasPermissions::DeleteVersion)
== Blobs::BlobSasPermissions::DeleteVersion)
{
verify_blob_delete_version(sasToken);
verify_blob_delete_version(sasToken2);
}
}
accountSasBuilder.SetPermissions(AccountSasPermissions::All);
// Expires
{
AccountSasBuilder builder2 = accountSasBuilder;
builder2.StartsOn = ToISO8601(std::chrono::system_clock::now() - std::chrono::minutes(5));
builder2.ExpiresOn = ToISO8601(std::chrono::system_clock::now() - std::chrono::minutes(1));
auto sasToken = builder2.ToSasQueryParameters(*keyCredential);
EXPECT_THROW(verify_blob_create(sasToken), StorageError);
}
// Without start time
{
AccountSasBuilder builder2 = accountSasBuilder;
builder2.StartsOn.Reset();
auto sasToken = builder2.ToSasQueryParameters(*keyCredential);
EXPECT_NO_THROW(verify_blob_create(sasToken));
}
// IP
{
AccountSasBuilder builder2 = accountSasBuilder;
builder2.IPRange = "1.1.1.1";
auto sasToken = builder2.ToSasQueryParameters(*keyCredential);
EXPECT_THROW(verify_blob_create(sasToken), StorageError);
builder2.IPRange = "0.0.0.0-255.255.255.255";
sasToken = builder2.ToSasQueryParameters(*keyCredential);
EXPECT_NO_THROW(verify_blob_create(sasToken));
}
// Account SAS Service
{
AccountSasBuilder builder2 = accountSasBuilder;
builder2.Services = AccountSasServices::Files;
auto sasToken = builder2.ToSasQueryParameters(*keyCredential);
EXPECT_THROW(verify_blob_create(sasToken), StorageError);
builder2.Services = AccountSasServices::All;
sasToken = builder2.ToSasQueryParameters(*keyCredential);
EXPECT_NO_THROW(verify_blob_create(sasToken));
}
// Account SAS Resource Types
{
AccountSasBuilder builder2 = accountSasBuilder;
builder2.ResourceTypes = AccountSasResource::Service;
auto sasToken = builder2.ToSasQueryParameters(*keyCredential);
EXPECT_THROW(verify_blob_create(sasToken), StorageError);
auto serviceClient = Blobs::BlobServiceClient(serviceUri + sasToken);
EXPECT_NO_THROW(serviceClient.ListBlobContainersSegment());
}
for (auto permissions :
{Blobs::BlobContainerSasPermissions::All,
Blobs::BlobContainerSasPermissions::Read,
Blobs::BlobContainerSasPermissions::Write,
Blobs::BlobContainerSasPermissions::Delete,
Blobs::BlobContainerSasPermissions::List,
Blobs::BlobContainerSasPermissions::Add,
Blobs::BlobContainerSasPermissions::Create,
Blobs::BlobContainerSasPermissions::Tags})
{
containerSasBuilder.SetPermissions(permissions);
auto sasToken = containerSasBuilder.ToSasQueryParameters(*keyCredential);
auto sasToken2 = containerSasBuilder.ToSasQueryParameters(userDelegationKey, accountName);
if ((permissions & Blobs::BlobContainerSasPermissions::Read)
== Blobs::BlobContainerSasPermissions::Read)
{
verify_blob_read(sasToken);
verify_blob_read(sasToken2);
}
if ((permissions & Blobs::BlobContainerSasPermissions::Write)
== Blobs::BlobContainerSasPermissions::Write)
{
verify_blob_write(sasToken);
verify_blob_write(sasToken2);
}
if ((permissions & Blobs::BlobContainerSasPermissions::Delete)
== Blobs::BlobContainerSasPermissions::Delete)
{
verify_blob_delete(sasToken);
verify_blob_delete(sasToken2);
}
if ((permissions & Blobs::BlobContainerSasPermissions::List)
== Blobs::BlobContainerSasPermissions::List)
{
verify_blob_list(sasToken);
verify_blob_list(sasToken2);
}
if ((permissions & Blobs::BlobContainerSasPermissions::Add)
== Blobs::BlobContainerSasPermissions::Add)
{
verify_blob_add(sasToken);
verify_blob_add(sasToken2);
}
if ((permissions & Blobs::BlobContainerSasPermissions::Create)
== Blobs::BlobContainerSasPermissions::Create)
{
verify_blob_create(sasToken);
verify_blob_create(sasToken2);
}
if ((permissions & Blobs::BlobContainerSasPermissions::Tags)
== Blobs::BlobContainerSasPermissions::Tags)
{
verify_blob_tags(sasToken);
verify_blob_tags(sasToken2);
}
}
blobSasBuilder.SetPermissions(Blobs::BlobSasPermissions::All);
// Expires
{
Blobs::BlobSasBuilder builder2 = blobSasBuilder;
builder2.StartsOn = ToISO8601(std::chrono::system_clock::now() - std::chrono::minutes(5));
builder2.ExpiresOn = ToISO8601(std::chrono::system_clock::now() - std::chrono::minutes(1));
auto sasToken = builder2.ToSasQueryParameters(*keyCredential);
EXPECT_THROW(verify_blob_create(sasToken), StorageError);
auto sasToken2 = builder2.ToSasQueryParameters(userDelegationKey, accountName);
EXPECT_THROW(verify_blob_create(sasToken2), StorageError);
}
// Without start time
{
Blobs::BlobSasBuilder builder2 = blobSasBuilder;
builder2.StartsOn.Reset();
auto sasToken = builder2.ToSasQueryParameters(*keyCredential);
EXPECT_NO_THROW(verify_blob_create(sasToken));
auto sasToken2 = builder2.ToSasQueryParameters(userDelegationKey, accountName);
EXPECT_NO_THROW(verify_blob_create(sasToken2));
}
// IP
{
Blobs::BlobSasBuilder builder2 = blobSasBuilder;
builder2.IPRange = "0.0.0.0-0.0.0.1";
auto sasToken = builder2.ToSasQueryParameters(*keyCredential);
EXPECT_THROW(verify_blob_create(sasToken), StorageError);
auto sasToken2 = builder2.ToSasQueryParameters(userDelegationKey, accountName);
EXPECT_THROW(verify_blob_create(sasToken2), StorageError);
builder2.IPRange = "0.0.0.0-255.255.255.255";
sasToken = builder2.ToSasQueryParameters(*keyCredential);
EXPECT_NO_THROW(verify_blob_create(sasToken));
sasToken2 = builder2.ToSasQueryParameters(userDelegationKey, accountName);
EXPECT_NO_THROW(verify_blob_create(sasToken2));
}
// response headers override
{
Blobs::BlobHttpHeaders headers;
headers.ContentType = "application/x-binary";
headers.ContentLanguage = "en-US";
headers.ContentDisposition = "attachment";
headers.CacheControl = "no-cache";
headers.ContentEncoding = "identify";
Blobs::BlobSasBuilder builder2 = blobSasBuilder;
builder2.ContentType = "application/x-binary";
builder2.ContentLanguage = "en-US";
builder2.ContentDisposition = "attachment";
builder2.CacheControl = "no-cache";
builder2.ContentEncoding = "identify";
auto sasToken = builder2.ToSasQueryParameters(*keyCredential);
auto blobClient = Blobs::AppendBlobClient(blobUri + sasToken);
blobClient0.Create();
auto p = blobClient.GetProperties();
EXPECT_EQ(p->HttpHeaders.ContentType, headers.ContentType);
EXPECT_EQ(p->HttpHeaders.ContentLanguage, headers.ContentLanguage);
EXPECT_EQ(p->HttpHeaders.ContentDisposition, headers.ContentDisposition);
EXPECT_EQ(p->HttpHeaders.CacheControl, headers.CacheControl);
EXPECT_EQ(p->HttpHeaders.ContentEncoding, headers.ContentEncoding);
auto sasToken2 = builder2.ToSasQueryParameters(userDelegationKey, accountName);
blobClient = Blobs::AppendBlobClient(blobUri + sasToken2);
p = blobClient.GetProperties();
EXPECT_EQ(p->HttpHeaders.ContentType, headers.ContentType);
EXPECT_EQ(p->HttpHeaders.ContentLanguage, headers.ContentLanguage);
EXPECT_EQ(p->HttpHeaders.ContentDisposition, headers.ContentDisposition);
EXPECT_EQ(p->HttpHeaders.CacheControl, headers.CacheControl);
EXPECT_EQ(p->HttpHeaders.ContentEncoding, headers.ContentEncoding);
}
blobClient0.Create();
Blobs::BlobSasBuilder BlobSnapshotSasBuilder = blobSasBuilder;
BlobSnapshotSasBuilder.Resource = Blobs::BlobSasResource::BlobSnapshot;
std::string blobSnapshotUri;
auto create_snapshot = [&]() {
std::string snapshot = blobClient0.CreateSnapshot()->Snapshot;
BlobSnapshotSasBuilder.Snapshot = snapshot;
blobSnapshotUri = blobClient0.WithSnapshot(snapshot).GetUri();
};
auto verify_blob_snapshot_read = [&](const std::string sas) {
UriBuilder blobSnapshotUriWithSas(blobSnapshotUri);
blobSnapshotUriWithSas.AppendQueries(sas);
auto blobSnapshotClient = Blobs::AppendBlobClient(blobSnapshotUriWithSas.ToString());
auto downloadedContent = blobSnapshotClient.Download();
EXPECT_TRUE(ReadBodyStream(downloadedContent->BodyStream).empty());
};
auto verify_blob_snapshot_delete = [&](const std::string sas) {
UriBuilder blobSnapshotUriWithSas(blobSnapshotUri);
blobSnapshotUriWithSas.AppendQueries(sas);
auto blobSnapshotClient = Blobs::AppendBlobClient(blobSnapshotUriWithSas.ToString());
EXPECT_NO_THROW(blobSnapshotClient.Delete());
};
for (auto permissions : {
Blobs::BlobSasPermissions::Read | Blobs::BlobSasPermissions::Delete,
Blobs::BlobSasPermissions::Read,
Blobs::BlobSasPermissions::Delete,
})
{
create_snapshot();
BlobSnapshotSasBuilder.SetPermissions(permissions);
auto sasToken = BlobSnapshotSasBuilder.ToSasQueryParameters(*keyCredential);
auto sasToken2 = BlobSnapshotSasBuilder.ToSasQueryParameters(userDelegationKey, accountName);
if ((permissions & Blobs::BlobSasPermissions::Read) == Blobs::BlobSasPermissions::Read)
{
verify_blob_snapshot_read(sasToken);
verify_blob_snapshot_read(sasToken2);
}
if ((permissions & Blobs::BlobSasPermissions::Delete) == Blobs::BlobSasPermissions::Delete)
{
create_snapshot();
sasToken = BlobSnapshotSasBuilder.ToSasQueryParameters(*keyCredential);
verify_blob_snapshot_delete(sasToken);
create_snapshot();
sasToken2 = BlobSnapshotSasBuilder.ToSasQueryParameters(userDelegationKey, accountName);
verify_blob_snapshot_delete(sasToken2);
}
}
}
}}} // namespace Azure::Storage::Test