From 71bdfddfee42903c04436530f60761b187b8eac9 Mon Sep 17 00:00:00 2001 From: JinmingHu Date: Fri, 18 Mar 2022 21:36:13 +0800 Subject: [PATCH] Fix bug where we cannot use SAS authentication to move file/directory (#3422) * Fix bug where we cannot use SAS authentication to move file/directory * CL * ut --- .../azure-storage-files-datalake/CHANGELOG.md | 2 + .../src/datalake_directory_client.cpp | 4 +- .../src/datalake_file_system_client.cpp | 4 +- .../ut/datalake_directory_client_test.cpp | 30 ++++++++++++++ .../ut/datalake_file_system_client_test.cpp | 40 +++++++++++++++++++ .../ut/datalake_file_system_client_test.hpp | 1 + 6 files changed, 77 insertions(+), 4 deletions(-) diff --git a/sdk/storage/azure-storage-files-datalake/CHANGELOG.md b/sdk/storage/azure-storage-files-datalake/CHANGELOG.md index 06a562642..bb5811174 100644 --- a/sdk/storage/azure-storage-files-datalake/CHANGELOG.md +++ b/sdk/storage/azure-storage-files-datalake/CHANGELOG.md @@ -8,6 +8,8 @@ ### Bugs Fixed +- Fixed a bug where file/directory renaming cannot be authenticated with SAS. + ### Other Changes ## 12.3.1 (2022-03-09) diff --git a/sdk/storage/azure-storage-files-datalake/src/datalake_directory_client.cpp b/sdk/storage/azure-storage-files-datalake/src/datalake_directory_client.cpp index 002e02197..1ac31d8f5 100644 --- a/sdk/storage/azure-storage-files-datalake/src/datalake_directory_client.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/datalake_directory_client.cpp @@ -115,7 +115,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { protocolLayerOptions.SourceIfNoneMatch = options.SourceAccessConditions.IfNoneMatch; protocolLayerOptions.SourceIfModifiedSince = options.SourceAccessConditions.IfModifiedSince; protocolLayerOptions.SourceIfUnmodifiedSince = options.SourceAccessConditions.IfUnmodifiedSince; - protocolLayerOptions.RenameSource = "/" + sourceDfsUrl.GetPath(); + protocolLayerOptions.RenameSource = "/" + sourceDfsUrl.GetRelativeUrl(); auto response = _detail::PathClient::Create( *m_pipeline, destinationDfsUrl, protocolLayerOptions, context); @@ -163,7 +163,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { protocolLayerOptions.SourceIfNoneMatch = options.SourceAccessConditions.IfNoneMatch; protocolLayerOptions.SourceIfModifiedSince = options.SourceAccessConditions.IfModifiedSince; protocolLayerOptions.SourceIfUnmodifiedSince = options.SourceAccessConditions.IfUnmodifiedSince; - protocolLayerOptions.RenameSource = "/" + sourceDfsUrl.GetPath(); + protocolLayerOptions.RenameSource = "/" + sourceDfsUrl.GetRelativeUrl(); auto response = _detail::PathClient::Create( *m_pipeline, destinationDfsUrl, protocolLayerOptions, context); diff --git a/sdk/storage/azure-storage-files-datalake/src/datalake_file_system_client.cpp b/sdk/storage/azure-storage-files-datalake/src/datalake_file_system_client.cpp index 85e42e751..c478c0cf5 100644 --- a/sdk/storage/azure-storage-files-datalake/src/datalake_file_system_client.cpp +++ b/sdk/storage/azure-storage-files-datalake/src/datalake_file_system_client.cpp @@ -352,7 +352,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { protocolLayerOptions.SourceIfNoneMatch = options.SourceAccessConditions.IfNoneMatch; protocolLayerOptions.SourceIfModifiedSince = options.SourceAccessConditions.IfModifiedSince; protocolLayerOptions.SourceIfUnmodifiedSince = options.SourceAccessConditions.IfUnmodifiedSince; - protocolLayerOptions.RenameSource = "/" + sourceDfsUrl.GetPath(); + protocolLayerOptions.RenameSource = "/" + sourceDfsUrl.GetRelativeUrl(); auto result = _detail::PathClient::Create( *m_pipeline, destinationDfsUrl, protocolLayerOptions, context); @@ -400,7 +400,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { protocolLayerOptions.SourceIfNoneMatch = options.SourceAccessConditions.IfNoneMatch; protocolLayerOptions.SourceIfModifiedSince = options.SourceAccessConditions.IfModifiedSince; protocolLayerOptions.SourceIfUnmodifiedSince = options.SourceAccessConditions.IfUnmodifiedSince; - protocolLayerOptions.RenameSource = "/" + sourceDfsUrl.GetPath(); + protocolLayerOptions.RenameSource = "/" + sourceDfsUrl.GetRelativeUrl(); auto result = _detail::PathClient::Create( *m_pipeline, destinationDfsUrl, protocolLayerOptions, context); diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_directory_client_test.cpp b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_directory_client_test.cpp index d333e2d2e..84f77e178 100644 --- a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_directory_client_test.cpp +++ b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_directory_client_test.cpp @@ -167,6 +167,36 @@ namespace Azure { namespace Storage { namespace Test { EXPECT_THROW(newFileClient.GetProperties(), StorageException); } + TEST_F(DataLakeDirectoryClientTest, RenameFileSasAuthentication_LIVEONLY_) + { + const std::string testName(GetTestName()); + const std::string sourceFilename = testName + "1"; + const std::string destinationFilename = testName + "2"; + auto baseDirectoryClient = m_fileSystemClient->GetDirectoryClient("based"); + baseDirectoryClient.Create(); + auto fileClient = baseDirectoryClient.GetFileClient(sourceFilename); + fileClient.CreateIfNotExists(); + + Files::DataLake::DataLakeDirectoryClient directoryClientSas( + Files::DataLake::_detail::GetDfsUrlFromUrl(baseDirectoryClient.GetUrl()) + GetSas()); + directoryClientSas.RenameFile(sourceFilename, destinationFilename); + EXPECT_THROW( + baseDirectoryClient.GetFileClient(sourceFilename).GetProperties(), StorageException); + EXPECT_NO_THROW(m_fileSystemClient->GetFileClient(destinationFilename).GetProperties()); + + const std::string sourceDirectoryName = testName + "3"; + const std::string destinationDirectoryName = testName + "4"; + auto directoryClient = baseDirectoryClient.GetSubdirectoryClient(sourceDirectoryName); + directoryClient.CreateIfNotExists(); + + directoryClientSas.RenameSubdirectory(sourceDirectoryName, destinationDirectoryName); + EXPECT_THROW( + baseDirectoryClient.GetSubdirectoryClient(sourceDirectoryName).GetProperties(), + StorageException); + EXPECT_NO_THROW( + m_fileSystemClient->GetDirectoryClient(destinationDirectoryName).GetProperties()); + } + TEST_F(DataLakeDirectoryClientTest, RenameFileAccessCondition) { const std::string testName(GetTestName()); diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_system_client_test.cpp b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_system_client_test.cpp index c10849c15..615e1096d 100644 --- a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_system_client_test.cpp +++ b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_system_client_test.cpp @@ -18,6 +18,18 @@ namespace Azure { namespace Storage { namespace Test { const size_t PathTestSize = 5; + std::string DataLakeFileSystemClientTest::GetSas() + { + Sas::DataLakeSasBuilder sasBuilder; + sasBuilder.Protocol = Sas::SasProtocol::HttpsAndHttp; + sasBuilder.ExpiresOn = std::chrono::system_clock::now() + std::chrono::hours(72); + sasBuilder.FileSystemName = m_fileSystemName; + sasBuilder.Resource = Sas::DataLakeSasResource::FileSystem; + sasBuilder.SetPermissions(Sas::DataLakeFileSystemSasPermissions::All); + return sasBuilder.GenerateSasToken( + *_internal::ParseConnectionString(AdlsGen2ConnectionString()).KeyCredential); + } + void DataLakeFileSystemClientTest::CreateDirectoryList() { std::string const directoryName(GetFileSystemValidName()); @@ -555,4 +567,32 @@ namespace Azure { namespace Storage { namespace Test { EXPECT_THROW(newDirectoryClient.GetProperties(), StorageException); } + TEST_F(DataLakeFileSystemClientTest, RenameFileSasAuthentication_LIVEONLY_) + { + const std::string testName(GetTestName()); + const std::string sourceFilename = testName + "1"; + const std::string destinationFilename = testName + "2"; + auto fileClient = m_fileSystemClient->GetFileClient(sourceFilename); + fileClient.CreateIfNotExists(); + + Files::DataLake::DataLakeFileSystemClient fileSystemClientSas( + Files::DataLake::_detail::GetDfsUrlFromUrl(m_fileSystemClient->GetUrl()) + GetSas()); + fileSystemClientSas.RenameFile(sourceFilename, destinationFilename); + EXPECT_THROW( + m_fileSystemClient->GetFileClient(sourceFilename).GetProperties(), StorageException); + EXPECT_NO_THROW(m_fileSystemClient->GetFileClient(destinationFilename).GetProperties()); + + const std::string sourceDirectoryName = testName + "3"; + const std::string destinationDirectoryName = testName + "4"; + auto directoryClient = m_fileSystemClient->GetDirectoryClient(sourceDirectoryName); + directoryClient.CreateIfNotExists(); + + fileSystemClientSas.RenameDirectory(sourceDirectoryName, destinationDirectoryName); + EXPECT_THROW( + m_fileSystemClient->GetDirectoryClient(sourceDirectoryName).GetProperties(), + StorageException); + EXPECT_NO_THROW( + m_fileSystemClient->GetDirectoryClient(destinationDirectoryName).GetProperties()); + } + }}} // namespace Azure::Storage::Test diff --git a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_system_client_test.hpp b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_system_client_test.hpp index 8d55c465e..fe8b045bf 100644 --- a/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_system_client_test.hpp +++ b/sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_system_client_test.hpp @@ -12,6 +12,7 @@ namespace Azure { namespace Storage { namespace Test { protected: void SetUp(); void TearDown(); + std::string GetSas(); void CreateDirectoryList(); std::vector ListAllPaths(