diff --git a/sdk/storage/assets.json b/sdk/storage/assets.json index 90f24d81b0..3f15b51cf9 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_fafb185a5f" + "Tag": "cpp/storage_b3174d14d3" } diff --git a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_client.hpp b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_client.hpp index 697c5ed299..c832291420 100644 --- a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_client.hpp +++ b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_client.hpp @@ -42,6 +42,17 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::shared_ptr credential, const ShareClientOptions& options = ShareClientOptions()); + /** + * @brief Initialize a new instance of ShareClient using shared key authentication. + * @param shareUrl The URL of the file share this client's request targets. + * @param credential The token credential used to sign requests. + * @param options Optional parameters used to initialize the client. + */ + explicit ShareClient( + const std::string& shareUrl, + std::shared_ptr credential, + const ShareClientOptions& options = ShareClientOptions()); + /** * @brief Initialize a new instance of ShareClient using anonymous access or shared access * signature. @@ -232,6 +243,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::shared_ptr m_pipeline; Nullable m_allowTrailingDot; Nullable m_allowSourceTrailingDot; + Nullable m_shareTokenIntent; explicit ShareClient( Azure::Core::Url shareUrl, diff --git a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_directory_client.hpp b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_directory_client.hpp index 84b91ae950..182a689b8b 100644 --- a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_directory_client.hpp +++ b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_directory_client.hpp @@ -46,6 +46,17 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::shared_ptr credential, const ShareClientOptions& options = ShareClientOptions()); + /** + * @brief Initialize a new instance of ShareDirectoryClient using shared key authentication. + * @param shareDirectoryUrl The URL of the directory this client's request targets. + * @param credential The token credential used to sign requests. + * @param options Optional parameters used to initialize the client. + */ + explicit ShareDirectoryClient( + const std::string& shareDirectoryUrl, + std::shared_ptr credential, + const ShareClientOptions& options = ShareClientOptions()); + /** * @brief Initialize a new instance of ShareDirectoryClient using anonymous access or shared * access signature. @@ -262,6 +273,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::shared_ptr m_pipeline; Nullable m_allowTrailingDot; Nullable m_allowSourceTrailingDot; + Nullable m_shareTokenIntent; explicit ShareDirectoryClient( Azure::Core::Url shareDirectoryUrl, diff --git a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_file_client.hpp b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_file_client.hpp index 56cfb1c2af..ee77fcf8b5 100644 --- a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_file_client.hpp +++ b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_file_client.hpp @@ -45,6 +45,17 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::shared_ptr credential, const ShareClientOptions& options = ShareClientOptions()); + /** + * @brief Initialize a new instance of ShareFileClient using shared key authentication. + * @param shareFileUrl The URL of the file this client's request targets. + * @param credential The token credential used to sign requests. + * @param options Optional parameters used to initialize the client. + */ + explicit ShareFileClient( + const std::string& shareFileUrl, + std::shared_ptr credential, + const ShareClientOptions& options = ShareClientOptions()); + /** * @brief Initialize a new instance of ShareFileClient using anonymous access or shared access * signature. @@ -365,6 +376,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::shared_ptr m_pipeline; Nullable m_allowTrailingDot; Nullable m_allowSourceTrailingDot; + Nullable m_shareTokenIntent; explicit ShareFileClient( Azure::Core::Url shareFileUrl, 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 7c363522fa..6f39304ddf 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 @@ -40,6 +40,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { * Supported by x-ms-version 2022-11-02 and above. */ Nullable AllowSourceTrailingDot; + + /** + * Share Token Intent. For use with token authentication. Used to indicate the intent of the + * request. This is currently required when using token authentication. + */ + Nullable ShareTokenIntent; }; /** diff --git a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_service_client.hpp b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_service_client.hpp index 0764fd9a13..8fca51c3a0 100644 --- a/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_service_client.hpp +++ b/sdk/storage/azure-storage-files-shares/inc/azure/storage/files/shares/share_service_client.hpp @@ -41,6 +41,17 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::shared_ptr credential, const ShareClientOptions& options = ShareClientOptions()); + /** + * @brief Initialize a new instance of ShareServiceClient using shared key authentication. + * @param serviceUrl The service URL this client's request targets. + * @param credential The token credential used to sign requests. + * @param options Optional parameters used to initialize the client. + */ + explicit ShareServiceClient( + const std::string& serviceUrl, + std::shared_ptr credential, + const ShareClientOptions& options = ShareClientOptions()); + /** * @brief Initialize a new instance of ShareServiceClient using anonymous access or shared * access signature. @@ -104,5 +115,6 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::shared_ptr m_pipeline; Nullable m_allowTrailingDot; Nullable m_allowSourceTrailingDot; + Nullable m_shareTokenIntent; }; }}}} // namespace Azure::Storage::Files::Shares 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 6e0b809ec7..d9acab2b17 100644 --- a/sdk/storage/azure-storage-files-shares/src/share_client.cpp +++ b/sdk/storage/azure-storage-files-shares/src/share_client.cpp @@ -44,7 +44,8 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::shared_ptr credential, const ShareClientOptions& options) : m_shareUrl(shareUrl), m_allowTrailingDot(options.AllowTrailingDot), - m_allowSourceTrailingDot(options.AllowSourceTrailingDot) + m_allowSourceTrailingDot(options.AllowSourceTrailingDot), + m_shareTokenIntent(options.ShareTokenIntent) { ShareClientOptions newOptions = options; newOptions.PerRetryPolicies.emplace_back( @@ -63,9 +64,40 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::move(perOperationPolicies)); } + ShareClient::ShareClient( + const std::string& shareUrl, + std::shared_ptr credential, + const ShareClientOptions& options) + : m_shareUrl(shareUrl), m_allowTrailingDot(options.AllowTrailingDot), + m_allowSourceTrailingDot(options.AllowSourceTrailingDot), + m_shareTokenIntent(options.ShareTokenIntent) + { + ShareClientOptions newOptions = options; + + std::vector> perRetryPolicies; + std::vector> perOperationPolicies; + perRetryPolicies.emplace_back(std::make_unique<_internal::StoragePerRetryPolicy>()); + { + Azure::Core::Credentials::TokenRequestContext tokenContext; + tokenContext.Scopes.emplace_back(_internal::StorageScope); + perRetryPolicies.emplace_back( + std::make_unique( + credential, tokenContext)); + } + perOperationPolicies.emplace_back( + std::make_unique<_internal::StorageServiceVersionPolicy>(newOptions.ApiVersion)); + m_pipeline = std::make_shared( + newOptions, + _internal::FileServicePackageName, + _detail::PackageVersion::ToString(), + std::move(perRetryPolicies), + std::move(perOperationPolicies)); + } + ShareClient::ShareClient(const std::string& shareUrl, const ShareClientOptions& options) : m_shareUrl(shareUrl), m_allowTrailingDot(options.AllowTrailingDot), - m_allowSourceTrailingDot(options.AllowSourceTrailingDot) + m_allowSourceTrailingDot(options.AllowSourceTrailingDot), + m_shareTokenIntent(options.ShareTokenIntent) { std::vector> perRetryPolicies; std::vector> perOperationPolicies; @@ -85,6 +117,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { ShareDirectoryClient directoryClient(m_shareUrl, m_pipeline); directoryClient.m_allowTrailingDot = m_allowTrailingDot; directoryClient.m_allowSourceTrailingDot = m_allowSourceTrailingDot; + directoryClient.m_shareTokenIntent = m_shareTokenIntent; return directoryClient; } @@ -267,6 +300,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { (void)options; auto protocolLayerOptions = _detail::ShareClient::CreateSharePermissionOptions(); protocolLayerOptions.SharePermission.Permission = permission; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::ShareClient::CreatePermission( *m_pipeline, m_shareUrl, protocolLayerOptions, context); } @@ -279,6 +313,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { (void)options; auto protocolLayerOptions = _detail::ShareClient::GetSharePermissionOptions(); protocolLayerOptions.FilePermissionKey = permissionKey; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; 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 03c7a4570a..1695c4ca41 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 @@ -46,7 +46,8 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::shared_ptr credential, const ShareClientOptions& options) : m_shareDirectoryUrl(shareDirectoryUrl), m_allowTrailingDot(options.AllowTrailingDot), - m_allowSourceTrailingDot(options.AllowSourceTrailingDot) + m_allowSourceTrailingDot(options.AllowSourceTrailingDot), + m_shareTokenIntent(options.ShareTokenIntent) { ShareClientOptions newOptions = options; newOptions.PerRetryPolicies.emplace_back( @@ -67,9 +68,40 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { ShareDirectoryClient::ShareDirectoryClient( const std::string& shareDirectoryUrl, + std::shared_ptr credential, const ShareClientOptions& options) : m_shareDirectoryUrl(shareDirectoryUrl), m_allowTrailingDot(options.AllowTrailingDot), - m_allowSourceTrailingDot(options.AllowSourceTrailingDot) + m_allowSourceTrailingDot(options.AllowSourceTrailingDot), + m_shareTokenIntent(options.ShareTokenIntent) + { + ShareClientOptions newOptions = options; + + std::vector> perRetryPolicies; + std::vector> perOperationPolicies; + perRetryPolicies.emplace_back(std::make_unique<_internal::StoragePerRetryPolicy>()); + { + Azure::Core::Credentials::TokenRequestContext tokenContext; + tokenContext.Scopes.emplace_back(_internal::StorageScope); + perRetryPolicies.emplace_back( + std::make_unique( + credential, tokenContext)); + } + perOperationPolicies.emplace_back( + std::make_unique<_internal::StorageServiceVersionPolicy>(newOptions.ApiVersion)); + m_pipeline = std::make_shared( + newOptions, + _internal::FileServicePackageName, + _detail::PackageVersion::ToString(), + std::move(perRetryPolicies), + std::move(perOperationPolicies)); + } + + ShareDirectoryClient::ShareDirectoryClient( + const std::string& shareDirectoryUrl, + const ShareClientOptions& options) + : m_shareDirectoryUrl(shareDirectoryUrl), m_allowTrailingDot(options.AllowTrailingDot), + m_allowSourceTrailingDot(options.AllowSourceTrailingDot), + m_shareTokenIntent(options.ShareTokenIntent) { std::vector> perRetryPolicies; std::vector> perOperationPolicies; @@ -92,6 +124,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { ShareDirectoryClient subdirectoryClient(builder, m_pipeline); subdirectoryClient.m_allowTrailingDot = m_allowTrailingDot; subdirectoryClient.m_allowSourceTrailingDot = m_allowSourceTrailingDot; + subdirectoryClient.m_shareTokenIntent = m_shareTokenIntent; return subdirectoryClient; } @@ -102,6 +135,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { ShareFileClient fileClient(builder, m_pipeline); fileClient.m_allowTrailingDot = m_allowTrailingDot; fileClient.m_allowSourceTrailingDot = m_allowSourceTrailingDot; + fileClient.m_shareTokenIntent = m_shareTokenIntent; return fileClient; } @@ -172,6 +206,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.FilePermission = std::string(FileInheritPermission); } protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto result = _detail::DirectoryClient::Create( *m_pipeline, m_shareDirectoryUrl, protocolLayerOptions, context); Models::CreateDirectoryResult ret; @@ -255,6 +290,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { } protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; protocolLayerOptions.AllowSourceTrailingDot = m_allowSourceTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto response = _detail::FileClient::Rename( *m_pipeline, destinationFileUrl, protocolLayerOptions, context); @@ -262,6 +298,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto renamedFileClient = ShareFileClient(destinationFileUrl, m_pipeline); renamedFileClient.m_allowTrailingDot = m_allowTrailingDot; renamedFileClient.m_allowSourceTrailingDot = m_allowSourceTrailingDot; + renamedFileClient.m_shareTokenIntent = m_shareTokenIntent; return Azure::Response( std::move(renamedFileClient), std::move(response.RawResponse)); } @@ -315,6 +352,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { } protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; protocolLayerOptions.AllowSourceTrailingDot = m_allowSourceTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto response = _detail::DirectoryClient::Rename( *m_pipeline, destinationDirectoryUrl, protocolLayerOptions, context); @@ -322,6 +360,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto renamedSubdirectoryClient = ShareDirectoryClient(destinationDirectoryUrl, m_pipeline); renamedSubdirectoryClient.m_allowTrailingDot = m_allowTrailingDot; renamedSubdirectoryClient.m_allowSourceTrailingDot = m_allowSourceTrailingDot; + renamedSubdirectoryClient.m_shareTokenIntent = m_shareTokenIntent; return Azure::Response( std::move(renamedSubdirectoryClient), std::move(response.RawResponse)); } @@ -333,6 +372,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { (void)options; auto protocolLayerOptions = _detail::DirectoryClient::DeleteDirectoryOptions(); protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto result = _detail::DirectoryClient::Delete( *m_pipeline, m_shareDirectoryUrl, protocolLayerOptions, context); Models::DeleteDirectoryResult ret; @@ -370,6 +410,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { (void)options; auto protocolLayerOptions = _detail::DirectoryClient::GetDirectoryPropertiesOptions(); protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::DirectoryClient::GetProperties( *m_pipeline, m_shareDirectoryUrl, protocolLayerOptions, context); } @@ -421,6 +462,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.FilePermission = FilePreserveSmbProperties; } protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::DirectoryClient::SetProperties( *m_pipeline, m_shareDirectoryUrl, protocolLayerOptions, context); } @@ -435,6 +477,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.Metadata = std::map(metadata.begin(), metadata.end()); protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::DirectoryClient::SetMetadata( *m_pipeline, m_shareDirectoryUrl, protocolLayerOptions, context); } @@ -451,6 +494,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.Include = options.Include; protocolLayerOptions.IncludeExtendedInfo = options.IncludeExtendedInfo; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto response = _detail::DirectoryClient::ListFilesAndDirectoriesSegment( *m_pipeline, m_shareDirectoryUrl, protocolLayerOptions, context); @@ -522,6 +566,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.MaxResults = options.PageSizeHint; protocolLayerOptions.Recursive = options.Recursive; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto response = _detail::DirectoryClient::ListHandles( *m_pipeline, m_shareDirectoryUrl, protocolLayerOptions, context); @@ -569,6 +614,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto protocolLayerOptions = _detail::DirectoryClient::ForceDirectoryCloseHandlesOptions(); protocolLayerOptions.HandleId = handleId; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto result = _detail::DirectoryClient::ForceCloseHandles( *m_pipeline, m_shareDirectoryUrl, protocolLayerOptions, context); Models::ForceCloseDirectoryHandleResult ret; @@ -585,6 +631,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.Marker = options.ContinuationToken; protocolLayerOptions.Recursive = options.Recursive; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto response = _detail::DirectoryClient::ForceCloseHandles( *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 88a0ca8963..67566595c4 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 @@ -51,7 +51,8 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::shared_ptr credential, const ShareClientOptions& options) : m_shareFileUrl(shareFileUrl), m_allowTrailingDot(options.AllowTrailingDot), - m_allowSourceTrailingDot(options.AllowSourceTrailingDot) + m_allowSourceTrailingDot(options.AllowSourceTrailingDot), + m_shareTokenIntent(options.ShareTokenIntent) { ShareClientOptions newOptions = options; newOptions.PerRetryPolicies.emplace_back( @@ -72,9 +73,40 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { ShareFileClient::ShareFileClient( const std::string& shareFileUrl, + std::shared_ptr credential, const ShareClientOptions& options) : m_shareFileUrl(shareFileUrl), m_allowTrailingDot(options.AllowTrailingDot), - m_allowSourceTrailingDot(options.AllowSourceTrailingDot) + m_allowSourceTrailingDot(options.AllowSourceTrailingDot), + m_shareTokenIntent(options.ShareTokenIntent) + { + ShareClientOptions newOptions = options; + + std::vector> perRetryPolicies; + std::vector> perOperationPolicies; + perRetryPolicies.emplace_back(std::make_unique<_internal::StoragePerRetryPolicy>()); + { + Azure::Core::Credentials::TokenRequestContext tokenContext; + tokenContext.Scopes.emplace_back(_internal::StorageScope); + perRetryPolicies.emplace_back( + std::make_unique( + credential, tokenContext)); + } + perOperationPolicies.emplace_back( + std::make_unique<_internal::StorageServiceVersionPolicy>(newOptions.ApiVersion)); + m_pipeline = std::make_shared( + newOptions, + _internal::FileServicePackageName, + _detail::PackageVersion::ToString(), + std::move(perRetryPolicies), + std::move(perOperationPolicies)); + } + + ShareFileClient::ShareFileClient( + const std::string& shareFileUrl, + const ShareClientOptions& options) + : m_shareFileUrl(shareFileUrl), m_allowTrailingDot(options.AllowTrailingDot), + m_allowSourceTrailingDot(options.AllowSourceTrailingDot), + m_shareTokenIntent(options.ShareTokenIntent) { std::vector> perRetryPolicies; std::vector> perOperationPolicies; @@ -182,6 +214,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { } protocolLayerOptions.LeaseId = options.AccessConditions.LeaseId; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto result = _detail::FileClient::Create(*m_pipeline, m_shareFileUrl, protocolLayerOptions, context); Models::CreateFileResult ret; @@ -201,6 +234,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto protocolLayerOptions = _detail::FileClient::DeleteFileOptions(); protocolLayerOptions.LeaseId = options.AccessConditions.LeaseId; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto result = _detail::FileClient::Delete(*m_pipeline, m_shareFileUrl, protocolLayerOptions, context); Models::DeleteFileResult ret; @@ -261,6 +295,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { } protocolLayerOptions.LeaseId = options.AccessConditions.LeaseId; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto downloadResponse = _detail::FileClient::Download(*m_pipeline, m_shareFileUrl, protocolLayerOptions, context); @@ -389,6 +424,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.LeaseId = options.AccessConditions.LeaseId; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; protocolLayerOptions.AllowSourceTrailingDot = m_allowSourceTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto response = _detail::FileClient::StartCopy( *m_pipeline, m_shareFileUrl, protocolLayerOptions, context); @@ -407,6 +443,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.CopyId = std::move(copyId); protocolLayerOptions.LeaseId = options.AccessConditions.LeaseId; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::FileClient::AbortCopy( *m_pipeline, m_shareFileUrl, protocolLayerOptions, context); } @@ -418,6 +455,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto protocolLayerOptions = _detail::FileClient::GetFilePropertiesOptions(); protocolLayerOptions.LeaseId = options.AccessConditions.LeaseId; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::FileClient::GetProperties( *m_pipeline, m_shareFileUrl, protocolLayerOptions, context); } @@ -493,6 +531,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.FileContentDisposition = httpHeaders.ContentDisposition; } protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::FileClient::SetHttpHeaders( *m_pipeline, m_shareFileUrl, protocolLayerOptions, context); @@ -508,6 +547,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { = std::map(metadata.begin(), metadata.end()); protocolLayerOptions.LeaseId = options.AccessConditions.LeaseId; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::FileClient::SetMetadata( *m_pipeline, m_shareFileUrl, protocolLayerOptions, context); } @@ -532,6 +572,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.LeaseId = options.AccessConditions.LeaseId; protocolLayerOptions.FileLastWrittenMode = options.FileLastWrittenMode; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::FileClient::UploadRange( *m_pipeline, m_shareFileUrl, content, protocolLayerOptions, context); } @@ -550,6 +591,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.LeaseId = options.AccessConditions.LeaseId; protocolLayerOptions.FileLastWrittenMode = options.FileLastWrittenMode; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto response = _detail::FileClient::UploadRange( *m_pipeline, m_shareFileUrl, @@ -587,6 +629,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.LeaseId = options.AccessConditions.LeaseId; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::FileClient::GetRangeList( *m_pipeline, m_shareFileUrl, protocolLayerOptions, context); } @@ -616,6 +659,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.Prevsharesnapshot = std::move(previousShareSnapshot); protocolLayerOptions.LeaseId = options.AccessConditions.LeaseId; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; return _detail::FileClient::GetRangeList( *m_pipeline, m_shareFileUrl, protocolLayerOptions, context); } @@ -628,6 +672,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.Marker = options.ContinuationToken; protocolLayerOptions.MaxResults = options.PageSizeHint; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto response = _detail::FileClient::ListHandles( *m_pipeline, m_shareFileUrl, protocolLayerOptions, context); @@ -675,6 +720,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { auto protocolLayerOptions = _detail::FileClient::ForceFileCloseHandlesOptions(); protocolLayerOptions.HandleId = handleId; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto result = _detail::FileClient::ForceCloseHandles( *m_pipeline, m_shareFileUrl, protocolLayerOptions, context); return Azure::Response( @@ -689,6 +735,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.HandleId = FileAllHandles; protocolLayerOptions.Marker = options.ContinuationToken; protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto response = _detail::FileClient::ForceCloseHandles( *m_pipeline, m_shareFileUrl, protocolLayerOptions, context); @@ -1014,6 +1061,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.Metadata = std::map(options.Metadata.begin(), options.Metadata.end()); protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; auto createResult = _detail::FileClient::Create(*m_pipeline, m_shareFileUrl, protocolLayerOptions, context); @@ -1130,6 +1178,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.Metadata = std::map(options.Metadata.begin(), options.Metadata.end()); protocolLayerOptions.AllowTrailingDot = m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_shareTokenIntent; 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 4527310a5b..e847ea0c10 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 @@ -26,6 +26,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.ProposedLeaseId = GetLeaseId(); protocolLayerOptions.Duration = static_cast(duration.count()); protocolLayerOptions.AllowTrailingDot = m_fileClient.Value().m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_fileClient.Value().m_shareTokenIntent; auto response = _detail::FileClient::AcquireLease( *(m_fileClient.Value().m_pipeline), @@ -112,6 +113,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { _detail::FileClient::ReleaseFileLeaseOptions protocolLayerOptions; protocolLayerOptions.LeaseId = GetLeaseId(); protocolLayerOptions.AllowTrailingDot = m_fileClient.Value().m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_fileClient.Value().m_shareTokenIntent; auto response = _detail::FileClient::ReleaseLease( *(m_fileClient.Value().m_pipeline), @@ -162,6 +164,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { protocolLayerOptions.LeaseId = GetLeaseId(); protocolLayerOptions.ProposedLeaseId = proposedLeaseId; protocolLayerOptions.AllowTrailingDot = m_fileClient.Value().m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_fileClient.Value().m_shareTokenIntent; auto response = _detail::FileClient::ChangeLease( *(m_fileClient.Value().m_pipeline), @@ -222,6 +225,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { _detail::FileClient::BreakFileLeaseOptions protocolLayerOptions; protocolLayerOptions.AllowTrailingDot = m_fileClient.Value().m_allowTrailingDot; + protocolLayerOptions.FileRequestIntent = m_fileClient.Value().m_shareTokenIntent; auto response = _detail::FileClient::BreakLease( *(m_fileClient.Value().m_pipeline), 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 d7f2a215b6..89340f519a 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 @@ -41,7 +41,8 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { std::shared_ptr credential, const ShareClientOptions& options) : m_serviceUrl(serviceUrl), m_allowTrailingDot(options.AllowTrailingDot), - m_allowSourceTrailingDot(options.AllowSourceTrailingDot) + m_allowSourceTrailingDot(options.AllowSourceTrailingDot), + m_shareTokenIntent(options.ShareTokenIntent) { ShareClientOptions newOptions = options; newOptions.PerRetryPolicies.emplace_back( @@ -62,9 +63,40 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { ShareServiceClient::ShareServiceClient( const std::string& serviceUrl, + std::shared_ptr credential, const ShareClientOptions& options) : m_serviceUrl(serviceUrl), m_allowTrailingDot(options.AllowTrailingDot), - m_allowSourceTrailingDot(options.AllowSourceTrailingDot) + m_allowSourceTrailingDot(options.AllowSourceTrailingDot), + m_shareTokenIntent(options.ShareTokenIntent) + { + ShareClientOptions newOptions = options; + + std::vector> perRetryPolicies; + std::vector> perOperationPolicies; + perRetryPolicies.emplace_back(std::make_unique<_internal::StoragePerRetryPolicy>()); + { + Azure::Core::Credentials::TokenRequestContext tokenContext; + tokenContext.Scopes.emplace_back(_internal::StorageScope); + perRetryPolicies.emplace_back( + std::make_unique( + credential, tokenContext)); + } + perOperationPolicies.emplace_back( + std::make_unique<_internal::StorageServiceVersionPolicy>(newOptions.ApiVersion)); + m_pipeline = std::make_shared( + newOptions, + _internal::FileServicePackageName, + _detail::PackageVersion::ToString(), + std::move(perRetryPolicies), + std::move(perOperationPolicies)); + } + + ShareServiceClient::ShareServiceClient( + const std::string& serviceUrl, + const ShareClientOptions& options) + : m_serviceUrl(serviceUrl), m_allowTrailingDot(options.AllowTrailingDot), + m_allowSourceTrailingDot(options.AllowSourceTrailingDot), + m_shareTokenIntent(options.ShareTokenIntent) { std::vector> perRetryPolicies; std::vector> perOperationPolicies; @@ -86,6 +118,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { ShareClient shareClient(builder, m_pipeline); shareClient.m_allowTrailingDot = m_allowTrailingDot; shareClient.m_allowSourceTrailingDot = m_allowSourceTrailingDot; + shareClient.m_shareTokenIntent = m_shareTokenIntent; return shareClient; } 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 63475b85b3..3b8fb2943f 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,4 +642,25 @@ namespace Azure { namespace Storage { namespace Test { } } + TEST_F(FileShareClientTest, DISABLED_OAuth) + { + // Create from client secret credential. + std::shared_ptr credential + = std::make_shared( + AadTenantId(), AadClientId(), AadClientSecret()); + auto options = InitStorageClientOptions(); + options.ShareTokenIntent = Files::Shares::Models::ShareTokenIntent::Backup; + + auto serviceClient + = Files::Shares::ShareServiceClient(m_shareServiceClient->GetUrl(), credential, options); + auto shareClient = serviceClient.GetShareClient(m_shareName); + + 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)); + } }}} // 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 a3239e0251..c082789ea3 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 @@ -1011,4 +1011,68 @@ namespace Azure { namespace Storage { namespace Test { // allowTrailingDot = false, allowSourceTrailingDot = false testTrailingDot(false, false); } + + TEST_F(FileShareDirectoryClientTest, DISABLED_OAuth) + { + const std::string directoryName = RandomString(); + + // Create from client secret credential. + std::shared_ptr credential + = std::make_shared( + AadTenantId(), AadClientId(), AadClientSecret()); + auto options = InitStorageClientOptions(); + options.ShareTokenIntent = Files::Shares::Models::ShareTokenIntent::Backup; + + auto shareClient = Files::Shares::ShareClient(m_shareClient->GetUrl(), credential, options); + auto rootDirectoryClient = shareClient.GetRootDirectoryClient(); + auto directoryClient = rootDirectoryClient.GetSubdirectoryClient(directoryName); + + // Create + EXPECT_NO_THROW(directoryClient.Create()); + + // ListFilesAndDirectories + EXPECT_NO_THROW(directoryClient.ListFilesAndDirectories()); + + // ListHandles + EXPECT_NO_THROW(directoryClient.ListHandles()); + + // GetProperties + EXPECT_NO_THROW(directoryClient.GetProperties()); + + // SetProperties + EXPECT_NO_THROW(directoryClient.SetProperties(Files::Shares::Models::FileSmbProperties())); + + // SetMetadata + EXPECT_NO_THROW(directoryClient.SetMetadata(RandomMetadata())); + + // ForceCloseHandles + EXPECT_NO_THROW(directoryClient.ForceCloseAllHandles()); + + // Rename File + const std::string fileName = RandomString() + "_file"; + const std::string destFileName = fileName + "_dest"; + auto fileClient = directoryClient.GetFileClient(fileName); + fileClient.Create(512); + auto destFileClient = directoryClient.GetFileClient(destFileName); + EXPECT_NO_THROW( + destFileClient + = directoryClient.RenameFile(fileName, directoryName + "/" + destFileName).Value); + EXPECT_NO_THROW(destFileClient.Delete()); + + // Rename Directory + const std::string subdirectoryName = RandomString() + "_sub"; + const std::string destSubdirectoryName = subdirectoryName + "_dest"; + auto subdirectoryClient = directoryClient.GetSubdirectoryClient(subdirectoryName); + subdirectoryClient.Create(); + auto destSubdirectoryClient = directoryClient.GetSubdirectoryClient(destSubdirectoryName); + EXPECT_NO_THROW( + destSubdirectoryClient + = directoryClient + .RenameSubdirectory(subdirectoryName, directoryName + "/" + destSubdirectoryName) + .Value); + EXPECT_NO_THROW(destSubdirectoryClient.Delete()); + + // Delete + EXPECT_NO_THROW(directoryClient.Delete()); + } }}} // 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 effad67425..bbff4e9173 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 @@ -1109,6 +1109,10 @@ namespace Azure { namespace Storage { namespace Test { auto range = fileClient.GetRangeList().Value; EXPECT_EQ(range.Ranges.size(), 1L); + // GetRangeListDiff + auto snapshot = m_shareClient->CreateSnapshot().Value.Snapshot; + EXPECT_NO_THROW(fileClient.GetRangeListDiff(snapshot)); + // ClearRange EXPECT_NO_THROW(fileClient.ClearRange(0, fileSize)); @@ -1292,4 +1296,132 @@ namespace Azure { namespace Storage { namespace Test { // allowTrailingDot = false testTrailingDot(false); } + + TEST_F(FileShareFileClientTest, DISABLED_OAuth) + { + const std::string fileName = RandomString(); + + // Create from client secret credential. + std::shared_ptr credential + = std::make_shared( + AadTenantId(), AadClientId(), AadClientSecret()); + auto options = InitStorageClientOptions(); + options.ShareTokenIntent = Files::Shares::Models::ShareTokenIntent::Backup; + + auto shareClient = Files::Shares::ShareClient(m_shareClient->GetUrl(), credential, options); + auto rootDirectoryClient = shareClient.GetRootDirectoryClient(); + auto fileClient = rootDirectoryClient.GetFileClient(fileName); + std::string leaseId1 = RandomUUID(); + Files::Shares::ShareLeaseClient leaseClient(fileClient, leaseId1); + + size_t fileSize = 512; + std::vector content(RandomBuffer(fileSize)); + auto memBodyStream = Core::IO::MemoryBodyStream(content); + + // Create + EXPECT_NO_THROW(fileClient.Create(fileSize)); + + // GetProperties + EXPECT_NO_THROW(fileClient.GetProperties()); + + // ListHandles + EXPECT_NO_THROW(fileClient.ListHandles()); + + // Download + EXPECT_NO_THROW(fileClient.Download()); + + // SetProperties + EXPECT_NO_THROW(fileClient.SetProperties( + Files::Shares::Models::FileHttpHeaders(), Files::Shares::Models::FileSmbProperties())); + + // SetMetadata + EXPECT_NO_THROW(fileClient.SetMetadata(RandomMetadata())); + + // ForceCloseHandles + EXPECT_NO_THROW(fileClient.ForceCloseAllHandles()); + + // UploadRange + EXPECT_NO_THROW(fileClient.UploadRange(0L, memBodyStream)); + + // GetRangeList + EXPECT_NO_THROW(fileClient.GetRangeList()); + + // GetRangeListDiff + auto snapshot = m_shareClient->CreateSnapshot().Value.Snapshot; + EXPECT_NO_THROW(fileClient.GetRangeListDiff(snapshot)); + + // ClearRange + EXPECT_NO_THROW(fileClient.ClearRange(0, fileSize)); + + // UploadFrom buffer + EXPECT_NO_THROW(fileClient.UploadFrom(content.data(), fileSize)); + + // UploadFrom file + const std::string tempFilename = "file" + RandomString(); + WriteFile(tempFilename, content); + EXPECT_NO_THROW(fileClient.UploadFrom(tempFilename)); + + // Acquire + EXPECT_NO_THROW(leaseClient.Acquire(Files::Shares::ShareLeaseClient::InfiniteLeaseDuration)); + + // Change + std::string leaseId2 = RandomUUID(); + EXPECT_NO_THROW(leaseClient.Change(leaseId2)); + + // Break + EXPECT_NO_THROW(leaseClient.Break()); + + // Release + EXPECT_NO_THROW(leaseClient.Release()); + + // Delete + EXPECT_NO_THROW(fileClient.Delete()); + } + + TEST_F(FileShareFileClientTest, DISABLED_OAuthCopy) + { + const std::string fileName = RandomString(); + + // Create from client secret credential. + std::shared_ptr credential + = std::make_shared( + AadTenantId(), AadClientId(), AadClientSecret()); + auto options = InitStorageClientOptions(); + options.ShareTokenIntent = Files::Shares::Models::ShareTokenIntent::Backup; + + auto shareClient = Files::Shares::ShareClient(m_shareClient->GetUrl(), credential, options); + auto rootDirectoryClient = shareClient.GetRootDirectoryClient(); + auto fileClient = rootDirectoryClient.GetFileClient(fileName); + + size_t fileSize = 1 * 1024 * 1024; + std::vector content(RandomBuffer(fileSize)); + auto memBodyStream = Core::IO::MemoryBodyStream(content); + + auto createResult = fileClient.Create(fileSize).Value; + fileClient.UploadRange(0, memBodyStream); + + const std::string destFileName = fileName + "_dest"; + auto destFileClient = rootDirectoryClient.GetFileClient(destFileName); + + // StartCopy + auto copyOperation = destFileClient.StartCopy(fileClient.GetUrl()); + EXPECT_EQ( + copyOperation.GetRawResponse().GetStatusCode(), + Azure::Core::Http::HttpStatusCode::Accepted); + copyOperation.Poll(); + EXPECT_TRUE(copyOperation.Value().CopyId.HasValue()); + + // AbortCopy + // This exception is intentionally. It is difficult to test AbortCopyAsync() in a + // deterministic way. + try + { + destFileClient.AbortCopy(copyOperation.Value().CopyId.Value()); + } + catch (StorageException& e) + { + EXPECT_EQ(e.ErrorCode, "NoPendingCopyOperation"); + } + EXPECT_NO_THROW(destFileClient.Delete()); + } }}} // namespace Azure::Storage::Test