Skip to content

Commit

Permalink
feat(rest): support generateIdToken in impersonation url (#14853)
Browse files Browse the repository at this point in the history
  • Loading branch information
cuiy0006 authored Nov 22, 2024
1 parent a89788f commit bb5800b
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,32 +67,21 @@ ParseImpersonatedServiceAccountCredentials(std::string const& content,
}
// We strip the service account from the path URL.
auto url = it->get<std::string>();
auto colon = url.rfind(':');
if (colon == std::string::npos) {
return internal::InvalidArgumentError(
"Malformed `service_account_impersonation_url` field contents on data "
"from " +
source,
GCP_ERROR_INFO());
}
if (url.substr(colon) != ":generateAccessToken") {
// While `generateIdToken` is a valid RPC, we do not currently support ID
// token flow. So we might as well error when parsing the credentials.
return internal::InvalidArgumentError(
"Only access token authentication is supported for impersonated "
"service accounts from " +
source,
GCP_ERROR_INFO());
}
auto slash = url.rfind('/', colon);
auto slash = url.rfind('/');
if (slash == std::string::npos) {
return internal::InvalidArgumentError(
"Malformed `service_account_impersonation_url` field contents on data "
"from " +
source,
GCP_ERROR_INFO());
}
info.service_account = std::string{url.substr(slash + 1, colon - slash - 1)};

// In the url, after the last slash, it is in the format of
// `service_account[:action]`
auto service_account_action = url.substr(slash + 1);
auto colon = service_account_action.rfind(':');
auto end = colon == std::string::npos ? service_account_action.size() : colon;
info.service_account = service_account_action.substr(0, end);

it = credentials.find("delegates");
if (it != credentials.end()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,19 @@ auto constexpr kFullValidConfig = R"""({
"type": "impersonated_service_account"
})""";

auto constexpr kFullValidConfigNoAction = R"""({
"service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/[email protected]",
"delegates": [
"[email protected]",
"[email protected]"
],
"quota_project_id": "my-project",
"source_credentials": {
"type": "authorized_user"
},
"type": "impersonated_service_account"
})""";

TEST(ParseImpersonatedServiceAccountCredentials, Success) {
auto actual =
ParseImpersonatedServiceAccountCredentials(kFullValidConfig, "test-data");
Expand Down Expand Up @@ -146,6 +159,19 @@ TEST(ImpersonateServiceAccountCredentialsTest, Basic) {
ASSERT_THAT(token, StatusIs(StatusCode::kPermissionDenied));
}

TEST(ParseImpersonatedServiceAccountCredentialsWithoutAction, Success) {
auto actual = ParseImpersonatedServiceAccountCredentials(
kFullValidConfigNoAction, "test-data");
ASSERT_STATUS_OK(actual);
EXPECT_EQ(actual->service_account, "[email protected]");
EXPECT_THAT(actual->delegates,
ElementsAre("[email protected]",
"[email protected]"));
EXPECT_THAT(actual->quota_project_id, Optional<std::string>("my-project"));
EXPECT_THAT(actual->source_credentials,
AllOf(HasSubstr("type"), HasSubstr("authorized_user")));
}

} // namespace
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace oauth2_internal
Expand Down

0 comments on commit bb5800b

Please sign in to comment.