From 2518a5861dbc57358cea38540cd5dbafb233bf67 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 20 Aug 2024 23:19:43 +0000 Subject: [PATCH] started working on tests --- ...cp_service_account_identity_credentials.cc | 2 +- ...gcp_service_account_identity_credentials.h | 4 +- test/core/security/credentials_test.cc | 61 +++++++++++++++++++ 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/src/core/lib/security/credentials/gcp_service_account_identity/gcp_service_account_identity_credentials.cc b/src/core/lib/security/credentials/gcp_service_account_identity/gcp_service_account_identity_credentials.cc index 6c6ddcddfb0..7ae3c7fc637 100644 --- a/src/core/lib/security/credentials/gcp_service_account_identity/gcp_service_account_identity_credentials.cc +++ b/src/core/lib/security/credentials/gcp_service_account_identity/gcp_service_account_identity_credentials.cc @@ -182,7 +182,7 @@ GcpServiceAccountIdentityCallCredentials::StartHttpRequest( // channel. This would allow us to cancel an authentication query when under // extreme memory pressure. auto uri = grpc_core::URI::Create( - "http", "metadata.google.internal", + "http", "metadata.google.internal.", "/computeMetadata/v1/instance/service-accounts/default/identity", {{"audience", audience_}}, /*fragment=*/""); CHECK_OK(uri); // params are hardcoded diff --git a/src/core/lib/security/credentials/gcp_service_account_identity/gcp_service_account_identity_credentials.h b/src/core/lib/security/credentials/gcp_service_account_identity/gcp_service_account_identity_credentials.h index d91c82298fa..1581b5a499f 100644 --- a/src/core/lib/security/credentials/gcp_service_account_identity/gcp_service_account_identity_credentials.h +++ b/src/core/lib/security/credentials/gcp_service_account_identity/gcp_service_account_identity_credentials.h @@ -60,8 +60,8 @@ class JwtTokenFetcherCallCredentials : public TokenFetcherCredentials { class GcpServiceAccountIdentityCallCredentials : public JwtTokenFetcherCallCredentials { public: - explicit GcpServiceAccountIdentityCallCredentials(std::string audience) - : audience_(std::move(audience)) {} + explicit GcpServiceAccountIdentityCallCredentials(absl::string_view audience) + : audience_(audience) {} std::string debug_string() override; diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc index 49796a9ac10..952f2059074 100644 --- a/test/core/security/credentials_test.cc +++ b/test/core/security/credentials_test.cc @@ -59,6 +59,7 @@ #include "src/core/lib/security/credentials/external/file_external_account_credentials.h" #include "src/core/lib/security/credentials/external/url_external_account_credentials.h" #include "src/core/lib/security/credentials/fake/fake_credentials.h" +#include "src/core/lib/security/credentials/gcp_service_account_identity/gcp_service_account_identity_credentials.h" #include "src/core/lib/security/credentials/google_default/google_default_credentials.h" #include "src/core/lib/security/credentials/iam/iam_credentials.h" #include "src/core/lib/security/credentials/jwt/jwt_credentials.h" @@ -4482,6 +4483,66 @@ TEST(CredentialsTest, TestXdsCredentialsCompareFailure) { grpc_channel_credentials_release(xds_creds_2); } +class GcpServiceAccountIdentityCredentialsTest : public ::testing::Test { + protected: + static int HttpGetOverride( + const grpc_http_request* request, const char* host, const char* path, + Timestamp /*deadline*/, grpc_closure* on_done, + grpc_http_response* response) { + // Validate request. + EXPECT_EQ(absl::string_view(host), "metadata.google.internal."); + EXPECT_EQ( + absl::string_view(path), + "/computeMetadata/v1/instance/service-accounts/default/identity"); +// FIXME +#if 0 + EXPECT_THAT( + uri.query_parameter_map(), + ::testing::ElementsAre(::testing::Pair("audience", g_audience))); +#endif + EXPECT_EQ(request->hdr_count, 1); + if (request->hdr_count > 1) { + EXPECT_EQ(absl::string_view(request->hdrs[0].key), "Metadata-Flavor"); + EXPECT_EQ(absl::string_view(request->hdrs[0].value), "Google"); + } + // Generate response. + CHECK_NE(g_token, nullptr); + *response = http_response(200, g_token); + ExecCtx::Run(DEBUG_LOCATION, on_done, absl::OkStatus()); + return 1; + } + + // Constructs a synthetic JWT token that's just valid enough for the + // call creds to extract the expiration date. + static std::string MakeToken(Timestamp expiration) { + gpr_timespec ts = expiration.as_timespec(GPR_CLOCK_REALTIME); + std::string json = absl::StrCat("{\"exp\":", ts.tv_sec, "}"); + return absl::StrCat("foo.", absl::WebSafeBase64Escape(json), ".bar"); + } + + static absl::string_view g_audience; + static const char* g_token; +}; + +absl::string_view GcpServiceAccountIdentityCredentialsTest::g_audience; +const char* GcpServiceAccountIdentityCredentialsTest::g_token = nullptr; + +TEST_F(GcpServiceAccountIdentityCredentialsTest, Basic) { + g_audience = "CV-6"; + auto token = MakeToken(Timestamp::Now() + Duration::Hours(1)); + g_token = token.c_str(); + ExecCtx exec_ctx; + auto creds = + MakeRefCounted(g_audience); + CHECK_EQ(creds->min_security_level(), GRPC_PRIVACY_AND_INTEGRITY); + auto state = RequestMetadataState::NewInstance(absl::OkStatus(), g_token); + HttpRequest::SetOverride(HttpGetOverride, httpcli_post_should_not_be_called, + httpcli_put_should_not_be_called); + state->RunRequestMetadataTest(creds.get(), kTestUrlScheme, kTestAuthority, + kTestPath); + ExecCtx::Get()->Flush(); +} + } // namespace } // namespace grpc_core