Added support for Set/GetAccessPolicy in DataLakeFileSystemClient (#1411)

* Added support for Set/GetAccessPolicy in FileSystemClient

* Address review comments

* Changed Private to None.
This commit is contained in:
Kan Tang 2021-01-21 03:55:48 -08:00 committed by GitHub
parent 473c7ee0b0
commit 13afe30353
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 218 additions and 0 deletions

View File

@ -5,6 +5,7 @@
### New Features
- Added `Owner`, `Permissions`, and `Group` to `GetDataLakePathAccessControlResult`.
- Added support for `GetAccessPolicy` and `SetAccessPolicy` in `DataLakeFileSystemClient`.
### Breaking Changes

View File

@ -177,6 +177,31 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
bool recursive,
const ListPathsSinglePageOptions& options = ListPathsSinglePageOptions()) const;
/**
* @brief Gets the permissions for this file system. The permissions indicate whether
* file system data may be accessed publicly.
*
* @param options Optional parameters to execute this function.
* @return A GetDataLakeFileSystemAccessPolicyResult describing the container's access policy.
* @remark This request is sent to blob endpoint.
*/
Azure::Core::Response<Models::GetDataLakeFileSystemAccessPolicyResult> GetAccessPolicy(
const GetDataLakeFileSystemAccessPolicyOptions& options
= GetDataLakeFileSystemAccessPolicyOptions()) const;
/**
* @brief Sets the permissions for the specified file system. The permissions indicate
* whether file system's data may be accessed publicly.
*
* @param options Optional
* parameters to execute this function.
* @return A SetDataLakeFileSystemAccessPolicyResult describing the updated file system.
* @remark This request is sent to blob endpoint.
*/
Azure::Core::Response<Models::SetDataLakeFileSystemAccessPolicyResult> SetAccessPolicy(
const SetDataLakeFileSystemAccessPolicyOptions& options
= SetDataLakeFileSystemAccessPolicyOptions()) const;
private:
Azure::Core::Http::Url m_dfsUrl;
Blobs::BlobContainerClient m_blobContainerClient;

View File

