Skip to content

Commit

Permalink
feat(storage): per-operation options / ObjectAccessControl
Browse files Browse the repository at this point in the history
Support per-operation `google::cloud::Options` for operations related to
`ObjectAccessControl` resources.
  • Loading branch information
coryan committed Jun 8, 2022
1 parent e6c39c1 commit 3ba8eb2
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 8 deletions.
7 changes: 7 additions & 0 deletions google/cloud/storage/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -1938,6 +1938,7 @@ class Client {
StatusOr<std::vector<ObjectAccessControl>> ListObjectAcl(
std::string const& bucket_name, std::string const& object_name,
Options&&... options) {
auto const span = MakeSpan(std::forward<Options>(options)...);
internal::ListObjectAclRequest request(bucket_name, object_name);
request.set_multiple_options(std::forward<Options>(options)...);
auto result = raw_client_->ListObjectAcl(request);
Expand Down Expand Up @@ -1975,6 +1976,7 @@ class Client {
std::string const& entity,
std::string const& role,
Options&&... options) {
auto const span = MakeSpan(std::forward<Options>(options)...);
internal::CreateObjectAclRequest request(bucket_name, object_name, entity,
role);
request.set_multiple_options(std::forward<Options>(options)...);
Expand Down Expand Up @@ -2005,6 +2007,7 @@ class Client {
Status DeleteObjectAcl(std::string const& bucket_name,
std::string const& object_name,
std::string const& entity, Options&&... options) {
auto const span = MakeSpan(std::forward<Options>(options)...);
internal::DeleteObjectAclRequest request(bucket_name, object_name, entity);
request.set_multiple_options(std::forward<Options>(options)...);
return raw_client_->DeleteObjectAcl(request).status();
Expand Down Expand Up @@ -2033,6 +2036,7 @@ class Client {
std::string const& object_name,
std::string const& entity,
Options&&... options) {
auto const span = MakeSpan(std::forward<Options>(options)...);
internal::GetObjectAclRequest request(bucket_name, object_name, entity);
request.set_multiple_options(std::forward<Options>(options)...);
return raw_client_->GetObjectAcl(request);
Expand Down Expand Up @@ -2072,6 +2076,7 @@ class Client {
std::string const& object_name,
ObjectAccessControl const& acl,
Options&&... options) {
auto const span = MakeSpan(std::forward<Options>(options)...);
internal::UpdateObjectAclRequest request(bucket_name, object_name,
acl.entity(), acl.role());
request.set_multiple_options(std::forward<Options>(options)...);
Expand Down Expand Up @@ -2119,6 +2124,7 @@ class Client {
std::string const& bucket_name, std::string const& object_name,
std::string const& entity, ObjectAccessControl const& original_acl,
ObjectAccessControl const& new_acl, Options&&... options) {
auto const span = MakeSpan(std::forward<Options>(options)...);
internal::PatchObjectAclRequest request(bucket_name, object_name, entity,
original_acl, new_acl);
request.set_multiple_options(std::forward<Options>(options)...);
Expand Down Expand Up @@ -2164,6 +2170,7 @@ class Client {
std::string const& bucket_name, std::string const& object_name,
std::string const& entity, ObjectAccessControlPatchBuilder const& builder,
Options&&... options) {
auto const span = MakeSpan(std::forward<Options>(options)...);
internal::PatchObjectAclRequest request(bucket_name, object_name, entity,
builder);
request.set_multiple_options(std::forward<Options>(options)...);
Expand Down
36 changes: 28 additions & 8 deletions google/cloud/storage/client_object_acl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ namespace cloud {
namespace storage {
namespace {

using ::google::cloud::internal::CurrentOptions;
using ::google::cloud::storage::testing::canonical_errors::TransientError;
using ::testing::Return;
using ms = std::chrono::milliseconds;
Expand Down Expand Up @@ -59,14 +60,17 @@ TEST_F(ObjectAccessControlsTest, ListObjectAcl) {
.WillOnce(
Return(StatusOr<internal::ListObjectAclResponse>(TransientError())))
.WillOnce([&expected](internal::ListObjectAclRequest const& r) {
EXPECT_EQ(CurrentOptions().get<AuthorityOption>(), "a-default");
EXPECT_EQ(CurrentOptions().get<UserProjectOption>(), "u-p-test");
EXPECT_EQ("test-bucket", r.bucket_name());
EXPECT_EQ("test-object", r.object_name());

return make_status_or(internal::ListObjectAclResponse{expected});
});
auto client = ClientForMock();
StatusOr<std::vector<ObjectAccessControl>> actual =
client.ListObjectAcl("test-bucket", "test-object");
client.ListObjectAcl("test-bucket", "test-object",
Options{}.set<UserProjectOption>("u-p-test"));
ASSERT_STATUS_OK(actual);
EXPECT_EQ(expected, *actual);
}
Expand Down Expand Up @@ -104,6 +108,8 @@ TEST_F(ObjectAccessControlsTest, CreateObjectAcl) {
EXPECT_CALL(*mock_, CreateObjectAcl)
.WillOnce(Return(StatusOr<ObjectAccessControl>(TransientError())))
.WillOnce([&expected](internal::CreateObjectAclRequest const& r) {
EXPECT_EQ(CurrentOptions().get<AuthorityOption>(), "a-default");
EXPECT_EQ(CurrentOptions().get<UserProjectOption>(), "u-p-test");
EXPECT_EQ("test-bucket", r.bucket_name());
EXPECT_EQ("test-object", r.object_name());
EXPECT_EQ("user-test-user-1", r.entity());
Expand All @@ -114,7 +120,8 @@ TEST_F(ObjectAccessControlsTest, CreateObjectAcl) {
auto client = ClientForMock();
StatusOr<ObjectAccessControl> actual =
client.CreateObjectAcl("test-bucket", "test-object", "user-test-user-1",
ObjectAccessControl::ROLE_READER());
ObjectAccessControl::ROLE_READER(),
Options{}.set<UserProjectOption>("u-p-test"));
ASSERT_STATUS_OK(actual);
// Compare just a few fields because the values for most of the fields are
// hard to predict when testing against the production environment.
Expand Down Expand Up @@ -159,14 +166,17 @@ TEST_F(ObjectAccessControlsTest, DeleteObjectAcl) {
EXPECT_CALL(*mock_, DeleteObjectAcl)
.WillOnce(Return(StatusOr<internal::EmptyResponse>(TransientError())))
.WillOnce([](internal::DeleteObjectAclRequest const& r) {
EXPECT_EQ(CurrentOptions().get<AuthorityOption>(), "a-default");
EXPECT_EQ(CurrentOptions().get<UserProjectOption>(), "u-p-test");
EXPECT_EQ("test-bucket", r.bucket_name());
EXPECT_EQ("test-object", r.object_name());
EXPECT_EQ("user-test-user", r.entity());

return make_status_or(internal::EmptyResponse{});
});
auto client = ClientForMock();
client.DeleteObjectAcl("test-bucket", "test-object", "user-test-user");
client.DeleteObjectAcl("test-bucket", "test-object", "user-test-user",
Options{}.set<UserProjectOption>("u-p-test"));
SUCCEED();
}

Expand Down Expand Up @@ -207,6 +217,8 @@ TEST_F(ObjectAccessControlsTest, GetObjectAcl) {
EXPECT_CALL(*mock_, GetObjectAcl)
.WillOnce(Return(StatusOr<ObjectAccessControl>(TransientError())))
.WillOnce([&expected](internal::GetObjectAclRequest const& r) {
EXPECT_EQ(CurrentOptions().get<AuthorityOption>(), "a-default");
EXPECT_EQ(CurrentOptions().get<UserProjectOption>(), "u-p-test");
EXPECT_EQ("test-bucket", r.bucket_name());
EXPECT_EQ("test-object", r.object_name());
EXPECT_EQ("user-test-user-1", r.entity());
Expand All @@ -215,7 +227,8 @@ TEST_F(ObjectAccessControlsTest, GetObjectAcl) {
});
auto client = ClientForMock();
StatusOr<ObjectAccessControl> actual =
client.GetObjectAcl("test-bucket", "test-object", "user-test-user-1");
client.GetObjectAcl("test-bucket", "test-object", "user-test-user-1",
Options{}.set<UserProjectOption>("u-p-test"));
ASSERT_STATUS_OK(actual);
EXPECT_EQ(expected, *actual);
}
Expand Down Expand Up @@ -256,6 +269,8 @@ TEST_F(ObjectAccessControlsTest, UpdateObjectAcl) {
EXPECT_CALL(*mock_, UpdateObjectAcl)
.WillOnce(Return(StatusOr<ObjectAccessControl>(TransientError())))
.WillOnce([expected](internal::UpdateObjectAclRequest const& r) {
EXPECT_EQ(CurrentOptions().get<AuthorityOption>(), "a-default");
EXPECT_EQ(CurrentOptions().get<UserProjectOption>(), "u-p-test");
EXPECT_EQ("test-bucket", r.bucket_name());
EXPECT_EQ("test-object", r.object_name());
EXPECT_EQ("user-test-user", r.entity());
Expand All @@ -266,7 +281,9 @@ TEST_F(ObjectAccessControlsTest, UpdateObjectAcl) {
ObjectAccessControl acl =
ObjectAccessControl().set_role("OWNER").set_entity("user-test-user");
auto client = ClientForMock();
auto actual = client.UpdateObjectAcl("test-bucket", "test-object", acl);
auto actual =
client.UpdateObjectAcl("test-bucket", "test-object", acl,
Options{}.set<UserProjectOption>("u-p-test"));
ASSERT_STATUS_OK(actual);
EXPECT_EQ(expected, *actual);
}
Expand Down Expand Up @@ -313,6 +330,8 @@ TEST_F(ObjectAccessControlsTest, PatchObjectAcl) {
EXPECT_CALL(*mock_, PatchObjectAcl)
.WillOnce(Return(StatusOr<ObjectAccessControl>(TransientError())))
.WillOnce([result](internal::PatchObjectAclRequest const& r) {
EXPECT_EQ(CurrentOptions().get<AuthorityOption>(), "a-default");
EXPECT_EQ(CurrentOptions().get<UserProjectOption>(), "u-p-test");
EXPECT_EQ("test-bucket", r.bucket_name());
EXPECT_EQ("test-object", r.object_name());
EXPECT_EQ("user-test-user-1", r.entity());
Expand All @@ -323,9 +342,10 @@ TEST_F(ObjectAccessControlsTest, PatchObjectAcl) {
return make_status_or(result);
});
auto client = ClientForMock();
auto actual = client.PatchObjectAcl(
"test-bucket", "test-object", "user-test-user-1",
ObjectAccessControlPatchBuilder().set_role("OWNER"));
auto actual =
client.PatchObjectAcl("test-bucket", "test-object", "user-test-user-1",
ObjectAccessControlPatchBuilder().set_role("OWNER"),
Options{}.set<UserProjectOption>("u-p-test"));
ASSERT_STATUS_OK(actual);
EXPECT_EQ(result, *actual);
}
Expand Down

0 comments on commit 3ba8eb2

Please sign in to comment.