diff --git a/.vscode/cspell.json b/.vscode/cspell.json index 36885d792a..5bd1c30606 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -228,6 +228,8 @@ "Schulze", "scus", "SDDL", + "Sddl", + "sddl", "sdpath", "serializers", "Seriot", diff --git a/sdk/storage/assets.json b/sdk/storage/assets.json index 3f1bbef7ee..5828dec166 100644 --- a/sdk/storage/assets.json +++ b/sdk/storage/assets.json @@ -2,5 +2,5 @@ "AssetsRepo": "Azure/azure-sdk-assets", "AssetsRepoPrefixPath": "cpp", "TagPrefix": "cpp/storage", - "Tag": "cpp/storage_c3a4a21ce9" + "Tag": "cpp/storage_90767ef070" } diff --git a/sdk/storage/azure-storage-blobs/inc/azure/storage/blobs/blob_sas_builder.hpp b/sdk/storage/azure-storage-blobs/inc/azure/storage/blobs/blob_sas_builder.hpp index 2b56651d06..adbbeaee3f 100644 --- a/sdk/storage/azure-storage-blobs/inc/azure/storage/blobs/blob_sas_builder.hpp +++ b/sdk/storage/azure-storage-blobs/inc/azure/storage/blobs/blob_sas_builder.hpp @@ -327,6 +327,29 @@ namespace Azure { namespace Storage { namespace Sas { const Blobs::Models::UserDelegationKey& userDelegationKey, const std::string& accountName); + /** + * @brief For debugging purposes only. + * + * @param credential + * The storage account's shared key credential. + * @return Returns the string to sign that will be used to generate the signature for the SAS + * URL. + */ + std::string GenerateSasStringToSign(const StorageSharedKeyCredential& credential); + + /** + * @brief For debugging purposes only. + * + * @param userDelegationKey UserDelegationKey returned from + * BlobServiceClient.GetUserDelegationKey. + * @param accountName The name of the storage account. + * @return Returns the string to sign that will be used to generate the signature for the SAS + * URL. + */ + std::string GenerateSasStringToSign( + const Blobs::Models::UserDelegationKey& userDelegationKey, + const std::string& accountName); + private: std::string Permissions; }; diff --git a/sdk/storage/azure-storage-blobs/inc/azure/storage/blobs/rest_client.hpp b/sdk/storage/azure-storage-blobs/inc/azure/storage/blobs/rest_client.hpp index 0278ca167c..e0682a4fc5 100644 --- a/sdk/storage/azure-storage-blobs/inc/azure/storage/blobs/rest_client.hpp +++ b/sdk/storage/azure-storage-blobs/inc/azure/storage/blobs/rest_client.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -38,51 +39,35 @@ namespace Azure { namespace Storage { namespace Blobs { * @brief The algorithm used to produce the encryption key hash. Currently, the only accepted * value is "AES256". Must be provided if the x-ms-encryption-key header is provided. */ - class EncryptionAlgorithmType final { + class EncryptionAlgorithmType final + : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new EncryptionAlgorithmType instance */ EncryptionAlgorithmType() = default; /** Constructs a new EncryptionAlgorithmType from a string. */ - explicit EncryptionAlgorithmType(std::string value) : m_value(std::move(value)) {} - /** Compares with another EncryptionAlgorithmType. */ - bool operator==(const EncryptionAlgorithmType& other) const + explicit EncryptionAlgorithmType(std::string value) : ExtendableEnumeration(std::move(value)) { - return m_value == other.m_value; } - /** Compares with another EncryptionAlgorithmType. */ - bool operator!=(const EncryptionAlgorithmType& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + /** Constant value of type EncryptionAlgorithmType: Aes256 */ AZ_STORAGE_BLOBS_DLLEXPORT const static EncryptionAlgorithmType Aes256; - - private: - std::string m_value; }; /** * @brief Extensible enum used to specify how the service should look for a block ID. */ - class BlockType final { + class BlockType final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new BlockType instance */ BlockType() = default; /** Constructs a new BlockType from a string. */ - explicit BlockType(std::string value) : m_value(std::move(value)) {} - /** Compares with another BlockType. */ - bool operator==(const BlockType& other) const { return m_value == other.m_value; } - /** Compares with another BlockType. */ - bool operator!=(const BlockType& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit BlockType(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type BlockType: Committed */ AZ_STORAGE_BLOBS_DLLEXPORT const static BlockType Committed; /** Constant value of type BlockType: Uncommitted */ AZ_STORAGE_BLOBS_DLLEXPORT const static BlockType Uncommitted; /** Constant value of type BlockType: Latest */ AZ_STORAGE_BLOBS_DLLEXPORT const static BlockType Latest; - - private: - std::string m_value; }; /** * @brief The retention policy which determines how long the associated data should persist. @@ -97,7 +82,7 @@ namespace Azure { namespace Storage { namespace Blobs { * Indicates the number of days that metrics or logging or soft-deleted data should be * retained. All data older than this value will be deleted. */ - Nullable Days; + Nullable Days; }; /** * @brief Azure Analytics Logging settings. @@ -180,7 +165,7 @@ namespace Azure { namespace Storage { namespace Blobs { /** * The maximum amount time that a browser should cache the preflight OPTIONS request. */ - int32_t MaxAgeInSeconds = int32_t(); + std::int32_t MaxAgeInSeconds = std::int32_t(); }; /** * @brief The properties that enable an account to host a static website. @@ -249,27 +234,20 @@ namespace Azure { namespace Storage { namespace Blobs { /** * @brief The status of the secondary location. */ - class GeoReplicationStatus final { + class GeoReplicationStatus final + : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new GeoReplicationStatus instance */ GeoReplicationStatus() = default; /** Constructs a new GeoReplicationStatus from a string. */ - explicit GeoReplicationStatus(std::string value) : m_value(std::move(value)) {} - /** Compares with another GeoReplicationStatus. */ - bool operator==(const GeoReplicationStatus& other) const { return m_value == other.m_value; } - /** Compares with another GeoReplicationStatus. */ - bool operator!=(const GeoReplicationStatus& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit GeoReplicationStatus(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type GeoReplicationStatus: Live */ AZ_STORAGE_BLOBS_DLLEXPORT const static GeoReplicationStatus Live; /** Constant value of type GeoReplicationStatus: Bootstrap */ AZ_STORAGE_BLOBS_DLLEXPORT const static GeoReplicationStatus Bootstrap; /** Constant value of type GeoReplicationStatus: Unavailable */ AZ_STORAGE_BLOBS_DLLEXPORT const static GeoReplicationStatus Unavailable; - - private: - std::string m_value; }; /** * @brief Geo-Replication information for the Secondary Storage Service. @@ -300,41 +278,28 @@ namespace Azure { namespace Storage { namespace Blobs { /** * @brief The current lease status of the blob. */ - class LeaseStatus final { + class LeaseStatus final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new LeaseStatus instance */ LeaseStatus() = default; /** Constructs a new LeaseStatus from a string. */ - explicit LeaseStatus(std::string value) : m_value(std::move(value)) {} - /** Compares with another LeaseStatus. */ - bool operator==(const LeaseStatus& other) const { return m_value == other.m_value; } - /** Compares with another LeaseStatus. */ - bool operator!=(const LeaseStatus& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit LeaseStatus(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type LeaseStatus: Locked */ AZ_STORAGE_BLOBS_DLLEXPORT const static LeaseStatus Locked; /** Constant value of type LeaseStatus: Unlocked */ AZ_STORAGE_BLOBS_DLLEXPORT const static LeaseStatus Unlocked; - - private: - std::string m_value; }; /** * @brief The current lease state of the blob. */ - class LeaseState final { + class LeaseState final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new LeaseState instance */ LeaseState() = default; /** Constructs a new LeaseState from a string. */ - explicit LeaseState(std::string value) : m_value(std::move(value)) {} - /** Compares with another LeaseState. */ - bool operator==(const LeaseState& other) const { return m_value == other.m_value; } - /** Compares with another LeaseState. */ - bool operator!=(const LeaseState& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit LeaseState(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type LeaseState: Available */ AZ_STORAGE_BLOBS_DLLEXPORT const static LeaseState Available; /** Constant value of type LeaseState: Leased */ @@ -345,58 +310,40 @@ namespace Azure { namespace Storage { namespace Blobs { AZ_STORAGE_BLOBS_DLLEXPORT const static LeaseState Breaking; /** Constant value of type LeaseState: Broken */ AZ_STORAGE_BLOBS_DLLEXPORT const static LeaseState Broken; - - private: - std::string m_value; }; /** * @brief When a blob is leased, specifies whether the lease is of infinite or fixed duration. */ - class LeaseDurationType final { + class LeaseDurationType final + : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new LeaseDurationType instance */ LeaseDurationType() = default; /** Constructs a new LeaseDurationType from a string. */ - explicit LeaseDurationType(std::string value) : m_value(std::move(value)) {} - /** Compares with another LeaseDurationType. */ - bool operator==(const LeaseDurationType& other) const { return m_value == other.m_value; } - /** Compares with another LeaseDurationType. */ - bool operator!=(const LeaseDurationType& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit LeaseDurationType(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type LeaseDurationType: Infinite */ AZ_STORAGE_BLOBS_DLLEXPORT const static LeaseDurationType Infinite; /** Constant value of type LeaseDurationType: Fixed */ AZ_STORAGE_BLOBS_DLLEXPORT const static LeaseDurationType Fixed; - - private: - std::string m_value; }; /** * @brief Specifies whether data in the container may be accessed publicly and the level of * access. */ - class PublicAccessType final { + class PublicAccessType final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new PublicAccessType instance */ PublicAccessType() = default; /** Constructs a new PublicAccessType from a string. */ - explicit PublicAccessType(std::string value) : m_value(std::move(value)) {} - /** Compares with another PublicAccessType. */ - bool operator==(const PublicAccessType& other) const { return m_value == other.m_value; } - /** Compares with another PublicAccessType. */ - bool operator!=(const PublicAccessType& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit PublicAccessType(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type PublicAccessType: BlobContainer */ AZ_STORAGE_BLOBS_DLLEXPORT const static PublicAccessType BlobContainer; /** Constant value of type PublicAccessType: Blob */ AZ_STORAGE_BLOBS_DLLEXPORT const static PublicAccessType Blob; /** Constant value of type PublicAccessType: None */ AZ_STORAGE_BLOBS_DLLEXPORT const static PublicAccessType None; - - private: - std::string m_value; }; /** * @brief Properties of a container. @@ -455,7 +402,7 @@ namespace Azure { namespace Storage { namespace Blobs { * Remaining days before this container will be permanently deleted. Only valid when this * container was deleted. */ - Nullable RemainingRetentionDays; + Nullable RemainingRetentionDays; /** * Indicates if version level worm is enabled on this container. */ @@ -594,18 +541,13 @@ namespace Azure { namespace Storage { namespace Blobs { /** * @brief Identifies the sku name of the account. */ - class SkuName final { + class SkuName final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new SkuName instance */ SkuName() = default; /** Constructs a new SkuName from a string. */ - explicit SkuName(std::string value) : m_value(std::move(value)) {} - /** Compares with another SkuName. */ - bool operator==(const SkuName& other) const { return m_value == other.m_value; } - /** Compares with another SkuName. */ - bool operator!=(const SkuName& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit SkuName(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type SkuName: StandardLrs */ AZ_STORAGE_BLOBS_DLLEXPORT const static SkuName StandardLrs; /** Constant value of type SkuName: StandardGrs */ @@ -622,25 +564,17 @@ namespace Azure { namespace Storage { namespace Blobs { AZ_STORAGE_BLOBS_DLLEXPORT const static SkuName StandardGzrs; /** Constant value of type SkuName: StandardRagzrs */ AZ_STORAGE_BLOBS_DLLEXPORT const static SkuName StandardRagzrs; - - private: - std::string m_value; }; /** * @brief Identifies the account kind. */ - class AccountKind final { + class AccountKind final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new AccountKind instance */ AccountKind() = default; /** Constructs a new AccountKind from a string. */ - explicit AccountKind(std::string value) : m_value(std::move(value)) {} - /** Compares with another AccountKind. */ - bool operator==(const AccountKind& other) const { return m_value == other.m_value; } - /** Compares with another AccountKind. */ - bool operator!=(const AccountKind& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit AccountKind(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type AccountKind: Storage */ AZ_STORAGE_BLOBS_DLLEXPORT const static AccountKind Storage; /** Constant value of type AccountKind: BlobStorage */ @@ -651,9 +585,6 @@ namespace Azure { namespace Storage { namespace Blobs { AZ_STORAGE_BLOBS_DLLEXPORT const static AccountKind FileStorage; /** Constant value of type AccountKind: BlockBlobStorage */ AZ_STORAGE_BLOBS_DLLEXPORT const static AccountKind BlockBlobStorage; - - private: - std::string m_value; }; /** * @brief Blob info from a Filter Blobs API call. @@ -946,7 +877,7 @@ namespace Azure { namespace Storage { namespace Blobs { /** * Approximate time remaining in the lease period, in seconds. */ - int32_t LeaseTime = int32_t(); + std::int32_t LeaseTime = std::int32_t(); }; /** * @brief Response type for #Azure::Storage::Blobs::BlobContainerClient::ChangeLease. @@ -984,18 +915,13 @@ namespace Azure { namespace Storage { namespace Blobs { /** * @brief Status of the copy operation. */ - class CopyStatus final { + class CopyStatus final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new CopyStatus instance */ CopyStatus() = default; /** Constructs a new CopyStatus from a string. */ - explicit CopyStatus(std::string value) : m_value(std::move(value)) {} - /** Compares with another CopyStatus. */ - bool operator==(const CopyStatus& other) const { return m_value == other.m_value; } - /** Compares with another CopyStatus. */ - bool operator!=(const CopyStatus& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit CopyStatus(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type CopyStatus: Pending */ AZ_STORAGE_BLOBS_DLLEXPORT const static CopyStatus Pending; /** Constant value of type CopyStatus: Success */ @@ -1004,25 +930,17 @@ namespace Azure { namespace Storage { namespace Blobs { AZ_STORAGE_BLOBS_DLLEXPORT const static CopyStatus Aborted; /** Constant value of type CopyStatus: Failed */ AZ_STORAGE_BLOBS_DLLEXPORT const static CopyStatus Failed; - - private: - std::string m_value; }; /** * @brief Optional. Indicates the tier to be set on the blob. */ - class AccessTier final { + class AccessTier final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new AccessTier instance */ AccessTier() = default; /** Constructs a new AccessTier from a string. */ - explicit AccessTier(std::string value) : m_value(std::move(value)) {} - /** Compares with another AccessTier. */ - bool operator==(const AccessTier& other) const { return m_value == other.m_value; } - /** Compares with another AccessTier. */ - bool operator!=(const AccessTier& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit AccessTier(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type AccessTier: P1 */ AZ_STORAGE_BLOBS_DLLEXPORT const static AccessTier P1; /** Constant value of type AccessTier: P2 */ @@ -1061,9 +979,6 @@ namespace Azure { namespace Storage { namespace Blobs { AZ_STORAGE_BLOBS_DLLEXPORT const static AccessTier Premium; /** Constant value of type AccessTier: Cold */ AZ_STORAGE_BLOBS_DLLEXPORT const static AccessTier Cold; - - private: - std::string m_value; }; /** * @brief For blob storage LRS accounts, valid values are @@ -1071,50 +986,35 @@ namespace Azure { namespace Storage { namespace Blobs { * not complete then this value indicates that rehydrate is pending and also tells the * destination tier. */ - class ArchiveStatus final { + class ArchiveStatus final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new ArchiveStatus instance */ ArchiveStatus() = default; /** Constructs a new ArchiveStatus from a string. */ - explicit ArchiveStatus(std::string value) : m_value(std::move(value)) {} - /** Compares with another ArchiveStatus. */ - bool operator==(const ArchiveStatus& other) const { return m_value == other.m_value; } - /** Compares with another ArchiveStatus. */ - bool operator!=(const ArchiveStatus& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit ArchiveStatus(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type ArchiveStatus: RehydratePendingToHot */ AZ_STORAGE_BLOBS_DLLEXPORT const static ArchiveStatus RehydratePendingToHot; /** Constant value of type ArchiveStatus: RehydratePendingToCool */ AZ_STORAGE_BLOBS_DLLEXPORT const static ArchiveStatus RehydratePendingToCool; /** Constant value of type ArchiveStatus: RehydratePendingToCold */ AZ_STORAGE_BLOBS_DLLEXPORT const static ArchiveStatus RehydratePendingToCold; - - private: - std::string m_value; }; /** * @brief Optional: Indicates the priority with which to rehydrate an archived blob. */ - class RehydratePriority final { + class RehydratePriority final + : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new RehydratePriority instance */ RehydratePriority() = default; /** Constructs a new RehydratePriority from a string. */ - explicit RehydratePriority(std::string value) : m_value(std::move(value)) {} - /** Compares with another RehydratePriority. */ - bool operator==(const RehydratePriority& other) const { return m_value == other.m_value; } - /** Compares with another RehydratePriority. */ - bool operator!=(const RehydratePriority& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit RehydratePriority(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type RehydratePriority: High */ AZ_STORAGE_BLOBS_DLLEXPORT const static RehydratePriority High; /** Constant value of type RehydratePriority: Standard */ AZ_STORAGE_BLOBS_DLLEXPORT const static RehydratePriority Standard; - - private: - std::string m_value; }; /** * @brief Standard HTTP properties supported by containers and blobs. @@ -1150,28 +1050,20 @@ namespace Azure { namespace Storage { namespace Blobs { /** * @brief The replication status of blob with the given policy and rule identifiers. */ - class ObjectReplicationStatus final { + class ObjectReplicationStatus final + : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new ObjectReplicationStatus instance */ ObjectReplicationStatus() = default; /** Constructs a new ObjectReplicationStatus from a string. */ - explicit ObjectReplicationStatus(std::string value) : m_value(std::move(value)) {} - /** Compares with another ObjectReplicationStatus. */ - bool operator==(const ObjectReplicationStatus& other) const + explicit ObjectReplicationStatus(std::string value) : ExtendableEnumeration(std::move(value)) { - return m_value == other.m_value; } - /** Compares with another ObjectReplicationStatus. */ - bool operator!=(const ObjectReplicationStatus& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + /** Constant value of type ObjectReplicationStatus: Complete */ AZ_STORAGE_BLOBS_DLLEXPORT const static ObjectReplicationStatus Complete; /** Constant value of type ObjectReplicationStatus: Failed */ AZ_STORAGE_BLOBS_DLLEXPORT const static ObjectReplicationStatus Failed; - - private: - std::string m_value; }; /** * @brief Contains the object replication rule ID and replication status of a blob. @@ -1206,28 +1098,21 @@ namespace Azure { namespace Storage { namespace Blobs { /** * @brief Specifies the immutability policy mode to set on the blob. */ - class BlobImmutabilityPolicyMode final { + class BlobImmutabilityPolicyMode final + : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new BlobImmutabilityPolicyMode instance */ BlobImmutabilityPolicyMode() = default; /** Constructs a new BlobImmutabilityPolicyMode from a string. */ - explicit BlobImmutabilityPolicyMode(std::string value) : m_value(std::move(value)) {} - /** Compares with another BlobImmutabilityPolicyMode. */ - bool operator==(const BlobImmutabilityPolicyMode& other) const + explicit BlobImmutabilityPolicyMode(std::string value) + : ExtendableEnumeration(std::move(value)) { - return m_value == other.m_value; } - /** Compares with another BlobImmutabilityPolicyMode. */ - bool operator!=(const BlobImmutabilityPolicyMode& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + /** Constant value of type BlobImmutabilityPolicyMode: Unlocked */ AZ_STORAGE_BLOBS_DLLEXPORT const static BlobImmutabilityPolicyMode Unlocked; /** Constant value of type BlobImmutabilityPolicyMode: Locked */ AZ_STORAGE_BLOBS_DLLEXPORT const static BlobImmutabilityPolicyMode Locked; - - private: - std::string m_value; }; /** * @brief Immutability policy associated with the blob. @@ -1264,7 +1149,7 @@ namespace Azure { namespace Storage { namespace Blobs { /** * The current sequence number for a page blob. */ - Nullable SequenceNumber; + Nullable SequenceNumber; /** * The current lease status of the blob. */ @@ -1343,7 +1228,7 @@ namespace Azure { namespace Storage { namespace Blobs { * Remaining days before this blob will be permanently deleted. Only valid when this blob was * deleted. */ - Nullable RemainingRetentionDays; + Nullable RemainingRetentionDays; /** * The tier of page blob on a premium storage account or tier of block blob on blob storage or * general purpose v2 account. @@ -1363,7 +1248,7 @@ namespace Azure { namespace Storage { namespace Blobs { /** * SHA-256 hash of the encryption key. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; /** * The name of the encryption scope under which the blob is encrypted. */ @@ -1419,27 +1304,19 @@ namespace Azure { namespace Storage { namespace Blobs { /** * @brief Type of the blob. */ - class BlobType final { + class BlobType final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new BlobType instance */ BlobType() = default; /** Constructs a new BlobType from a string. */ - explicit BlobType(std::string value) : m_value(std::move(value)) {} - /** Compares with another BlobType. */ - bool operator==(const BlobType& other) const { return m_value == other.m_value; } - /** Compares with another BlobType. */ - bool operator!=(const BlobType& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit BlobType(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type BlobType: BlockBlob */ AZ_STORAGE_BLOBS_DLLEXPORT const static BlobType BlockBlob; /** Constant value of type BlobType: PageBlob */ AZ_STORAGE_BLOBS_DLLEXPORT const static BlobType PageBlob; /** Constant value of type BlobType: AppendBlob */ AZ_STORAGE_BLOBS_DLLEXPORT const static BlobType AppendBlob; - - private: - std::string m_value; }; namespace _detail { /** @@ -1478,7 +1355,7 @@ namespace Azure { namespace Storage { namespace Blobs { /** * Size in bytes. */ - int64_t BlobSize = int64_t(); + std::int64_t BlobSize = std::int64_t(); /** * Type of the blob. */ @@ -1601,11 +1478,11 @@ namespace Azure { namespace Storage { namespace Blobs { /** * The current sequence number for a page blob. */ - Nullable SequenceNumber; + Nullable SequenceNumber; /** * The number of committed blocks present in the blob. */ - Nullable CommittedBlockCount; + Nullable CommittedBlockCount; /** * If the blob has been sealed. This value is null for block blobs or page blobs. */ @@ -1631,7 +1508,7 @@ namespace Azure { namespace Storage { namespace Blobs { /** * SHA-256 hash of the encryption key used to encrypt the blob data and metadata. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; /** * Name of the encryption scope used to encrypt the blob data and metadata. */ @@ -1647,7 +1524,7 @@ namespace Azure { namespace Storage { namespace Blobs { /** * The number of tags associated with the blob. */ - Nullable TagCount; + Nullable TagCount; /** * String identifier for this copy operation. Use with Get Blob Properties to check the status * of this copy operation, or pass to Abort Copy Blob to abort a pending copy. @@ -1718,7 +1595,7 @@ namespace Azure { namespace Storage { namespace Blobs { /** * Size of the blob in bytes. */ - int64_t BlobSize = int64_t(); + std::int64_t BlobSize = std::int64_t(); /** * Indicates the range of bytes returned. */ @@ -1842,7 +1719,7 @@ namespace Azure { namespace Storage { namespace Blobs { /** * Size of the blob in bytes. */ - int64_t BlobSize = int64_t(); + std::int64_t BlobSize = std::int64_t(); /** * The ETag contains a value that you can use to perform operations conditionally. If the * request version is 2011-08-18 or newer, the ETag value will be in quotes. @@ -1852,12 +1729,12 @@ namespace Azure { namespace Storage { namespace Blobs { * The current sequence number for a page blob. This header is not returned for block blobs or * append blobs. */ - Nullable SequenceNumber; + Nullable SequenceNumber; /** * The number of committed blocks present in the blob. This header is returned only for append * blobs. */ - Nullable CommittedBlockCount; + Nullable CommittedBlockCount; /** * The value of this header is set to true if the blob data and application metadata are * completely encrypted using the specified algorithm. Otherwise, the value is set to false @@ -1869,7 +1746,7 @@ namespace Azure { namespace Storage { namespace Blobs { * The SHA-256 hash of the encryption key used to encrypt the metadata. This header is only * returned when the metadata was encrypted with a customer-provided key. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; /** * Returns the name of the encryption scope used to encrypt the blob contents and application * metadata. Note that the absence of this header implies use of the default account @@ -1915,7 +1792,7 @@ namespace Azure { namespace Storage { namespace Blobs { /** * The number of tags associated with the blob. */ - Nullable TagCount; + Nullable TagCount; /** * The time this blob will expire. */ @@ -1944,25 +1821,18 @@ namespace Azure { namespace Storage { namespace Blobs { * options: include: Delete the base blob and all of its snapshots. only: Delete only the blob's * snapshots and not the blob itself. */ - class DeleteSnapshotsOption final { + class DeleteSnapshotsOption final + : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new DeleteSnapshotsOption instance */ DeleteSnapshotsOption() = default; /** Constructs a new DeleteSnapshotsOption from a string. */ - explicit DeleteSnapshotsOption(std::string value) : m_value(std::move(value)) {} - /** Compares with another DeleteSnapshotsOption. */ - bool operator==(const DeleteSnapshotsOption& other) const { return m_value == other.m_value; } - /** Compares with another DeleteSnapshotsOption. */ - bool operator!=(const DeleteSnapshotsOption& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit DeleteSnapshotsOption(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type DeleteSnapshotsOption: IncludeSnapshots */ AZ_STORAGE_BLOBS_DLLEXPORT const static DeleteSnapshotsOption IncludeSnapshots; /** Constant value of type DeleteSnapshotsOption: OnlySnapshots */ AZ_STORAGE_BLOBS_DLLEXPORT const static DeleteSnapshotsOption OnlySnapshots; - - private: - std::string m_value; }; /** * @brief Response type for #Azure::Storage::Blobs::BlobClient::Delete. @@ -1983,21 +1853,17 @@ namespace Azure { namespace Storage { namespace Blobs { /** * @brief Required. Indicates mode of the expiry time. */ - class ScheduleBlobExpiryOriginType final { + class ScheduleBlobExpiryOriginType final + : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new ScheduleBlobExpiryOriginType instance */ ScheduleBlobExpiryOriginType() = default; /** Constructs a new ScheduleBlobExpiryOriginType from a string. */ - explicit ScheduleBlobExpiryOriginType(std::string value) : m_value(std::move(value)) {} - /** Compares with another ScheduleBlobExpiryOriginType. */ - bool operator==(const ScheduleBlobExpiryOriginType& other) const + explicit ScheduleBlobExpiryOriginType(std::string value) + : ExtendableEnumeration(std::move(value)) { - return m_value == other.m_value; } - /** Compares with another ScheduleBlobExpiryOriginType. */ - bool operator!=(const ScheduleBlobExpiryOriginType& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + /** Constant value of type ScheduleBlobExpiryOriginType: NeverExpire */ AZ_STORAGE_BLOBS_DLLEXPORT const static ScheduleBlobExpiryOriginType NeverExpire; /** Constant value of type ScheduleBlobExpiryOriginType: RelativeToCreation */ @@ -2006,9 +1872,6 @@ namespace Azure { namespace Storage { namespace Blobs { AZ_STORAGE_BLOBS_DLLEXPORT const static ScheduleBlobExpiryOriginType RelativeToNow; /** Constant value of type ScheduleBlobExpiryOriginType: Absolute */ AZ_STORAGE_BLOBS_DLLEXPORT const static ScheduleBlobExpiryOriginType Absolute; - - private: - std::string m_value; }; /** * @brief Response type for Azure::Storage::Blobs::BlobClient::SetExpiry. @@ -2047,7 +1910,7 @@ namespace Azure { namespace Storage { namespace Blobs { * The current sequence number for a page blob. This header is not returned for block blobs or * append blobs. */ - Nullable SequenceNumber; + Nullable SequenceNumber; }; /** * @brief Response type for #Azure::Storage::Blobs::BlobClient::SetImmutabilityPolicy. @@ -2084,7 +1947,7 @@ namespace Azure { namespace Storage { namespace Blobs { * The field is deprecated and is always null. Use GetProperties() instead to check sequence * number for a page blob. */ - Nullable SequenceNumber; + Nullable SequenceNumber; /** * The ETag contains a value that you can use to perform operations conditionally. If the * request version is 2011-08-18 or newer, the ETag value will be in quotes. @@ -2111,7 +1974,7 @@ namespace Azure { namespace Storage { namespace Blobs { * The SHA-256 hash of the encryption key used to encrypt the metadata. This header is only * returned when the metadata was encrypted with a customer-provided key. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; /** * Returns the name of the encryption scope used to encrypt the blob contents and application * metadata. Note that the absence of this header implies use of the default account @@ -2219,7 +2082,7 @@ namespace Azure { namespace Storage { namespace Blobs { /** * Approximate time remaining in the lease period, in seconds. */ - int32_t LeaseTime = int32_t(); + std::int32_t LeaseTime = std::int32_t(); }; } // namespace _detail /** @@ -2231,7 +2094,7 @@ namespace Azure { namespace Storage { namespace Blobs { * The field is deprecated and is always null. Use GetProperties() instead to get SHA256 of * the encryption key. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; /** * The field is deprecated and is always null. Use GetProperties() instead to check the * encryption scope. @@ -2304,28 +2167,20 @@ namespace Azure { namespace Storage { namespace Blobs { * @brief Optional, default 'replace'. Indicates if source tags should be copied or replaced * with the tags specified by x-ms-tags. */ - class BlobCopySourceTagsMode final { + class BlobCopySourceTagsMode final + : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new BlobCopySourceTagsMode instance */ BlobCopySourceTagsMode() = default; /** Constructs a new BlobCopySourceTagsMode from a string. */ - explicit BlobCopySourceTagsMode(std::string value) : m_value(std::move(value)) {} - /** Compares with another BlobCopySourceTagsMode. */ - bool operator==(const BlobCopySourceTagsMode& other) const + explicit BlobCopySourceTagsMode(std::string value) : ExtendableEnumeration(std::move(value)) { - return m_value == other.m_value; } - /** Compares with another BlobCopySourceTagsMode. */ - bool operator!=(const BlobCopySourceTagsMode& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + /** Constant value of type BlobCopySourceTagsMode: Replace */ AZ_STORAGE_BLOBS_DLLEXPORT const static BlobCopySourceTagsMode Replace; /** Constant value of type BlobCopySourceTagsMode: Copy */ AZ_STORAGE_BLOBS_DLLEXPORT const static BlobCopySourceTagsMode Copy; - - private: - std::string m_value; }; /** * @brief Response type for #Azure::Storage::Blobs::BlobClient::CopyFromUri. @@ -2404,42 +2259,29 @@ namespace Azure { namespace Storage { namespace Blobs { /** * @brief Required. The type of the provided query expression. */ - class QueryRequestQueryType final { + class QueryRequestQueryType final + : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new QueryRequestQueryType instance */ QueryRequestQueryType() = default; /** Constructs a new QueryRequestQueryType from a string. */ - explicit QueryRequestQueryType(std::string value) : m_value(std::move(value)) {} - /** Compares with another QueryRequestQueryType. */ - bool operator==(const QueryRequestQueryType& other) const + explicit QueryRequestQueryType(std::string value) : ExtendableEnumeration(std::move(value)) { - return m_value == other.m_value; } - /** Compares with another QueryRequestQueryType. */ - bool operator!=(const QueryRequestQueryType& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + /** Constant value of type QueryRequestQueryType: SQL */ AZ_STORAGE_BLOBS_DLLEXPORT const static QueryRequestQueryType SQL; - - private: - std::string m_value; }; /** * @brief The quick query format type. */ - class QueryFormatType final { + class QueryFormatType final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new QueryFormatType instance */ QueryFormatType() = default; /** Constructs a new QueryFormatType from a string. */ - explicit QueryFormatType(std::string value) : m_value(std::move(value)) {} - /** Compares with another QueryFormatType. */ - bool operator==(const QueryFormatType& other) const { return m_value == other.m_value; } - /** Compares with another QueryFormatType. */ - bool operator!=(const QueryFormatType& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit QueryFormatType(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type QueryFormatType: Delimited */ AZ_STORAGE_BLOBS_DLLEXPORT const static QueryFormatType Delimited; /** Constant value of type QueryFormatType: Json */ @@ -2448,9 +2290,6 @@ namespace Azure { namespace Storage { namespace Blobs { AZ_STORAGE_BLOBS_DLLEXPORT const static QueryFormatType Arrow; /** Constant value of type QueryFormatType: Parquet */ AZ_STORAGE_BLOBS_DLLEXPORT const static QueryFormatType Parquet; - - private: - std::string m_value; }; /** * @brief Groups the settings used for interpreting the blob data if the blob is delimited @@ -2493,21 +2332,16 @@ namespace Azure { namespace Storage { namespace Blobs { /** * @brief Type of blob query arrow field. */ - class BlobQueryArrowFieldType final { + class BlobQueryArrowFieldType final + : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new BlobQueryArrowFieldType instance */ BlobQueryArrowFieldType() = default; /** Constructs a new BlobQueryArrowFieldType from a string. */ - explicit BlobQueryArrowFieldType(std::string value) : m_value(std::move(value)) {} - /** Compares with another BlobQueryArrowFieldType. */ - bool operator==(const BlobQueryArrowFieldType& other) const + explicit BlobQueryArrowFieldType(std::string value) : ExtendableEnumeration(std::move(value)) { - return m_value == other.m_value; } - /** Compares with another BlobQueryArrowFieldType. */ - bool operator!=(const BlobQueryArrowFieldType& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + /** Constant value of type BlobQueryArrowFieldType: Int64 */ AZ_STORAGE_BLOBS_DLLEXPORT const static BlobQueryArrowFieldType Int64; /** Constant value of type BlobQueryArrowFieldType: Bool */ @@ -2520,9 +2354,6 @@ namespace Azure { namespace Storage { namespace Blobs { AZ_STORAGE_BLOBS_DLLEXPORT const static BlobQueryArrowFieldType Double; /** Constant value of type BlobQueryArrowFieldType: Decimal */ AZ_STORAGE_BLOBS_DLLEXPORT const static BlobQueryArrowFieldType Decimal; - - private: - std::string m_value; }; /** * @brief Groups settings regarding specific field of an arrow schema. @@ -2540,11 +2371,11 @@ namespace Azure { namespace Storage { namespace Blobs { /** * Precision of the field. */ - Nullable Precision; + Nullable Precision; /** * Scale of the field. */ - Nullable Scale; + Nullable Scale; }; namespace _detail { /** @@ -2669,7 +2500,7 @@ namespace Azure { namespace Storage { namespace Blobs { * The field is deprecated and is always null. Use GetProperties() instead to check sequence * number for a page blob. */ - Nullable SequenceNumber; + Nullable SequenceNumber; /** * The ETag contains a value that you can use to perform operations conditionally. If the * request version is 2011-08-18 or newer, the ETag value will be in quotes. @@ -2696,7 +2527,7 @@ namespace Azure { namespace Storage { namespace Blobs { * The SHA-256 hash of the encryption key used to encrypt the blob. This header is only * returned when the blob was encrypted with a customer-provided key. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; /** * Returns the name of the encryption scope used to encrypt the blob contents and application * metadata. Note that the absence of this header implies use of the default account @@ -2728,7 +2559,7 @@ namespace Azure { namespace Storage { namespace Blobs { /** * The current sequence number for the page blob. */ - int64_t SequenceNumber = int64_t(); + std::int64_t SequenceNumber = int64_t(); /** * The value of this header is set to true if the contents of the request are successfully * encrypted using the specified algorithm, and false otherwise. @@ -2738,7 +2569,7 @@ namespace Azure { namespace Storage { namespace Blobs { * The SHA-256 hash of the encryption key used to encrypt the pages. This header is only * returned when the pages were encrypted with a customer-provided key. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; /** * Returns the name of the encryption scope used to encrypt the blob contents and application * metadata. Note that the absence of this header implies use of the default account @@ -2765,7 +2596,7 @@ namespace Azure { namespace Storage { namespace Blobs { /** * The current sequence number for the page blob. */ - int64_t SequenceNumber = int64_t(); + std::int64_t SequenceNumber = int64_t(); }; /** * @brief Response type for #Azure::Storage::Blobs::PageBlobClient::UploadPagesFromUri. @@ -2791,7 +2622,7 @@ namespace Azure { namespace Storage { namespace Blobs { /** * The current sequence number for the page blob. */ - int64_t SequenceNumber = int64_t(); + std::int64_t SequenceNumber = int64_t(); /** * The value of this header is set to true if the contents of the request are successfully * encrypted using the specified algorithm, and false otherwise. @@ -2801,7 +2632,7 @@ namespace Azure { namespace Storage { namespace Blobs { * The SHA-256 hash of the encryption key used to encrypt the blob. This header is only * returned when the blob was encrypted with a customer-provided key. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; /** * Returns the name of the encryption scope used to encrypt the blob contents and application * metadata. Note that the absence of this header implies use of the default account @@ -2820,7 +2651,7 @@ namespace Azure { namespace Storage { namespace Blobs { /** * Size of the blob in bytes. */ - int64_t BlobSize = int64_t(); + std::int64_t BlobSize = std::int64_t(); /** * Array of PageRange. */ @@ -2841,7 +2672,7 @@ namespace Azure { namespace Storage { namespace Blobs { /** * Size of the blob in bytes. */ - int64_t BlobSize = int64_t(); + std::int64_t BlobSize = std::int64_t(); /** * Array of PageRange. */ @@ -2873,34 +2704,27 @@ namespace Azure { namespace Storage { namespace Blobs { * The current sequence number for a page blob. This header is not returned for block blobs or * append blobs. */ - int64_t SequenceNumber = int64_t(); + std::int64_t SequenceNumber = std::int64_t(); }; /** * @brief Required if the x-ms-blob-sequence-number header is set for the request. This property * applies to page blobs only. This property indicates how the service should modify the blob's * sequence number. */ - class SequenceNumberAction final { + class SequenceNumberAction final + : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new SequenceNumberAction instance */ SequenceNumberAction() = default; /** Constructs a new SequenceNumberAction from a string. */ - explicit SequenceNumberAction(std::string value) : m_value(std::move(value)) {} - /** Compares with another SequenceNumberAction. */ - bool operator==(const SequenceNumberAction& other) const { return m_value == other.m_value; } - /** Compares with another SequenceNumberAction. */ - bool operator!=(const SequenceNumberAction& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit SequenceNumberAction(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type SequenceNumberAction: Max */ AZ_STORAGE_BLOBS_DLLEXPORT const static SequenceNumberAction Max; /** Constant value of type SequenceNumberAction: Update */ AZ_STORAGE_BLOBS_DLLEXPORT const static SequenceNumberAction Update; /** Constant value of type SequenceNumberAction: Increment */ AZ_STORAGE_BLOBS_DLLEXPORT const static SequenceNumberAction Increment; - - private: - std::string m_value; }; /** * @brief Response type for #Azure::Storage::Blobs::PageBlobClient::UpdateSequenceNumber. @@ -2922,7 +2746,7 @@ namespace Azure { namespace Storage { namespace Blobs { * The current sequence number for a page blob. This header is not returned for block blobs or * append blobs. */ - int64_t SequenceNumber = int64_t(); + std::int64_t SequenceNumber = std::int64_t(); }; namespace _detail { /** @@ -2993,7 +2817,7 @@ namespace Azure { namespace Storage { namespace Blobs { * The SHA-256 hash of the encryption key used to encrypt the blob. This header is only * returned when the blob was encrypted with a customer-provided key. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; /** * Returns the name of the encryption scope used to encrypt the blob contents and application * metadata. Note that the absence of this header implies use of the default account @@ -3026,12 +2850,12 @@ namespace Azure { namespace Storage { namespace Blobs { * This response header is returned only for append operations. It returns the offset at which * the block was committed, in bytes. */ - int64_t AppendOffset = int64_t(); + std::int64_t AppendOffset = std::int64_t(); /** * The number of committed blocks present in the blob. This header is returned only for append * blobs. */ - int32_t CommittedBlockCount = int32_t(); + std::int32_t CommittedBlockCount = std::int32_t(); /** * The value of this header is set to true if the contents of the request are successfully * encrypted using the specified algorithm, and false otherwise. @@ -3041,7 +2865,7 @@ namespace Azure { namespace Storage { namespace Blobs { * The SHA-256 hash of the encryption key used to encrypt the block. This header is only * returned when the block was encrypted with a customer-provided key. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; /** * Returns the name of the encryption scope used to encrypt the blob contents and application * metadata. Note that the absence of this header implies use of the default account @@ -3074,17 +2898,17 @@ namespace Azure { namespace Storage { namespace Blobs { * This response header is returned only for append operations. It returns the offset at which * the block was committed, in bytes. */ - int64_t AppendOffset = int64_t(); + std::int64_t AppendOffset = std::int64_t(); /** * The number of committed blocks present in the blob. This header is returned only for append * blobs. */ - int32_t CommittedBlockCount = int32_t(); + std::int32_t CommittedBlockCount = std::int32_t(); /** * The SHA-256 hash of the encryption key used to encrypt the block. This header is only * returned when the block was encrypted with a customer-provided key. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; /** * Returns the name of the encryption scope used to encrypt the blob contents and application * metadata. Note that the absence of this header implies use of the default account @@ -3154,7 +2978,7 @@ namespace Azure { namespace Storage { namespace Blobs { * The SHA-256 hash of the encryption key used to encrypt the blob. This header is only * returned when the blob was encrypted with a customer-provided key. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; /** * Returns the name of the encryption scope used to encrypt the blob contents and application * metadata. Note that the absence of this header implies use of the default account @@ -3198,7 +3022,7 @@ namespace Azure { namespace Storage { namespace Blobs { * The SHA-256 hash of the encryption key used to encrypt the blob. This header is only * returned when the blob was encrypted with a customer-provided key. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; /** * Returns the name of the encryption scope used to encrypt the blob contents and application * metadata. Note that the absence of this header implies use of the default account @@ -3226,7 +3050,7 @@ namespace Azure { namespace Storage { namespace Blobs { * The SHA-256 hash of the encryption key used to encrypt the block. This header is only * returned when the block was encrypted with a customer-provided key. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; /** * Returns the name of the encryption scope used to encrypt the blob contents and application * metadata. Note that the absence of this header implies use of the default account @@ -3254,7 +3078,7 @@ namespace Azure { namespace Storage { namespace Blobs { * The SHA-256 hash of the encryption key used to encrypt the block. This header is only * returned when the block was encrypted with a customer-provided key. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; /** * Returns the name of the encryption scope used to encrypt the blob contents and application * metadata. Note that the absence of this header implies use of the default account @@ -3316,7 +3140,7 @@ namespace Azure { namespace Storage { namespace Blobs { * The SHA-256 hash of the encryption key used to encrypt the blob. This header is only * returned when the blob was encrypted with a customer-provided key. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; /** * Returns the name of the encryption scope used to encrypt the blob contents and application * metadata. Note that the absence of this header implies use of the default account @@ -3336,33 +3160,25 @@ namespace Azure { namespace Storage { namespace Blobs { /** * The block size in bytes. */ - int64_t Size = int64_t(); + std::int64_t Size = std::int64_t(); }; /** * @brief Specifies whether to return the list of committed blocks, the list of uncommitted * blocks, or both lists together. */ - class BlockListType final { + class BlockListType final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new BlockListType instance */ BlockListType() = default; /** Constructs a new BlockListType from a string. */ - explicit BlockListType(std::string value) : m_value(std::move(value)) {} - /** Compares with another BlockListType. */ - bool operator==(const BlockListType& other) const { return m_value == other.m_value; } - /** Compares with another BlockListType. */ - bool operator!=(const BlockListType& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit BlockListType(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type BlockListType: Committed */ AZ_STORAGE_BLOBS_DLLEXPORT const static BlockListType Committed; /** Constant value of type BlockListType: Uncommitted */ AZ_STORAGE_BLOBS_DLLEXPORT const static BlockListType Uncommitted; /** Constant value of type BlockListType: All */ AZ_STORAGE_BLOBS_DLLEXPORT const static BlockListType All; - - private: - std::string m_value; }; /** * @brief Response type for #Azure::Storage::Blobs::BlockBlobClient::GetBlockList. @@ -3383,7 +3199,7 @@ namespace Azure { namespace Storage { namespace Blobs { /** * Size of the blob in bytes. */ - int64_t BlobSize = 0; + std::int64_t BlobSize = 0; /** * List of committed blocks. */ @@ -3426,7 +3242,7 @@ namespace Azure { namespace Storage { namespace Blobs { { Nullable Prefix; Nullable Marker; - Nullable MaxResults; + Nullable MaxResults; Nullable Include; }; static Response ListBlobContainers( @@ -3465,7 +3281,7 @@ namespace Azure { namespace Storage { namespace Blobs { { Nullable Where; Nullable Marker; - Nullable MaxResults; + Nullable MaxResults; }; static Response FindBlobsByTags( Core::Http::_internal::HttpPipeline& pipeline, @@ -3574,7 +3390,7 @@ namespace Azure { namespace Storage { namespace Blobs { { Nullable Where; Nullable Marker; - Nullable MaxResults; + Nullable MaxResults; }; static Response FindBlobsByTags( Core::Http::_internal::HttpPipeline& pipeline, @@ -3583,7 +3399,7 @@ namespace Azure { namespace Storage { namespace Blobs { const Core::Context& context); struct AcquireBlobContainerLeaseOptions final { - Nullable Duration; + Nullable Duration; Nullable ProposedLeaseId; Nullable IfModifiedSince; Nullable IfUnmodifiedSince; @@ -3617,7 +3433,7 @@ namespace Azure { namespace Storage { namespace Blobs { const Core::Context& context); struct BreakBlobContainerLeaseOptions final { - Nullable BreakPeriod; + Nullable BreakPeriod; Nullable IfModifiedSince; Nullable IfUnmodifiedSince; }; @@ -3642,7 +3458,7 @@ namespace Azure { namespace Storage { namespace Blobs { { Nullable Prefix; Nullable Marker; - Nullable MaxResults; + Nullable MaxResults; Nullable Include; }; static Response ListBlobs( @@ -3655,7 +3471,7 @@ namespace Azure { namespace Storage { namespace Blobs { Nullable Prefix; std::string Delimiter; Nullable Marker; - Nullable MaxResults; + Nullable MaxResults; Nullable Include; Nullable ShowOnly; }; @@ -3684,7 +3500,7 @@ namespace Azure { namespace Storage { namespace Blobs { Nullable RangeGetContentMD5; Nullable RangeGetContentCRC64; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable IfModifiedSince; Nullable IfUnmodifiedSince; @@ -3704,7 +3520,7 @@ namespace Azure { namespace Storage { namespace Blobs { Nullable VersionId; Nullable LeaseId; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable IfModifiedSince; Nullable IfUnmodifiedSince; @@ -3757,7 +3573,7 @@ namespace Azure { namespace Storage { namespace Blobs { { std::string BlobCacheControl; std::string BlobContentType; - std::vector BlobContentMD5; + std::vector BlobContentMD5; std::string BlobContentEncoding; std::string BlobContentLanguage; Nullable LeaseId; @@ -3806,7 +3622,7 @@ namespace Azure { namespace Storage { namespace Blobs { std::map Metadata; Nullable LeaseId; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable EncryptionScope; Nullable IfModifiedSince; @@ -3822,7 +3638,7 @@ namespace Azure { namespace Storage { namespace Blobs { const Core::Context& context); struct AcquireBlobLeaseOptions final { - Nullable Duration; + Nullable Duration; Nullable ProposedLeaseId; Nullable IfModifiedSince; Nullable IfUnmodifiedSince; @@ -3880,7 +3696,7 @@ namespace Azure { namespace Storage { namespace Blobs { const Core::Context& context); struct BreakBlobLeaseOptions final { - Nullable BreakPeriod; + Nullable BreakPeriod; Nullable IfModifiedSince; Nullable IfUnmodifiedSince; ETag IfMatch; @@ -3896,7 +3712,7 @@ namespace Azure { namespace Storage { namespace Blobs { { std::map Metadata; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable EncryptionScope; Nullable IfModifiedSince; @@ -3955,7 +3771,7 @@ namespace Azure { namespace Storage { namespace Blobs { Nullable IfTags; std::string CopySource; Nullable LeaseId; - Nullable> SourceContentMD5; + Nullable> SourceContentMD5; Nullable BlobTagsString; Nullable ImmutabilityPolicyExpiry; Nullable ImmutabilityPolicyMode; @@ -3963,7 +3779,7 @@ namespace Azure { namespace Storage { namespace Blobs { Nullable CopySourceAuthorization; Nullable EncryptionScope; Nullable CopySourceTags; - Nullable> SourceContentcrc64; + Nullable> SourceContentcrc64; }; static Response CopyFromUri( Core::Http::_internal::HttpPipeline& pipeline, @@ -4008,7 +3824,7 @@ namespace Azure { namespace Storage { namespace Blobs { Nullable Snapshot; Nullable LeaseId; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable IfModifiedSince; Nullable IfUnmodifiedSince; @@ -4038,8 +3854,8 @@ namespace Azure { namespace Storage { namespace Blobs { { std::map Tags; Nullable VersionId; - Nullable> TransactionalContentMD5; - Nullable> TransactionalContentCrc64; + Nullable> TransactionalContentMD5; + Nullable> TransactionalContentCrc64; Nullable IfTags; Nullable LeaseId; }; @@ -4057,13 +3873,13 @@ namespace Azure { namespace Storage { namespace Blobs { std::string BlobContentType; std::string BlobContentEncoding; std::string BlobContentLanguage; - std::vector BlobContentMD5; + std::vector BlobContentMD5; std::string BlobCacheControl; std::map Metadata; Nullable LeaseId; std::string BlobContentDisposition; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable EncryptionScope; Nullable IfModifiedSince; @@ -4071,8 +3887,8 @@ namespace Azure { namespace Storage { namespace Blobs { ETag IfMatch; ETag IfNoneMatch; Nullable IfTags; - int64_t BlobContentLength = int64_t(); - Nullable BlobSequenceNumber; + std::int64_t BlobContentLength = std::int64_t(); + Nullable BlobSequenceNumber; Nullable BlobTagsString; Nullable ImmutabilityPolicyExpiry; Nullable ImmutabilityPolicyMode; @@ -4085,17 +3901,17 @@ namespace Azure { namespace Storage { namespace Blobs { const Core::Context& context); struct UploadPageBlobPagesOptions final { - Nullable> TransactionalContentMD5; - Nullable> TransactionalContentCrc64; + Nullable> TransactionalContentMD5; + Nullable> TransactionalContentCrc64; Nullable Range; Nullable LeaseId; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable EncryptionScope; - Nullable IfSequenceNumberLessThanOrEqualTo; - Nullable IfSequenceNumberLessThan; - Nullable IfSequenceNumberEqualTo; + Nullable IfSequenceNumberLessThanOrEqualTo; + Nullable IfSequenceNumberLessThan; + Nullable IfSequenceNumberEqualTo; Nullable IfModifiedSince; Nullable IfUnmodifiedSince; ETag IfMatch; @@ -4113,12 +3929,12 @@ namespace Azure { namespace Storage { namespace Blobs { Nullable Range; Nullable LeaseId; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable EncryptionScope; - Nullable IfSequenceNumberLessThanOrEqualTo; - Nullable IfSequenceNumberLessThan; - Nullable IfSequenceNumberEqualTo; + Nullable IfSequenceNumberLessThanOrEqualTo; + Nullable IfSequenceNumberLessThan; + Nullable IfSequenceNumberEqualTo; Nullable IfModifiedSince; Nullable IfUnmodifiedSince; ETag IfMatch; @@ -4134,17 +3950,17 @@ namespace Azure { namespace Storage { namespace Blobs { { std::string SourceUrl; std::string SourceRange; - Nullable> SourceContentMD5; - Nullable> SourceContentcrc64; + Nullable> SourceContentMD5; + Nullable> SourceContentcrc64; std::string Range; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable EncryptionScope; Nullable LeaseId; - Nullable IfSequenceNumberLessThanOrEqualTo; - Nullable IfSequenceNumberLessThan; - Nullable IfSequenceNumberEqualTo; + Nullable IfSequenceNumberLessThanOrEqualTo; + Nullable IfSequenceNumberLessThan; + Nullable IfSequenceNumberEqualTo; Nullable IfModifiedSince; Nullable IfUnmodifiedSince; ETag IfMatch; @@ -4172,7 +3988,7 @@ namespace Azure { namespace Storage { namespace Blobs { ETag IfNoneMatch; Nullable IfTags; Nullable Marker; - Nullable MaxResults; + Nullable MaxResults; }; static Response GetPageRanges( Core::Http::_internal::HttpPipeline& pipeline, @@ -4192,7 +4008,7 @@ namespace Azure { namespace Storage { namespace Blobs { ETag IfNoneMatch; Nullable IfTags; Nullable Marker; - Nullable MaxResults; + Nullable MaxResults; }; static Response GetPageRangesDiff( Core::Http::_internal::HttpPipeline& pipeline, @@ -4203,7 +4019,7 @@ namespace Azure { namespace Storage { namespace Blobs { { Nullable LeaseId; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable EncryptionScope; Nullable IfModifiedSince; @@ -4211,7 +4027,7 @@ namespace Azure { namespace Storage { namespace Blobs { ETag IfMatch; ETag IfNoneMatch; Nullable IfTags; - int64_t BlobContentLength = int64_t(); + std::int64_t BlobContentLength = std::int64_t(); }; static Response Resize( Core::Http::_internal::HttpPipeline& pipeline, @@ -4227,7 +4043,7 @@ namespace Azure { namespace Storage { namespace Blobs { ETag IfNoneMatch; Nullable IfTags; Models::SequenceNumberAction SequenceNumberAction; - Nullable BlobSequenceNumber; + Nullable BlobSequenceNumber; }; static Response UpdateSequenceNumber( Core::Http::_internal::HttpPipeline& pipeline, @@ -4256,13 +4072,13 @@ namespace Azure { namespace Storage { namespace Blobs { std::string BlobContentType; std::string BlobContentEncoding; std::string BlobContentLanguage; - std::vector BlobContentMD5; + std::vector BlobContentMD5; std::string BlobCacheControl; std::map Metadata; Nullable LeaseId; std::string BlobContentDisposition; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable EncryptionScope; Nullable IfModifiedSince; @@ -4282,13 +4098,13 @@ namespace Azure { namespace Storage { namespace Blobs { const Core::Context& context); struct AppendAppendBlobBlockOptions final { - Nullable> TransactionalContentMD5; - Nullable> TransactionalContentCrc64; + Nullable> TransactionalContentMD5; + Nullable> TransactionalContentCrc64; Nullable LeaseId; - Nullable MaxSize; - Nullable AppendPosition; + Nullable MaxSize; + Nullable AppendPosition; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable EncryptionScope; Nullable IfModifiedSince; @@ -4307,16 +4123,16 @@ namespace Azure { namespace Storage { namespace Blobs { { std::string SourceUrl; Nullable SourceRange; - Nullable> SourceContentMD5; - Nullable> SourceContentcrc64; - Nullable> TransactionalContentMD5; + Nullable> SourceContentMD5; + Nullable> SourceContentcrc64; + Nullable> TransactionalContentMD5; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable EncryptionScope; Nullable LeaseId; - Nullable MaxSize; - Nullable AppendPosition; + Nullable MaxSize; + Nullable AppendPosition; Nullable IfModifiedSince; Nullable IfUnmodifiedSince; ETag IfMatch; @@ -4340,7 +4156,7 @@ namespace Azure { namespace Storage { namespace Blobs { Nullable IfUnmodifiedSince; ETag IfMatch; ETag IfNoneMatch; - Nullable AppendPosition; + Nullable AppendPosition; }; static Response Seal( Core::Http::_internal::HttpPipeline& pipeline, @@ -4352,17 +4168,17 @@ namespace Azure { namespace Storage { namespace Blobs { public: struct UploadBlockBlobOptions final { - Nullable> TransactionalContentMD5; + Nullable> TransactionalContentMD5; std::string BlobContentType; std::string BlobContentEncoding; std::string BlobContentLanguage; - std::vector BlobContentMD5; + std::vector BlobContentMD5; std::string BlobCacheControl; std::map Metadata; Nullable LeaseId; std::string BlobContentDisposition; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable EncryptionScope; Nullable Tier; @@ -4375,7 +4191,7 @@ namespace Azure { namespace Storage { namespace Blobs { Nullable ImmutabilityPolicyExpiry; Nullable ImmutabilityPolicyMode; Nullable LegalHold; - Nullable> TransactionalContentCrc64; + Nullable> TransactionalContentCrc64; }; static Response Upload( Core::Http::_internal::HttpPipeline& pipeline, @@ -4388,13 +4204,13 @@ namespace Azure { namespace Storage { namespace Blobs { std::string BlobContentType; std::string BlobContentEncoding; std::string BlobContentLanguage; - std::vector BlobContentMD5; + std::vector BlobContentMD5; std::string BlobCacheControl; std::map Metadata; Nullable LeaseId; std::string BlobContentDisposition; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable EncryptionScope; Nullable Tier; @@ -4408,13 +4224,13 @@ namespace Azure { namespace Storage { namespace Blobs { ETag SourceIfMatch; ETag SourceIfNoneMatch; Nullable SourceIfTags; - Nullable> SourceContentMD5; + Nullable> SourceContentMD5; Nullable BlobTagsString; std::string CopySource; Nullable CopySourceBlobProperties; Nullable CopySourceAuthorization; Nullable CopySourceTags; - Nullable> SourceContentcrc64; + Nullable> SourceContentcrc64; }; static Response UploadFromUri( Core::Http::_internal::HttpPipeline& pipeline, @@ -4424,11 +4240,11 @@ namespace Azure { namespace Storage { namespace Blobs { struct StageBlockBlobBlockOptions final { std::string BlockId; - Nullable> TransactionalContentMD5; - Nullable> TransactionalContentCrc64; + Nullable> TransactionalContentMD5; + Nullable> TransactionalContentCrc64; Nullable LeaseId; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable EncryptionScope; }; @@ -4443,10 +4259,10 @@ namespace Azure { namespace Storage { namespace Blobs { std::string BlockId; std::string SourceUrl; Nullable SourceRange; - Nullable> SourceContentMD5; - Nullable> SourceContentcrc64; + Nullable> SourceContentMD5; + Nullable> SourceContentcrc64; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable EncryptionScope; Nullable LeaseId; @@ -4468,14 +4284,14 @@ namespace Azure { namespace Storage { namespace Blobs { std::string BlobContentType; std::string BlobContentEncoding; std::string BlobContentLanguage; - std::vector BlobContentMD5; - Nullable> TransactionalContentMD5; - Nullable> TransactionalContentCrc64; + std::vector BlobContentMD5; + Nullable> TransactionalContentMD5; + Nullable> TransactionalContentCrc64; std::map Metadata; Nullable LeaseId; std::string BlobContentDisposition; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable EncryptionScope; Nullable Tier; diff --git a/sdk/storage/azure-storage-blobs/src/blob_sas_builder.cpp b/sdk/storage/azure-storage-blobs/src/blob_sas_builder.cpp index 34701184ad..6666219435 100644 --- a/sdk/storage/azure-storage-blobs/src/blob_sas_builder.cpp +++ b/sdk/storage/azure-storage-blobs/src/blob_sas_builder.cpp @@ -323,4 +323,84 @@ namespace Azure { namespace Storage { namespace Sas { return builder.GetAbsoluteUrl(); } + std::string BlobSasBuilder::GenerateSasStringToSign(const StorageSharedKeyCredential& credential) + { + std::string canonicalName = "/blob/" + credential.AccountName + "/" + BlobContainerName; + if (Resource == BlobSasResource::Blob || Resource == BlobSasResource::BlobSnapshot + || Resource == BlobSasResource::BlobVersion) + { + canonicalName += "/" + BlobName; + } + std::string protocol = _detail::SasProtocolToString(Protocol); + std::string resource = BlobSasResourceToString(Resource); + + std::string snapshotVersion; + if (Resource == BlobSasResource::BlobSnapshot) + { + snapshotVersion = Snapshot; + } + else if (Resource == BlobSasResource::BlobVersion) + { + snapshotVersion = BlobVersionId; + } + + std::string startsOnStr = StartsOn.HasValue() + ? StartsOn.Value().ToString( + Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate) + : ""; + std::string expiresOnStr = Identifier.empty() + ? ExpiresOn.ToString( + Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate) + : ""; + + return Permissions + "\n" + startsOnStr + "\n" + expiresOnStr + "\n" + canonicalName + "\n" + + Identifier + "\n" + (IPRange.HasValue() ? IPRange.Value() : "") + "\n" + protocol + "\n" + + SasVersion + "\n" + resource + "\n" + snapshotVersion + "\n" + EncryptionScope + "\n" + + CacheControl + "\n" + ContentDisposition + "\n" + ContentEncoding + "\n" + ContentLanguage + + "\n" + ContentType; + } + + std::string BlobSasBuilder::GenerateSasStringToSign( + const Blobs::Models::UserDelegationKey& userDelegationKey, + const std::string& accountName) + { + std::string canonicalName = "/blob/" + accountName + "/" + BlobContainerName; + if (Resource == BlobSasResource::Blob || Resource == BlobSasResource::BlobSnapshot + || Resource == BlobSasResource::BlobVersion) + { + canonicalName += "/" + BlobName; + } + std::string protocol = _detail::SasProtocolToString(Protocol); + std::string resource = BlobSasResourceToString(Resource); + + std::string snapshotVersion; + if (Resource == BlobSasResource::BlobSnapshot) + { + snapshotVersion = Snapshot; + } + else if (Resource == BlobSasResource::BlobVersion) + { + snapshotVersion = BlobVersionId; + } + + std::string startsOnStr = StartsOn.HasValue() + ? StartsOn.Value().ToString( + Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate) + : ""; + std::string expiresOnStr = ExpiresOn.ToString( + Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate); + std::string signedStartsOnStr = userDelegationKey.SignedStartsOn.ToString( + Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate); + std::string signedExpiresOnStr = userDelegationKey.SignedExpiresOn.ToString( + Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate); + + return Permissions + "\n" + startsOnStr + "\n" + expiresOnStr + "\n" + canonicalName + "\n" + + userDelegationKey.SignedObjectId + "\n" + userDelegationKey.SignedTenantId + "\n" + + signedStartsOnStr + "\n" + signedExpiresOnStr + "\n" + userDelegationKey.SignedService + + "\n" + userDelegationKey.SignedVersion + "\n\n\n\n" + + (IPRange.HasValue() ? IPRange.Value() : "") + "\n" + protocol + "\n" + SasVersion + "\n" + + resource + "\n" + snapshotVersion + "\n" + EncryptionScope + "\n" + CacheControl + "\n" + + ContentDisposition + "\n" + ContentEncoding + "\n" + ContentLanguage + "\n" + ContentType; + } + }}} // namespace Azure::Storage::Sas diff --git a/sdk/storage/azure-storage-blobs/swagger/README.md b/sdk/storage/azure-storage-blobs/swagger/README.md index 662835fa89..e7483ffc5c 100644 --- a/sdk/storage/azure-storage-blobs/swagger/README.md +++ b/sdk/storage/azure-storage-blobs/swagger/README.md @@ -9,7 +9,7 @@ package-name: azure-storage-blobs namespace: Azure::Storage::Blobs output-folder: generated clear-output-folder: true -input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/storage/data-plane/Microsoft.BlobStorage/stable/2021-12-02/blob.json +input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/storage/data-plane/Microsoft.BlobStorage/stable/2024-08-04/blob.json ``` ## ModelFour Options diff --git a/sdk/storage/azure-storage-blobs/test/ut/blob_sas_test.cpp b/sdk/storage/azure-storage-blobs/test/ut/blob_sas_test.cpp index 3dafa59d80..d6e753166e 100644 --- a/sdk/storage/azure-storage-blobs/test/ut/blob_sas_test.cpp +++ b/sdk/storage/azure-storage-blobs/test/ut/blob_sas_test.cpp @@ -771,4 +771,82 @@ namespace Azure { namespace Storage { namespace Test { EXPECT_TRUE(e.AdditionalInformation.count("ExtendedErrorDetail") != 0); } } + + TEST(SasStringToSignTest, GenerateStringToSign) + { + std::string accountName = "testAccountName"; + std::string accountKey = "dGVzdEFjY291bnRLZXk="; + std::string blobUrl = "https://testAccountName.blob.core.windows.net/container/blob"; + auto keyCredential = std::make_shared(accountName, accountKey); + auto sasStartsOn = std::chrono::system_clock::now() - std::chrono::minutes(5); + auto sasExpiresOn = std::chrono::system_clock::now() + std::chrono::minutes(60); + + // Account Sas + { + Sas::AccountSasBuilder accountSasBuilder; + accountSasBuilder.Protocol = Sas::SasProtocol::HttpsAndHttp; + accountSasBuilder.StartsOn = sasStartsOn; + accountSasBuilder.ExpiresOn = sasExpiresOn; + accountSasBuilder.Services = Sas::AccountSasServices::Blobs; + accountSasBuilder.ResourceTypes = Sas::AccountSasResource::All; + accountSasBuilder.SetPermissions(Sas::AccountSasPermissions::Read); + auto sasToken = accountSasBuilder.GenerateSasToken(*keyCredential); + auto signature = Azure::Core::Url::Decode( + Azure::Core::Url(blobUrl + sasToken).GetQueryParameters().find("sig")->second); + auto stringToSign = accountSasBuilder.GenerateSasStringToSign(*keyCredential); + auto signatureFromStringToSign = Azure::Core::Convert::Base64Encode(_internal::HmacSha256( + std::vector(stringToSign.begin(), stringToSign.end()), + Azure::Core::Convert::Base64Decode(accountKey))); + EXPECT_EQ(signature, signatureFromStringToSign); + } + + // Blob Sas + { + Sas::BlobSasBuilder blobSasBuilder; + blobSasBuilder.Protocol = Sas::SasProtocol::HttpsAndHttp; + blobSasBuilder.StartsOn = sasStartsOn; + blobSasBuilder.ExpiresOn = sasExpiresOn; + blobSasBuilder.BlobContainerName = "container"; + blobSasBuilder.BlobName = "blob"; + blobSasBuilder.Resource = Sas::BlobSasResource::Blob; + blobSasBuilder.SetPermissions(Sas::BlobSasPermissions::Read); + auto sasToken = blobSasBuilder.GenerateSasToken(*keyCredential); + auto signature = Azure::Core::Url::Decode( + Azure::Core::Url(blobUrl + sasToken).GetQueryParameters().find("sig")->second); + auto stringToSign = blobSasBuilder.GenerateSasStringToSign(*keyCredential); + auto signatureFromStringToSign = Azure::Core::Convert::Base64Encode(_internal::HmacSha256( + std::vector(stringToSign.begin(), stringToSign.end()), + Azure::Core::Convert::Base64Decode(accountKey))); + EXPECT_EQ(signature, signatureFromStringToSign); + } + + // Blob User Delegation Sas + { + Blobs::Models::UserDelegationKey userDelegationKey; + userDelegationKey.SignedObjectId = "testSignedObjectId"; + userDelegationKey.SignedTenantId = "testSignedTenantId"; + userDelegationKey.SignedStartsOn = sasStartsOn; + userDelegationKey.SignedExpiresOn = sasExpiresOn; + userDelegationKey.SignedService = "b"; + userDelegationKey.SignedVersion = "2020-08-04"; + userDelegationKey.Value = accountKey; + + Sas::BlobSasBuilder blobSasBuilder; + blobSasBuilder.Protocol = Sas::SasProtocol::HttpsAndHttp; + blobSasBuilder.StartsOn = sasStartsOn; + blobSasBuilder.ExpiresOn = sasExpiresOn; + blobSasBuilder.BlobContainerName = "container"; + blobSasBuilder.BlobName = "blob"; + blobSasBuilder.Resource = Sas::BlobSasResource::Blob; + blobSasBuilder.SetPermissions(Sas::BlobSasPermissions::Read); + auto sasToken = blobSasBuilder.GenerateSasToken(userDelegationKey, accountName); + auto signature = Azure::Core::Url::Decode( + Azure::Core::Url(blobUrl + sasToken).GetQueryParameters().find("sig")->second); + auto stringToSign = blobSasBuilder.GenerateSasStringToSign(userDelegationKey, accountName); + auto signatureFromStringToSign = Azure::Core::Convert::Base64Encode(_internal::HmacSha256( + std::vector(stringToSign.begin(), stringToSign.end()), + Azure::Core::Convert::Base64Decode(accountKey))); + EXPECT_EQ(signature, signatureFromStringToSign); + } + } }}} // namespace Azure::Storage::Test diff --git a/sdk/storage/azure-storage-common/inc/azure/storage/common/account_sas_builder.hpp b/sdk/storage/azure-storage-common/inc/azure/storage/common/account_sas_builder.hpp index cf407526e0..d50dd86ab0 100644 --- a/sdk/storage/azure-storage-common/inc/azure/storage/common/account_sas_builder.hpp +++ b/sdk/storage/azure-storage-common/inc/azure/storage/common/account_sas_builder.hpp @@ -286,6 +286,16 @@ namespace Azure { namespace Storage { namespace Sas { */ std::string GenerateSasToken(const StorageSharedKeyCredential& credential); + /** + * @brief For debugging purposes only. + * + * @param credential + * The storage account's shared key credential. + * @return Returns the string to sign that will be used to generate the signature for the SAS + * URL. + */ + std::string GenerateSasStringToSign(const StorageSharedKeyCredential& credential); + private: std::string Permissions; }; diff --git a/sdk/storage/azure-storage-common/src/account_sas_builder.cpp b/sdk/storage/azure-storage-common/src/account_sas_builder.cpp index dd8af8b5ff..7735dcae26 100644 --- a/sdk/storage/azure-storage-common/src/account_sas_builder.cpp +++ b/sdk/storage/azure-storage-common/src/account_sas_builder.cpp @@ -144,4 +144,50 @@ namespace Azure { namespace Storage { namespace Sas { return builder.GetAbsoluteUrl(); } + std::string AccountSasBuilder::GenerateSasStringToSign( + const StorageSharedKeyCredential& credential) + { + std::string protocol = _detail::SasProtocolToString(Protocol); + + std::string services; + if ((Services & AccountSasServices::Blobs) == AccountSasServices::Blobs) + { + services += "b"; + } + if ((Services & AccountSasServices::Queue) == AccountSasServices::Queue) + { + services += "q"; + } + if ((Services & AccountSasServices::Files) == AccountSasServices::Files) + { + services += "f"; + } + + std::string resourceTypes; + if ((ResourceTypes & AccountSasResource::Service) == AccountSasResource::Service) + { + resourceTypes += "s"; + } + if ((ResourceTypes & AccountSasResource::Container) == AccountSasResource::Container) + { + resourceTypes += "c"; + } + if ((ResourceTypes & AccountSasResource::Object) == AccountSasResource::Object) + { + resourceTypes += "o"; + } + + std::string startsOnStr = StartsOn.HasValue() + ? StartsOn.Value().ToString( + Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate) + : ""; + std::string expiresOnStr = ExpiresOn.ToString( + Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate); + + return credential.AccountName + "\n" + Permissions + "\n" + services + "\n" + resourceTypes + + "\n" + startsOnStr + "\n" + expiresOnStr + "\n" + + (IPRange.HasValue() ? IPRange.Value() : "") + "\n" + protocol + "\n" + SasVersion + "\n" + + EncryptionScope + "\n"; + } + }}} // namespace Azure::Storage::Sas diff --git a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_sas_builder.hpp b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_sas_builder.hpp index 47d8988119..61c7be17d6 100644 --- a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_sas_builder.hpp +++ b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_sas_builder.hpp @@ -341,6 +341,29 @@ namespace Azure { namespace Storage { namespace Sas { const Files::DataLake::Models::UserDelegationKey& userDelegationKey, const std::string& accountName); + /** + * @brief For debugging purposes only. + * + * @param credential + * The storage account's shared key credential. + * @return Returns the string to sign that will be used to generate the signature for the SAS + * URL. + */ + std::string GenerateSasStringToSign(const StorageSharedKeyCredential& credential); + + /** + * @brief For debugging purposes only. + * + * @param userDelegationKey UserDelegationKey returned from + * BlobServiceClient.GetUserDelegationKey. + * @param accountName The name of the storage account. + * @return Returns the string to sign that will be used to generate the signature for the SAS + * URL. + */ + std::string GenerateSasStringToSign( + const Blobs::Models::UserDelegationKey& userDelegationKey, + const std::string& accountName); + private: std::string Permissions; }; diff --git a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp index 27b56be0d3..9dfdbfcf21 100644 --- a/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp +++ b/sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/rest_client.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -30,47 +31,29 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { } // namespace _detail namespace Models { namespace _detail { - class PathRenameMode final { + class PathRenameMode final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new PathRenameMode instance */ PathRenameMode() = default; /** Constructs a new PathRenameMode from a string. */ - explicit PathRenameMode(std::string value) : m_value(std::move(value)) {} - /** Compares with another PathRenameMode. */ - bool operator==(const PathRenameMode& other) const { return m_value == other.m_value; } - /** Compares with another PathRenameMode. */ - bool operator!=(const PathRenameMode& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit PathRenameMode(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type PathRenameMode: Legacy */ AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PathRenameMode Legacy; /** Constant value of type PathRenameMode: Posix */ AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PathRenameMode Posix; - - private: - std::string m_value; }; - class PathSetAccessControlListRecursiveMode final { + class PathSetAccessControlListRecursiveMode final + : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new PathSetAccessControlListRecursiveMode instance */ PathSetAccessControlListRecursiveMode() = default; /** Constructs a new PathSetAccessControlListRecursiveMode from a string. */ explicit PathSetAccessControlListRecursiveMode(std::string value) - : m_value(std::move(value)) - { - } - /** Compares with another PathSetAccessControlListRecursiveMode. */ - bool operator==(const PathSetAccessControlListRecursiveMode& other) const + : ExtendableEnumeration(std::move(value)) { - return m_value == other.m_value; } - /** Compares with another PathSetAccessControlListRecursiveMode. */ - bool operator!=(const PathSetAccessControlListRecursiveMode& other) const - { - return !(*this == other); - } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + /** Constant value of type PathSetAccessControlListRecursiveMode: Set */ AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PathSetAccessControlListRecursiveMode Set; /** Constant value of type PathSetAccessControlListRecursiveMode: Modify */ @@ -79,36 +62,25 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { /** Constant value of type PathSetAccessControlListRecursiveMode: Remove */ AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PathSetAccessControlListRecursiveMode Remove; - - private: - std::string m_value; }; } // namespace _detail /** * @brief Specifies whether data in the file system may be accessed publicly and the level of * access. */ - class PublicAccessType final { + class PublicAccessType final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new PublicAccessType instance */ PublicAccessType() = default; /** Constructs a new PublicAccessType from a string. */ - explicit PublicAccessType(std::string value) : m_value(std::move(value)) {} - /** Compares with another PublicAccessType. */ - bool operator==(const PublicAccessType& other) const { return m_value == other.m_value; } - /** Compares with another PublicAccessType. */ - bool operator!=(const PublicAccessType& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit PublicAccessType(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type PublicAccessType: None */ AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PublicAccessType None; /** Constant value of type PublicAccessType: FileSystem */ AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PublicAccessType FileSystem; /** Constant value of type PublicAccessType: Path */ AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PublicAccessType Path; - - private: - std::string m_value; }; namespace _detail { struct PathItem final @@ -116,7 +88,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { std::string Name; bool IsDirectory = false; DateTime LastModified; - int64_t FileSize = int64_t(); + std::int64_t FileSize = std::int64_t(); std::string Owner; std::string Group; std::string Permissions; @@ -151,25 +123,17 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { * @brief Required only for Create File and Create Directory. The value must be "file" or * "directory". */ - class PathResourceType final { + class PathResourceType final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new PathResourceType instance */ PathResourceType() = default; /** Constructs a new PathResourceType from a string. */ - explicit PathResourceType(std::string value) : m_value(std::move(value)) {} - /** Compares with another PathResourceType. */ - bool operator==(const PathResourceType& other) const { return m_value == other.m_value; } - /** Compares with another PathResourceType. */ - bool operator!=(const PathResourceType& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit PathResourceType(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type PathResourceType: Directory */ AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PathResourceType Directory; /** Constant value of type PathResourceType: File */ AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static PathResourceType File; - - private: - std::string m_value; }; /** * @brief Response type for #Azure::Storage::Files::DataLake::DataLakePathClient::Create. @@ -192,7 +156,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { /** * The size of the resource in bytes. */ - Nullable FileSize; + Nullable FileSize; /** * The value of this header is set to true if the contents of the request are successfully * encrypted using the specified algorithm, and false otherwise. @@ -202,7 +166,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { * The SHA-256 hash of the encryption key used to encrypt the blob. This header is only * returned when the blob was encrypted with a customer-provided key. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; }; /** * @brief Response type for #Azure::Storage::Files::DataLake::DataLakePathClient::Delete. @@ -255,9 +219,9 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { */ struct SetAccessControlListRecursiveResult final { - int32_t NumberOfSuccessfulDirectories = int32_t(); - int32_t NumberOfSuccessfulFiles = int32_t(); - int32_t NumberOfFailures = int32_t(); + std::int32_t NumberOfSuccessfulDirectories = std::int32_t(); + std::int32_t NumberOfSuccessfulFiles = std::int32_t(); + std::int32_t NumberOfFailures = std::int32_t(); /** * Array of AclFailedEntry. */ @@ -317,18 +281,13 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { * lease. If "release" it will release the lease only on flush. If "acquire-release" it will * acquire & complete the operation & release the lease once operation is done. */ - class LeaseAction final { + class LeaseAction final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new LeaseAction instance */ LeaseAction() = default; /** Constructs a new LeaseAction from a string. */ - explicit LeaseAction(std::string value) : m_value(std::move(value)) {} - /** Compares with another LeaseAction. */ - bool operator==(const LeaseAction& other) const { return m_value == other.m_value; } - /** Compares with another LeaseAction. */ - bool operator!=(const LeaseAction& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit LeaseAction(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type LeaseAction: Acquire */ AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static LeaseAction Acquire; /** Constant value of type LeaseAction: AutoRenew */ @@ -337,9 +296,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static LeaseAction Release; /** Constant value of type LeaseAction: AcquireRelease */ AZ_STORAGE_FILES_DATALAKE_DLLEXPORT const static LeaseAction AcquireRelease; - - private: - std::string m_value; }; /** * @brief Response type for #Azure::Storage::Files::DataLake::DataLakeFileClient::Flush. @@ -358,7 +314,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { /** * The size of the resource in bytes. */ - int64_t FileSize = int64_t(); + std::int64_t FileSize = std::int64_t(); /** * The value of this header is set to true if the contents of the request are successfully * encrypted using the specified algorithm, and false otherwise. @@ -368,7 +324,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { * The SHA-256 hash of the encryption key used to encrypt the blob. This header is only * returned when the blob was encrypted with a customer-provided key. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; /** * If the lease was auto-renewed with this request. */ @@ -393,7 +349,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { * The SHA-256 hash of the encryption key used to encrypt the blob. This header is only * returned when the blob was encrypted with a customer-provided key. */ - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; /** * If the lease was auto-renewed with this request. */ @@ -406,11 +362,11 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { struct ListFileSystemPathsOptions final { Nullable RequestId; - Nullable Timeout; + Nullable Timeout; Nullable ContinuationToken; Nullable Path; bool Recursive = bool(); - Nullable MaxResults; + Nullable MaxResults; Nullable Upn; }; static Response ListPaths( @@ -424,7 +380,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { struct CreatePathOptions final { Nullable RequestId; - Nullable Timeout; + Nullable Timeout; Nullable Resource; Nullable ContinuationToken; Nullable Mode; @@ -448,13 +404,13 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Nullable SourceIfModifiedSince; Nullable SourceIfUnmodifiedSince; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable Owner; Nullable Group; Nullable Acl; Nullable ProposedLeaseId; - Nullable LeaseDuration; + Nullable LeaseDuration; Nullable ExpiryOptions; Nullable ExpiresOn; Nullable EncryptionContext; @@ -467,7 +423,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { struct DeletePathOptions final { Nullable RequestId; - Nullable Timeout; + Nullable Timeout; Nullable Recursive; Nullable ContinuationToken; Nullable LeaseId; @@ -504,7 +460,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Nullable ContinuationToken; std::string Mode; Nullable ForceFlag; - Nullable MaxRecords; + Nullable MaxRecords; Nullable Acl; }; static Response @@ -541,13 +497,13 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { public: struct FlushFileOptions final { - Nullable Position; + Nullable Position; Nullable RetainUncommittedData; Nullable Close; - Nullable> ContentMD5; + Nullable> ContentMD5; Nullable LeaseId; Nullable LeaseAction; - Nullable LeaseDuration; + Nullable LeaseDuration; Nullable ProposedLeaseId; Nullable CacheControl; Nullable ContentType; @@ -559,7 +515,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { Nullable IfModifiedSince; Nullable IfUnmodifiedSince; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; }; static Response Flush( @@ -569,15 +525,15 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { const Core::Context& context); struct AppendFileOptions final { - Nullable Position; - Nullable> TransactionalContentHash; - Nullable> TransactionalContentCrc64; + Nullable Position; + Nullable> TransactionalContentHash; + Nullable> TransactionalContentCrc64; Nullable LeaseId; Nullable LeaseAction; - Nullable LeaseDuration; + Nullable LeaseDuration; Nullable ProposedLeaseId; Nullable EncryptionKey; - Nullable> EncryptionKeySha256; + Nullable> EncryptionKeySha256; Nullable EncryptionAlgorithm; Nullable Flush; }; diff --git a/sdk/storage/azure-storage-files-datalake/src/datalake_sas_builder.cpp b/sdk/storage/azure-storage-files-datalake/src/datalake_sas_builder.cpp index b54493c44c..c425684bde 100644 --- a/sdk/storage/azure-storage-files-datalake/src/datalake_sas_builder.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/datalake_sas_builder.cpp @@ -306,4 +306,63 @@ namespace Azure { namespace Storage { namespace Sas { return builder.GetAbsoluteUrl(); } + std::string DataLakeSasBuilder::GenerateSasStringToSign( + const StorageSharedKeyCredential& credential) + { + std::string canonicalName = "/blob/" + credential.AccountName + "/" + FileSystemName; + if (Resource == DataLakeSasResource::File) + { + canonicalName += "/" + Path; + } + std::string protocol = _detail::SasProtocolToString(Protocol); + std::string resource = DataLakeSasResourceToString(Resource); + + std::string startsOnStr = StartsOn.HasValue() + ? StartsOn.Value().ToString( + Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate) + : ""; + std::string expiresOnStr = Identifier.empty() + ? ExpiresOn.ToString( + Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate) + : ""; + + return Permissions + "\n" + startsOnStr + "\n" + expiresOnStr + "\n" + canonicalName + "\n" + + Identifier + "\n" + (IPRange.HasValue() ? IPRange.Value() : "") + "\n" + protocol + "\n" + + SasVersion + "\n" + resource + "\n" + "\n" + EncryptionScope + "\n" + CacheControl + "\n" + + ContentDisposition + "\n" + ContentEncoding + "\n" + ContentLanguage + "\n" + ContentType; + } + + std::string DataLakeSasBuilder::GenerateSasStringToSign( + const Blobs::Models::UserDelegationKey& userDelegationKey, + const std::string& accountName) + { + std::string canonicalName = "/blob/" + accountName + "/" + FileSystemName; + if (Resource == DataLakeSasResource::File || Resource == DataLakeSasResource::Directory) + { + canonicalName += "/" + Path; + } + std::string protocol = _detail::SasProtocolToString(Protocol); + std::string resource = DataLakeSasResourceToString(Resource); + + std::string startsOnStr = StartsOn.HasValue() + ? StartsOn.Value().ToString( + Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate) + : ""; + std::string expiresOnStr = ExpiresOn.ToString( + Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate); + std::string signedStartsOnStr = userDelegationKey.SignedStartsOn.ToString( + Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate); + std::string signedExpiresOnStr = userDelegationKey.SignedExpiresOn.ToString( + Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate); + + return Permissions + "\n" + startsOnStr + "\n" + expiresOnStr + "\n" + canonicalName + "\n" + + userDelegationKey.SignedObjectId + "\n" + userDelegationKey.SignedTenantId + "\n" + + signedStartsOnStr + "\n" + signedExpiresOnStr + "\n" + userDelegationKey.SignedService + + "\n" + userDelegationKey.SignedVersion + "\n" + PreauthorizedAgentObjectId + "\n" + + AgentObjectId + "\n" + CorrelationId + "\n" + (IPRange.HasValue() ? IPRange.Value() : "") + + "\n" + protocol + "\n" + SasVersion + "\n" + resource + "\n" + "\n" + EncryptionScope + + "\n" + CacheControl + "\n" + ContentDisposition + "\n" + ContentEncoding + "\n" + + ContentLanguage + "\n" + ContentType; + } + }}} // namespace Azure::Storage::Sas diff --git a/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp b/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp index 24ebdde414..8b24eb0397 100644 --- a/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/rest_client.cpp @@ -108,7 +108,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { vectorElement2.LastModified = DateTime::Parse( var0["lastModified"].get(), Azure::DateTime::DateFormat::Rfc1123); vectorElement2.FileSize = var0["contentLength"].is_number_integer() - ? var0["contentLength"].get() + ? var0["contentLength"].get() : std::stoll(var0["contentLength"].get()); vectorElement2.Owner = var0["owner"].get(); vectorElement2.Group = var0["group"].get(); @@ -504,13 +504,13 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { = Core::Json::_internal::json::parse(responseBody.begin(), responseBody.end()); response.NumberOfSuccessfulDirectories = jsonRoot["directoriesSuccessful"].is_number_integer() - ? jsonRoot["directoriesSuccessful"].get() + ? jsonRoot["directoriesSuccessful"].get() : std::stoi(jsonRoot["directoriesSuccessful"].get()); response.NumberOfSuccessfulFiles = jsonRoot["filesSuccessful"].is_number_integer() - ? jsonRoot["filesSuccessful"].get() + ? jsonRoot["filesSuccessful"].get() : std::stoi(jsonRoot["filesSuccessful"].get()); response.NumberOfFailures = jsonRoot["failureCount"].is_number_integer() - ? jsonRoot["failureCount"].get() + ? jsonRoot["failureCount"].get() : std::stoi(jsonRoot["failureCount"].get()); for (const auto& var0 : jsonRoot.count("failedEntries") != 0 && jsonRoot["failedEntries"].is_array() diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_sas_test.cpp b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_sas_test.cpp index 641cec6c16..363f18c7e3 100644 --- a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_sas_test.cpp +++ b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_sas_test.cpp @@ -795,4 +795,64 @@ namespace Azure { namespace Storage { namespace Test { EXPECT_TRUE(e.AdditionalInformation.count("ExtendedErrorDetail") != 0); } } + + TEST(SasStringToSignTest, GenerateStringToSign) + { + std::string accountName = "testAccountName"; + std::string accountKey = "dGVzdEFjY291bnRLZXk="; + std::string blobUrl = "https://testAccountName.blob.core.windows.net/container/blob"; + auto keyCredential = std::make_shared(accountName, accountKey); + auto sasStartsOn = std::chrono::system_clock::now() - std::chrono::minutes(5); + auto sasExpiresOn = std::chrono::system_clock::now() + std::chrono::minutes(60); + + // Datalake Sas + { + Sas::DataLakeSasBuilder datalakeSasBuilder; + datalakeSasBuilder.Protocol = Sas::SasProtocol::HttpsAndHttp; + datalakeSasBuilder.StartsOn = sasStartsOn; + datalakeSasBuilder.ExpiresOn = sasExpiresOn; + datalakeSasBuilder.FileSystemName = "filesystem"; + datalakeSasBuilder.Path = "path"; + datalakeSasBuilder.Resource = Sas::DataLakeSasResource::File; + datalakeSasBuilder.SetPermissions(Sas::DataLakeSasPermissions::Read); + auto sasToken = datalakeSasBuilder.GenerateSasToken(*keyCredential); + auto signature = Azure::Core::Url::Decode( + Azure::Core::Url(blobUrl + sasToken).GetQueryParameters().find("sig")->second); + auto stringToSign = datalakeSasBuilder.GenerateSasStringToSign(*keyCredential); + auto signatureFromStringToSign = Azure::Core::Convert::Base64Encode(_internal::HmacSha256( + std::vector(stringToSign.begin(), stringToSign.end()), + Azure::Core::Convert::Base64Decode(accountKey))); + EXPECT_EQ(signature, signatureFromStringToSign); + } + + // Datalake User Delegation Sas + { + Blobs::Models::UserDelegationKey userDelegationKey; + userDelegationKey.SignedObjectId = "testSignedObjectId"; + userDelegationKey.SignedTenantId = "testSignedTenantId"; + userDelegationKey.SignedStartsOn = sasStartsOn; + userDelegationKey.SignedExpiresOn = sasExpiresOn; + userDelegationKey.SignedService = "b"; + userDelegationKey.SignedVersion = "2020-08-04"; + userDelegationKey.Value = accountKey; + + Sas::DataLakeSasBuilder datalakeSasBuilder; + datalakeSasBuilder.Protocol = Sas::SasProtocol::HttpsAndHttp; + datalakeSasBuilder.StartsOn = sasStartsOn; + datalakeSasBuilder.ExpiresOn = sasExpiresOn; + datalakeSasBuilder.FileSystemName = "container"; + datalakeSasBuilder.Path = "blob"; + datalakeSasBuilder.Resource = Sas::DataLakeSasResource::File; + datalakeSasBuilder.SetPermissions(Sas::DataLakeSasPermissions::Read); + auto sasToken = datalakeSasBuilder.GenerateSasToken(userDelegationKey, accountName); + auto signature = Azure::Core::Url::Decode( + Azure::Core::Url(blobUrl + sasToken).GetQueryParameters().find("sig")->second); + auto stringToSign + = datalakeSasBuilder.GenerateSasStringToSign(userDelegationKey, accountName); + auto signatureFromStringToSign = Azure::Core::Convert::Base64Encode(_internal::HmacSha256( + std::vector(stringToSign.begin(), stringToSign.end()), + Azure::Core::Convert::Base64Decode(accountKey))); + EXPECT_EQ(signature, signatureFromStringToSign); + } + } }}} // namespace Azure::Storage::Test diff --git a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/rest_client.hpp b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/rest_client.hpp index 4ae1343f66..3e1b741de2 100644 --- a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/rest_client.hpp +++ b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/rest_client.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -31,7 +32,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { /** * The version used for the operations to Azure storage services. */ - constexpr static const char* ApiVersion = "2024-08-04"; + constexpr static const char* ApiVersion = "2024-11-04"; } // namespace _detail namespace Models { /** @@ -49,7 +50,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { * value will be deleted. Metrics data is deleted on a best-effort basis after the retention * period expires. */ - Nullable Days; + Nullable Days; }; /** * @brief Storage Analytics metrics for file service. @@ -106,7 +107,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { /** * The maximum amount time that a browser should cache the preflight OPTIONS request. */ - int32_t MaxAgeInSeconds = int32_t(); + std::int32_t MaxAgeInSeconds = std::int32_t(); }; /** * @brief Settings for SMB multichannel. @@ -138,6 +139,19 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { */ SmbSettings Settings; }; + /** + * @brief Valid value is backup. + */ + class ShareTokenIntent final : public Core::_internal::ExtendableEnumeration { + public: + /** Constructs a new ShareTokenIntent instance */ + ShareTokenIntent() = default; + /** Constructs a new ShareTokenIntent from a string. */ + explicit ShareTokenIntent(std::string value) : ExtendableEnumeration(std::move(value)) {} + + /** Constant value of type ShareTokenIntent: Backup */ + AZ_STORAGE_FILES_SHARES_DLLEXPORT const static ShareTokenIntent Backup; + }; /** * @brief Response type for #Azure::Storage::Files::Shares::ShareServiceClient::SetProperties. */ @@ -169,18 +183,13 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { /** * @brief Specifies the access tier of the share. */ - class AccessTier final { + class AccessTier final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new AccessTier instance */ AccessTier() = default; /** Constructs a new AccessTier from a string. */ - explicit AccessTier(std::string value) : m_value(std::move(value)) {} - /** Compares with another AccessTier. */ - bool operator==(const AccessTier& other) const { return m_value == other.m_value; } - /** Compares with another AccessTier. */ - bool operator!=(const AccessTier& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit AccessTier(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type AccessTier: TransactionOptimized */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static AccessTier TransactionOptimized; /** Constant value of type AccessTier: Hot */ @@ -189,48 +198,32 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { AZ_STORAGE_FILES_SHARES_DLLEXPORT const static AccessTier Cool; /** Constant value of type AccessTier: Premium */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static AccessTier Premium; - - private: - std::string m_value; }; /** * @brief The current lease status of the share. */ - class LeaseStatus final { + class LeaseStatus final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new LeaseStatus instance */ LeaseStatus() = default; /** Constructs a new LeaseStatus from a string. */ - explicit LeaseStatus(std::string value) : m_value(std::move(value)) {} - /** Compares with another LeaseStatus. */ - bool operator==(const LeaseStatus& other) const { return m_value == other.m_value; } - /** Compares with another LeaseStatus. */ - bool operator!=(const LeaseStatus& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit LeaseStatus(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type LeaseStatus: Locked */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static LeaseStatus Locked; /** Constant value of type LeaseStatus: Unlocked */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static LeaseStatus Unlocked; - - private: - std::string m_value; }; /** * @brief Lease state of the share. */ - class LeaseState final { + class LeaseState final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new LeaseState instance */ LeaseState() = default; /** Constructs a new LeaseState from a string. */ - explicit LeaseState(std::string value) : m_value(std::move(value)) {} - /** Compares with another LeaseState. */ - bool operator==(const LeaseState& other) const { return m_value == other.m_value; } - /** Compares with another LeaseState. */ - bool operator!=(const LeaseState& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit LeaseState(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type LeaseState: Available */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static LeaseState Available; /** Constant value of type LeaseState: Leased */ @@ -241,80 +234,54 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { AZ_STORAGE_FILES_SHARES_DLLEXPORT const static LeaseState Breaking; /** Constant value of type LeaseState: Broken */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static LeaseState Broken; - - private: - std::string m_value; }; /** * @brief When a share is leased, specifies whether the lease is of infinite or fixed duration. */ - class LeaseDurationType final { + class LeaseDurationType final + : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new LeaseDurationType instance */ LeaseDurationType() = default; /** Constructs a new LeaseDurationType from a string. */ - explicit LeaseDurationType(std::string value) : m_value(std::move(value)) {} - /** Compares with another LeaseDurationType. */ - bool operator==(const LeaseDurationType& other) const { return m_value == other.m_value; } - /** Compares with another LeaseDurationType. */ - bool operator!=(const LeaseDurationType& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit LeaseDurationType(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type LeaseDurationType: Infinite */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static LeaseDurationType Infinite; /** Constant value of type LeaseDurationType: Fixed */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static LeaseDurationType Fixed; - - private: - std::string m_value; }; /** * @brief The protocols that have been enabled on the share. */ - class ShareProtocols final { + class ShareProtocols final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new ShareProtocols instance */ ShareProtocols() = default; /** Constructs a new ShareProtocols from a string. */ - explicit ShareProtocols(std::string value) : m_value(std::move(value)) {} - /** Compares with another ShareProtocols. */ - bool operator==(const ShareProtocols& other) const { return m_value == other.m_value; } - /** Compares with another ShareProtocols. */ - bool operator!=(const ShareProtocols& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit ShareProtocols(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type ShareProtocols: Smb */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static ShareProtocols Smb; /** Constant value of type ShareProtocols: Nfs */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static ShareProtocols Nfs; - - private: - std::string m_value; }; /** * @brief Root squash to set on the share. Only valid for NFS shares. */ - class ShareRootSquash final { + class ShareRootSquash final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new ShareRootSquash instance */ ShareRootSquash() = default; /** Constructs a new ShareRootSquash from a string. */ - explicit ShareRootSquash(std::string value) : m_value(std::move(value)) {} - /** Compares with another ShareRootSquash. */ - bool operator==(const ShareRootSquash& other) const { return m_value == other.m_value; } - /** Compares with another ShareRootSquash. */ - bool operator!=(const ShareRootSquash& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit ShareRootSquash(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type ShareRootSquash: NoRootSquash */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static ShareRootSquash NoRootSquash; /** Constant value of type ShareRootSquash: RootSquash */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static ShareRootSquash RootSquash; /** Constant value of type ShareRootSquash: AllSquash */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static ShareRootSquash AllSquash; - - private: - std::string m_value; }; /** * @brief Properties of a share. @@ -332,23 +299,23 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { /** * The Quota for the item. */ - int64_t Quota = int64_t(); + std::int64_t Quota = std::int64_t(); /** * Provisioned Iops. */ - Nullable ProvisionedIops; + Nullable ProvisionedIops; /** * Provisioned Ingress MBps. */ - Nullable ProvisionedIngressMBps; + Nullable ProvisionedIngressMBps; /** * Provisioned Egress MBps. */ - Nullable ProvisionedEgressMBps; + Nullable ProvisionedEgressMBps; /** * Provisioned Bandwidth MBps. */ - Nullable ProvisionedBandwidthMBps; + Nullable ProvisionedBandwidthMBps; /** * Next allowed Quota Downgrade Time. */ @@ -360,7 +327,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { /** * Remaining retention days. */ - int32_t RemainingRetentionDays = int32_t(); + std::int32_t RemainingRetentionDays = std::int32_t(); /** * Specifies the access tier of the share. */ @@ -399,6 +366,20 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { * returned for shares, not for snapshots. */ Nullable EnableSnapshotVirtualDirectoryAccess; + /** + * Optional. Boolean. Default if not specified is false. This property enables paid bursting. + */ + Nullable PaidBurstingEnabled; + /** + * Optional. Integer. Default if not specified is the maximum IOPS the file share can support. + * Current maximum for a file share is 102,400 IOPS. + */ + Nullable PaidBurstingMaxIops; + /** + * Optional. Integer. Default if not specified is the maximum throughput the file share can + * support. Current maximum for a file share is 10,340 MiB/sec. + */ + Nullable PaidBurstingMaxBandwidthMibps; }; /** * @brief A listed Azure Storage share item. @@ -473,7 +454,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::string ServiceEndpoint; Nullable Prefix; Nullable Marker; - Nullable MaxResults; + Nullable MaxResults; /** * Array of ShareItem. */ @@ -527,19 +508,19 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { /** * Returns the current share quota in GB. */ - int64_t Quota = int64_t(); + std::int64_t Quota = std::int64_t(); /** * Returns the current share provisioned IOPS. */ - Nullable ProvisionedIops; + Nullable ProvisionedIops; /** * Returns the current share provisioned ingress in megabytes per second. */ - Nullable ProvisionedIngressMBps; + Nullable ProvisionedIngressMBps; /** * Returns the current share provisioned egress in megabytes per second. */ - Nullable ProvisionedEgressMBps; + Nullable ProvisionedEgressMBps; /** * Returns the current share next allowed quota downgrade time. */ @@ -547,7 +528,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { /** * Returns the current share provisioned bandwidth in megabits per second. */ - Nullable ProvisionedBandwidthMBps; + Nullable ProvisionedBandwidthMBps; /** * When a share is leased, specifies whether the lease is of infinite or fixed duration. */ @@ -582,27 +563,34 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { * returned for shares, not for snapshots. */ Nullable EnableSnapshotVirtualDirectoryAccess; + /** + * Optional. Boolean. Default if not specified is false. This property enables paid bursting. + */ + Nullable PaidBurstingEnabled; + /** + * Optional. Integer. Default if not specified is the maximum IOPS the file share can support. + * Current maximum for a file share is 102,400 IOPS. + */ + Nullable PaidBurstingMaxIops; + /** + * Optional. Integer. Default if not specified is the maximum throughput the file share can + * support. Current maximum for a file share is 10,340 MiB/sec. + */ + Nullable PaidBurstingMaxBandwidthMibps; }; /** * @brief Specifies the option include to delete the base share and all of its snapshots. */ - class DeleteSnapshotsOption final { + class DeleteSnapshotsOption final + : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new DeleteSnapshotsOption instance */ DeleteSnapshotsOption() = default; /** Constructs a new DeleteSnapshotsOption from a string. */ - explicit DeleteSnapshotsOption(std::string value) : m_value(std::move(value)) {} - /** Compares with another DeleteSnapshotsOption. */ - bool operator==(const DeleteSnapshotsOption& other) const { return m_value == other.m_value; } - /** Compares with another DeleteSnapshotsOption. */ - bool operator!=(const DeleteSnapshotsOption& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit DeleteSnapshotsOption(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type DeleteSnapshotsOption: Include */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static DeleteSnapshotsOption Include; - - private: - std::string m_value; }; /** * @brief Response type for #Azure::Storage::Files::Shares::ShareClient::Delete. @@ -714,7 +702,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { /** * Approximate time remaining in the lease period, in seconds. */ - int32_t LeaseTime = int32_t(); + std::int32_t LeaseTime = std::int32_t(); }; } // namespace _detail /** @@ -748,25 +736,24 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { DateTime LastModified; }; /** - * @brief Valid value is backup. + * @brief Optional. Available for version 2023-06-01 and later. Specifies the format in which + * the permission is returned. Acceptable values are SDDL or binary. If + * x-ms-file-permission-format is unspecified or explicitly set to SDDL, the permission is + * returned in SDDL format. If x-ms-file-permission-format is explicitly set to binary, the + * permission is returned as a base64 string representing the binary encoding of the permission. */ - class ShareTokenIntent final { + class FilePermissionFormat final + : public Core::_internal::ExtendableEnumeration { public: - /** Constructs a new ShareTokenIntent instance */ - ShareTokenIntent() = default; - /** Constructs a new ShareTokenIntent from a string. */ - explicit ShareTokenIntent(std::string value) : m_value(std::move(value)) {} - /** Compares with another ShareTokenIntent. */ - bool operator==(const ShareTokenIntent& other) const { return m_value == other.m_value; } - /** Compares with another ShareTokenIntent. */ - bool operator!=(const ShareTokenIntent& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } - /** Constant value of type ShareTokenIntent: Backup */ - AZ_STORAGE_FILES_SHARES_DLLEXPORT const static ShareTokenIntent Backup; + /** Constructs a new FilePermissionFormat instance */ + FilePermissionFormat() = default; + /** Constructs a new FilePermissionFormat from a string. */ + explicit FilePermissionFormat(std::string value) : ExtendableEnumeration(std::move(value)) {} - private: - std::string m_value; + /** Constant value of type FilePermissionFormat: Sddl */ + AZ_STORAGE_FILES_SHARES_DLLEXPORT const static FilePermissionFormat Sddl; + /** Constant value of type FilePermissionFormat: Binary */ + AZ_STORAGE_FILES_SHARES_DLLEXPORT const static FilePermissionFormat Binary; }; /** * @brief Response type for #Azure::Storage::Files::Shares::ShareClient::CreatePermission. @@ -788,6 +775,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { * The permission in the Security Descriptor Definition Language (SDDL). */ std::string Permission; + Nullable Format; }; } // namespace _detail /** @@ -889,7 +877,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { * The approximate size of the data stored in bytes. Note that this value may not include all * recently created or recently resized files. */ - int64_t ShareUsageInBytes = int64_t(); + std::int64_t ShareUsageInBytes = std::int64_t(); /** * The ETag contains a value that you can use to perform operations conditionally, in quotes. */ @@ -1161,7 +1149,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { * handle is closed or the op-lock is broken. To retrieve current property values, call Get * File Properties. */ - int64_t FileSize = int64_t(); + std::int64_t FileSize = std::int64_t(); /** * The time the file was last accessed. */ @@ -1250,7 +1238,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::string DirectoryPath; StringEncoded Prefix; Nullable Marker; - Nullable MaxResults; + Nullable MaxResults; /** * Abstract for entries that can be listed from Directory. */ @@ -1261,27 +1249,19 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { /** * @brief Access rights of the access policy. */ - class AccessRight final { + class AccessRight final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new AccessRight instance */ AccessRight() = default; /** Constructs a new AccessRight from a string. */ - explicit AccessRight(std::string value) : m_value(std::move(value)) {} - /** Compares with another AccessRight. */ - bool operator==(const AccessRight& other) const { return m_value == other.m_value; } - /** Compares with another AccessRight. */ - bool operator!=(const AccessRight& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit AccessRight(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type AccessRight: Read */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static AccessRight Read; /** Constant value of type AccessRight: Write */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static AccessRight Write; /** Constant value of type AccessRight: Delete */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static AccessRight Delete; - - private: - std::string m_value; }; /** * @brief A listed Azure Storage handle item. @@ -1343,11 +1323,11 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { /** * Contains count of number of handles closed. */ - int32_t NumberOfHandlesClosed = int32_t(); + std::int32_t NumberOfHandlesClosed = std::int32_t(); /** * Contains count of number of handles that failed to close. */ - int32_t NumberOfHandlesFailedToClose = int32_t(); + std::int32_t NumberOfHandlesFailedToClose = std::int32_t(); }; /** * @brief Response type for #Azure::Storage::Files::Shares::DirectoryClient::Rename. @@ -1462,18 +1442,13 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { /** * @brief Status of a copy operation. */ - class CopyStatus final { + class CopyStatus final : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new CopyStatus instance */ CopyStatus() = default; /** Constructs a new CopyStatus from a string. */ - explicit CopyStatus(std::string value) : m_value(std::move(value)) {} - /** Compares with another CopyStatus. */ - bool operator==(const CopyStatus& other) const { return m_value == other.m_value; } - /** Compares with another CopyStatus. */ - bool operator!=(const CopyStatus& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit CopyStatus(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type CopyStatus: Pending */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static CopyStatus Pending; /** Constant value of type CopyStatus: Success */ @@ -1482,9 +1457,6 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { AZ_STORAGE_FILES_SHARES_DLLEXPORT const static CopyStatus Aborted; /** Constant value of type CopyStatus: Failed */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static CopyStatus Failed; - - private: - std::string m_value; }; /** * @brief Detailed information of the downloaded file. @@ -1586,7 +1558,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { /** * Size of the file in bytes. */ - int64_t FileSize = int64_t(); + std::int64_t FileSize = std::int64_t(); /** * MD5 hash for the downloaded range of data. */ @@ -1626,7 +1598,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { * The size of the file in bytes. This header returns the value of the 'x-ms-content-length' * header that is stored with the file. */ - int64_t FileSize = int64_t(); + std::int64_t FileSize = std::int64_t(); /** * The ETag contains a value that you can use to perform operations conditionally, in quotes. */ @@ -1813,25 +1785,18 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { /** * @brief If the file last write time should be preserved or overwritten. */ - class FileLastWrittenMode final { + class FileLastWrittenMode final + : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new FileLastWrittenMode instance */ FileLastWrittenMode() = default; /** Constructs a new FileLastWrittenMode from a string. */ - explicit FileLastWrittenMode(std::string value) : m_value(std::move(value)) {} - /** Compares with another FileLastWrittenMode. */ - bool operator==(const FileLastWrittenMode& other) const { return m_value == other.m_value; } - /** Compares with another FileLastWrittenMode. */ - bool operator!=(const FileLastWrittenMode& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit FileLastWrittenMode(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type FileLastWrittenMode: Now */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static FileLastWrittenMode Now; /** Constant value of type FileLastWrittenMode: Preserve */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static FileLastWrittenMode Preserve; - - private: - std::string m_value; }; /** * @brief Response type for #Azure::Storage::Files::Shares::ShareFileClient::UploadRange. @@ -1913,32 +1878,25 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { /** * The size of the file in bytes. */ - int64_t FileSize = int64_t(); + std::int64_t FileSize = std::int64_t(); }; /** * @brief Specifies the option to copy file security descriptor from source file or to set it * using the value which is defined by the header value of x-ms-file-permission or * x-ms-file-permission-key. */ - class PermissionCopyMode final { + class PermissionCopyMode final + : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new PermissionCopyMode instance */ PermissionCopyMode() = default; /** Constructs a new PermissionCopyMode from a string. */ - explicit PermissionCopyMode(std::string value) : m_value(std::move(value)) {} - /** Compares with another PermissionCopyMode. */ - bool operator==(const PermissionCopyMode& other) const { return m_value == other.m_value; } - /** Compares with another PermissionCopyMode. */ - bool operator!=(const PermissionCopyMode& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit PermissionCopyMode(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type PermissionCopyMode: Source */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static PermissionCopyMode Source; /** Constant value of type PermissionCopyMode: Override */ AZ_STORAGE_FILES_SHARES_DLLEXPORT const static PermissionCopyMode Override; - - private: - std::string m_value; }; namespace _detail { /** @@ -1998,11 +1956,11 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { /** * Contains count of number of handles closed. */ - int32_t NumberOfHandlesClosed = int32_t(); + std::int32_t NumberOfHandlesClosed = std::int32_t(); /** * Contains count of number of handles that failed to close. */ - int32_t NumberOfHandlesFailedToClose = int32_t(); + std::int32_t NumberOfHandlesFailedToClose = std::int32_t(); }; /** * @brief Response type for #Azure::Storage::Files::Shares::FileClient::Rename. @@ -2061,6 +2019,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { struct SetServicePropertiesOptions final { Models::ShareServiceProperties ShareServiceProperties; + Nullable FileRequestIntent; }; static Response SetProperties( Core::Http::_internal::HttpPipeline& pipeline, @@ -2069,6 +2028,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const Core::Context& context); struct GetServicePropertiesOptions final { + Nullable FileRequestIntent; }; static Response GetProperties( Core::Http::_internal::HttpPipeline& pipeline, @@ -2079,8 +2039,9 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { Nullable Prefix; Nullable Marker; - Nullable MaxResults; + Nullable MaxResults; Nullable Include; + Nullable FileRequestIntent; }; static Response ListSharesSegment( Core::Http::_internal::HttpPipeline& pipeline, @@ -2093,11 +2054,15 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { struct CreateShareOptions final { std::map Metadata; - Nullable Quota; + Nullable Quota; Nullable AccessTier; Nullable EnabledProtocols; Nullable RootSquash; Nullable EnableSnapshotVirtualDirectoryAccess; + Nullable PaidBurstingEnabled; + Nullable PaidBurstingMaxBandwidthMibps; + Nullable PaidBurstingMaxIops; + Nullable FileRequestIntent; }; static Response Create( Core::Http::_internal::HttpPipeline& pipeline, @@ -2108,6 +2073,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { Nullable Sharesnapshot; Nullable LeaseId; + Nullable FileRequestIntent; }; static Response GetProperties( Core::Http::_internal::HttpPipeline& pipeline, @@ -2119,6 +2085,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Nullable Sharesnapshot; Nullable DeleteSnapshots; Nullable LeaseId; + Nullable FileRequestIntent; }; static Response Delete( Core::Http::_internal::HttpPipeline& pipeline, @@ -2127,9 +2094,10 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const Core::Context& context); struct AcquireShareLeaseOptions final { - Nullable Duration; + Nullable Duration; Nullable ProposedLeaseId; Nullable Sharesnapshot; + Nullable FileRequestIntent; }; static Response AcquireLease( Core::Http::_internal::HttpPipeline& pipeline, @@ -2140,6 +2108,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { std::string LeaseId; Nullable Sharesnapshot; + Nullable FileRequestIntent; }; static Response ReleaseLease( Core::Http::_internal::HttpPipeline& pipeline, @@ -2151,6 +2120,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::string LeaseId; Nullable ProposedLeaseId; Nullable Sharesnapshot; + Nullable FileRequestIntent; }; static Response ChangeLease( Core::Http::_internal::HttpPipeline& pipeline, @@ -2161,6 +2131,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { std::string LeaseId; Nullable Sharesnapshot; + Nullable FileRequestIntent; }; static Response RenewLease( Core::Http::_internal::HttpPipeline& pipeline, @@ -2169,9 +2140,10 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const Core::Context& context); struct BreakShareLeaseOptions final { - Nullable BreakPeriod; + Nullable BreakPeriod; Nullable LeaseId; Nullable Sharesnapshot; + Nullable FileRequestIntent; }; static Response BreakLease( Core::Http::_internal::HttpPipeline& pipeline, @@ -2181,6 +2153,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { struct CreateShareSnapshotOptions final { std::map Metadata; + Nullable FileRequestIntent; }; static Response CreateSnapshot( Core::Http::_internal::HttpPipeline& pipeline, @@ -2200,6 +2173,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { struct GetSharePermissionOptions final { std::string FilePermissionKey; + Nullable FilePermissionFormat; Nullable FileRequestIntent; }; static Response GetPermission( @@ -2209,11 +2183,15 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const Core::Context& context); struct SetSharePropertiesOptions final { - Nullable Quota; + Nullable Quota; Nullable AccessTier; Nullable LeaseId; Nullable RootSquash; Nullable EnableSnapshotVirtualDirectoryAccess; + Nullable PaidBurstingEnabled; + Nullable PaidBurstingMaxBandwidthMibps; + Nullable PaidBurstingMaxIops; + Nullable FileRequestIntent; }; static Response SetProperties( Core::Http::_internal::HttpPipeline& pipeline, @@ -2224,6 +2202,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { std::map Metadata; Nullable LeaseId; + Nullable FileRequestIntent; }; static Response SetMetadata( Core::Http::_internal::HttpPipeline& pipeline, @@ -2233,6 +2212,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { struct GetShareAccessPolicyOptions final { Nullable LeaseId; + Nullable FileRequestIntent; }; static Response GetAccessPolicy( Core::Http::_internal::HttpPipeline& pipeline, @@ -2243,6 +2223,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { std::vector ShareAcl; Nullable LeaseId; + Nullable FileRequestIntent; }; static Response SetAccessPolicy( Core::Http::_internal::HttpPipeline& pipeline, @@ -2252,6 +2233,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { struct GetShareStatisticsOptions final { Nullable LeaseId; + Nullable FileRequestIntent; }; static Response GetStatistics( Core::Http::_internal::HttpPipeline& pipeline, @@ -2266,6 +2248,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Nullable AllowTrailingDot; std::map Metadata; Nullable FilePermission; + Nullable FilePermissionFormat; Nullable FilePermissionKey; std::string FileAttributes; Nullable FileCreationTime; @@ -2302,6 +2285,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { struct SetDirectoryPropertiesOptions final { Nullable FilePermission; + Nullable FilePermissionFormat; Nullable FilePermissionKey; std::string FileAttributes; Nullable FileCreationTime; @@ -2331,7 +2315,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Nullable Prefix; Nullable Sharesnapshot; Nullable Marker; - Nullable MaxResults; + Nullable MaxResults; Nullable Include; Nullable IncludeExtendedInfo; Nullable AllowTrailingDot; @@ -2346,7 +2330,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { struct ListDirectoryHandlesOptions final { Nullable Marker; - Nullable MaxResults; + Nullable MaxResults; Nullable Sharesnapshot; Nullable Recursive; Nullable AllowTrailingDot; @@ -2383,6 +2367,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Nullable FileLastWriteTime; Nullable FileChangeTime; Nullable FilePermission; + Nullable FilePermissionFormat; Nullable FilePermissionKey; std::map Metadata; Nullable AllowTrailingDot; @@ -2400,15 +2385,16 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { struct CreateFileOptions final { Nullable AllowTrailingDot; - int64_t FileContentLength = int64_t(); + std::int64_t FileContentLength = std::int64_t(); Nullable FileContentType; Nullable FileContentEncoding; Nullable FileContentLanguage; Nullable FileCacheControl; - Nullable> FileContentMD5; + Nullable> FileContentMD5; Nullable FileContentDisposition; std::map Metadata; Nullable FilePermission; + Nullable FilePermissionFormat; Nullable FilePermissionKey; std::string FileAttributes; Nullable FileCreationTime; @@ -2460,14 +2446,15 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const Core::Context& context); struct SetFileHttpHeadersOptions final { - Nullable FileContentLength; + Nullable FileContentLength; Nullable FileContentType; Nullable FileContentEncoding; Nullable FileContentLanguage; Nullable FileCacheControl; - Nullable> FileContentMD5; + Nullable> FileContentMD5; Nullable FileContentDisposition; Nullable FilePermission; + Nullable FilePermissionFormat; Nullable FilePermissionKey; std::string FileAttributes; Nullable FileCreationTime; @@ -2496,7 +2483,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const Core::Context& context); struct AcquireFileLeaseOptions final { - Nullable Duration; + Nullable Duration; Nullable ProposedLeaseId; Nullable AllowTrailingDot; Nullable FileRequestIntent; @@ -2544,7 +2531,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { std::string Range; std::string FileRangeWrite; - Nullable> ContentMD5; + Nullable> ContentMD5; Nullable LeaseId; Nullable FileLastWrittenMode; Nullable AllowTrailingDot; @@ -2561,9 +2548,9 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::string Range; std::string CopySource; Nullable SourceRange; - Nullable> SourceContentCrc64; - Nullable> SourceIfMatchCrc64; - Nullable> SourceIfNoneMatchCrc64; + Nullable> SourceContentCrc64; + Nullable> SourceIfMatchCrc64; + Nullable> SourceIfNoneMatchCrc64; Nullable LeaseId; Nullable CopySourceAuthorization; Nullable FileLastWrittenMode; @@ -2629,7 +2616,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { struct ListFileHandlesOptions final { Nullable Marker; - Nullable MaxResults; + Nullable MaxResults; Nullable Sharesnapshot; Nullable AllowTrailingDot; Nullable FileRequestIntent; @@ -2664,6 +2651,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Nullable FileLastWriteTime; Nullable FileChangeTime; Nullable FilePermission; + Nullable FilePermissionFormat; Nullable FilePermissionKey; std::map Metadata; Nullable FileContentType; diff --git a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_options.hpp b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_options.hpp index 4e81ead933..d8fc0e6e13 100644 --- a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_options.hpp +++ b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_options.hpp @@ -181,6 +181,24 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { * returned for shares, not for snapshots. */ Nullable EnableSnapshotVirtualDirectoryAccess; + + /** + * Optional. Boolean. Version 2023-11-03 and newer. Default if not specified is false. This + * property enables paid bursting. + */ + Nullable EnablePaidBursting; + + /** + * Optional. Integer. Version 2023-11-03 and newer. Default if not specified is the maximum IOPS + * the file share can support. Current maximum for a file share is 102,400 IOPS. + */ + Nullable PaidBurstingMaxIops; + + /** + * Optional. Integer. Version 2023-11-03 and newer. Default if not specified is the maximum + * throughput the file share can support. Current maximum for a file share is 10,340 MiB/sec. + */ + Nullable PaidBurstingMaxBandwidthMibps; }; /** @@ -240,6 +258,24 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { * returned for shares, not for snapshots. */ Nullable EnableSnapshotVirtualDirectoryAccess; + + /** + * Optional. Boolean. Version 2023-11-03 and newer. Default if not specified is false. This + * property enables paid bursting. + */ + Nullable EnablePaidBursting; + + /** + * Optional. Integer. Version 2023-11-03 and newer. Default if not specified is the maximum IOPS + * the file share can support. Current maximum for a file share is 102,400 IOPS. + */ + Nullable PaidBurstingMaxIops; + + /** + * Optional. Integer. Version 2023-11-03 and newer. Default if not specified is the maximum + * throughput the file share can support. Current maximum for a file share is 10,340 MiB/sec. + */ + Nullable PaidBurstingMaxBandwidthMibps; }; /** @@ -275,6 +311,13 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { */ struct CreateSharePermissionOptions final { + /** + * Optional. Available for version 2024-11-04 and later. Specifies + * the format in which the permission is returned.If FilePermissionFormat is unspecified or + * explicitly set to SDDL format, the permission will be + * returned in SDDL format. + */ + Nullable FilePermissionFormat; }; /** @@ -282,6 +325,13 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { */ struct GetSharePermissionOptions final { + /** + * Optional. Available for version 2024-11-04 and later. Specifies + * the format in which the permission is returned.If FilePermissionFormat is unspecified or + * explicitly set to SDDL format, the permission will be + * returned in SDDL format. + */ + Nullable FilePermissionFormat; }; /** @@ -300,6 +350,14 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { */ Azure::Nullable DirectoryPermission; + /** + * Optional. Available for version 2024-11-04 and later. Specifies + * the format in which the permission is returned.If DirectoryPermissionFormat is unspecified or + * explicitly set to SDDL format, the permission will be + * returned in SDDL format. + */ + Nullable DirectoryPermissionFormat; + /** * SMB properties to set for the directory. */ @@ -351,6 +409,14 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { */ Azure::Nullable FilePermission; + /** + * Optional. Available for version 2024-11-04 and later. Specifies + * the format in which the permission is returned.If FilePermissionFormat is unspecified or + * explicitly set to SDDL format, the permission will be + * returned in SDDL format. + */ + Nullable FilePermissionFormat; + /** * A name-value pair to associate with a file storage object. */ @@ -407,6 +473,14 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { */ Azure::Nullable FilePermission; + /** + * Optional. Available for version 2024-11-04 and later. Specifies + * the format in which the permission is returned.If FilePermissionFormat is unspecified or + * explicitly set to SDDL format, the permission will be + * returned in SDDL format. + */ + Nullable FilePermissionFormat; + /** * A name-value pair to associate with a file storage object. */ @@ -441,6 +515,14 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { * group and dacl. */ Azure::Nullable FilePermission; + + /** + * Optional. Available for version 2024-11-04 and later. Specifies + * the format in which the permission is returned.If FilePermissionFormat is unspecified or + * explicitly set to SDDL format format, the permission will be + * returned in SDDL format. + */ + Nullable FilePermissionFormat; }; /** @@ -554,10 +636,19 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { /** * This permission is the security descriptor for the file specified in the Security - * Descriptor Definition Language (SDDL). If not specified, 'inherit' is used. + * Descriptor Definition Language (SDDL) or base64 encoded + * binary format. If not specified, 'inherit' is used. */ Azure::Nullable Permission; + /** + * Optional. Available for version 2024-11-04 and later. Specifies + * the format in which the permission is returned.If FilePermissionFormat is unspecified or + * explicitly set to SDDL format format, the permission will be + * returned in SDDL format. + */ + Nullable FilePermissionFormat; + /** * SMB properties to set for the file. */ @@ -686,10 +777,19 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { /** * This permission is the security descriptor for the file specified in the Security - * Descriptor Definition Language (SDDL). If not specified, 'inherit' is used. + * Descriptor Definition Language (SDDL) or base64 encoded + * binary format. If not specified, 'inherit' is used. */ Azure::Nullable Permission; + /** + * Optional. Available for version 2024-11-04 and later. Specifies + * the format in which the permission is returned.If FilePermissionFormat is unspecified or + * explicitly set to SDDL format format, the permission will be + * returned in SDDL format. + */ + Nullable FilePermissionFormat; + /** * Specify this to resize a file to the specified value. */ @@ -922,6 +1022,14 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { */ Azure::Nullable FilePermission; + /** + * Optional. Available for version 2024-11-04 and later. Specifies + * the format in which the permission is returned.If FilePermissionFormat is unspecified or + * explicitly set to SDDL format, the permission will be + * returned in SDDL format. + */ + Nullable FilePermissionFormat; + /** * @brief Options for parallel transfer. */ diff --git a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_sas_builder.hpp b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_sas_builder.hpp index 77f7a4eac6..08838a02fc 100644 --- a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_sas_builder.hpp +++ b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_sas_builder.hpp @@ -230,6 +230,16 @@ namespace Azure { namespace Storage { namespace Sas { */ std::string GenerateSasToken(const StorageSharedKeyCredential& credential); + /** + * @brief For debugging purposes only. + * + * @param credential + * The storage account's shared key credential. + * @return Returns the string to sign that will be used to generate the signature for the SAS + * URL. + */ + std::string GenerateSasStringToSign(const StorageSharedKeyCredential& credential); + private: std::string Permissions; }; diff --git a/sdk/storage/azure-storage-files-shares/src/rest_client.cpp b/sdk/storage/azure-storage-files-shares/src/rest_client.cpp index d13da01884..c9939363a5 100644 --- a/sdk/storage/azure-storage-files-shares/src/rest_client.cpp +++ b/sdk/storage/azure-storage-files-shares/src/rest_client.cpp @@ -86,6 +86,7 @@ std::string ListFilesIncludeFlagsToString( } // namespace namespace Azure { namespace Storage { namespace Files { namespace Shares { namespace Models { + const ShareTokenIntent ShareTokenIntent::Backup("backup"); const AccessTier AccessTier::TransactionOptimized("TransactionOptimized"); const AccessTier AccessTier::Hot("Hot"); const AccessTier AccessTier::Cool("Cool"); @@ -105,7 +106,8 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const ShareRootSquash ShareRootSquash::RootSquash("RootSquash"); const ShareRootSquash ShareRootSquash::AllSquash("AllSquash"); const DeleteSnapshotsOption DeleteSnapshotsOption::Include("include"); - const ShareTokenIntent ShareTokenIntent::Backup("backup"); + const FilePermissionFormat FilePermissionFormat::Sddl("sddl"); + const FilePermissionFormat FilePermissionFormat::Binary("binary"); FileAttributes::FileAttributes(const std::string& value) { const std::string delimiter = " | "; @@ -317,7 +319,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.SetHeader("Content-Length", std::to_string(requestBody.Length())); request.GetUrl().AppendQueryParameter("restype", "service"); request.GetUrl().AppendQueryParameter("comp", "properties"); - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); + if (options.FileRequestIntent.HasValue() + && !options.FileRequestIntent.Value().ToString().empty()) + { + request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Accepted) @@ -337,8 +344,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); request.GetUrl().AppendQueryParameter("restype", "service"); request.GetUrl().AppendQueryParameter("comp", "properties"); - request.SetHeader("x-ms-version", "2024-08-04"); - (void)options; + request.SetHeader("x-ms-version", "2024-11-04"); + if (options.FileRequestIntent.HasValue() + && !options.FileRequestIntent.Value().ToString().empty()) + { + request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -569,7 +580,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { _internal::UrlEncodeQueryParameter( ListSharesIncludeFlagsToString(options.Include.Value()))); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); + if (options.FileRequestIntent.HasValue() + && !options.FileRequestIntent.Value().ToString().empty()) + { + request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -615,6 +631,9 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { kEnabledProtocols, kRootSquash, kEnableSnapshotVirtualDirectoryAccess, + kPaidBurstingEnabled, + kPaidBurstingMaxIops, + kPaidBurstingMaxBandwidthMibps, kNextMarker, }; const std::unordered_map XmlTagEnumMap{ @@ -650,6 +669,9 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { {"RootSquash", XmlTagEnum::kRootSquash}, {"EnableSnapshotVirtualDirectoryAccess", XmlTagEnum::kEnableSnapshotVirtualDirectoryAccess}, + {"PaidBurstingEnabled", XmlTagEnum::kPaidBurstingEnabled}, + {"PaidBurstingMaxIops", XmlTagEnum::kPaidBurstingMaxIops}, + {"PaidBurstingMaxBandwidthMibps", XmlTagEnum::kPaidBurstingMaxBandwidthMibps}, {"NextMarker", XmlTagEnum::kNextMarker}, }; std::vector xmlPath; @@ -877,6 +899,30 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { vectorElement1.Details.EnableSnapshotVirtualDirectoryAccess = node.Value == std::string("true"); } + else if ( + xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare + && xmlPath[3] == XmlTagEnum::kProperties + && xmlPath[4] == XmlTagEnum::kPaidBurstingEnabled) + { + vectorElement1.Details.PaidBurstingEnabled = node.Value == std::string("true"); + } + else if ( + xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare + && xmlPath[3] == XmlTagEnum::kProperties + && xmlPath[4] == XmlTagEnum::kPaidBurstingMaxIops) + { + vectorElement1.Details.PaidBurstingMaxIops = std::stoll(node.Value); + } + else if ( + xmlPath.size() == 5 && xmlPath[0] == XmlTagEnum::kEnumerationResults + && xmlPath[1] == XmlTagEnum::kShares && xmlPath[2] == XmlTagEnum::kShare + && xmlPath[3] == XmlTagEnum::kProperties + && xmlPath[4] == XmlTagEnum::kPaidBurstingMaxBandwidthMibps) + { + vectorElement1.Details.PaidBurstingMaxBandwidthMibps = std::stoll(node.Value); + } else if ( xmlPath.size() == 2 && xmlPath[0] == XmlTagEnum::kEnumerationResults && xmlPath[1] == XmlTagEnum::kNextMarker) @@ -934,7 +980,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-access-tier", options.AccessTier.Value().ToString()); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.EnabledProtocols.HasValue() && !options.EnabledProtocols.Value().ToString().empty()) { @@ -950,6 +996,29 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { "x-ms-enable-snapshot-virtual-directory-access", options.EnableSnapshotVirtualDirectoryAccess.Value() ? "true" : "false"); } + if (options.PaidBurstingEnabled.HasValue()) + { + request.SetHeader( + "x-ms-share-paid-bursting-enabled", + options.PaidBurstingEnabled.Value() ? "true" : "false"); + } + if (options.PaidBurstingMaxBandwidthMibps.HasValue()) + { + request.SetHeader( + "x-ms-share-paid-bursting-max-bandwidth-mibps", + std::to_string(options.PaidBurstingMaxBandwidthMibps.Value())); + } + if (options.PaidBurstingMaxIops.HasValue()) + { + request.SetHeader( + "x-ms-share-paid-bursting-max-iops", + std::to_string(options.PaidBurstingMaxIops.Value())); + } + if (options.FileRequestIntent.HasValue() + && !options.FileRequestIntent.Value().ToString().empty()) + { + request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Created) @@ -975,11 +1044,16 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.GetUrl().AppendQueryParameter( "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value())); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); } + if (options.FileRequestIntent.HasValue() + && !options.FileRequestIntent.Value().ToString().empty()) + { + request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -1068,6 +1142,22 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { = pRawResponse->GetHeaders().at("x-ms-enable-snapshot-virtual-directory-access") == std::string("true"); } + if (pRawResponse->GetHeaders().count("x-ms-share-paid-bursting-enabled") != 0) + { + response.PaidBurstingEnabled + = pRawResponse->GetHeaders().at("x-ms-share-paid-bursting-enabled") + == std::string("true"); + } + if (pRawResponse->GetHeaders().count("x-ms-share-paid-bursting-max-iops") != 0) + { + response.PaidBurstingMaxIops + = std::stoll(pRawResponse->GetHeaders().at("x-ms-share-paid-bursting-max-iops")); + } + if (pRawResponse->GetHeaders().count("x-ms-share-paid-bursting-max-bandwidth-mibps") != 0) + { + response.PaidBurstingMaxBandwidthMibps = std::stoll( + pRawResponse->GetHeaders().at("x-ms-share-paid-bursting-max-bandwidth-mibps")); + } return Response(std::move(response), std::move(pRawResponse)); } Response ShareClient::Delete( @@ -1083,7 +1173,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.GetUrl().AppendQueryParameter( "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value())); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.DeleteSnapshots.HasValue() && !options.DeleteSnapshots.Value().ToString().empty()) { request.SetHeader("x-ms-delete-snapshots", options.DeleteSnapshots.Value().ToString()); @@ -1092,6 +1182,11 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); } + if (options.FileRequestIntent.HasValue() + && !options.FileRequestIntent.Value().ToString().empty()) + { + request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Accepted) @@ -1119,12 +1214,17 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-proposed-lease-id", options.ProposedLeaseId.Value()); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty()) { request.GetUrl().AppendQueryParameter( "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value())); } + if (options.FileRequestIntent.HasValue() + && !options.FileRequestIntent.Value().ToString().empty()) + { + request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Created) @@ -1153,12 +1253,17 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-lease-id", options.LeaseId); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty()) { request.GetUrl().AppendQueryParameter( "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value())); } + if (options.FileRequestIntent.HasValue() + && !options.FileRequestIntent.Value().ToString().empty()) + { + request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -1190,12 +1295,17 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-proposed-lease-id", options.ProposedLeaseId.Value()); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty()) { request.GetUrl().AppendQueryParameter( "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value())); } + if (options.FileRequestIntent.HasValue() + && !options.FileRequestIntent.Value().ToString().empty()) + { + request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -1224,12 +1334,17 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-lease-id", options.LeaseId); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty()) { request.GetUrl().AppendQueryParameter( "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value())); } + if (options.FileRequestIntent.HasValue() + && !options.FileRequestIntent.Value().ToString().empty()) + { + request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -1262,12 +1377,17 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.Sharesnapshot.HasValue() && !options.Sharesnapshot.Value().empty()) { request.GetUrl().AppendQueryParameter( "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value())); } + if (options.FileRequestIntent.HasValue() + && !options.FileRequestIntent.Value().ToString().empty()) + { + request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Accepted) @@ -1295,7 +1415,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-meta-" + p.first, p.second); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); + if (options.FileRequestIntent.HasValue() + && !options.FileRequestIntent.Value().ToString().empty()) + { + request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Created) @@ -1320,6 +1445,10 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { auto jsonRoot = Core::Json::_internal::json::object(); jsonRoot["permission"] = options.SharePermission.Permission; + if (options.SharePermission.Format.HasValue()) + { + jsonRoot["format"] = options.SharePermission.Format.Value().ToString(); + } jsonBody = jsonRoot.dump(); } Core::IO::MemoryBodyStream requestBody( @@ -1329,7 +1458,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.SetHeader("Content-Length", std::to_string(requestBody.Length())); request.GetUrl().AppendQueryParameter("restype", "share"); request.GetUrl().AppendQueryParameter("comp", "filepermission"); - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.FileRequestIntent.HasValue() && !options.FileRequestIntent.Value().ToString().empty()) { @@ -1359,7 +1488,13 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-file-permission-key", options.FilePermissionKey); } - request.SetHeader("x-ms-version", "2024-08-04"); + if (options.FilePermissionFormat.HasValue() + && !options.FilePermissionFormat.Value().ToString().empty()) + { + request.SetHeader( + "x-ms-file-permission-format", options.FilePermissionFormat.Value().ToString()); + } + request.SetHeader("x-ms-version", "2024-11-04"); if (options.FileRequestIntent.HasValue() && !options.FileRequestIntent.Value().ToString().empty()) { @@ -1377,6 +1512,10 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto jsonRoot = Core::Json::_internal::json::parse(responseBody.begin(), responseBody.end()); response.Permission = jsonRoot["permission"].get(); + if (jsonRoot.count("format") != 0) + { + response.Format = Models::FilePermissionFormat(jsonRoot["format"].get()); + } } return Response( std::move(response), std::move(pRawResponse)); @@ -1390,7 +1529,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); request.GetUrl().AppendQueryParameter("restype", "share"); request.GetUrl().AppendQueryParameter("comp", "properties"); - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.Quota.HasValue()) { request.SetHeader("x-ms-share-quota", std::to_string(options.Quota.Value())); @@ -1413,6 +1552,29 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { "x-ms-enable-snapshot-virtual-directory-access", options.EnableSnapshotVirtualDirectoryAccess.Value() ? "true" : "false"); } + if (options.PaidBurstingEnabled.HasValue()) + { + request.SetHeader( + "x-ms-share-paid-bursting-enabled", + options.PaidBurstingEnabled.Value() ? "true" : "false"); + } + if (options.PaidBurstingMaxBandwidthMibps.HasValue()) + { + request.SetHeader( + "x-ms-share-paid-bursting-max-bandwidth-mibps", + std::to_string(options.PaidBurstingMaxBandwidthMibps.Value())); + } + if (options.PaidBurstingMaxIops.HasValue()) + { + request.SetHeader( + "x-ms-share-paid-bursting-max-iops", + std::to_string(options.PaidBurstingMaxIops.Value())); + } + if (options.FileRequestIntent.HasValue() + && !options.FileRequestIntent.Value().ToString().empty()) + { + request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -1439,11 +1601,16 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-meta-" + p.first, p.second); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); } + if (options.FileRequestIntent.HasValue() + && !options.FileRequestIntent.Value().ToString().empty()) + { + request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -1465,11 +1632,16 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); request.GetUrl().AppendQueryParameter("restype", "share"); request.GetUrl().AppendQueryParameter("comp", "acl"); - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); } + if (options.FileRequestIntent.HasValue() + && !options.FileRequestIntent.Value().ToString().empty()) + { + request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -1612,11 +1784,16 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.SetHeader("Content-Length", std::to_string(requestBody.Length())); request.GetUrl().AppendQueryParameter("restype", "share"); request.GetUrl().AppendQueryParameter("comp", "acl"); - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); } + if (options.FileRequestIntent.HasValue() + && !options.FileRequestIntent.Value().ToString().empty()) + { + request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -1639,11 +1816,16 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto request = Core::Http::Request(Core::Http::HttpMethod::Get, url); request.GetUrl().AppendQueryParameter("restype", "share"); request.GetUrl().AppendQueryParameter("comp", "stats"); - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); } + if (options.FileRequestIntent.HasValue() + && !options.FileRequestIntent.Value().ToString().empty()) + { + request.SetHeader("x-ms-file-request-intent", options.FileRequestIntent.Value().ToString()); + } auto pRawResponse = pipeline.Send(request, context); auto httpStatusCode = pRawResponse->GetStatusCode(); if (httpStatusCode != Core::Http::HttpStatusCode::Ok) @@ -1725,11 +1907,17 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-meta-" + p.first, p.second); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.FilePermission.HasValue() && !options.FilePermission.Value().empty()) { request.SetHeader("x-ms-file-permission", options.FilePermission.Value()); } + if (options.FilePermissionFormat.HasValue() + && !options.FilePermissionFormat.Value().ToString().empty()) + { + request.SetHeader( + "x-ms-file-permission-format", options.FilePermissionFormat.Value().ToString()); + } if (options.FilePermissionKey.HasValue() && !options.FilePermissionKey.Value().empty()) { request.SetHeader("x-ms-file-permission-key", options.FilePermissionKey.Value()); @@ -1814,7 +2002,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.GetUrl().AppendQueryParameter( "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value())); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.FileRequestIntent.HasValue() && !options.FileRequestIntent.Value().ToString().empty()) { @@ -1880,7 +2068,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.SetHeader( "x-ms-allow-trailing-dot", options.AllowTrailingDot.Value() ? "true" : "false"); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.FileRequestIntent.HasValue() && !options.FileRequestIntent.Value().ToString().empty()) { @@ -1904,11 +2092,17 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); request.GetUrl().AppendQueryParameter("restype", "directory"); request.GetUrl().AppendQueryParameter("comp", "properties"); - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.FilePermission.HasValue() && !options.FilePermission.Value().empty()) { request.SetHeader("x-ms-file-permission", options.FilePermission.Value()); } + if (options.FilePermissionFormat.HasValue() + && !options.FilePermissionFormat.Value().ToString().empty()) + { + request.SetHeader( + "x-ms-file-permission-format", options.FilePermissionFormat.Value().ToString()); + } if (options.FilePermissionKey.HasValue() && !options.FilePermissionKey.Value().empty()) { request.SetHeader("x-ms-file-permission-key", options.FilePermissionKey.Value()); @@ -1994,7 +2188,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-meta-" + p.first, p.second); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.AllowTrailingDot.HasValue()) { request.SetHeader( @@ -2048,7 +2242,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.GetUrl().AppendQueryParameter( "maxresults", std::to_string(options.MaxResults.Value())); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.Include.HasValue() && !ListFilesIncludeFlagsToString(options.Include.Value()).empty()) { @@ -2441,7 +2635,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-recursive", options.Recursive.Value() ? "true" : "false"); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.AllowTrailingDot.HasValue()) { request.SetHeader( @@ -2654,7 +2848,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-recursive", options.Recursive.Value() ? "true" : "false"); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.AllowTrailingDot.HasValue()) { request.SetHeader( @@ -2692,7 +2886,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); request.GetUrl().AppendQueryParameter("restype", "directory"); request.GetUrl().AppendQueryParameter("comp", "rename"); - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (!options.RenameSource.empty()) { request.SetHeader("x-ms-file-rename-source", options.RenameSource); @@ -2736,6 +2930,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-file-permission", options.FilePermission.Value()); } + if (options.FilePermissionFormat.HasValue() + && !options.FilePermissionFormat.Value().ToString().empty()) + { + request.SetHeader( + "x-ms-file-permission-format", options.FilePermissionFormat.Value().ToString()); + } if (options.FilePermissionKey.HasValue() && !options.FilePermissionKey.Value().empty()) { request.SetHeader("x-ms-file-permission-key", options.FilePermissionKey.Value()); @@ -2800,7 +3000,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.SetHeader( "x-ms-allow-trailing-dot", options.AllowTrailingDot.Value() ? "true" : "false"); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); request.SetHeader("x-ms-content-length", std::to_string(options.FileContentLength)); request.SetHeader("x-ms-type", "file"); if (options.FileContentType.HasValue() && !options.FileContentType.Value().empty()) @@ -2838,6 +3038,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-file-permission", options.FilePermission.Value()); } + if (options.FilePermissionFormat.HasValue() + && !options.FilePermissionFormat.Value().ToString().empty()) + { + request.SetHeader( + "x-ms-file-permission-format", options.FilePermissionFormat.Value().ToString()); + } if (options.FilePermissionKey.HasValue() && !options.FilePermissionKey.Value().empty()) { request.SetHeader("x-ms-file-permission-key", options.FilePermissionKey.Value()); @@ -2920,7 +3126,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.SetHeader( "x-ms-allow-trailing-dot", options.AllowTrailingDot.Value() ? "true" : "false"); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.Range.HasValue() && !options.Range.Value().empty()) { request.SetHeader("x-ms-range", options.Range.Value()); @@ -3105,7 +3311,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.GetUrl().AppendQueryParameter( "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value())); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); @@ -3243,7 +3449,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.SetHeader( "x-ms-allow-trailing-dot", options.AllowTrailingDot.Value() ? "true" : "false"); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); @@ -3270,7 +3476,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); request.GetUrl().AppendQueryParameter("comp", "properties"); - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.FileContentLength.HasValue()) { request.SetHeader("x-ms-content-length", std::to_string(options.FileContentLength.Value())); @@ -3306,6 +3512,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-file-permission", options.FilePermission.Value()); } + if (options.FilePermissionFormat.HasValue() + && !options.FilePermissionFormat.Value().ToString().empty()) + { + request.SetHeader( + "x-ms-file-permission-format", options.FilePermissionFormat.Value().ToString()); + } if (options.FilePermissionKey.HasValue() && !options.FilePermissionKey.Value().empty()) { request.SetHeader("x-ms-file-permission-key", options.FilePermissionKey.Value()); @@ -3394,7 +3606,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-meta-" + p.first, p.second); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); @@ -3438,7 +3650,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-proposed-lease-id", options.ProposedLeaseId.Value()); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.AllowTrailingDot.HasValue()) { request.SetHeader( @@ -3476,7 +3688,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-lease-id", options.LeaseId); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.AllowTrailingDot.HasValue()) { request.SetHeader( @@ -3517,7 +3729,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-proposed-lease-id", options.ProposedLeaseId.Value()); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.AllowTrailingDot.HasValue()) { request.SetHeader( @@ -3555,7 +3767,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.AllowTrailingDot.HasValue()) { request.SetHeader( @@ -3602,7 +3814,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("Content-MD5", Core::Convert::Base64Encode(options.ContentMD5.Value())); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); @@ -3689,7 +3901,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { "x-ms-source-if-none-match-crc64", Core::Convert::Base64Encode(options.SourceIfNoneMatchCrc64.Value())); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); @@ -3765,7 +3977,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { "prevsharesnapshot", _internal::UrlEncodeQueryParameter(options.Prevsharesnapshot.Value())); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.Range.HasValue() && !options.Range.Value().empty()) { request.SetHeader("x-ms-range", options.Range.Value()); @@ -3894,7 +4106,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const Core::Context& context) { auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); for (const auto& p : options.Metadata) { request.SetHeader("x-ms-meta-" + p.first, p.second); @@ -3992,7 +4204,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { "copyid", _internal::UrlEncodeQueryParameter(options.CopyId)); } request.SetHeader("x-ms-copy-action", "abort"); - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.LeaseId.HasValue() && !options.LeaseId.Value().empty()) { request.SetHeader("x-ms-lease-id", options.LeaseId.Value()); @@ -4039,7 +4251,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { request.GetUrl().AppendQueryParameter( "sharesnapshot", _internal::UrlEncodeQueryParameter(options.Sharesnapshot.Value())); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.AllowTrailingDot.HasValue()) { request.SetHeader( @@ -4248,7 +4460,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-handle-id", options.HandleId); } - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (options.AllowTrailingDot.HasValue()) { request.SetHeader( @@ -4285,7 +4497,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { auto request = Core::Http::Request(Core::Http::HttpMethod::Put, url); request.GetUrl().AppendQueryParameter("comp", "rename"); - request.SetHeader("x-ms-version", "2024-08-04"); + request.SetHeader("x-ms-version", "2024-11-04"); if (!options.RenameSource.empty()) { request.SetHeader("x-ms-file-rename-source", options.RenameSource); @@ -4329,6 +4541,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-file-permission", options.FilePermission.Value()); } + if (options.FilePermissionFormat.HasValue() + && !options.FilePermissionFormat.Value().ToString().empty()) + { + request.SetHeader( + "x-ms-file-permission-format", options.FilePermissionFormat.Value().ToString()); + } if (options.FilePermissionKey.HasValue() && !options.FilePermissionKey.Value().empty()) { request.SetHeader("x-ms-file-permission-key", options.FilePermissionKey.Value()); diff --git a/sdk/storage/azure-storage-files-shares/src/share_client.cpp b/sdk/storage/azure-storage-files-shares/src/share_client.cpp index 5aa5d7a070..01f3660e58 100644 --- a/sdk/storage/azure-storage-files-shares/src/share_client.cpp +++ b/sdk/storage/azure-storage-files-shares/src/share_client.cpp @@ -151,6 +151,10 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.RootSquash = options.RootSquash; protocolLayerOptions.EnableSnapshotVirtualDirectoryAccess = options.EnableSnapshotVirtualDirectoryAccess; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; + protocolLayerOptions.PaidBurstingEnabled = options.EnablePaidBursting; + protocolLayerOptions.PaidBurstingMaxIops = options.PaidBurstingMaxIops; + protocolLayerOptions.PaidBurstingMaxBandwidthMibps = options.PaidBurstingMaxBandwidthMibps; auto result = _detail::ShareClient::Create(*m_pipeline, m_shareUrl, protocolLayerOptions, context); Models::CreateShareResult ret; @@ -190,6 +194,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { protocolLayerOptions.DeleteSnapshots = Models::DeleteSnapshotsOption::Include; } + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto result = _detail::ShareClient::Delete(*m_pipeline, m_shareUrl, protocolLayerOptions, context); Models::DeleteShareResult ret; @@ -225,6 +230,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto protocolLayerOptions = _detail::ShareClient::CreateShareSnapshotOptions(); protocolLayerOptions.Metadata = std::map(options.Metadata.begin(), options.Metadata.end()); + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::ShareClient::CreateSnapshot( *m_pipeline, m_shareUrl, protocolLayerOptions, context); } @@ -235,6 +241,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { (void)options; auto protocolLayerOptions = _detail::ShareClient::GetSharePropertiesOptions(); + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::ShareClient::GetProperties( *m_pipeline, m_shareUrl, protocolLayerOptions, context); } @@ -249,6 +256,10 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.RootSquash = options.RootSquash; protocolLayerOptions.EnableSnapshotVirtualDirectoryAccess = options.EnableSnapshotVirtualDirectoryAccess; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; + protocolLayerOptions.PaidBurstingEnabled = options.EnablePaidBursting; + protocolLayerOptions.PaidBurstingMaxIops = options.PaidBurstingMaxIops; + protocolLayerOptions.PaidBurstingMaxBandwidthMibps = options.PaidBurstingMaxBandwidthMibps; return _detail::ShareClient::SetProperties( *m_pipeline, m_shareUrl, protocolLayerOptions, context); } @@ -262,6 +273,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto protocolLayerOptions = _detail::ShareClient::SetShareMetadataOptions(); protocolLayerOptions.Metadata = std::map(metadata.begin(), metadata.end()); + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::ShareClient::SetMetadata( *m_pipeline, m_shareUrl, protocolLayerOptions, context); } @@ -272,6 +284,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { (void)options; auto protocolLayerOptions = _detail::ShareClient::GetShareAccessPolicyOptions(); + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::ShareClient::GetAccessPolicy( *m_pipeline, m_shareUrl, protocolLayerOptions, context); } @@ -284,6 +297,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { (void)options; auto protocolLayerOptions = _detail::ShareClient::SetShareAccessPolicyOptions(); protocolLayerOptions.ShareAcl = accessPolicy; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::ShareClient::SetAccessPolicy( *m_pipeline, m_shareUrl, protocolLayerOptions, context); } @@ -294,6 +308,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { (void)options; auto protocolLayerOptions = _detail::ShareClient::GetShareStatisticsOptions(); + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::ShareClient::GetStatistics( *m_pipeline, m_shareUrl, protocolLayerOptions, context); } @@ -306,6 +321,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { (void)options; auto protocolLayerOptions = _detail::ShareClient::CreateSharePermissionOptions(); protocolLayerOptions.SharePermission.Permission = permission; + protocolLayerOptions.SharePermission.Format = options.FilePermissionFormat; protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::ShareClient::CreatePermission( *m_pipeline, m_shareUrl, protocolLayerOptions, context); @@ -316,10 +332,10 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { const GetSharePermissionOptions& options, const Azure::Core::Context& context) const { - (void)options; auto protocolLayerOptions = _detail::ShareClient::GetSharePermissionOptions(); protocolLayerOptions.FilePermissionKey = permissionKey; protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; + protocolLayerOptions.FilePermissionFormat = options.FilePermissionFormat; auto result = _detail::ShareClient::GetPermission( *m_pipeline, m_shareUrl, protocolLayerOptions, context); diff --git a/sdk/storage/azure-storage-files-shares/src/share_directory_client.cpp b/sdk/storage/azure-storage-files-shares/src/share_directory_client.cpp index 64c86dac3c..462dd34298 100644 --- a/sdk/storage/azure-storage-files-shares/src/share_directory_client.cpp +++ b/sdk/storage/azure-storage-files-shares/src/share_directory_client.cpp @@ -209,6 +209,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { } protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; + protocolLayerOptions.FilePermissionFormat = options.DirectoryPermissionFormat; auto result = _detail::DirectoryClient::Create( *m_pipeline, m_shareDirectoryUrl, protocolLayerOptions, context); Models::CreateDirectoryResult ret; @@ -294,6 +295,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.AllowSourceTrailingDot = m_allowSourceTrailingDot; protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; protocolLayerOptions.FileContentType = options.ContentType; + protocolLayerOptions.FilePermissionFormat = options.FilePermissionFormat; auto response = _detail::FileClient::Rename( *m_pipeline, destinationFileUrl, protocolLayerOptions, context); @@ -356,6 +358,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; protocolLayerOptions.AllowSourceTrailingDot = m_allowSourceTrailingDot; protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; + protocolLayerOptions.FilePermissionFormat = options.FilePermissionFormat; auto response = _detail::DirectoryClient::Rename( *m_pipeline, destinationDirectoryUrl, protocolLayerOptions, context); @@ -466,6 +469,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { } protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; + protocolLayerOptions.FilePermissionFormat = options.FilePermissionFormat; return _detail::DirectoryClient::SetProperties( *m_pipeline, m_shareDirectoryUrl, protocolLayerOptions, context); } diff --git a/sdk/storage/azure-storage-files-shares/src/share_file_client.cpp b/sdk/storage/azure-storage-files-shares/src/share_file_client.cpp index 2b60055378..1e5490950d 100644 --- a/sdk/storage/azure-storage-files-shares/src/share_file_client.cpp +++ b/sdk/storage/azure-storage-files-shares/src/share_file_client.cpp @@ -217,6 +217,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.LeaseId = options.AccessConditions.LeaseId; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; + protocolLayerOptions.FilePermissionFormat = options.FilePermissionFormat; auto result = _detail::FileClient::Create(*m_pipeline, m_shareFileUrl, protocolLayerOptions, context); Models::CreateFileResult ret; @@ -541,6 +542,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { } protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; + protocolLayerOptions.FilePermissionFormat = options.FilePermissionFormat; return _detail::FileClient::SetHttpHeaders( *m_pipeline, m_shareFileUrl, protocolLayerOptions, context); @@ -1082,6 +1084,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { = std::map(options.Metadata.begin(), options.Metadata.end()); protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; + protocolLayerOptions.FilePermissionFormat = options.FilePermissionFormat; auto createResult = _detail::FileClient::Create(*m_pipeline, m_shareFileUrl, protocolLayerOptions, context); @@ -1199,6 +1202,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { = std::map(options.Metadata.begin(), options.Metadata.end()); protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; + protocolLayerOptions.FilePermissionFormat = options.FilePermissionFormat; auto createResult = _detail::FileClient::Create(*m_pipeline, m_shareFileUrl, protocolLayerOptions, context); diff --git a/sdk/storage/azure-storage-files-shares/src/share_lease_client.cpp b/sdk/storage/azure-storage-files-shares/src/share_lease_client.cpp index faaf70de25..e25a164ba1 100644 --- a/sdk/storage/azure-storage-files-shares/src/share_lease_client.cpp +++ b/sdk/storage/azure-storage-files-shares/src/share_lease_client.cpp @@ -47,6 +47,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { _detail::ShareClient::AcquireShareLeaseOptions protocolLayerOptions; protocolLayerOptions.ProposedLeaseId = GetLeaseId(); protocolLayerOptions.Duration = static_cast(duration.count()); + protocolLayerOptions.FileRequestIntent = m_shareClient.Value().m_shareTokenIntent; auto response = _detail::ShareClient::AcquireLease( *(m_shareClient.Value().m_pipeline), @@ -82,6 +83,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { _detail::ShareClient::RenewShareLeaseOptions protocolLayerOptions; protocolLayerOptions.LeaseId = GetLeaseId(); + protocolLayerOptions.FileRequestIntent = m_shareClient.Value().m_shareTokenIntent; auto response = _detail::ShareClient::RenewLease( *(m_shareClient.Value().m_pipeline), @@ -132,6 +134,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { _detail::ShareClient::ReleaseShareLeaseOptions protocolLayerOptions; protocolLayerOptions.LeaseId = GetLeaseId(); + protocolLayerOptions.FileRequestIntent = m_shareClient.Value().m_shareTokenIntent; auto response = _detail::ShareClient::ReleaseLease( *(m_shareClient.Value().m_pipeline), @@ -190,6 +193,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { _detail::ShareClient::ChangeShareLeaseOptions protocolLayerOptions; protocolLayerOptions.LeaseId = GetLeaseId(); protocolLayerOptions.ProposedLeaseId = proposedLeaseId; + protocolLayerOptions.FileRequestIntent = m_shareClient.Value().m_shareTokenIntent; auto response = _detail::ShareClient::ChangeLease( *(m_shareClient.Value().m_pipeline), @@ -243,6 +247,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { else if (m_shareClient.HasValue()) { _detail::ShareClient::BreakShareLeaseOptions protocolLayerOptions; + protocolLayerOptions.FileRequestIntent = m_shareClient.Value().m_shareTokenIntent; auto response = _detail::ShareClient::BreakLease( diff --git a/sdk/storage/azure-storage-files-shares/src/share_sas_builder.cpp b/sdk/storage/azure-storage-files-shares/src/share_sas_builder.cpp index ce480d0f98..9185b7e06d 100644 --- a/sdk/storage/azure-storage-files-shares/src/share_sas_builder.cpp +++ b/sdk/storage/azure-storage-files-shares/src/share_sas_builder.cpp @@ -157,4 +157,29 @@ namespace Azure { namespace Storage { namespace Sas { return builder.GetAbsoluteUrl(); } + std::string ShareSasBuilder::GenerateSasStringToSign(const StorageSharedKeyCredential& credential) + { + std::string canonicalName = "/file/" + credential.AccountName + "/" + ShareName; + if (Resource == ShareSasResource::File) + { + canonicalName += "/" + FilePath; + } + std::string protocol = _detail::SasProtocolToString(Protocol); + std::string resource = ShareSasResourceToString(Resource); + + std::string startsOnStr = StartsOn.HasValue() + ? StartsOn.Value().ToString( + Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate) + : ""; + std::string expiresOnStr = Identifier.empty() + ? ExpiresOn.ToString( + Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate) + : ""; + + return Permissions + "\n" + startsOnStr + "\n" + expiresOnStr + "\n" + canonicalName + "\n" + + Identifier + "\n" + (IPRange.HasValue() ? IPRange.Value() : "") + "\n" + protocol + "\n" + + SasVersion + "\n" + CacheControl + "\n" + ContentDisposition + "\n" + ContentEncoding + + "\n" + ContentLanguage + "\n" + ContentType; + } + }}} // namespace Azure::Storage::Sas diff --git a/sdk/storage/azure-storage-files-shares/src/share_service_client.cpp b/sdk/storage/azure-storage-files-shares/src/share_service_client.cpp index 8b4f65ea58..ea7743e287 100644 --- a/sdk/storage/azure-storage-files-shares/src/share_service_client.cpp +++ b/sdk/storage/azure-storage-files-shares/src/share_service_client.cpp @@ -133,6 +133,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.Marker = options.ContinuationToken; protocolLayerOptions.MaxResults = options.PageSizeHint; protocolLayerOptions.Prefix = options.Prefix; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto response = _detail::ServiceClient::ListSharesSegment( *m_pipeline, m_serviceUrl, protocolLayerOptions, context); @@ -160,6 +161,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { (void)options; auto protocolLayerOptions = _detail::ServiceClient::SetServicePropertiesOptions(); protocolLayerOptions.ShareServiceProperties = std::move(properties); + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::ServiceClient::SetProperties( *m_pipeline, m_serviceUrl, protocolLayerOptions, context); } @@ -170,6 +172,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { (void)options; auto protocolLayerOptions = _detail::ServiceClient::GetServicePropertiesOptions(); + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto result = _detail::ServiceClient::GetProperties( *m_pipeline, m_serviceUrl, protocolLayerOptions, context); Models::ShareServiceProperties ret; diff --git a/sdk/storage/azure-storage-files-shares/swagger/README.md b/sdk/storage/azure-storage-files-shares/swagger/README.md index 345aa9350f..d0fe69848c 100644 --- a/sdk/storage/azure-storage-files-shares/swagger/README.md +++ b/sdk/storage/azure-storage-files-shares/swagger/README.md @@ -9,7 +9,7 @@ package-name: azure-storage-files-shares namespace: Azure::Storage::Files::Shares output-folder: generated clear-output-folder: true -input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/storage/data-plane/Microsoft.FileStorage/stable/2024-08-04/file.json +input-file: https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/storage/data-plane/Microsoft.FileStorage/stable/2024-11-04/file.json ``` ## ModelFour Options @@ -79,12 +79,12 @@ directive: "name": "ApiVersion", "modelAsString": false }, - "enum": ["2024-08-04"] + "enum": ["2024-11-04"] }; - from: swagger-document where: $.parameters transform: > - $.ApiVersionParameter.enum[0] = "2024-08-04"; + $.ApiVersionParameter.enum[0] = "2024-11-04"; ``` ### Rename Operations @@ -470,6 +470,9 @@ directive: $["x-ms-enabled-protocols"]["x-ms-enum"] = {"name": "ShareProtocols", "modelAsString": false}; $["x-ms-enabled-protocols"]["x-ms-enum"]["values"] = [{"value": "SMB", "name": "Smb"},{"value": "NFS", "name": "Nfs"}]; $["x-ms-enable-snapshot-virtual-directory-access"]["x-nullable"] = true; + $["x-ms-share-paid-bursting-enabled"]["x-nullable"] = true; + $["x-ms-share-paid-bursting-max-iops"]["x-nullable"] = true; + $["x-ms-share-paid-bursting-max-bandwidth-mibps"]["x-nullable"] = true; - from: swagger-document where: $["x-ms-paths"]["/{shareName}?restype=share"].get.responses["200"] transform: > @@ -1069,6 +1072,9 @@ directive: $.ShareItemDetails.properties["RootSquash"].description = "Root squash to set on the share. Only valid for NFS shares."; $.ShareItemDetails.properties["Last-Modified"].description = "The date and time the share was last modified."; $.ShareItemDetails.properties["EnableSnapshotVirtualDirectoryAccess"].description = "Version 2023-08-03 and newer. Specifies whether the snapshot virtual directory should be accessible at the root of share mount point when NFS is enabled. This header is only returned for shares, not for snapshots."; + $.ShareItemDetails.properties["PaidBurstingEnabled"].description = "Optional. Boolean. Default if not specified is false. This property enables paid bursting."; + $.ShareItemDetails.properties["PaidBurstingMaxIops"].description = "Optional. Integer. Default if not specified is the maximum IOPS the file share can support. Current maximum for a file share is 102,400 IOPS."; + $.ShareItemDetails.properties["PaidBurstingMaxBandwidthMibps"].description = "Optional. Integer. Default if not specified is the maximum throughput the file share can support. Current maximum for a file share is 10,340 MiB/sec."; $.ShareItemInternal.properties["Name"].description = "The name of the share."; $.ShareItemInternal.properties["Snapshot"].description = "The snapshot of the share."; $.ShareItemInternal.properties["Deleted"].description = "True if the share is deleted."; diff --git a/sdk/storage/azure-storage-files-shares/test/ut/share_client_test.cpp b/sdk/storage/azure-storage-files-shares/test/ut/share_client_test.cpp index 237df6ceaa..0c61e3b0b3 100644 --- a/sdk/storage/azure-storage-files-shares/test/ut/share_client_test.cpp +++ b/sdk/storage/azure-storage-files-shares/test/ut/share_client_test.cpp @@ -642,19 +642,59 @@ namespace Azure { namespace Storage { namespace Test { TEST_F(FileShareClientTest, OAuth_PLAYBACKONLY_) { - // Create from client secret credential. std::shared_ptr credential = GetTestCredential(); auto options = InitStorageClientOptions(); options.ShareTokenIntent = Files::Shares::Models::ShareTokenIntent::Backup; + std::string shareName = LowercaseRandomString(); auto serviceClient = Files::Shares::ShareServiceClient(m_shareServiceClient->GetUrl(), credential, options); - auto shareClient = serviceClient.GetShareClient(m_shareName); + auto shareClient = serviceClient.GetShareClient(shareName); + std::string leaseId1 = RandomUUID(); + Files::Shares::ShareLeaseClient leaseClient(shareClient, leaseId1); + + // Create + EXPECT_NO_THROW(shareClient.Create()); + + // Get Properties + EXPECT_NO_THROW(shareClient.GetProperties()); + + // Set Properties + EXPECT_NO_THROW(shareClient.SetProperties()); + + // Acquire + EXPECT_NO_THROW(leaseClient.Acquire(Files::Shares::ShareLeaseClient::InfiniteLeaseDuration)); + + // Renew + EXPECT_NO_THROW(leaseClient.Renew()); + // Change + std::string leaseId2 = RandomUUID(); + EXPECT_NO_THROW(leaseClient.Change(leaseId2)); + + // Break + EXPECT_NO_THROW(leaseClient.Break()); + + // Release + EXPECT_NO_THROW(leaseClient.Release()); + + // SetMetadata + EXPECT_NO_THROW(shareClient.SetMetadata(RandomMetadata())); + + // Create Snapshot + EXPECT_NO_THROW(shareClient.CreateSnapshot()); + + // Set Access Policy + std::vector identifiers; + EXPECT_NO_THROW(shareClient.SetAccessPolicy(identifiers)); + + // Get Access Policy + EXPECT_NO_THROW(shareClient.GetAccessPolicy()); + + // Set/Get Permission std::string permission = "O:S-1-5-21-2127521184-1604012920-1887927527-21560751G:S-1-5-21-" "2127521184-1604012920-1887927527-513D:AI(A;;FA;;;SY)(A;;FA;;;BA)(A;;" "0x1200a9;;;S-1-5-21-397955417-626881126-188441444-3053964)"; - Files::Shares::Models::CreateSharePermissionResult created; EXPECT_NO_THROW(created = shareClient.CreatePermission(permission).Value); EXPECT_NO_THROW(shareClient.GetPermission(created.FilePermissionKey)); @@ -662,7 +702,12 @@ namespace Azure { namespace Storage { namespace Test { // OAuth Constructor auto shareClient1 = Files::Shares::ShareClient(m_shareClient->GetUrl(), GetTestCredential(), options); - EXPECT_NO_THROW(shareClient1.GetPermission(created.FilePermissionKey)); + EXPECT_NO_THROW(shareClient1.GetProperties()); + + // Delete + Azure::Storage::Files::Shares::DeleteShareOptions deleteOptions; + deleteOptions.DeleteSnapshots = true; + EXPECT_NO_THROW(shareClient.Delete(deleteOptions)); } TEST_F(FileShareClientTest, WithSnapshot) @@ -735,4 +780,46 @@ namespace Azure { namespace Storage { namespace Test { properties.EnableSnapshotVirtualDirectoryAccess.HasValue() && !properties.EnableSnapshotVirtualDirectoryAccess.Value()); } + + TEST_F(FileShareClientTest, FilePermissionFormat_PLAYBACKONLY_) + { + auto sddlPermission + = "O:S-1-5-21-2127521184-1604012920-1887927527-21560751G:S-1-5-21-2127521184-1604012920-" + "1887927527-513D:AI(A;;FA;;;SY)(A;;FA;;;BA)(A;;0x1200a9;;;S-1-5-21-397955417-626881126-" + "188441444-3053964)S:NO_ACCESS_CONTROL"; + auto binaryPermission = "AQAUhGwAAACIAAAAAAAAABQAAAACAFgAAwAAAAAAFAD/" + "AR8AAQEAAAAAAAUSAAAAAAAYAP8BHwABAgAAAAAABSAAAAAgAgAAAAAkAKkAEgABBQAAAA" + "AABRUAAABZUbgXZnJdJWRjOwuMmS4AAQUAAAAAAAUVAAAAoGXPfnhLm1/nfIdwr/" + "1IAQEFAAAAAAAFFQAAAKBlz354S5tf53yHcAECAAA="; + // sddl format + { + auto permissionFormat = Files::Shares::Models::FilePermissionFormat::Sddl; + Files::Shares::CreateSharePermissionOptions options; + options.FilePermissionFormat = permissionFormat; + auto permissionKey + = m_shareClient->CreatePermission(sddlPermission, options).Value.FilePermissionKey; + Files::Shares::GetSharePermissionOptions getOptions; + getOptions.FilePermissionFormat = permissionFormat; + auto permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(sddlPermission, permission); + getOptions.FilePermissionFormat = Files::Shares::Models::FilePermissionFormat::Binary; + permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(binaryPermission, permission); + } + // binary format + { + auto permissionFormat = Files::Shares::Models::FilePermissionFormat::Binary; + Files::Shares::CreateSharePermissionOptions options; + options.FilePermissionFormat = Files::Shares::Models::FilePermissionFormat::Binary; + auto permissionKey + = m_shareClient->CreatePermission(binaryPermission, options).Value.FilePermissionKey; + Files::Shares::GetSharePermissionOptions getOptions; + getOptions.FilePermissionFormat = permissionFormat; + auto permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(binaryPermission, permission); + getOptions.FilePermissionFormat = Files::Shares::Models::FilePermissionFormat::Sddl; + permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(sddlPermission, permission); + } + } }}} // namespace Azure::Storage::Test diff --git a/sdk/storage/azure-storage-files-shares/test/ut/share_directory_client_test.cpp b/sdk/storage/azure-storage-files-shares/test/ut/share_directory_client_test.cpp index 48a76a956b..e28b41b3a9 100644 --- a/sdk/storage/azure-storage-files-shares/test/ut/share_directory_client_test.cpp +++ b/sdk/storage/azure-storage-files-shares/test/ut/share_directory_client_test.cpp @@ -1229,4 +1229,150 @@ namespace Azure { namespace Storage { namespace Test { m_fileShareDirectoryClient->GetUrl(), credential, clientOptions); EXPECT_THROW(directoryClient.GetProperties(), StorageException); } + + TEST_F(FileShareDirectoryClientTest, FilePermissionFormat_PLAYBACKONLY_) + { + auto sddlPermission + = "O:S-1-5-21-2127521184-1604012920-1887927527-21560751G:S-1-5-21-2127521184-1604012920-" + "1887927527-513D:AI(A;;FA;;;SY)(A;;FA;;;BA)(A;;0x1200a9;;;S-1-5-21-397955417-626881126-" + "188441444-3053964)S:NO_ACCESS_CONTROL"; + auto sddlPermissionNoControlFlag + = "O:S-1-5-21-2127521184-1604012920-1887927527-21560751G:S-1-5-21-2127521184-1604012920-" + "1887927527-513D:(A;;FA;;;SY)(A;;FA;;;BA)(A;;0x1200a9;;;S-1-5-21-397955417-626881126-" + "188441444-3053964)"; + auto binaryPermission = "AQAUhGwAAACIAAAAAAAAABQAAAACAFgAAwAAAAAAFAD/" + "AR8AAQEAAAAAAAUSAAAAAAAYAP8BHwABAgAAAAAABSAAAAAgAgAAAAAkAKkAEgABBQAAAA" + "AABRUAAABZUbgXZnJdJWRjOwuMmS4AAQUAAAAAAAUVAAAAoGXPfnhLm1/nfIdwr/" + "1IAQEFAAAAAAAFFQAAAKBlz354S5tf53yHcAECAAA="; + auto binaryPermissionNoControlFlag + = "AQAEgGwAAACIAAAAAAAAABQAAAACAFgAAwAAAAAAFAD/" + "AR8AAQEAAAAAAAUSAAAAAAAYAP8BHwABAgAAAAAABSAAAAAgAgAAAAAkAKkAEgABBQAAAAAABRUAAABZUbgXZnJd" + "JWRjOwuMmS4AAQUAAAAAAAUVAAAAoGXPfnhLm1/nfIdwr/" + "1IAQEFAAAAAAAFFQAAAKBlz354S5tf53yHcAECAAA="; + + // sddl format + { + auto permissionFormat = Files::Shares::Models::FilePermissionFormat::Sddl; + auto directoryClient + = m_shareClient->GetRootDirectoryClient().GetSubdirectoryClient(LowercaseRandomString()); + + // Create + Files::Shares::CreateDirectoryOptions options; + options.DirectoryPermissionFormat = permissionFormat; + options.DirectoryPermission = sddlPermission; + auto permissionKey + = directoryClient.Create(options).Value.SmbProperties.PermissionKey.Value(); + Files::Shares::GetSharePermissionOptions getOptions; + getOptions.FilePermissionFormat = permissionFormat; + auto permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(sddlPermissionNoControlFlag, permission); + + // Set Properties + Files::Shares::SetDirectoryPropertiesOptions setOptions; + setOptions.FilePermissionFormat = permissionFormat; + setOptions.FilePermission = sddlPermission; + m_fileShareDirectoryClient->SetProperties( + Files::Shares::Models::FileSmbProperties(), setOptions); + permissionKey + = m_fileShareDirectoryClient->GetProperties().Value.SmbProperties.PermissionKey.Value(); + permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(sddlPermission, permission); + + // Rename File + auto sourceFileName = LowercaseRandomString(); + auto fileClient = m_fileShareDirectoryClient->GetFileClient(sourceFileName); + fileClient.Create(1); + Files::Shares::RenameFileOptions renameOptions; + renameOptions.FilePermissionFormat = permissionFormat; + renameOptions.FilePermission = sddlPermission; + auto destFileClient + = m_fileShareDirectoryClient + ->RenameFile( + sourceFileName, m_directoryName + "/" + LowercaseRandomString(), renameOptions) + .Value; + permissionKey = destFileClient.GetProperties().Value.SmbProperties.PermissionKey.Value(); + permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(sddlPermission, permission); + + // Rename Subdirectory + auto sourceDirectoryName = LowercaseRandomString(); + auto subdirectoryClient + = m_fileShareDirectoryClient->GetSubdirectoryClient(sourceDirectoryName); + subdirectoryClient.Create(); + Files::Shares::RenameDirectoryOptions renameDirOptions; + renameDirOptions.FilePermissionFormat = permissionFormat; + renameDirOptions.FilePermission = sddlPermission; + auto destDirectoryClient = m_fileShareDirectoryClient + ->RenameSubdirectory( + sourceDirectoryName, + m_directoryName + "/" + LowercaseRandomString(), + renameDirOptions) + .Value; + permissionKey = destDirectoryClient.GetProperties().Value.SmbProperties.PermissionKey.Value(); + permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(sddlPermission, permission); + } + // binary format + { + auto permissionFormat = Files::Shares::Models::FilePermissionFormat::Binary; + auto directoryClient + = m_shareClient->GetRootDirectoryClient().GetSubdirectoryClient(LowercaseRandomString()); + + // Create + Files::Shares::CreateDirectoryOptions options; + options.DirectoryPermissionFormat = permissionFormat; + options.DirectoryPermission = binaryPermission; + auto permissionKey + = directoryClient.Create(options).Value.SmbProperties.PermissionKey.Value(); + Files::Shares::GetSharePermissionOptions getOptions; + getOptions.FilePermissionFormat = permissionFormat; + auto permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(binaryPermissionNoControlFlag, permission); + + // Set Properties + Files::Shares::SetDirectoryPropertiesOptions setOptions; + setOptions.FilePermissionFormat = permissionFormat; + setOptions.FilePermission = binaryPermission; + m_fileShareDirectoryClient->SetProperties( + Files::Shares::Models::FileSmbProperties(), setOptions); + permissionKey + = m_fileShareDirectoryClient->GetProperties().Value.SmbProperties.PermissionKey.Value(); + permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(binaryPermission, permission); + + // Rename File + auto sourceFileName = LowercaseRandomString(); + auto fileClient = m_fileShareDirectoryClient->GetFileClient(sourceFileName); + fileClient.Create(1); + Files::Shares::RenameFileOptions renameOptions; + renameOptions.FilePermissionFormat = permissionFormat; + renameOptions.FilePermission = binaryPermission; + auto destFileClient + = m_fileShareDirectoryClient + ->RenameFile( + sourceFileName, m_directoryName + "/" + LowercaseRandomString(), renameOptions) + .Value; + permissionKey = destFileClient.GetProperties().Value.SmbProperties.PermissionKey.Value(); + permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(binaryPermission, permission); + + // Rename Subdirectory + auto sourceDirectoryName = LowercaseRandomString(); + auto subdirectoryClient + = m_fileShareDirectoryClient->GetSubdirectoryClient(sourceDirectoryName); + subdirectoryClient.Create(); + Files::Shares::RenameDirectoryOptions renameDirOptions; + renameDirOptions.FilePermissionFormat = permissionFormat; + renameDirOptions.FilePermission = binaryPermission; + auto destDirectoryClient = m_fileShareDirectoryClient + ->RenameSubdirectory( + sourceDirectoryName, + m_directoryName + "/" + LowercaseRandomString(), + renameDirOptions) + .Value; + permissionKey = destDirectoryClient.GetProperties().Value.SmbProperties.PermissionKey.Value(); + permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(binaryPermission, permission); + } + } }}} // namespace Azure::Storage::Test diff --git a/sdk/storage/azure-storage-files-shares/test/ut/share_file_client_test.cpp b/sdk/storage/azure-storage-files-shares/test/ut/share_file_client_test.cpp index 47a49c7a1f..c009f2b7d7 100644 --- a/sdk/storage/azure-storage-files-shares/test/ut/share_file_client_test.cpp +++ b/sdk/storage/azure-storage-files-shares/test/ut/share_file_client_test.cpp @@ -1863,4 +1863,134 @@ namespace Azure { namespace Storage { namespace Test { EXPECT_EQ(andAccessRights, accessRightsA & accessRightsB); EXPECT_EQ(xorAccessRights, accessRightsA ^ accessRightsB); } + + TEST_F(FileShareFileClientTest, FilePermissionFormat_PLAYBACKONLY_) + { + auto sddlPermission + = "O:S-1-5-21-2127521184-1604012920-1887927527-21560751G:S-1-5-21-2127521184-1604012920-" + "1887927527-513D:AI(A;;FA;;;SY)(A;;FA;;;BA)(A;;0x1200a9;;;S-1-5-21-397955417-626881126-" + "188441444-3053964)S:NO_ACCESS_CONTROL"; + auto sddlPermissionNoControlFlag + = "O:S-1-5-21-2127521184-1604012920-1887927527-21560751G:S-1-5-21-2127521184-1604012920-" + "1887927527-513D:(A;;FA;;;SY)(A;;FA;;;BA)(A;;0x1200a9;;;S-1-5-21-397955417-626881126-" + "188441444-3053964)"; + auto binaryPermission = "AQAUhGwAAACIAAAAAAAAABQAAAACAFgAAwAAAAAAFAD/" + "AR8AAQEAAAAAAAUSAAAAAAAYAP8BHwABAgAAAAAABSAAAAAgAgAAAAAkAKkAEgABBQAAAA" + "AABRUAAABZUbgXZnJdJWRjOwuMmS4AAQUAAAAAAAUVAAAAoGXPfnhLm1/nfIdwr/" + "1IAQEFAAAAAAAFFQAAAKBlz354S5tf53yHcAECAAA="; + auto binaryPermissionNoControlFlag + = "AQAEgGwAAACIAAAAAAAAABQAAAACAFgAAwAAAAAAFAD/" + "AR8AAQEAAAAAAAUSAAAAAAAYAP8BHwABAgAAAAAABSAAAAAgAgAAAAAkAKkAEgABBQAAAAAABRUAAABZUbgXZnJd" + "JWRjOwuMmS4AAQUAAAAAAAUVAAAAoGXPfnhLm1/nfIdwr/" + "1IAQEFAAAAAAAFFQAAAKBlz354S5tf53yHcAECAAA="; + // sddl format + { + auto permissionFormat = Files::Shares::Models::FilePermissionFormat::Sddl; + auto fileClient + = m_shareClient->GetRootDirectoryClient().GetFileClient(LowercaseRandomString()); + + // Create + Files::Shares::CreateFileOptions options; + options.FilePermissionFormat = permissionFormat; + options.Permission = sddlPermission; + auto permissionKey = fileClient.Create(1, options).Value.SmbProperties.PermissionKey.Value(); + Files::Shares::GetSharePermissionOptions getOptions; + getOptions.FilePermissionFormat = permissionFormat; + auto permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(sddlPermissionNoControlFlag, permission); + + // Set Properties + Files::Shares::SetFilePropertiesOptions setOptions; + setOptions.FilePermissionFormat = permissionFormat; + setOptions.Permission = sddlPermission; + fileClient.SetProperties( + Files::Shares::Models::FileHttpHeaders(), + Files::Shares::Models::FileSmbProperties(), + setOptions); + permissionKey = fileClient.GetProperties().Value.SmbProperties.PermissionKey.Value(); + permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(sddlPermission, permission); + + // Upload From + size_t fileSize = 512; + std::vector content(RandomBuffer(fileSize)); + auto memBodyStream = Core::IO::MemoryBodyStream(content); + + Files::Shares::UploadFileFromOptions uploadFromOptions; + uploadFromOptions.FilePermission = sddlPermission; + uploadFromOptions.FilePermissionFormat = permissionFormat; + + // UploadFrom buffer + auto fileClient2 + = m_shareClient->GetRootDirectoryClient().GetFileClient(LowercaseRandomString()); + EXPECT_NO_THROW(fileClient2.UploadFrom(content.data(), fileSize, uploadFromOptions)); + permissionKey = fileClient2.GetProperties().Value.SmbProperties.PermissionKey.Value(); + permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(sddlPermissionNoControlFlag, permission); + + // UploadFrom file + auto fileClient3 + = m_shareClient->GetRootDirectoryClient().GetFileClient(LowercaseRandomString()); + const std::string tempFilename = "file" + RandomString(); + WriteFile(tempFilename, content); + EXPECT_NO_THROW(fileClient3.UploadFrom(tempFilename, uploadFromOptions)); + permissionKey = fileClient3.GetProperties().Value.SmbProperties.PermissionKey.Value(); + permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(sddlPermissionNoControlFlag, permission); + } + // binary format + { + auto permissionFormat = Files::Shares::Models::FilePermissionFormat::Binary; + auto fileClient = m_shareClient->GetRootDirectoryClient().GetFileClient(RandomString()); + + // Create + Files::Shares::CreateFileOptions options; + options.FilePermissionFormat = permissionFormat; + options.Permission = binaryPermission; + auto permissionKey = fileClient.Create(1, options).Value.SmbProperties.PermissionKey.Value(); + Files::Shares::GetSharePermissionOptions getOptions; + getOptions.FilePermissionFormat = permissionFormat; + auto permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(binaryPermissionNoControlFlag, permission); + + // Set Properties + Files::Shares::SetFilePropertiesOptions setOptions; + setOptions.FilePermissionFormat = permissionFormat; + setOptions.Permission = binaryPermission; + fileClient.SetProperties( + Files::Shares::Models::FileHttpHeaders(), + Files::Shares::Models::FileSmbProperties(), + setOptions); + permissionKey = fileClient.GetProperties().Value.SmbProperties.PermissionKey.Value(); + permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(binaryPermission, permission); + + // Upload From + size_t fileSize = 512; + std::vector content(RandomBuffer(fileSize)); + auto memBodyStream = Core::IO::MemoryBodyStream(content); + + Files::Shares::UploadFileFromOptions uploadFromOptions; + uploadFromOptions.FilePermission = binaryPermission; + uploadFromOptions.FilePermissionFormat = permissionFormat; + + // UploadFrom buffer + auto fileClient2 + = m_shareClient->GetRootDirectoryClient().GetFileClient(LowercaseRandomString()); + EXPECT_NO_THROW(fileClient2.UploadFrom(content.data(), fileSize, uploadFromOptions)); + permissionKey = fileClient2.GetProperties().Value.SmbProperties.PermissionKey.Value(); + permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(binaryPermissionNoControlFlag, permission); + + // UploadFrom file + auto fileClient3 + = m_shareClient->GetRootDirectoryClient().GetFileClient(LowercaseRandomString()); + const std::string tempFilename = "file" + RandomString(); + WriteFile(tempFilename, content); + EXPECT_NO_THROW(fileClient3.UploadFrom(tempFilename, uploadFromOptions)); + permissionKey = fileClient3.GetProperties().Value.SmbProperties.PermissionKey.Value(); + permission = m_shareClient->GetPermission(permissionKey, getOptions).Value; + EXPECT_EQ(binaryPermissionNoControlFlag, permission); + } + } }}} // namespace Azure::Storage::Test diff --git a/sdk/storage/azure-storage-files-shares/test/ut/share_sas_test.cpp b/sdk/storage/azure-storage-files-shares/test/ut/share_sas_test.cpp index ed3a34ccdd..829982fe2f 100644 --- a/sdk/storage/azure-storage-files-shares/test/ut/share_sas_test.cpp +++ b/sdk/storage/azure-storage-files-shares/test/ut/share_sas_test.cpp @@ -528,4 +528,34 @@ namespace Azure { namespace Storage { namespace Test { EXPECT_TRUE(e.AdditionalInformation.count("ExtendedErrorDetail") != 0); } } + + TEST(SasStringToSignTest, GenerateStringToSign) + { + std::string accountName = "testAccountName"; + std::string accountKey = "dGVzdEFjY291bnRLZXk="; + std::string shareUrl = "https://testAccountName.file.core.windows.net/container/blob"; + auto keyCredential = std::make_shared(accountName, accountKey); + auto sasStartsOn = std::chrono::system_clock::now() - std::chrono::minutes(5); + auto sasExpiresOn = std::chrono::system_clock::now() + std::chrono::minutes(60); + + // Share Sas + { + Sas::ShareSasBuilder shareSasBuilder; + shareSasBuilder.Protocol = Sas::SasProtocol::HttpsAndHttp; + shareSasBuilder.StartsOn = sasStartsOn; + shareSasBuilder.ExpiresOn = sasExpiresOn; + shareSasBuilder.ShareName = "share"; + shareSasBuilder.FilePath = "file"; + shareSasBuilder.Resource = Sas::ShareSasResource::File; + shareSasBuilder.SetPermissions(Sas::ShareSasPermissions::Read); + auto sasToken = shareSasBuilder.GenerateSasToken(*keyCredential); + auto signature = Azure::Core::Url::Decode( + Azure::Core::Url(shareUrl + sasToken).GetQueryParameters().find("sig")->second); + auto stringToSign = shareSasBuilder.GenerateSasStringToSign(*keyCredential); + auto signatureFromStringToSign = Azure::Core::Convert::Base64Encode(_internal::HmacSha256( + std::vector(stringToSign.begin(), stringToSign.end()), + Azure::Core::Convert::Base64Decode(accountKey))); + EXPECT_EQ(signature, signatureFromStringToSign); + } + } }}} // namespace Azure::Storage::Test diff --git a/sdk/storage/azure-storage-files-shares/test/ut/share_service_client_test.cpp b/sdk/storage/azure-storage-files-shares/test/ut/share_service_client_test.cpp index ff21526d1c..27942c8b51 100644 --- a/sdk/storage/azure-storage-files-shares/test/ut/share_service_client_test.cpp +++ b/sdk/storage/azure-storage-files-shares/test/ut/share_service_client_test.cpp @@ -417,4 +417,84 @@ namespace Azure { namespace Storage { namespace Test { premiumFileShareServiceClient.SetProperties(originalProperties); } + TEST_F(FileShareServiceClientTest, OAuth_PLAYBACKONLY_) + { + std::shared_ptr credential = GetTestCredential(); + auto options = InitStorageClientOptions(); + options.ShareTokenIntent = Files::Shares::Models::ShareTokenIntent::Backup; + + auto shareServiceClient + = Files::Shares::ShareServiceClient(m_shareServiceClient->GetUrl(), credential, options); + // Get Properties + Files::Shares::Models::ShareServiceProperties properties; + EXPECT_NO_THROW(properties = shareServiceClient.GetProperties().Value); + + // Set Properties + properties.Protocol.Reset(); + EXPECT_NO_THROW(shareServiceClient.SetProperties(properties)); + + // List Shares + EXPECT_NO_THROW(shareServiceClient.ListShares()); + } + + TEST_F(FileShareServiceClientTest, PremiumSharePaidBurst_PLAYBACKONLY_) + { + auto shareServiceClient = *m_premiumShareServiceClient; + auto shareName = LowercaseRandomString(); + auto shareClient = shareServiceClient.GetShareClient(shareName); + + // Create + Files::Shares::CreateShareOptions createOptions; + createOptions.EnablePaidBursting = true; + createOptions.PaidBurstingMaxIops = 1000; + createOptions.PaidBurstingMaxBandwidthMibps = 5000; + shareClient.Create(createOptions); + + // Get Properties + auto properties = shareClient.GetProperties().Value; + EXPECT_TRUE(properties.PaidBurstingEnabled.HasValue()); + EXPECT_TRUE(properties.PaidBurstingEnabled.Value()); + EXPECT_TRUE(properties.PaidBurstingMaxIops.HasValue()); + EXPECT_EQ(properties.PaidBurstingMaxIops.Value(), 1000); + EXPECT_TRUE(properties.PaidBurstingMaxBandwidthMibps.HasValue()); + EXPECT_EQ(properties.PaidBurstingMaxBandwidthMibps.Value(), 5000); + + // Set Properties + Files::Shares::SetSharePropertiesOptions setPropertiesOptions; + setPropertiesOptions.EnablePaidBursting = true; + setPropertiesOptions.PaidBurstingMaxIops = 500; + setPropertiesOptions.PaidBurstingMaxBandwidthMibps = 1000; + shareClient.SetProperties(setPropertiesOptions); + + // List Shares + Azure::Nullable shareItem; + for (auto page = shareServiceClient.ListShares(); page.HasPage(); page.MoveToNextPage()) + { + for (const auto& share : page.Shares) + { + if (share.Name == shareName) + { + shareItem = share; + } + } + } + ASSERT_TRUE(shareItem.HasValue()); + EXPECT_TRUE(shareItem.Value().Details.PaidBurstingEnabled.HasValue()); + EXPECT_TRUE(shareItem.Value().Details.PaidBurstingEnabled.Value()); + EXPECT_TRUE(shareItem.Value().Details.PaidBurstingMaxIops.HasValue()); + EXPECT_EQ(shareItem.Value().Details.PaidBurstingMaxIops.Value(), 500); + EXPECT_TRUE(shareItem.Value().Details.PaidBurstingMaxBandwidthMibps.HasValue()); + EXPECT_EQ(shareItem.Value().Details.PaidBurstingMaxBandwidthMibps.Value(), 1000); + + // Set Properties EnablePaidBursting = false + setPropertiesOptions.EnablePaidBursting = false; + setPropertiesOptions.PaidBurstingMaxIops.Reset(); + setPropertiesOptions.PaidBurstingMaxBandwidthMibps.Reset(); + shareClient.SetProperties(setPropertiesOptions); + properties = shareClient.GetProperties().Value; + EXPECT_TRUE(properties.PaidBurstingEnabled.HasValue()); + EXPECT_FALSE(properties.PaidBurstingEnabled.Value()); + + shareClient.DeleteIfExists(); + } }}} // namespace Azure::Storage::Test diff --git a/sdk/storage/azure-storage-queues/inc/azure/storage/queues/queue_sas_builder.hpp b/sdk/storage/azure-storage-queues/inc/azure/storage/queues/queue_sas_builder.hpp index 3dd1b0ffcd..2c16a92dc8 100644 --- a/sdk/storage/azure-storage-queues/inc/azure/storage/queues/queue_sas_builder.hpp +++ b/sdk/storage/azure-storage-queues/inc/azure/storage/queues/queue_sas_builder.hpp @@ -129,6 +129,16 @@ namespace Azure { namespace Storage { namespace Sas { */ std::string GenerateSasToken(const StorageSharedKeyCredential& credential); + /** + * @brief For debugging purposes only. + * + * @param credential + * The storage account's shared key credential. + * @return Returns the string to sign that will be used to generate the signature for the SAS + * URL. + */ + std::string GenerateSasStringToSign(const StorageSharedKeyCredential& credential); + private: std::string Permissions; }; diff --git a/sdk/storage/azure-storage-queues/inc/azure/storage/queues/rest_client.hpp b/sdk/storage/azure-storage-queues/inc/azure/storage/queues/rest_client.hpp index e93b1e9380..9cd2db0c34 100644 --- a/sdk/storage/azure-storage-queues/inc/azure/storage/queues/rest_client.hpp +++ b/sdk/storage/azure-storage-queues/inc/azure/storage/queues/rest_client.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -42,7 +43,7 @@ namespace Azure { namespace Storage { namespace Queues { * Indicates the number of days that metrics or logging or soft-deleted data should be * retained. All data older than this value will be deleted. */ - Nullable Days; + Nullable Days; }; /** * @brief Azure Analytics Logging settings. @@ -126,7 +127,7 @@ namespace Azure { namespace Storage { namespace Queues { /** * The maximum amount time that a browser should cache the preflight OPTIONS request. */ - int32_t MaxAgeInSeconds = int32_t(); + std::int32_t MaxAgeInSeconds = std::int32_t(); }; /** * @brief Response type for #Azure::Storage::Queues::QueueServiceClient::SetProperties. @@ -159,27 +160,20 @@ namespace Azure { namespace Storage { namespace Queues { /** * @brief The status of the secondary location. */ - class GeoReplicationStatus final { + class GeoReplicationStatus final + : public Core::_internal::ExtendableEnumeration { public: /** Constructs a new GeoReplicationStatus instance */ GeoReplicationStatus() = default; /** Constructs a new GeoReplicationStatus from a string. */ - explicit GeoReplicationStatus(std::string value) : m_value(std::move(value)) {} - /** Compares with another GeoReplicationStatus. */ - bool operator==(const GeoReplicationStatus& other) const { return m_value == other.m_value; } - /** Compares with another GeoReplicationStatus. */ - bool operator!=(const GeoReplicationStatus& other) const { return !(*this == other); } - /** Converts the value to a string. */ - const std::string& ToString() const { return m_value; } + explicit GeoReplicationStatus(std::string value) : ExtendableEnumeration(std::move(value)) {} + /** Constant value of type GeoReplicationStatus: Live */ AZ_STORAGE_QUEUES_DLLEXPORT const static GeoReplicationStatus Live; /** Constant value of type GeoReplicationStatus: Bootstrap */ AZ_STORAGE_QUEUES_DLLEXPORT const static GeoReplicationStatus Bootstrap; /** Constant value of type GeoReplicationStatus: Unavailable */ AZ_STORAGE_QUEUES_DLLEXPORT const static GeoReplicationStatus Unavailable; - - private: - std::string m_value; }; /** * @brief Geo-Replication information for the Secondary Storage Service. @@ -302,7 +296,7 @@ namespace Azure { namespace Storage { namespace Queues { * The approximate number of messages in the queue. This number is not lower than the actual * number of messages in the queue, but could be higher. */ - int32_t ApproximateMessageCount = int32_t(); + std::int32_t ApproximateMessageCount = std::int32_t(); }; /** * @brief Response type for #Azure::Storage::Queues::QueueClient::SetMetadata. @@ -378,7 +372,7 @@ namespace Azure { namespace Storage { namespace Queues { /** * The number of times the message has been dequeued. */ - int64_t DequeueCount = int64_t(); + std::int64_t DequeueCount = std::int64_t(); /** * The content of the Message. */ @@ -460,7 +454,7 @@ namespace Azure { namespace Storage { namespace Queues { /** * The number of times the message has been dequeued. */ - int64_t DequeueCount = int64_t(); + std::int64_t DequeueCount = std::int64_t(); /** * The content of the Message. */ @@ -529,7 +523,7 @@ namespace Azure { namespace Storage { namespace Queues { { Nullable Prefix; Nullable Marker; - Nullable MaxResults; + Nullable MaxResults; Nullable Include; }; static Response ListQueuesSegment( @@ -593,8 +587,8 @@ namespace Azure { namespace Storage { namespace Queues { const Core::Context& context); struct ReceiveQueueMessagesOptions final { - Nullable NumberOfMessages; - Nullable Visibilitytimeout; + Nullable NumberOfMessages; + Nullable Visibilitytimeout; }; static Response ReceiveMessages( Core::Http::_internal::HttpPipeline& pipeline, @@ -612,8 +606,8 @@ namespace Azure { namespace Storage { namespace Queues { struct EnqueueQueueMessageOptions final { Models::_detail::QueueMessageInternal QueueMessage; - Nullable Visibilitytimeout; - Nullable MessageTimeToLive; + Nullable Visibilitytimeout; + Nullable MessageTimeToLive; }; static Response EnqueueMessage( Core::Http::_internal::HttpPipeline& pipeline, @@ -622,7 +616,7 @@ namespace Azure { namespace Storage { namespace Queues { const Core::Context& context); struct PeekQueueMessagesOptions final { - Nullable NumberOfMessages; + Nullable NumberOfMessages; }; static Response PeekMessages( Core::Http::_internal::HttpPipeline& pipeline, @@ -633,7 +627,7 @@ namespace Azure { namespace Storage { namespace Queues { { Models::_detail::QueueMessageInternal QueueMessage; std::string PopReceipt; - int32_t Visibilitytimeout = int32_t(); + std::int32_t Visibilitytimeout = std::int32_t(); }; static Response UpdateMessage( Core::Http::_internal::HttpPipeline& pipeline, @@ -652,7 +646,7 @@ namespace Azure { namespace Storage { namespace Queues { struct UpdateQueueMessageVisibilityOptions final { std::string PopReceipt; - int32_t Visibilitytimeout = int32_t(); + std::int32_t Visibilitytimeout = std::int32_t(); }; static Response UpdateMessageVisibility( Core::Http::_internal::HttpPipeline& pipeline, diff --git a/sdk/storage/azure-storage-queues/src/queue_sas_builder.cpp b/sdk/storage/azure-storage-queues/src/queue_sas_builder.cpp index 477d478356..e67b88f4c7 100644 --- a/sdk/storage/azure-storage-queues/src/queue_sas_builder.cpp +++ b/sdk/storage/azure-storage-queues/src/queue_sas_builder.cpp @@ -87,4 +87,24 @@ namespace Azure { namespace Storage { namespace Sas { return builder.GetAbsoluteUrl(); } + std::string QueueSasBuilder::GenerateSasStringToSign(const StorageSharedKeyCredential& credential) + { + std::string canonicalName = "/queue/" + credential.AccountName + "/" + QueueName; + + std::string protocol = _detail::SasProtocolToString(Protocol); + + std::string startsOnStr = StartsOn.HasValue() + ? StartsOn.Value().ToString( + Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate) + : ""; + std::string expiresOnStr = Identifier.empty() + ? ExpiresOn.ToString( + Azure::DateTime::DateFormat::Rfc3339, Azure::DateTime::TimeFractionFormat::Truncate) + : ""; + + return Permissions + "\n" + startsOnStr + "\n" + expiresOnStr + "\n" + canonicalName + "\n" + + Identifier + "\n" + (IPRange.HasValue() ? IPRange.Value() : "") + "\n" + protocol + "\n" + + SasVersion; + } + }}} // namespace Azure::Storage::Sas diff --git a/sdk/storage/azure-storage-queues/test/ut/queue_sas_test.cpp b/sdk/storage/azure-storage-queues/test/ut/queue_sas_test.cpp index ef370d35aa..d5987b90b6 100644 --- a/sdk/storage/azure-storage-queues/test/ut/queue_sas_test.cpp +++ b/sdk/storage/azure-storage-queues/test/ut/queue_sas_test.cpp @@ -349,4 +349,32 @@ namespace Azure { namespace Storage { namespace Test { } } + TEST(SasStringToSignTest, GenerateStringToSign) + { + std::string accountName = "testAccountName"; + std::string accountKey = "dGVzdEFjY291bnRLZXk="; + std::string queueUrl = "https://testAccountName.queue.core.windows.net/container/blob"; + auto keyCredential = std::make_shared(accountName, accountKey); + auto sasStartsOn = std::chrono::system_clock::now() - std::chrono::minutes(5); + auto sasExpiresOn = std::chrono::system_clock::now() + std::chrono::minutes(60); + + // Share Sas + { + Sas::QueueSasBuilder queueSasBuilder; + queueSasBuilder.Protocol = Sas::SasProtocol::HttpsAndHttp; + queueSasBuilder.StartsOn = sasStartsOn; + queueSasBuilder.ExpiresOn = sasExpiresOn; + queueSasBuilder.QueueName = "share"; + queueSasBuilder.SetPermissions(Sas::QueueSasPermissions::Read); + auto sasToken = queueSasBuilder.GenerateSasToken(*keyCredential); + auto signature = Azure::Core::Url::Decode( + Azure::Core::Url(queueUrl + sasToken).GetQueryParameters().find("sig")->second); + auto stringToSign = queueSasBuilder.GenerateSasStringToSign(*keyCredential); + auto signatureFromStringToSign = Azure::Core::Convert::Base64Encode(_internal::HmacSha256( + std::vector(stringToSign.begin(), stringToSign.end()), + Azure::Core::Convert::Base64Decode(accountKey))); + EXPECT_EQ(signature, signatureFromStringToSign); + } + } + }}} // namespace Azure::Storage::Test