@ -12,6 +12,7 @@
#include <azure/storage/blobs/blob_options.hpp>
#include <azure/storage/common/access_conditions.hpp>
#include "azure/storage/files/datalake/datalake_responses.hpp"
#include "azure/storage/files/datalake/protocol/datalake_rest_client.hpp"
namespace Azure { namespace Storage { namespace Files { namespace DataLake {
@ -208,6 +209,50 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
Azure::Core::Nullable<std::string> Directory;
};
/**
* @brief Optional parameters for FileSystemClient::GetAccessPolicy.
*/
struct GetDataLakeFileSystemAccessPolicyOptions
{
/**
* @brief Context for cancelling long running operations.
*/
Azure::Core::Context Context;
/**
* @brief Optional conditions that must be met to perform this operation.
*/
LeaseAccessConditions AccessConditions;
};
/**
* @brief Optional parameters for FileSystemClient::SetAccessPolicy.
*/
struct SetDataLakeFileSystemAccessPolicyOptions
{
/**
* @brief Context for cancelling long running operations.
*/
Azure::Core::Context Context;
/**
* @brief Specifies whether data in the file system may be accessed publicly and the level
* of access.
*/
Models::PublicAccessType AccessType = Models::PublicAccessType::None;
/**
* @brief Stored access policies that you can use to provide fine grained control over
* file system permissions.
*/
std::vector<Models::DataLakeSignedIdentifier> SignedIdentifiers;
/**
* @brief Optional conditions that must be met to perform this operation.
*/
FileSystemAccessConditions AccessConditions;
};
/**
* @brief Optional parameters for PathClient::Append
*/

View File

@ -22,6 +22,17 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { nam
// FileSystemClient models:
using ListPathsSinglePageResult = FileSystemListPathsResult;
using DataLakeSignedIdentifier = Blobs::Models::BlobSignedIdentifier;
struct GetDataLakeFileSystemAccessPolicyResult
{
PublicAccessType AccessType = PublicAccessType::None;
std::string ETag;
Azure::Core::DateTime LastModified;
std::vector<DataLakeSignedIdentifier> SignedIdentifiers;
}; // struct GetDataLakeFileSystemAccessPolicyResult
using SetDataLakeFileSystemAccessPolicyResult = Blobs::Models::SetBlobContainerAccessPolicyResult;
struct GetDataLakeFileSystemPropertiesResult
{

View File

@ -214,6 +214,22 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
std::vector<Models::FileSystem> Filesystems;
};
class PublicAccessType {
public:
PublicAccessType() = default;
explicit PublicAccessType(std::string value) : m_value(std::move(value)) {}
bool operator==(const PublicAccessType& other) const { return m_value == other.m_value; }
bool operator!=(const PublicAccessType& other) const { return !(*this == other); }
const std::string& Get() const { return m_value; }
const static PublicAccessType FileSystem;
const static PublicAccessType Path;
const static PublicAccessType None;
private:
std::string m_value;
}; // extensible enum PublicAccessType
// The value must be "account" for all account operations.
class AccountResourceType {
public:

View File

@ -304,4 +304,71 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake {
m_dfsUrl, *m_pipeline, options.Context, protocolLayerOptions);
}
Azure::Core::Response<Models::GetDataLakeFileSystemAccessPolicyResult>
DataLakeFileSystemClient::GetAccessPolicy(
const GetDataLakeFileSystemAccessPolicyOptions& options) const
{
Blobs::GetBlobContainerAccessPolicyOptions blobOptions;
blobOptions.Context = options.Context;
blobOptions.AccessConditions.LeaseId = options.AccessConditions.LeaseId;
auto result = m_blobContainerClient.GetAccessPolicy(blobOptions);
Models::GetDataLakeFileSystemAccessPolicyResult ret;
if (result->AccessType == Blobs::Models::PublicAccessType::BlobContainer)
{
ret.AccessType = Models::PublicAccessType::FileSystem;
}
else if (result->AccessType == Blobs::Models::PublicAccessType::Blob)
{
ret.AccessType = Models::PublicAccessType::Path;
}
else if (result->AccessType == Blobs::Models::PublicAccessType::Private)
{
ret.AccessType = Models::PublicAccessType::None;
}
else
{
ret.AccessType = Models::PublicAccessType(result->AccessType.Get());
}
ret.ETag = std::move(result->ETag);
ret.LastModified = std::move(result->LastModified);
ret.SignedIdentifiers = std::move(result->SignedIdentifiers);
return Azure::Core::Response<Models::GetDataLakeFileSystemAccessPolicyResult>(
std::move(ret), result.ExtractRawResponse());
}
Azure::Core::Response<Models::SetDataLakeFileSystemAccessPolicyResult>
DataLakeFileSystemClient::SetAccessPolicy(
const SetDataLakeFileSystemAccessPolicyOptions& options) const
{
Blobs::SetBlobContainerAccessPolicyOptions blobOptions;
blobOptions.Context = options.Context;
blobOptions.AccessConditions.IfModifiedSince = options.AccessConditions.IfModifiedSince;
blobOptions.AccessConditions.IfUnmodifiedSince = options.AccessConditions.IfUnmodifiedSince;
blobOptions.AccessConditions.LeaseId = options.AccessConditions.LeaseId;
blobOptions.SignedIdentifiers = options.SignedIdentifiers;
if (options.AccessType == Models::PublicAccessType::FileSystem)
{
blobOptions.AccessType = Blobs::Models::PublicAccessType::BlobContainer;
}
else if (options.AccessType == Models::PublicAccessType::Path)
{
blobOptions.AccessType = Blobs::Models::PublicAccessType::Blob;
}
else if (options.AccessType == Models::PublicAccessType::None)
{
blobOptions.AccessType = Blobs::Models::PublicAccessType::Private;
}
else
{
blobOptions.AccessType = Blobs::Models::PublicAccessType(options.AccessType.Get());
}
auto result = m_blobContainerClient.SetAccessPolicy(blobOptions);
Models::SetDataLakeFileSystemAccessPolicyResult ret;
ret.ETag = std::move(result->ETag);
ret.LastModified = std::move(result->LastModified);
return Azure::Core::Response<Models::SetDataLakeFileSystemAccessPolicyResult>(
std::move(ret), result.ExtractRawResponse());
}
}}}} // namespace Azure::Storage::Files::DataLake

