Skip to content

Commit 6f0dfff

Browse files
committed
Storage/feature/stg87-hns encryption context (Azure#4383)
* hns_encryption_context
1 parent 46315c5 commit 6f0dfff

File tree

7 files changed

+68
-0
lines changed

7 files changed

+68
-0
lines changed

sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_options.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,14 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
634634
* Specify the access condition for the path.
635635
*/
636636
PathAccessConditions AccessConditions;
637+
638+
/**
639+
* Encryption context of the file. Encryption context is metadata that is not encrypted when
640+
* stored on the file. The primary application of this field is to store non-encrypted data that
641+
* can be used to derive the customer-provided key for a file.
642+
* Not applicable for directories.
643+
*/
644+
Azure::Nullable<std::string> EncryptionContext;
637645
};
638646

639647
/**

sdk/storage/azure-storage-files-datalake/inc/azure/storage/files/datalake/datalake_responses.hpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,14 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
266266
*/
267267
Nullable<std::string> EncryptionScope;
268268

269+
/**
270+
* Encryption context of the file. Encryption context is metadata that is not encrypted when
271+
* stored on the file. The primary application of this field is to store non-encrypted data
272+
* that can be used to derive the customer-provided key for a file.
273+
* Not applicable for directories.
274+
*/
275+
Nullable<std::string> EncryptionContext;
276+
269277
/**
270278
* The creation time of the path.
271279
*/
@@ -349,6 +357,14 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
349357
*/
350358
Nullable<std::string> EncryptionScope;
351359

360+
/**
361+
* Encryption context of the file. Encryption context is metadata that is not encrypted when
362+
* stored on the file. The primary application of this field is to store non-encrypted data
363+
* that can be used to derive the customer-provided key for a file.
364+
* Not applicable for directories.
365+
*/
366+
Nullable<std::string> EncryptionContext;
367+
352368
/**
353369
* The copy ID of the path, if the path is created from a copy operation.
354370
*/
@@ -664,6 +680,14 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
664680
* The encryption scope.
665681
*/
666682
Azure::Nullable<std::string> EncryptionScope;
683+
684+
/*
685+
* Encryption context of the file. Encryption context is metadata that is not encrypted when
686+
* stored on the file. The primary application of this field is to store non-encrypted data
687+
* that can be used to derive the customer-provided key for a file.
688+
* Not applicable for directories.
689+
*/
690+
Nullable<std::string> EncryptionContext;
667691
};
668692

669693
/**

sdk/storage/azure-storage-files-datalake/src/datalake_file_client.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
211211
ret.Details.EncryptionKeySha256 = std::move(response.Value.Details.EncryptionKeySha256);
212212
ret.Details.EncryptionScope = std::move(response.Value.Details.EncryptionScope);
213213
ret.Details.IsServerEncrypted = response.Value.Details.IsServerEncrypted;
214+
ret.Details.EncryptionContext
215+
= Azure::Core::Http::_internal::HttpShared::GetHeaderOrEmptyString(
216+
response.RawResponse->GetHeaders(), _detail::EncryptionContextHeaderName);
214217
return Azure::Response<Models::DownloadFileResult>(
215218
std::move(ret), std::move(response.RawResponse));
216219
}

sdk/storage/azure-storage-files-datalake/src/datalake_file_system_client.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
292292
item.Group = std::move(path.Group);
293293
item.Permissions = std::move(path.Permissions);
294294
item.EncryptionScope = std::move(path.EncryptionScope);
295+
item.EncryptionContext = std::move(path.EncryptionContext);
295296
item.ETag = std::move(path.ETag);
296297
if (path.CreatedOn.HasValue())
297298
{

sdk/storage/azure-storage-files-datalake/src/datalake_path_client.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
208208
protocolLayerOptions.Owner = options.Owner;
209209
protocolLayerOptions.Group = options.Group;
210210
protocolLayerOptions.ProposedLeaseId = options.LeaseId;
211+
protocolLayerOptions.EncryptionContext = options.EncryptionContext;
211212
if (options.Acls.HasValue())
212213
{
213214
protocolLayerOptions.Acl = Models::Acl::SerializeAcls(options.Acls.Value());
@@ -341,6 +342,8 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
341342
ret.VersionId = std::move(response.Value.VersionId);
342343
ret.IsCurrentVersion = std::move(response.Value.IsCurrentVersion);
343344
ret.IsDirectory = _detail::MetadataIncidatesIsDirectory(ret.Metadata);
345+
ret.EncryptionContext = Azure::Core::Http::_internal::HttpShared::GetHeaderOrEmptyString(
346+
response.RawResponse->GetHeaders(), _detail::EncryptionContextHeaderName);
344347
return Azure::Response<Models::PathProperties>(std::move(ret), std::move(response.RawResponse));
345348
}
346349

sdk/storage/azure-storage-files-datalake/src/private/datalake_constants.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { nam
1111
constexpr static const char* DataLakePathNotFound = "PathNotFound";
1212
constexpr static const char* DataLakePathAlreadyExists = "PathAlreadyExists";
1313
constexpr static const char* DataLakeIsDirectoryKey = "hdi_isFolder";
14+
constexpr static const char* EncryptionContextHeaderName = "x-ms-encryption-context";
1415

1516
}}}}} // namespace Azure::Storage::Files::DataLake::_detail

sdk/storage/azure-storage-files-datalake/test/ut/datalake_file_client_test.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,34 @@ namespace Azure { namespace Storage { namespace Test {
466466
}
467467
}
468468

469+
TEST_F(DataLakeFileClientTest, DISABLED_CreateWithEncryptionContext)
470+
{
471+
std::string encryptionContext = "encryptionContext";
472+
const std::string fileName = RandomString();
473+
auto fileClient = m_fileSystemClient->GetFileClient(fileName);
474+
Files::DataLake::CreateFileOptions options;
475+
options.EncryptionContext = encryptionContext;
476+
// Assert Create
477+
EXPECT_NO_THROW(fileClient.Create(options));
478+
// Assert GetProperties
479+
auto properties = fileClient.GetProperties();
480+
EXPECT_TRUE(properties.Value.EncryptionContext.HasValue());
481+
EXPECT_EQ(encryptionContext, properties.Value.EncryptionContext.Value());
482+
// Assert Download
483+
auto downloadResult = fileClient.Download();
484+
EXPECT_TRUE(downloadResult.Value.Details.EncryptionContext.HasValue());
485+
EXPECT_EQ(encryptionContext, downloadResult.Value.Details.EncryptionContext.Value());
486+
// Assert ListPaths
487+
auto paths = m_fileSystemClient->ListPaths(false).Paths;
488+
auto iter = std::find_if(
489+
paths.begin(), paths.end(), [&fileName](const Files::DataLake::Models::PathItem& path) {
490+
return path.Name == fileName;
491+
});
492+
EXPECT_NE(paths.end(), iter);
493+
EXPECT_TRUE(iter->EncryptionContext.HasValue());
494+
EXPECT_EQ(encryptionContext, iter->EncryptionContext.Value());
495+
}
496+
469497
TEST_F(DataLakeFileClientTest, FileReadReturns)
470498
{
471499
const int32_t bufferSize = 20;

0 commit comments

Comments
 (0)