diff --git a/.vscode/cspell.json b/.vscode/cspell.json index 21c218a116..0adc040a35 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -225,6 +225,8 @@ "Schulze", "scus", "SDDL", + "Sddl", + "sddl", "sdpath", "serializers", "Seriot", diff --git a/sdk/storage/assets.json b/sdk/storage/assets.json index da2ed90f7b..ea934e0225 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_f113099cfb" + "Tag": "cpp/storage_3a6c7a0852" } 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 af6aa6af18..645724feef 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 @@ -796,6 +796,33 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { */ DateTime LastModified; }; + /** + * @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 FilePermissionFormat final { + public: + /** Constructs a new FilePermissionFormat instance */ + FilePermissionFormat() = default; + /** Constructs a new FilePermissionFormat from a string. */ + explicit FilePermissionFormat(std::string value) : m_value(std::move(value)) {} + /** Compares with another FilePermissionFormat. */ + bool operator==(const FilePermissionFormat& other) const { return m_value == other.m_value; } + /** Compares with another FilePermissionFormat. */ + bool operator!=(const FilePermissionFormat& other) const { return !(*this == other); } + /** Converts the value to a string. */ + const std::string& ToString() const { return 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; + + private: + std::string m_value; + }; /** * @brief Response type for #Azure::Storage::Files::Shares::ShareClient::CreatePermission. */ @@ -816,6 +843,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 /** @@ -2243,6 +2271,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { struct GetSharePermissionOptions final { std::string FilePermissionKey; + Nullable FilePermissionFormat; Nullable FileRequestIntent; }; static Response GetPermission( @@ -2353,6 +2382,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { struct SetDirectoryPropertiesOptions final { Nullable FilePermission; + Nullable FilePermissionFormat; Nullable FilePermissionKey; std::string FileAttributes; Nullable FileCreationTime; @@ -2434,6 +2464,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Nullable FileLastWriteTime; Nullable FileChangeTime; Nullable FilePermission; + Nullable FilePermissionFormat; Nullable FilePermissionKey; std::map Metadata; Nullable AllowTrailingDot; @@ -2460,6 +2491,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Nullable FileContentDisposition; std::map Metadata; Nullable FilePermission; + Nullable FilePermissionFormat; Nullable FilePermissionKey; std::string FileAttributes; Nullable FileCreationTime; @@ -2519,6 +2551,7 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { Nullable> FileContentMD5; Nullable FileContentDisposition; Nullable FilePermission; + Nullable FilePermissionFormat; Nullable FilePermissionKey; std::string FileAttributes; Nullable FileCreationTime; @@ -2715,6 +2748,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 d02d1e2065..5b259477e0 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 @@ -311,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 filePermissionKeyFormat is unspecified or + * explicitly set to SDDL format, the permission will be + * returned in SDDL format. + */ + Nullable FilePermissionFormat; }; /** @@ -318,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 filePermissionKeyFormat is unspecified or + * explicitly set to SDDL format, the permission will be + * returned in SDDL format. + */ + Nullable FilePermissionFormat; }; /** @@ -387,6 +401,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 filePermissionKeyFormat 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. */ @@ -443,6 +465,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 filePermissionKeyFormat 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. */ @@ -477,6 +507,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 filePermissionKeyFormat is unspecified or + * explicitly set to SDDL format format, the permission will be + * returned in SDDL format. + */ + Nullable FilePermissionFormat; }; /** @@ -590,10 +628,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 filePermissionKeyFormat 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. */ @@ -722,10 +769,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 filePermissionKeyFormat 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. */ 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 acc3e0a984..b8d07192c9 100644 --- a/sdk/storage/azure-storage-files-shares/src/rest_client.cpp +++ b/sdk/storage/azure-storage-files-shares/src/rest_client.cpp @@ -106,6 +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 FilePermissionFormat FilePermissionFormat::Sddl("sddl"); + const FilePermissionFormat FilePermissionFormat::Binary("binary"); FileAttributes::FileAttributes(const std::string& value) { const std::string delimiter = " | "; @@ -1443,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( @@ -1482,6 +1488,12 @@ namespace Azure { namespace Storage { namespace Files { namespace Shares { { request.SetHeader("x-ms-file-permission-key", options.FilePermissionKey); } + 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()) @@ -1500,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)); @@ -2075,6 +2091,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()); @@ -2902,6 +2924,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()); @@ -3004,6 +3032,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()); @@ -3472,6 +3506,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()); @@ -4495,6 +4535,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 cf91e30536..01f3660e58 100644 --- a/sdk/storage/azure-storage-files-shares/src/share_client.cpp +++ b/sdk/storage/azure-storage-files-shares/src/share_client.cpp @@ -321,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); @@ -331,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..434fe79c3b 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 @@ -294,6 +294,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 +357,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 +468,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..433a87c95d 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); 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 5c0dc9d457..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 @@ -780,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..b743d0ae5c 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,117 @@ 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 binaryPermission = "AQAUhGwAAACIAAAAAAAAABQAAAACAFgAAwAAAAAAFAD/" + "AR8AAQEAAAAAAAUSAAAAAAAYAP8BHwABAgAAAAAABSAAAAAgAgAAAAAkAKkAEgABBQAAAA" + "AABRUAAABZUbgXZnJdJWRjOwuMmS4AAQUAAAAAAAUVAAAAoGXPfnhLm1/nfIdwr/" + "1IAQEFAAAAAAAFFQAAAKBlz354S5tf53yHcAECAAA="; + // sddl format + { + auto permissionFormat = Files::Shares::Models::FilePermissionFormat::Sddl; + + // Set Properties + Files::Shares::SetDirectoryPropertiesOptions setOptions; + setOptions.FilePermissionFormat = permissionFormat; + setOptions.FilePermission = sddlPermission; + m_fileShareDirectoryClient->SetProperties( + Files::Shares::Models::FileSmbProperties(), setOptions); + auto permissionKey + = m_fileShareDirectoryClient->GetProperties().Value.SmbProperties.PermissionKey.Value(); + Files::Shares::GetSharePermissionOptions getOptions; + getOptions.FilePermissionFormat = permissionFormat; + auto 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; + // Set Properties + Files::Shares::SetDirectoryPropertiesOptions setOptions; + setOptions.FilePermissionFormat = permissionFormat; + setOptions.FilePermission = binaryPermission; + m_fileShareDirectoryClient->SetProperties( + Files::Shares::Models::FileSmbProperties(), setOptions); + auto permissionKey + = m_fileShareDirectoryClient->GetProperties().Value.SmbProperties.PermissionKey.Value(); + Files::Shares::GetSharePermissionOptions getOptions; + getOptions.FilePermissionFormat = permissionFormat; + auto 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 505f888c6b..024f79d3fd 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 @@ -1859,4 +1859,79 @@ 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(RandomString()); + + // 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); + } + // 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); + } + } }}} // namespace Azure::Storage::Test