View File

@ -16,6 +16,10 @@ namespace Azure { namespace Storage { namespace Files { namespace DataLake { nam
const PathExpiryOptions PathExpiryOptions::RelativeToNow("RelativeToNow");
const PathExpiryOptions PathExpiryOptions::Absolute("Absolute");
const PublicAccessType PublicAccessType::FileSystem("FileSystem");
const PublicAccessType PublicAccessType::Path("Path");
const PublicAccessType PublicAccessType::None("None");
const AccountResourceType AccountResourceType::Account("account");
const PathResourceType PathResourceType::Directory("directory");

View File

@ -347,4 +347,53 @@ namespace Azure { namespace Storage { namespace Test {
EXPECT_NO_THROW(clientSecretClient.Delete());
}
}
TEST_F(DataLakeFileSystemClientTest, GetSetAccessPolicy)
{
auto fileSystem = Files::DataLake::DataLakeFileSystemClient::CreateFromConnectionString(
AdlsGen2ConnectionString(), LowercaseRandomString());
fileSystem.Create();
Files::DataLake::SetDataLakeFileSystemAccessPolicyOptions options;
options.AccessType = Files::DataLake::Models::PublicAccessType::Path;
Files::DataLake::Models::DataLakeSignedIdentifier identifier;
identifier.Id = RandomString(64);
identifier.StartsOn = std::chrono::system_clock::now() - std::chrono::minutes(1);
identifier.ExpiresOn = std::chrono::system_clock::now() + std::chrono::minutes(1);
identifier.Permissions = "r";
options.SignedIdentifiers.emplace_back(identifier);
identifier.Id = RandomString(64);
identifier.StartsOn = std::chrono::system_clock::now() - std::chrono::minutes(2);
identifier.ExpiresOn = std::chrono::system_clock::now() + std::chrono::minutes(2);
identifier.Permissions = "racwdxlt";
options.SignedIdentifiers.emplace_back(identifier);
auto ret = fileSystem.SetAccessPolicy(options);
EXPECT_FALSE(ret->ETag.empty());
EXPECT_TRUE(IsValidTime(ret->LastModified));
auto ret2 = fileSystem.GetAccessPolicy();
EXPECT_EQ(ret2->ETag, ret->ETag);
EXPECT_EQ(ret2->LastModified, ret->LastModified);
EXPECT_EQ(ret2->AccessType, options.AccessType);
for (size_t i = 0; i < ret2->SignedIdentifiers.size(); ++i)
{
EXPECT_EQ(ret2->SignedIdentifiers[i].StartsOn, options.SignedIdentifiers[i].StartsOn);
EXPECT_EQ(ret2->SignedIdentifiers[i].ExpiresOn, options.SignedIdentifiers[i].ExpiresOn);
EXPECT_EQ(ret2->SignedIdentifiers[i].Id, options.SignedIdentifiers[i].Id);
EXPECT_EQ(ret2->SignedIdentifiers[i].Permissions, options.SignedIdentifiers[i].Permissions);
}
options.AccessType = Files::DataLake::Models::PublicAccessType::FileSystem;
EXPECT_NO_THROW(fileSystem.SetAccessPolicy(options));
ret2 = fileSystem.GetAccessPolicy();
EXPECT_EQ(ret2->AccessType, options.AccessType);
// options.AccessType = Files::DataLake::Models::PublicAccessType::Private;
// EXPECT_NO_THROW(fileSystem.SetAccessPolicy(options));
// ret2 = fileSystem.GetAccessPolicy();
// EXPECT_EQ(ret2->AccessType, options.AccessType.GetValue());
fileSystem.Delete();
}
}}} // namespace Azure::Storage::Test