[Storage Files Service] File sas (#568)
* File sas * rebase on lastest master
This commit is contained in:
parent
caf705c863
commit
07208d1720
@ -182,7 +182,7 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
* shared access signature, and the service version to use when handling requests made with this
|
||||
* shared access signature.
|
||||
*/
|
||||
std::string Version = c_ApiVersion;
|
||||
std::string Version = Details::c_defaultSasVersion;
|
||||
|
||||
/**
|
||||
* @brief The optional signed protocol field specifies the protocol permitted for a
|
||||
@ -271,8 +271,7 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
/**
|
||||
* @brief Sets the permissions for the blob container SAS.
|
||||
*
|
||||
* @param
|
||||
* permissions The allowed permissions.
|
||||
* @param permissions The allowed permissions.
|
||||
*/
|
||||
void SetPermissions(BlobContainerSasPermissions permissions)
|
||||
{
|
||||
@ -282,8 +281,7 @@ namespace Azure { namespace Storage { namespace Blobs {
|
||||
/**
|
||||
* @brief Sets the permissions for the blob SAS.
|
||||
*
|
||||
* @param permissions The
|
||||
* allowed permissions.
|
||||
* @param permissions The allowed permissions.
|
||||
*/
|
||||
void SetPermissions(BlobSasPermissions permissions);
|
||||
|
||||
@ -291,10 +289,8 @@ 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
|
||||
* authenticating requests.
|
||||
* @param credential The storage account's shared key credential.
|
||||
* @return The SAS query parameters used for authenticating requests.
|
||||
*/
|
||||
std::string ToSasQueryParameters(const SharedKeyCredential& credential);
|
||||
|
||||
@ -302,11 +298,9 @@ 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 credential UserDelegationKey retruned from BlobServiceClient.GetUserDelegationKey.
|
||||
* @param accountName The name of the storage account.
|
||||
* @return The SAS query parameters
|
||||
* used for authenticating requests.
|
||||
* @return The SAS query parameters used for authenticating requests.
|
||||
*/
|
||||
std::string ToSasQueryParameters(
|
||||
const UserDelegationKey& userDelegationKey,
|
||||
|
||||
@ -16,6 +16,9 @@ namespace Azure { namespace Storage {
|
||||
namespace Blobs {
|
||||
struct BlobSasBuilder;
|
||||
}
|
||||
namespace Files { namespace Shares {
|
||||
struct ShareSasBuilder;
|
||||
}} // namespace Files::Shares
|
||||
|
||||
struct SharedKeyCredential
|
||||
{
|
||||
@ -35,6 +38,7 @@ namespace Azure { namespace Storage {
|
||||
private:
|
||||
friend class SharedKeyPolicy;
|
||||
friend struct Blobs::BlobSasBuilder;
|
||||
friend struct Files::Shares::ShareSasBuilder;
|
||||
friend struct AccountSasBuilder;
|
||||
std::string GetAccountKey() const
|
||||
{
|
||||
|
||||
@ -12,6 +12,7 @@ set (AZURE_STORAGE_SHARES_HEADER
|
||||
inc/azure/storage/files/shares/share_file_client.hpp
|
||||
inc/azure/storage/files/shares/share_options.hpp
|
||||
inc/azure/storage/files/shares/share_responses.hpp
|
||||
inc/azure/storage/files/shares/share_sas_builder.hpp
|
||||
inc/azure/storage/files/shares/share_service_client.hpp
|
||||
inc/azure/storage/files/shares/shares.hpp
|
||||
)
|
||||
@ -20,6 +21,7 @@ set (AZURE_STORAGE_SHARES_SOURCE
|
||||
src/share_client.cpp
|
||||
src/share_directory_client.cpp
|
||||
src/share_file_client.cpp
|
||||
src/share_sas_builder.cpp
|
||||
src/share_service_client.cpp
|
||||
)
|
||||
|
||||
@ -47,6 +49,7 @@ target_sources(
|
||||
test/share_directory_client_test.hpp
|
||||
test/share_file_client_test.cpp
|
||||
test/share_file_client_test.hpp
|
||||
test/share_sas_test.cpp
|
||||
test/share_service_client_test.cpp
|
||||
test/share_service_client_test.hpp
|
||||
)
|
||||
|
||||
@ -0,0 +1,240 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "azure/core/nullable.hpp"
|
||||
#include "azure/storage/common/account_sas_builder.hpp"
|
||||
#include "azure/storage/common/constants.hpp"
|
||||
|
||||
namespace Azure { namespace Storage { namespace Files { namespace Shares {
|
||||
|
||||
/**
|
||||
* @brief Specifies which resources are accessible via the shared access signature.
|
||||
*/
|
||||
enum class ShareSasResource
|
||||
{
|
||||
/**
|
||||
* @brief Grants access to the content and metadata of the file.
|
||||
*/
|
||||
Share,
|
||||
|
||||
/**
|
||||
* @brief Grants access to the content and metadata of any file in the share, and to the list of
|
||||
* directories and files in the share.
|
||||
*/
|
||||
File,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The list of permissions that can be set for a file share's access policy.
|
||||
*/
|
||||
enum class ShareSasPermissions
|
||||
{
|
||||
/**
|
||||
* @brief Indicates that Read is permitted.
|
||||
*/
|
||||
Read = 1,
|
||||
|
||||
/**
|
||||
* @brief Indicates that Write is permitted.
|
||||
*/
|
||||
Write = 2,
|
||||
|
||||
/**
|
||||
* @brief Indicates that Delete is permitted.
|
||||
*/
|
||||
Delete = 4,
|
||||
|
||||
/**
|
||||
* @brief Indicates that List is permitted.
|
||||
*/
|
||||
List = 8,
|
||||
|
||||
/**
|
||||
* @brief Indicates that Create is permitted.
|
||||
*/
|
||||
Create = 16,
|
||||
|
||||
/**
|
||||
* @beirf Indicates that all permissions are set.
|
||||
*/
|
||||
All = ~0,
|
||||
};
|
||||
|
||||
inline ShareSasPermissions operator|(ShareSasPermissions lhs, ShareSasPermissions rhs)
|
||||
{
|
||||
using type = std::underlying_type_t<ShareSasPermissions>;
|
||||
return static_cast<ShareSasPermissions>(static_cast<type>(lhs) | static_cast<type>(rhs));
|
||||
}
|
||||
|
||||
inline ShareSasPermissions operator&(ShareSasPermissions lhs, ShareSasPermissions rhs)
|
||||
{
|
||||
using type = std::underlying_type_t<ShareSasPermissions>;
|
||||
return static_cast<ShareSasPermissions>(static_cast<type>(lhs) & static_cast<type>(rhs));
|
||||
}
|
||||
|
||||
std::string ShareSasPermissionsToString(ShareSasPermissions permissions);
|
||||
|
||||
/**
|
||||
* @brief The list of permissions that can be set for a share file's access policy.
|
||||
*/
|
||||
enum class ShareFileSasPermissions
|
||||
{
|
||||
/**
|
||||
* @brief Indicates that Read is permitted.
|
||||
*/
|
||||
Read = 1,
|
||||
|
||||
/**
|
||||
* @brief Indicates that Write is permitted.
|
||||
*/
|
||||
Write = 2,
|
||||
|
||||
/**
|
||||
* @brief Indicates that Delete is permitted.
|
||||
*/
|
||||
|
||||
Delete = 4,
|
||||
|
||||
/**
|
||||
* @brief Indicates that Create is permitted.
|
||||
*/
|
||||
Create = 8,
|
||||
|
||||
/**
|
||||
* @beirf Indicates that all permissions are set.
|
||||
*/
|
||||
All = ~0,
|
||||
};
|
||||
|
||||
inline ShareFileSasPermissions operator|(ShareFileSasPermissions lhs, ShareFileSasPermissions rhs)
|
||||
{
|
||||
using type = std::underlying_type_t<ShareFileSasPermissions>;
|
||||
return static_cast<ShareFileSasPermissions>(static_cast<type>(lhs) | static_cast<type>(rhs));
|
||||
}
|
||||
|
||||
inline ShareFileSasPermissions operator&(ShareFileSasPermissions lhs, ShareFileSasPermissions rhs)
|
||||
{
|
||||
using type = std::underlying_type_t<ShareFileSasPermissions>;
|
||||
return static_cast<ShareFileSasPermissions>(static_cast<type>(lhs) & static_cast<type>(rhs));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ShareSasBuilder is used to generate a Shared Access Signature (SAS) for an Azure
|
||||
* Storage share or file.
|
||||
*/
|
||||
struct ShareSasBuilder
|
||||
{
|
||||
/**
|
||||
* @brief The storage service version to use to authenticate requests made with this
|
||||
* shared access signature, and the service version to use when handling requests made with this
|
||||
* shared access signature.
|
||||
*/
|
||||
std::string Version = Azure::Storage::Details::c_defaultSasVersion;
|
||||
|
||||
/**
|
||||
* @brief The optional signed protocol field specifies the protocol permitted for a
|
||||
* request made with the SAS.
|
||||
*/
|
||||
SasProtocol Protocol;
|
||||
|
||||
/**
|
||||
* @brief Optionally specify the time at which the shared access signature becomes
|
||||
* valid.
|
||||
*/
|
||||
Azure::Core::Nullable<std::string> StartsOn;
|
||||
|
||||
/**
|
||||
* @brief The time at which the shared access signature becomes invalid. This field must
|
||||
* be omitted if it has been specified in an associated stored access policy.
|
||||
*/
|
||||
std::string ExpiresOn;
|
||||
|
||||
/**
|
||||
* @brief Specifies an IP address or a range of IP addresses from which to accept
|
||||
* requests. If the IP address from which the request originates does not match the IP address
|
||||
* or address range specified on the SAS token, the request is not authenticated. When
|
||||
* specifying a range of IP addresses, note that the range is inclusive.
|
||||
*/
|
||||
Azure::Core::Nullable<std::string> IPRange;
|
||||
|
||||
/**
|
||||
* @brief An optional unique value up to 64 characters in length that correlates to an
|
||||
* access policy specified for the share.
|
||||
*/
|
||||
std::string Identifier;
|
||||
|
||||
/**
|
||||
* @brief The name of the file share being made accessible.
|
||||
*/
|
||||
std::string ShareName;
|
||||
|
||||
/**
|
||||
* @brief The name of the share file being made accessible, or empty for a share SAS..
|
||||
*/
|
||||
std::string FilePath;
|
||||
|
||||
/**
|
||||
* @brief Specifies which resources are accessible via the shared access signature.
|
||||
*/
|
||||
ShareSasResource Resource;
|
||||
|
||||
/**
|
||||
* @brief Override the value returned for Cache-Control response header..
|
||||
*/
|
||||
std::string CacheControl;
|
||||
|
||||
/**
|
||||
* @brief Override the value returned for Content-Disposition response header..
|
||||
*/
|
||||
std::string ContentDisposition;
|
||||
|
||||
/**
|
||||
* @brief Override the value returned for Content-Encoding response header..
|
||||
*/
|
||||
std::string ContentEncoding;
|
||||
|
||||
/**
|
||||
* @brief Override the value returned for Content-Language response header..
|
||||
*/
|
||||
std::string ContentLanguage;
|
||||
|
||||
/**
|
||||
* @brief Override the value returned for Content-Type response header..
|
||||
*/
|
||||
std::string ContentType;
|
||||
|
||||
/**
|
||||
* @brief Sets the permissions for the share SAS.
|
||||
*
|
||||
* @param permissions The allowed permissions.
|
||||
*/
|
||||
void SetPermissions(ShareSasPermissions permissions)
|
||||
{
|
||||
Permissions = ShareSasPermissionsToString(permissions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the permissions for the share SAS.
|
||||
*
|
||||
* @param permissions The allowed permissions.
|
||||
*/
|
||||
void SetPermissions(ShareFileSasPermissions permissions);
|
||||
|
||||
/**
|
||||
* @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 authenticating requests.
|
||||
*/
|
||||
std::string ToSasQueryParameters(const SharedKeyCredential& credential);
|
||||
|
||||
private:
|
||||
std::string Permissions;
|
||||
};
|
||||
|
||||
}}}} // namespace Azure::Storage::Files::Shares
|
||||
145
sdk/storage/azure-storage-files-shares/src/share_sas_builder.cpp
Normal file
145
sdk/storage/azure-storage-files-shares/src/share_sas_builder.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "azure/storage/files/shares/share_sas_builder.hpp"
|
||||
#include "azure/core/http/http.hpp"
|
||||
#include "azure/storage/common/crypt.hpp"
|
||||
|
||||
namespace Azure { namespace Storage { namespace Files { namespace Shares {
|
||||
|
||||
namespace {
|
||||
std::string ShareSasResourceToString(ShareSasResource resource)
|
||||
{
|
||||
if (resource == ShareSasResource::Share)
|
||||
{
|
||||
return "s";
|
||||
}
|
||||
else if (resource == ShareSasResource::File)
|
||||
{
|
||||
return "f";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("unknown ShareSasResource value");
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::string ShareSasPermissionsToString(ShareSasPermissions permissions)
|
||||
{
|
||||
std::string permissions_str;
|
||||
// The order matters
|
||||
if ((permissions & ShareSasPermissions::Read) == ShareSasPermissions::Read)
|
||||
{
|
||||
permissions_str += "r";
|
||||
}
|
||||
if ((permissions & ShareSasPermissions::Create) == ShareSasPermissions::Create)
|
||||
{
|
||||
permissions_str += "c";
|
||||
}
|
||||
if ((permissions & ShareSasPermissions::Write) == ShareSasPermissions::Write)
|
||||
{
|
||||
permissions_str += "w";
|
||||
}
|
||||
if ((permissions & ShareSasPermissions::Delete) == ShareSasPermissions::Delete)
|
||||
{
|
||||
permissions_str += "d";
|
||||
}
|
||||
if ((permissions & ShareSasPermissions::List) == ShareSasPermissions::List)
|
||||
{
|
||||
permissions_str += "l";
|
||||
}
|
||||
return permissions_str;
|
||||
}
|
||||
|
||||
void ShareSasBuilder::SetPermissions(ShareFileSasPermissions permissions)
|
||||
{
|
||||
Permissions.clear();
|
||||
// The order matters
|
||||
if ((permissions & ShareFileSasPermissions::Read) == ShareFileSasPermissions::Read)
|
||||
{
|
||||
Permissions += "r";
|
||||
}
|
||||
if ((permissions & ShareFileSasPermissions::Create) == ShareFileSasPermissions::Create)
|
||||
{
|
||||
Permissions += "c";
|
||||
}
|
||||
if ((permissions & ShareFileSasPermissions::Write) == ShareFileSasPermissions::Write)
|
||||
{
|
||||
Permissions += "w";
|
||||
}
|
||||
if ((permissions & ShareFileSasPermissions::Delete) == ShareFileSasPermissions::Delete)
|
||||
{
|
||||
Permissions += "d";
|
||||
}
|
||||
}
|
||||
|
||||
std::string ShareSasBuilder::ToSasQueryParameters(const SharedKeyCredential& credential)
|
||||
{
|
||||
std::string canonicalName = "/file/" + credential.AccountName + "/" + ShareName;
|
||||
if (Resource == ShareSasResource::File)
|
||||
{
|
||||
canonicalName += "/" + FilePath;
|
||||
}
|
||||
std::string protocol = SasProtocolToString(Protocol);
|
||||
std::string resource = ShareSasResourceToString(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"
|
||||
+ CacheControl + "\n" + ContentDisposition + "\n" + ContentEncoding + "\n" + ContentLanguage
|
||||
+ "\n" + ContentType;
|
||||
|
||||
std::string signature
|
||||
= Base64Encode(Details::HmacSha256(stringToSign, Base64Decode(credential.GetAccountKey())));
|
||||
|
||||
Azure::Core::Http::Url builder;
|
||||
builder.AppendQuery("sv", Version);
|
||||
builder.AppendQuery("spr", protocol);
|
||||
if (StartsOn.HasValue())
|
||||
{
|
||||
builder.AppendQuery("st", StartsOn.GetValue());
|
||||
}
|
||||
if (!ExpiresOn.empty())
|
||||
{
|
||||
builder.AppendQuery("se", ExpiresOn);
|
||||
}
|
||||
if (IPRange.HasValue())
|
||||
{
|
||||
builder.AppendQuery("sip", IPRange.GetValue());
|
||||
}
|
||||
if (!Identifier.empty())
|
||||
{
|
||||
builder.AppendQuery("si", Identifier);
|
||||
}
|
||||
builder.AppendQuery("sr", resource);
|
||||
if (!Permissions.empty())
|
||||
{
|
||||
builder.AppendQuery("sp", Permissions);
|
||||
}
|
||||
builder.AppendQuery("sig", signature, true);
|
||||
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);
|
||||
}
|
||||
|
||||
return builder.GetAbsoluteUrl();
|
||||
}
|
||||
|
||||
}}}} // namespace Azure::Storage::Files::Shares
|
||||
221
sdk/storage/azure-storage-files-shares/test/share_sas_test.cpp
Normal file
221
sdk/storage/azure-storage-files-shares/test/share_sas_test.cpp
Normal file
@ -0,0 +1,221 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include "share_client_test.hpp"
|
||||
|
||||
#include "azure/storage/files/shares/share_sas_builder.hpp"
|
||||
|
||||
namespace Azure { namespace Storage { namespace Test {
|
||||
|
||||
TEST_F(FileShareClientTest, FileSasTest)
|
||||
{
|
||||
std::string fileName = RandomString();
|
||||
Files::Shares::ShareSasBuilder fileSasBuilder;
|
||||
fileSasBuilder.Protocol = SasProtocol::HttpsAndHtttp;
|
||||
fileSasBuilder.StartsOn = ToIso8601(std::chrono::system_clock::now() - std::chrono::minutes(5));
|
||||
fileSasBuilder.ExpiresOn
|
||||
= ToIso8601(std::chrono::system_clock::now() + std::chrono::minutes(60));
|
||||
fileSasBuilder.ShareName = m_shareName;
|
||||
fileSasBuilder.FilePath = fileName;
|
||||
fileSasBuilder.Resource = Files::Shares::ShareSasResource::File;
|
||||
|
||||
Files::Shares::ShareSasBuilder shareSasBuilder = fileSasBuilder;
|
||||
shareSasBuilder.FilePath.clear();
|
||||
shareSasBuilder.Resource = Files::Shares::ShareSasResource::Share;
|
||||
|
||||
auto keyCredential
|
||||
= Details::ParseConnectionString(StandardStorageConnectionString()).KeyCredential;
|
||||
auto accountName = keyCredential->AccountName;
|
||||
auto fileServiceClient0 = Files::Shares::ServiceClient::CreateFromConnectionString(
|
||||
StandardStorageConnectionString());
|
||||
auto shareClient0 = fileServiceClient0.GetShareClient(m_shareName);
|
||||
auto fileClient0 = shareClient0.GetFileClient(fileName);
|
||||
|
||||
std::string shareUri = shareClient0.GetUri();
|
||||
std::string fileUri = fileClient0.GetUri();
|
||||
|
||||
auto verifyFileRead = [&](const std::string& sas) {
|
||||
int64_t fileSize = 512;
|
||||
fileClient0.Create(fileSize);
|
||||
auto fileClient = Files::Shares::FileClient(fileUri + sas);
|
||||
auto downloadedContent = fileClient.Download();
|
||||
EXPECT_EQ(
|
||||
ReadBodyStream(downloadedContent->BodyStream).size(), static_cast<std::size_t>(fileSize));
|
||||
};
|
||||
|
||||
auto verifyFileCreate = [&](const std::string& sas) {
|
||||
int64_t fileSize = 512;
|
||||
auto fileClient = Files::Shares::FileClient(fileUri + sas);
|
||||
EXPECT_NO_THROW(fileClient.Create(fileSize));
|
||||
};
|
||||
|
||||
auto verifyFileWrite = [&](const std::string& sas) {
|
||||
int64_t fileSize = 512;
|
||||
fileClient0.Create(fileSize);
|
||||
auto fileClient = Files::Shares::FileClient(fileUri + sas);
|
||||
std::string fileContent = "a";
|
||||
EXPECT_NO_THROW(fileClient.UploadFrom(
|
||||
reinterpret_cast<const uint8_t*>(fileContent.data()), fileContent.size()));
|
||||
};
|
||||
|
||||
auto verifyFileDelete = [&](const std::string& sas) {
|
||||
int64_t fileSize = 512;
|
||||
fileClient0.Create(fileSize);
|
||||
auto fileClient = Files::Shares::FileClient(fileUri + sas);
|
||||
EXPECT_NO_THROW(fileClient.Delete());
|
||||
};
|
||||
|
||||
auto verifyFileList = [&](const std::string& sas) {
|
||||
auto shareClient = Files::Shares::ShareClient(shareUri + sas);
|
||||
EXPECT_NO_THROW(shareClient.ListFilesAndDirectoriesSegment());
|
||||
};
|
||||
|
||||
for (auto permissions :
|
||||
{Files::Shares::ShareSasPermissions::Read,
|
||||
Files::Shares::ShareSasPermissions::Write,
|
||||
Files::Shares::ShareSasPermissions::Delete,
|
||||
Files::Shares::ShareSasPermissions::List,
|
||||
Files::Shares::ShareSasPermissions::Create,
|
||||
Files::Shares::ShareSasPermissions::All})
|
||||
{
|
||||
shareSasBuilder.SetPermissions(permissions);
|
||||
auto sasToken = shareSasBuilder.ToSasQueryParameters(*keyCredential);
|
||||
|
||||
if ((permissions & Files::Shares::ShareSasPermissions::Read)
|
||||
== Files::Shares::ShareSasPermissions::Read)
|
||||
{
|
||||
verifyFileRead(sasToken);
|
||||
}
|
||||
if ((permissions & Files::Shares::ShareSasPermissions::Write)
|
||||
== Files::Shares::ShareSasPermissions::Write)
|
||||
{
|
||||
verifyFileWrite(sasToken);
|
||||
}
|
||||
if ((permissions & Files::Shares::ShareSasPermissions::Delete)
|
||||
== Files::Shares::ShareSasPermissions::Delete)
|
||||
{
|
||||
verifyFileDelete(sasToken);
|
||||
}
|
||||
if ((permissions & Files::Shares::ShareSasPermissions::List)
|
||||
== Files::Shares::ShareSasPermissions::List)
|
||||
{
|
||||
verifyFileList(sasToken);
|
||||
}
|
||||
if ((permissions & Files::Shares::ShareSasPermissions::Create)
|
||||
== Files::Shares::ShareSasPermissions::Create)
|
||||
{
|
||||
verifyFileCreate(sasToken);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto permissions :
|
||||
{Files::Shares::ShareFileSasPermissions::Read,
|
||||
Files::Shares::ShareFileSasPermissions::Write,
|
||||
Files::Shares::ShareFileSasPermissions::Delete,
|
||||
Files::Shares::ShareFileSasPermissions::Create})
|
||||
{
|
||||
fileSasBuilder.SetPermissions(permissions);
|
||||
auto sasToken = fileSasBuilder.ToSasQueryParameters(*keyCredential);
|
||||
|
||||
if ((permissions & Files::Shares::ShareFileSasPermissions::Read)
|
||||
== Files::Shares::ShareFileSasPermissions::Read)
|
||||
{
|
||||
verifyFileRead(sasToken);
|
||||
}
|
||||
if ((permissions & Files::Shares::ShareFileSasPermissions::Write)
|
||||
== Files::Shares::ShareFileSasPermissions::Write)
|
||||
{
|
||||
verifyFileWrite(sasToken);
|
||||
}
|
||||
if ((permissions & Files::Shares::ShareFileSasPermissions::Delete)
|
||||
== Files::Shares::ShareFileSasPermissions::Delete)
|
||||
{
|
||||
verifyFileDelete(sasToken);
|
||||
}
|
||||
if ((permissions & Files::Shares::ShareFileSasPermissions::Create)
|
||||
== Files::Shares::ShareFileSasPermissions::Create)
|
||||
{
|
||||
verifyFileCreate(sasToken);
|
||||
}
|
||||
}
|
||||
|
||||
fileSasBuilder.SetPermissions(Files::Shares::ShareFileSasPermissions::All);
|
||||
// Expires
|
||||
{
|
||||
Files::Shares::ShareSasBuilder builder2 = fileSasBuilder;
|
||||
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(verifyFileRead(sasToken), StorageError);
|
||||
}
|
||||
|
||||
// Without start time
|
||||
{
|
||||
Files::Shares::ShareSasBuilder builder2 = fileSasBuilder;
|
||||
builder2.StartsOn.Reset();
|
||||
auto sasToken = builder2.ToSasQueryParameters(*keyCredential);
|
||||
EXPECT_NO_THROW(verifyFileRead(sasToken));
|
||||
}
|
||||
|
||||
// IP
|
||||
{
|
||||
Files::Shares::ShareSasBuilder builder2 = fileSasBuilder;
|
||||
builder2.IPRange = "0.0.0.0-0.0.0.1";
|
||||
auto sasToken = builder2.ToSasQueryParameters(*keyCredential);
|
||||
EXPECT_THROW(verifyFileRead(sasToken), StorageError);
|
||||
|
||||
builder2.IPRange = "0.0.0.0-255.255.255.255";
|
||||
sasToken = builder2.ToSasQueryParameters(*keyCredential);
|
||||
EXPECT_NO_THROW(verifyFileRead(sasToken));
|
||||
}
|
||||
|
||||
// Identifier
|
||||
{
|
||||
Files::Shares::SignedIdentifier identifier;
|
||||
identifier.Id = RandomString(64);
|
||||
identifier.Policy.Start
|
||||
= ToIso8601(std::chrono::system_clock::now() - std::chrono::minutes(5));
|
||||
identifier.Policy.Expiry
|
||||
= ToIso8601(std::chrono::system_clock::now() + std::chrono::minutes(60));
|
||||
identifier.Policy.Permission
|
||||
= Files::Shares::ShareSasPermissionsToString(Files::Shares::ShareSasPermissions::Read);
|
||||
m_shareClient->SetAccessPolicy({identifier});
|
||||
|
||||
Files::Shares::ShareSasBuilder builder2 = fileSasBuilder;
|
||||
builder2.StartsOn.Reset();
|
||||
builder2.ExpiresOn.clear();
|
||||
builder2.SetPermissions(static_cast<Files::Shares::ShareSasPermissions>(0));
|
||||
builder2.Identifier = identifier.Id;
|
||||
|
||||
auto sasToken = builder2.ToSasQueryParameters(*keyCredential);
|
||||
EXPECT_NO_THROW(verifyFileRead(sasToken));
|
||||
}
|
||||
|
||||
// response headers override
|
||||
{
|
||||
Files::Shares::FileShareHttpHeaders headers;
|
||||
headers.ContentType = "application/x-binary";
|
||||
headers.ContentLanguage = "en-US";
|
||||
headers.ContentDisposition = "attachment";
|
||||
headers.CacheControl = "no-cache";
|
||||
headers.ContentEncoding = "identify";
|
||||
|
||||
Files::Shares::ShareSasBuilder builder2 = fileSasBuilder;
|
||||
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 fileClient = Files::Shares::FileClient(fileUri + sasToken);
|
||||
fileClient0.Create(0);
|
||||
auto p = fileClient.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);
|
||||
}
|
||||
}
|
||||
|
||||
}}} // namespace Azure::Storage::Test
|
||||
Loading…
Reference in New Issue
Block a user