Skip to content

Commit

Permalink
feat(GCS+gRPC): implement BucketAccessControl parser
Browse files Browse the repository at this point in the history
  • Loading branch information
coryan committed Dec 20, 2021
1 parent b2fe267 commit dc13c43
Show file tree
Hide file tree
Showing 8 changed files with 245 additions and 0 deletions.
3 changes: 3 additions & 0 deletions google/cloud/storage/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ if (GOOGLE_CLOUD_CPP_STORAGE_ENABLE_GRPC)
google_cloud_cpp_storage_grpc
grpc_plugin.cc
grpc_plugin.h
internal/grpc_bucket_access_control_parser.cc
internal/grpc_bucket_access_control_parser.h
internal/grpc_client.cc
internal/grpc_client.h
internal/grpc_configure_client_context.h
Expand Down Expand Up @@ -580,6 +582,7 @@ if (GOOGLE_CLOUD_CPP_STORAGE_ENABLE_GRPC)
if (BUILD_TESTING)
set(storage_client_grpc_unit_tests
# cmake-format: sort
internal/grpc_bucket_access_control_parser_test.cc
internal/grpc_client_failures_test.cc
internal/grpc_client_insert_object_media_test.cc
internal/grpc_client_read_object_test.cc
Expand Down
2 changes: 2 additions & 0 deletions google/cloud/storage/bucket_access_control.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ namespace storage {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
namespace internal {
struct BucketAccessControlParser;
struct GrpcBucketAccessControlParser;
} // namespace internal

/**
Expand Down Expand Up @@ -82,6 +83,7 @@ class BucketAccessControl : private internal::AccessControlCommon {
}

friend struct internal::BucketAccessControlParser;
friend struct internal::GrpcBucketAccessControlParser;
};

std::ostream& operator<<(std::ostream& os, BucketAccessControl const& rhs);
Expand Down
2 changes: 2 additions & 0 deletions google/cloud/storage/google_cloud_cpp_storage_grpc.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

google_cloud_cpp_storage_grpc_hdrs = [
"grpc_plugin.h",
"internal/grpc_bucket_access_control_parser.h",
"internal/grpc_client.h",
"internal/grpc_configure_client_context.h",
"internal/grpc_object_access_control_parser.h",
Expand All @@ -34,6 +35,7 @@ google_cloud_cpp_storage_grpc_hdrs = [

google_cloud_cpp_storage_grpc_srcs = [
"grpc_plugin.cc",
"internal/grpc_bucket_access_control_parser.cc",
"internal/grpc_client.cc",
"internal/grpc_object_access_control_parser.cc",
"internal/grpc_object_metadata_parser.cc",
Expand Down
2 changes: 2 additions & 0 deletions google/cloud/storage/internal/access_control_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ inline bool operator>=(ProjectTeam const& lhs, ProjectTeam const& rhs) {
}

namespace internal {
struct GrpcBucketAccessControlParser;
struct GrpcObjectAccessControlParser;

/**
Expand Down Expand Up @@ -131,6 +132,7 @@ class AccessControlCommon {
std::string const& self_link() const { return self_link_; }

private:
friend struct GrpcBucketAccessControlParser;
friend struct GrpcObjectAccessControlParser;
friend struct internal::AccessControlCommonParser;

Expand Down
68 changes: 68 additions & 0 deletions google/cloud/storage/internal/grpc_bucket_access_control_parser.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "google/cloud/storage/internal/grpc_bucket_access_control_parser.h"
#include "google/cloud/storage/version.h"

namespace google {
namespace cloud {
namespace storage {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
namespace internal {

google::storage::v2::BucketAccessControl GrpcBucketAccessControlParser::ToProto(
BucketAccessControl const& acl) {
google::storage::v2::BucketAccessControl result;
result.set_role(acl.role());
result.set_id(acl.id());
result.set_entity(acl.entity());
result.set_entity_id(acl.entity_id());
result.set_email(acl.email());
result.set_domain(acl.domain());
if (acl.has_project_team()) {
result.mutable_project_team()->set_project_number(
acl.project_team().project_number);
result.mutable_project_team()->set_team(acl.project_team().team);
}
return result;
}

BucketAccessControl GrpcBucketAccessControlParser::FromProto(
google::storage::v2::BucketAccessControl acl,
std::string const& bucket_name) {
BucketAccessControl result;
result.kind_ = "storage#bucketAccessControl";
result.bucket_ = bucket_name;
result.domain_ = std::move(*acl.mutable_domain());
result.email_ = std::move(*acl.mutable_email());
result.entity_ = std::move(*acl.mutable_entity());
result.entity_id_ = std::move(*acl.mutable_entity_id());
result.id_ = std::move(*acl.mutable_id());
if (acl.has_project_team()) {
result.project_team_ = ProjectTeam{
std::move(*acl.mutable_project_team()->mutable_project_number()),
std::move(*acl.mutable_project_team()->mutable_team()),
};
}
result.role_ = std::move(*acl.mutable_role());
result.self_link_.clear();

return result;
}

} // namespace internal
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace storage
} // namespace cloud
} // namespace google
42 changes: 42 additions & 0 deletions google/cloud/storage/internal/grpc_bucket_access_control_parser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_INTERNAL_GRPC_BUCKET_ACCESS_CONTROL_PARSER_H
#define GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_INTERNAL_GRPC_BUCKET_ACCESS_CONTROL_PARSER_H

#include "google/cloud/storage/internal/raw_client.h"
#include "google/cloud/storage/version.h"
#include <google/storage/v2/storage.pb.h>

namespace google {
namespace cloud {
namespace storage {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
namespace internal {

struct GrpcBucketAccessControlParser {
static google::storage::v2::BucketAccessControl ToProto(
BucketAccessControl const& acl);
static BucketAccessControl FromProto(
google::storage::v2::BucketAccessControl acl,
std::string const& bucket_name);
};

} // namespace internal
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace storage
} // namespace cloud
} // namespace google

#endif // GOOGLE_CLOUD_CPP_GOOGLE_CLOUD_STORAGE_INTERNAL_GRPC_BUCKET_ACCESS_CONTROL_PARSER_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "google/cloud/storage/internal/grpc_bucket_access_control_parser.h"
#include "google/cloud/storage/internal/bucket_access_control_parser.h"
#include "google/cloud/testing_util/is_proto_equal.h"
#include "google/cloud/testing_util/status_matchers.h"
#include <google/protobuf/text_format.h>
#include <gmock/gmock.h>

namespace google {
namespace cloud {
namespace storage {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
namespace internal {
namespace {

namespace storage_proto = ::google::storage::v2;
using ::google::cloud::testing_util::IsProtoEqual;

TEST(GrpcBucketAccessControlParser, FromProto) {
storage_proto::BucketAccessControl input;
EXPECT_TRUE(google::protobuf::TextFormat::ParseFromString(R"""(
role: "test-role"
id: "test-id"
entity: "test-entity"
entity_id: "test-entity-id"
email: "test-email"
domain: "test-domain"
project_team: {
project_number: "test-project-number"
team: "test-team"
}
)""",
&input));

auto const expected = BucketAccessControlParser::FromString(R"""({
"role": "test-role",
"id": "test-id",
"kind": "storage#bucketAccessControl",
"bucket": "test-bucket",
"entity": "test-entity",
"entityId": "test-entity-id",
"email": "test-email",
"domain": "test-domain",
"projectTeam": {
"projectNumber": "test-project-number",
"team": "test-team"
}
})""");
ASSERT_STATUS_OK(expected);

auto actual = GrpcBucketAccessControlParser::FromProto(input, "test-bucket");
EXPECT_EQ(*expected, actual);
}

TEST(GrpcBucketAccessControlParser, ToProtoSimple) {
auto acl = BucketAccessControlParser::FromString(R"""({
"role": "test-role",
"id": "test-id",
"kind": "storage#bucketAccessControl",
"bucket": "test-bucket",
"entity": "test-entity",
"entityId": "test-entity-id",
"email": "test-email",
"domain": "test-domain",
"projectTeam": {
"projectNumber": "test-project-number",
"team": "test-team"
}
})""");
ASSERT_STATUS_OK(acl);
auto actual = GrpcBucketAccessControlParser::ToProto(*acl);

storage_proto::BucketAccessControl expected;
EXPECT_TRUE(google::protobuf::TextFormat::ParseFromString(R"""(
role: "test-role"
id: "test-id"
entity: "test-entity"
entity_id: "test-entity-id"
email: "test-email"
domain: "test-domain"
project_team: {
project_number: "test-project-number"
team: "test-team"
}
)""",
&expected));

EXPECT_THAT(actual, IsProtoEqual(expected));
}

TEST(GrpcBucketAccessControlParser, MinimalFields) {
BucketAccessControl acl;
acl.set_role("test-role");
acl.set_entity("test-entity");
auto actual = GrpcBucketAccessControlParser::ToProto(acl);

storage_proto::BucketAccessControl expected;
EXPECT_TRUE(google::protobuf::TextFormat::ParseFromString(R"""(
role: "test-role"
entity: "test-entity"
)""",
&expected));

EXPECT_THAT(actual, IsProtoEqual(expected));
}

} // namespace
} // namespace internal
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace storage
} // namespace cloud
} // namespace google
1 change: 1 addition & 0 deletions google/cloud/storage/storage_client_grpc_unit_tests.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"""Automatically generated unit tests list - DO NOT EDIT."""

storage_client_grpc_unit_tests = [
"internal/grpc_bucket_access_control_parser_test.cc",
"internal/grpc_client_failures_test.cc",
"internal/grpc_client_insert_object_media_test.cc",
"internal/grpc_client_read_object_test.cc",
Expand Down

0 comments on commit dc13c43

Please sign in to comment.