User Delegation SAS (#358)
This commit is contained in:
parent
6e3c3d9acf
commit
b0b5a18d18
@ -42,7 +42,7 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
|
||||
/**
|
||||
* @brief The list of permissions that can be set for a blob container's access policy.
|
||||
*/
|
||||
*/
|
||||
enum class BlobContainerSasPermissions
|
||||
{
|
||||
/**
|
||||
@ -191,7 +191,7 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
* @brief Optionally specify the time at which the shared access signature becomes
|
||||
* valid.
|
||||
*/
|
||||
std::string StartsOn;
|
||||
Azure::Core::Nullable<std::string> StartsOn;
|
||||
|
||||
/**
|
||||
* @brief The time at which the shared access signature becomes invalid. This field must
|
||||
@ -220,7 +220,7 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
|
||||
/**
|
||||
* @brief The name of the blob being made accessible, or empty for a container SAS..
|
||||
*/
|
||||
*/
|
||||
std::string BlobName;
|
||||
|
||||
/**
|
||||
@ -237,7 +237,7 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
|
||||
/**
|
||||
* @brief Specifies which resources are accessible via the shared access signature.
|
||||
*/
|
||||
*/
|
||||
BlobSasResource Resource;
|
||||
|
||||
/**
|
||||
@ -267,7 +267,7 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
|
||||
/**
|
||||
* @brief Sets the permissions for the blob container SAS.
|
||||
*
|
||||
*
|
||||
* @param
|
||||
* permissions The allowed permissions.
|
||||
*/
|
||||
@ -275,7 +275,7 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
|
||||
/**
|
||||
* @brief Sets the permissions for the blob SAS.
|
||||
*
|
||||
*
|
||||
* @param permissions The
|
||||
* allowed permissions.
|
||||
*/
|
||||
@ -284,7 +284,7 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
/**
|
||||
* @brief Uses the SharedKeyCredential to sign this shared access signature, to produce
|
||||
* the proper SAS query parameters for authentication requests.
|
||||
*
|
||||
*
|
||||
* @param credential
|
||||
* The storage account's shared key credential.
|
||||
* @return The SAS query parameters used for
|
||||
@ -295,7 +295,7 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
/**
|
||||
* @brief Uses an account's user delegation key to sign this shared access signature, to
|
||||
* produce the proper SAS query parameters for authentication requests.
|
||||
*
|
||||
*
|
||||
* @param
|
||||
* credential UserDelegationKey retruned from BlobServiceClient.GetUserDelegationKey.
|
||||
* @param accountName The name of the storage account.
|
||||
|
||||
@ -28,6 +28,11 @@ namespace Azure { namespace Storage {
|
||||
HttpsOnly,
|
||||
};
|
||||
|
||||
inline std::string SasProtocolToString(SasProtocol protocol)
|
||||
{
|
||||
return protocol == SasProtocol::HttpsAndHtttp ? "https,http" : "https";
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Specifies the resource types accessible from an account level shared access
|
||||
* signature.
|
||||
|
||||
@ -42,7 +42,7 @@ namespace Azure { namespace Storage {
|
||||
}
|
||||
|
||||
// query must be encoded
|
||||
void SetQuery(const std::string& query);
|
||||
void AppendQueries(const std::string& query);
|
||||
|
||||
void AppendQuery(const std::string& key, const std::string& value, bool do_encoding = false)
|
||||
{
|
||||
|
||||
@ -7,6 +7,32 @@
|
||||
|
||||
namespace Azure { namespace Storage { namespace Blobs {
|
||||
|
||||
namespace {
|
||||
std::string BlobSasResourceToString(BlobSasResource resource)
|
||||
{
|
||||
if (resource == BlobSasResource::Container)
|
||||
{
|
||||
return "c";
|
||||
}
|
||||
else if (resource == BlobSasResource::Blob)
|
||||
{
|
||||
return "b";
|
||||
}
|
||||
else if (resource == BlobSasResource::BlobSnapshot)
|
||||
{
|
||||
return "bs";
|
||||
}
|
||||
else if (resource == BlobSasResource::BlobVersion)
|
||||
{
|
||||
return "bv";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("unknown BlobSasResource value");
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void BlobSasBuilder::SetPermissions(BlobContainerSasPermissions permissions)
|
||||
{
|
||||
Permissions.clear();
|
||||
@ -87,37 +113,14 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
{
|
||||
canonicalName += "/" + BlobName;
|
||||
}
|
||||
std::string protocol;
|
||||
if (Protocol == SasProtocol::HttpsAndHtttp)
|
||||
{
|
||||
protocol = "https,http";
|
||||
}
|
||||
else
|
||||
{
|
||||
protocol = "https";
|
||||
}
|
||||
std::string resource;
|
||||
if (Resource == BlobSasResource::Container)
|
||||
{
|
||||
resource = "c";
|
||||
}
|
||||
else if (Resource == BlobSasResource::Blob)
|
||||
{
|
||||
resource = "b";
|
||||
}
|
||||
else if (Resource == BlobSasResource::BlobSnapshot)
|
||||
{
|
||||
resource = "bs";
|
||||
}
|
||||
else if (Resource == BlobSasResource::BlobVersion)
|
||||
{
|
||||
resource = "bv";
|
||||
}
|
||||
std::string stringToSign = Permissions + "\n" + StartsOn + "\n" + ExpiresOn + "\n"
|
||||
+ canonicalName + "\n" + Identifier + "\n" + (IPRange.HasValue() ? IPRange.GetValue() : "")
|
||||
+ "\n" + protocol + "\n" + Version + "\n" + resource + "\n" + Snapshot + "\n" + CacheControl
|
||||
+ "\n" + ContentDisposition + "\n" + ContentEncoding + "\n" + ContentLanguage + "\n"
|
||||
+ ContentType;
|
||||
std::string protocol = SasProtocolToString(Protocol);
|
||||
std::string resource = BlobSasResourceToString(Resource);
|
||||
|
||||
std::string stringToSign = Permissions + "\n" + (StartsOn.HasValue() ? StartsOn.GetValue() : "")
|
||||
+ "\n" + ExpiresOn + "\n" + canonicalName + "\n" + Identifier + "\n"
|
||||
+ (IPRange.HasValue() ? IPRange.GetValue() : "") + "\n" + protocol + "\n" + Version + "\n"
|
||||
+ resource + "\n" + Snapshot + "\n" + CacheControl + "\n" + ContentDisposition + "\n"
|
||||
+ ContentEncoding + "\n" + ContentLanguage + "\n" + ContentType;
|
||||
|
||||
std::string signature
|
||||
= Base64Encode(HMAC_SHA256(stringToSign, Base64Decode(credential.GetAccountKey())));
|
||||
@ -125,7 +128,10 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
UriBuilder builder;
|
||||
builder.AppendQuery("sv", Version);
|
||||
builder.AppendQuery("spr", protocol);
|
||||
builder.AppendQuery("st", StartsOn);
|
||||
if (StartsOn.HasValue())
|
||||
{
|
||||
builder.AppendQuery("st", StartsOn.GetValue());
|
||||
}
|
||||
builder.AppendQuery("se", ExpiresOn);
|
||||
if (IPRange.HasValue())
|
||||
{
|
||||
@ -166,8 +172,69 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
const UserDelegationKey& userDelegationKey,
|
||||
const std::string& accountName)
|
||||
{
|
||||
unused(userDelegationKey, accountName);
|
||||
return std::string();
|
||||
std::string canonicalName = "/blob/" + accountName + "/" + ContainerName;
|
||||
if (Resource == BlobSasResource::Blob || Resource == BlobSasResource::BlobSnapshot)
|
||||
{
|
||||
canonicalName += "/" + BlobName;
|
||||
}
|
||||
std::string protocol = SasProtocolToString(Protocol);
|
||||
std::string resource = BlobSasResourceToString(Resource);
|
||||
|
||||
std::string stringToSign = Permissions + "\n" + (StartsOn.HasValue() ? StartsOn.GetValue() : "")
|
||||
+ "\n" + ExpiresOn + "\n" + canonicalName + "\n" + userDelegationKey.SignedObjectId + "\n"
|
||||
+ userDelegationKey.SignedTenantId + "\n" + userDelegationKey.SignedStartsOn + "\n"
|
||||
+ userDelegationKey.SignedExpiresOn + "\n" + userDelegationKey.SignedService + "\n"
|
||||
+ userDelegationKey.SignedVersion + "\n" + (IPRange.HasValue() ? IPRange.GetValue() : "")
|
||||
+ "\n" + protocol + "\n" + Version + "\n" + resource + "\n" + Snapshot + "\n" + CacheControl
|
||||
+ "\n" + ContentDisposition + "\n" + ContentEncoding + "\n" + ContentLanguage + "\n"
|
||||
+ ContentType;
|
||||
|
||||
std::string signature
|
||||
= Base64Encode(HMAC_SHA256(stringToSign, Base64Decode(userDelegationKey.Value)));
|
||||
|
||||
UriBuilder builder;
|
||||
builder.AppendQuery("sv", Version);
|
||||
builder.AppendQuery("sr", resource);
|
||||
if (StartsOn.HasValue())
|
||||
{
|
||||
builder.AppendQuery("st", StartsOn.GetValue());
|
||||
}
|
||||
builder.AppendQuery("se", ExpiresOn);
|
||||
builder.AppendQuery("sp", Permissions);
|
||||
if (IPRange.HasValue())
|
||||
{
|
||||
builder.AppendQuery("sip", IPRange.GetValue());
|
||||
}
|
||||
builder.AppendQuery("spr", protocol);
|
||||
builder.AppendQuery("skoid", userDelegationKey.SignedObjectId);
|
||||
builder.AppendQuery("sktid", userDelegationKey.SignedTenantId);
|
||||
builder.AppendQuery("skt", userDelegationKey.SignedStartsOn);
|
||||
builder.AppendQuery("ske", userDelegationKey.SignedExpiresOn);
|
||||
builder.AppendQuery("sks", userDelegationKey.SignedService);
|
||||
builder.AppendQuery("skv", userDelegationKey.SignedVersion);
|
||||
if (!CacheControl.empty())
|
||||
{
|
||||
builder.AppendQuery("rscc", CacheControl);
|
||||
}
|
||||
if (!ContentDisposition.empty())
|
||||
{
|
||||
builder.AppendQuery("rscd", ContentDisposition);
|
||||
}
|
||||
if (!ContentEncoding.empty())
|
||||
{
|
||||
builder.AppendQuery("rsce", ContentEncoding);
|
||||
}
|
||||
if (!ContentLanguage.empty())
|
||||
{
|
||||
builder.AppendQuery("rscl", ContentLanguage);
|
||||
}
|
||||
if (!ContentType.empty())
|
||||
{
|
||||
builder.AppendQuery("rsct", ContentType);
|
||||
}
|
||||
builder.AppendQuery("sig", signature, true);
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
}}} // namespace Azure::Storage::Blobs
|
||||
|
||||
@ -96,10 +96,10 @@ namespace Azure { namespace Storage { namespace Details {
|
||||
std::string sas = getWithDefault(connectionStringMap, "SharedAccessSignature");
|
||||
if (!sas.empty())
|
||||
{
|
||||
connectionStringParts.BlobServiceUri.SetQuery(sas);
|
||||
connectionStringParts.DataLakeServiceUri.SetQuery(sas);
|
||||
connectionStringParts.FileServiceUri.SetQuery(sas);
|
||||
connectionStringParts.QueueServiceUri.SetQuery(sas);
|
||||
connectionStringParts.BlobServiceUri.AppendQueries(sas);
|
||||
connectionStringParts.DataLakeServiceUri.AppendQueries(sas);
|
||||
connectionStringParts.FileServiceUri.AppendQueries(sas);
|
||||
connectionStringParts.QueueServiceUri.AppendQueries(sas);
|
||||
}
|
||||
|
||||
return connectionStringParts;
|
||||
|
||||
@ -47,7 +47,7 @@ namespace Azure { namespace Storage {
|
||||
if (pos != url.end() && *pos == '?')
|
||||
{
|
||||
auto queryIter = std::find(pos + 1, url.end(), '#');
|
||||
SetQuery(std::string(pos + 1, queryIter));
|
||||
AppendQueries(std::string(pos + 1, queryIter));
|
||||
pos = queryIter;
|
||||
}
|
||||
|
||||
@ -152,10 +152,8 @@ namespace Azure { namespace Storage {
|
||||
return encoded;
|
||||
}
|
||||
|
||||
void UriBuilder::SetQuery(const std::string& query)
|
||||
void UriBuilder::AppendQueries(const std::string& query)
|
||||
{
|
||||
m_query.clear();
|
||||
|
||||
std::string::const_iterator cur = query.begin();
|
||||
if (cur != query.end() && *cur == '?')
|
||||
{
|
||||
|
||||
@ -33,6 +33,7 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
|
||||
auto keyCredential
|
||||
= Details::ParseConnectionString(StandardStorageConnectionString()).KeyCredential;
|
||||
auto accountName = keyCredential->AccountName;
|
||||
auto blobServiceClient0
|
||||
= Blobs::BlobServiceClient::CreateFromConnectionString(StandardStorageConnectionString());
|
||||
auto blobContainerClient0 = blobServiceClient0.GetBlobContainerClient(m_containerName);
|
||||
@ -42,6 +43,14 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
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);
|
||||
@ -172,42 +181,50 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
{
|
||||
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.SetPermissions(AccountSasPermissions::All);
|
||||
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);
|
||||
@ -217,7 +234,6 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
// Without start time
|
||||
{
|
||||
AccountSasBuilder builder2 = accountSasBuilder;
|
||||
builder2.SetPermissions(AccountSasPermissions::All);
|
||||
builder2.StartsOn.Reset();
|
||||
auto sasToken = builder2.ToSasQueryParameters(*keyCredential);
|
||||
EXPECT_NO_THROW(verify_blob_create(sasToken));
|
||||
@ -226,39 +242,32 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
// IP
|
||||
{
|
||||
AccountSasBuilder builder2 = accountSasBuilder;
|
||||
builder2.SetPermissions(AccountSasPermissions::All);
|
||||
builder2.IPRange = "1.1.1.1";
|
||||
auto sasToken = builder2.ToSasQueryParameters(*keyCredential);
|
||||
auto blobClient = Blobs::AppendBlobClient(blobUri + sasToken);
|
||||
EXPECT_THROW(verify_blob_create(sasToken), StorageError);
|
||||
|
||||
builder2.IPRange = "0.0.0.0-255.255.255.255";
|
||||
sasToken = builder2.ToSasQueryParameters(*keyCredential);
|
||||
blobClient = Blobs::AppendBlobClient(blobUri + sasToken);
|
||||
EXPECT_NO_THROW(verify_blob_create(sasToken));
|
||||
}
|
||||
|
||||
// Account SAS Service
|
||||
{
|
||||
AccountSasBuilder builder2 = accountSasBuilder;
|
||||
builder2.SetPermissions(AccountSasPermissions::All);
|
||||
builder2.Services = AccountSasServices::Files;
|
||||
auto sasToken = builder2.ToSasQueryParameters(*keyCredential);
|
||||
auto blobClient = Blobs::AppendBlobClient(blobUri + sasToken);
|
||||
EXPECT_THROW(verify_blob_create(sasToken), StorageError);
|
||||
|
||||
builder2.Services = AccountSasServices::All;
|
||||
sasToken = builder2.ToSasQueryParameters(*keyCredential);
|
||||
blobClient = Blobs::AppendBlobClient(blobUri + sasToken);
|
||||
EXPECT_NO_THROW(verify_blob_create(sasToken));
|
||||
}
|
||||
|
||||
// Account SAS Resource Types
|
||||
{
|
||||
AccountSasBuilder builder2 = accountSasBuilder;
|
||||
builder2.SetPermissions(AccountSasPermissions::All);
|
||||
builder2.ResourceTypes = AccountSasResource::Service;
|
||||
auto sasToken = builder2.ToSasQueryParameters(*keyCredential);
|
||||
auto blobClient = Blobs::AppendBlobClient(blobUri + sasToken);
|
||||
EXPECT_THROW(verify_blob_create(sasToken), StorageError);
|
||||
|
||||
auto serviceClient = Blobs::BlobServiceClient(serviceUri + sasToken);
|
||||
@ -277,40 +286,49 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -322,6 +340,19 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
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
|
||||
@ -329,12 +360,15 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
Blobs::BlobSasBuilder builder2 = blobSasBuilder;
|
||||
builder2.IPRange = "0.0.0.0-0.0.0.1";
|
||||
auto sasToken = builder2.ToSasQueryParameters(*keyCredential);
|
||||
auto blobClient = Blobs::AppendBlobClient(blobUri + sasToken);
|
||||
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);
|
||||
blobClient = Blobs::AppendBlobClient(blobUri + sasToken);
|
||||
EXPECT_NO_THROW(verify_blob_create(sasToken));
|
||||
sasToken2 = builder2.ToSasQueryParameters(userDelegationKey, accountName);
|
||||
EXPECT_NO_THROW(verify_blob_create(sasToken2));
|
||||
}
|
||||
|
||||
// response headers override
|
||||
@ -361,6 +395,15 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
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();
|
||||
@ -369,14 +412,24 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
|
||||
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) {
|
||||
auto blobSnapshotClient = Blobs::AppendBlobClient(blobSnapshotUri + "&" + sas.substr(1));
|
||||
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) {
|
||||
auto blobSnapshotClient = Blobs::AppendBlobClient(blobSnapshotUri + "&" + sas.substr(1));
|
||||
UriBuilder blobSnapshotUriWithSas(blobSnapshotUri);
|
||||
blobSnapshotUriWithSas.AppendQueries(sas);
|
||||
auto blobSnapshotClient = Blobs::AppendBlobClient(blobSnapshotUriWithSas.ToString());
|
||||
EXPECT_NO_THROW(blobSnapshotClient.Delete());
|
||||
};
|
||||
|
||||
@ -386,19 +439,24 @@ namespace Azure { namespace Storage { namespace Test {
|
||||
Blobs::BlobSasPermissions::Delete,
|
||||
})
|
||||
{
|
||||
std::string snapshot = blobClient0.CreateSnapshot()->Snapshot;
|
||||
BlobSnapshotSasBuilder.Snapshot = snapshot;
|
||||
blobSnapshotUri = blobClient0.WithSnapshot(snapshot).GetUri();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user