Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions google/cloud/internal/oauth2_google_credentials.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ StatusOr<std::unique_ptr<Credentials>> LoadCredsFromString(
delegates.push_back(std::move(delegate));
}

auto& scopes = opts.lookup<ScopesOption>();
if (scopes.empty()) {
for (auto& scope : info->scopes) {
scopes.push_back(std::move(scope));
}
}

internal::ImpersonateServiceAccountConfig config(
// The base credentials (GUAC) are used to create the IAM REST Stub. We
// are going to override them by supplying our own IAM REST Stub,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,18 @@ ParseImpersonatedServiceAccountCredentials(std::string const& content,
}
}

it = credentials.find("scopes");
if (it != credentials.end()) {
if (!it->is_array()) {
return internal::InvalidArgumentError(
"Malformed `scopes` field is not an array on data from " + source,
GCP_ERROR_INFO());
}
for (auto const& scope : it->items()) {
info.scopes.push_back(scope.value().get<std::string>());
}
}

it = credentials.find("quota_project_id");
if (it != credentials.end()) {
if (!it->is_string()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
struct ImpersonatedServiceAccountCredentialsInfo {
std::string service_account;
std::vector<std::string> delegates;
std::vector<std::string> scopes;
absl::optional<std::string> quota_project_id;
std::string source_credentials;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,36 @@ auto constexpr kFullValidConfigNoAction = R"""({
"type": "impersonated_service_account"
})""";

auto constexpr kWithScopes = R"""({
"service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/sa3@developer.gserviceaccount.com:generateAccessToken",
"scopes": [
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/trace.append"
],
"source_credentials": {
"type": "authorized_user"
},
"type": "impersonated_service_account"
})""";

TEST(ParseImpersonatedServiceAccountCredentials, WithScopes) {
auto actual =
ParseImpersonatedServiceAccountCredentials(kWithScopes, "test-data");
ASSERT_STATUS_OK(actual);
EXPECT_THAT(actual->scopes,
ElementsAre("https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/trace.append"));
}

TEST(ParseImpersonatedServiceAccountCredentials, MalformedScopes) {
auto json = nlohmann::json::parse(kFullValidConfig);
json["scopes"] = "not-an-array";
auto actual = ParseImpersonatedServiceAccountCredentials(json.dump(), "");
EXPECT_THAT(actual,
StatusIs(StatusCode::kInvalidArgument,
AllOf(HasSubstr("Malformed"), HasSubstr("scopes"))));
}

TEST(ParseImpersonatedServiceAccountCredentials, Success) {
auto actual =
ParseImpersonatedServiceAccountCredentials(kFullValidConfig, "test-data");
Expand Down
Loading