Skip to content

Commit 0876509

Browse files
feat: resolve ambiguous ServiceAccountConfig constructors (#15886)
1 parent f3de489 commit 0876509

5 files changed

Lines changed: 31 additions & 14 deletions

File tree

google/cloud/credentials.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,14 @@ std::shared_ptr<Credentials> MakeImpersonateServiceAccountCredentials(
4848
std::shared_ptr<Credentials> MakeServiceAccountCredentials(
4949
std::string json_object, Options opts) {
5050
return std::make_shared<internal::ServiceAccountConfig>(
51-
std::move(json_object), absl::nullopt, std::move(opts));
51+
internal::ServiceAccountJsonObject{std::move(json_object)},
52+
std::move(opts));
5253
}
5354

5455
std::shared_ptr<Credentials> MakeServiceAccountCredentialsFromFile(
5556
std::string const& file_path, Options opts) {
5657
return std::make_shared<internal::ServiceAccountConfig>(
57-
absl::nullopt, file_path, std::move(opts));
58+
internal::ServiceAccountFilePath{file_path}, std::move(opts));
5859
}
5960

6061
std::shared_ptr<Credentials> MakeExternalAccountCredentials(

google/cloud/internal/credentials_impl.cc

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,14 @@ std::vector<std::string> const& ImpersonateServiceAccountConfig::delegates()
8787
return options_.get<DelegatesOption>();
8888
}
8989

90-
ServiceAccountConfig::ServiceAccountConfig(
91-
absl::optional<std::string> json_object,
92-
absl::optional<std::string> file_path, Options opts)
93-
: json_object_(std::move(json_object)),
94-
file_path_(std::move(file_path)),
90+
ServiceAccountConfig::ServiceAccountConfig(ServiceAccountFilePath path,
91+
Options opts)
92+
: file_path_(std::move(path.value)),
93+
options_(PopulateAuthOptions(std::move(opts))) {}
94+
95+
ServiceAccountConfig::ServiceAccountConfig(ServiceAccountJsonObject json,
96+
Options opts)
97+
: json_object_(std::move(json.value)),
9598
options_(PopulateAuthOptions(std::move(opts))) {}
9699

97100
ExternalAccountConfig::ExternalAccountConfig(std::string json_object,

google/cloud/internal/credentials_impl.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,22 @@ class ImpersonateServiceAccountConfig : public Credentials {
142142
Options options_;
143143
};
144144

145+
struct ServiceAccountFilePath {
146+
std::string value;
147+
explicit ServiceAccountFilePath(std::string p) : value(std::move(p)) {}
148+
};
149+
150+
struct ServiceAccountJsonObject {
151+
std::string value;
152+
explicit ServiceAccountJsonObject(std::string j) : value(std::move(j)) {}
153+
};
154+
145155
class ServiceAccountConfig : public Credentials {
146156
public:
147-
// Only one of json_object or file_path should have a value.
148-
// TODO(#15886): Use the C++ type system to make better constructors that
149-
// enforces this comment.
150-
ServiceAccountConfig(absl::optional<std::string> json_object,
151-
absl::optional<std::string> file_path, Options opts);
157+
// Just declarations ending with a semicolon
158+
explicit ServiceAccountConfig(ServiceAccountFilePath path, Options opts);
159+
160+
explicit ServiceAccountConfig(ServiceAccountJsonObject json, Options opts);
152161

153162
absl::optional<std::string> const& json_object() const {
154163
return json_object_;

google/cloud/internal/credentials_impl_test.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,14 @@ TEST(Credentials, ImpersonateServiceAccountCredentialsDefaultWithOptions) {
9797
}
9898

9999
TEST(Credentials, ServiceAccount) {
100+
// If MakeServiceAccountCredentials treats this string as a JSON object:
100101
auto credentials = MakeServiceAccountCredentials("test-only-invalid");
101102
TestCredentialsVisitor visitor;
102103
CredentialsVisitor::dispatch(*credentials, visitor);
103104
ASSERT_EQ("ServiceAccountConfig", visitor.name);
105+
// Update: Ensure the correct field is populated and the other is empty
104106
EXPECT_EQ("test-only-invalid", visitor.json_object);
107+
EXPECT_EQ(absl::nullopt, visitor.file_path);
105108
}
106109

107110
TEST(Credentials, ExternalAccount) {

google/cloud/internal/unified_rest_credentials_test.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,8 +404,9 @@ TEST(UnifiedRestCredentialsTest, ServiceAccount) {
404404
MockClientFactory client_factory;
405405
EXPECT_CALL(client_factory, Call).Times(0);
406406

407-
auto const config =
408-
internal::ServiceAccountConfig(contents.dump(), absl::nullopt, Options{});
407+
auto const config = internal::ServiceAccountConfig(
408+
internal::ServiceAccountJsonObject{contents.dump()}, Options{});
409+
409410
auto credentials = MapCredentials(config, client_factory.AsStdFunction());
410411
auto access_token = credentials->GetToken(now);
411412
ASSERT_STATUS_OK(access_token);

0 commit comments

Comments
 (0)