0

[google_apis] Crash if the API key was already configured

This CL crashes the application if the API key is overridden after its
first usage.

Bug: 40164066

Change-Id: I71044d1d5a7e6f2f808b85fa23013b23ee411469
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5890974
Reviewed-by: David Dorwin <ddorwin@chromium.org>
Reviewed-by: Alex Ilin <alexilin@chromium.org>
Reviewed-by: Sylvain Defresne <sdefresne@chromium.org>
Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com>
Commit-Queue: Mihai Sardarescu <msarda@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1373212}
This commit is contained in:
Mihai Sardarescu
2024-10-24 09:33:51 +00:00
committed by Chromium LUCI CQ
parent fa7f288e2c
commit 6075bf2174
5 changed files with 84 additions and 75 deletions

@ -105,7 +105,7 @@ std::optional<int> WebEngineMainDelegate::PreBrowserMain() {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
if (command_line->HasSwitch(switches::kGoogleApiKey)) {
#if BUILDFLAG(SUPPORT_EXTERNAL_GOOGLE_API_KEY)
google_apis::SetAPIKey(
google_apis::InitializeAndOverrideAPIKey(
command_line->GetSwitchValueASCII(switches::kGoogleApiKey));
#else
LOG(WARNING) << "Ignored " << switches::kGoogleApiKey;

@ -11,6 +11,7 @@
#include <string>
#include "base/check_is_test.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/no_destructor.h"
@ -54,6 +55,22 @@ ApiKeyCache& GetApiKeyCacheInstance() {
return *g_api_key_cache_instance;
}
#if BUILDFLAG(SUPPORT_EXTERNAL_GOOGLE_API_KEY)
// Explicitly creates the global API key cache.
//
// Expects that `g_api_key_cache_instance` is null, as this function must be
// called before any prior usage of the global API key cache.
ApiKeyCache& InitializeApiKeyCacheInstance() {
// Tests need to override the global instance of the API key cache, so it
// is not feasible to check that `g_api_key_cache_instance` is null in
// tests.
if (g_api_key_cache_instance) {
CHECK_IS_TEST(base::NotFatalUntil::M133);
}
return GetApiKeyCacheInstance();
}
#endif // BUILDFLAG(SUPPORT_EXTERNAL_GOOGLE_API_KEY)
} // namespace
const char kAPIKeysDevelopersHowToURL[] =
@ -105,12 +122,6 @@ const std::string& GetBocaAPIKey() {
}
#endif
#if BUILDFLAG(SUPPORT_EXTERNAL_GOOGLE_API_KEY)
void SetAPIKey(const std::string& api_key) {
GetApiKeyCacheInstance().set_api_key(api_key);
}
#endif
const std::string& GetMetricsKey() {
return GetApiKeyCacheInstance().metrics_key();
}
@ -127,17 +138,6 @@ const std::string& GetOAuth2ClientSecret(OAuth2Client client) {
return GetApiKeyCacheInstance().GetClientSecret(client);
}
#if BUILDFLAG(IS_IOS)
void SetOAuth2ClientID(OAuth2Client client, const std::string& client_id) {
GetApiKeyCacheInstance().SetClientID(client, client_id);
}
void SetOAuth2ClientSecret(OAuth2Client client,
const std::string& client_secret) {
GetApiKeyCacheInstance().SetClientSecret(client, client_secret);
}
#endif
bool IsGoogleChromeAPIKeyUsed() {
#if defined(USE_OFFICIAL_GOOGLE_API_KEYS)
return true;
@ -146,8 +146,32 @@ bool IsGoogleChromeAPIKeyUsed() {
#endif
}
#if BUILDFLAG(SUPPORT_EXTERNAL_GOOGLE_API_KEY)
void InitializeAndOverrideAPIKey(const std::string& api_key) {
ApiKeyCache& cache = InitializeApiKeyCacheInstance();
cache.set_api_key(api_key);
}
#endif // BUILDFLAG(SUPPORT_EXTERNAL_GOOGLE_API_KEY)
#if BUILDFLAG(IS_IOS)
void InitializeAndOverrideAPIKeyAndOAuthClient(
const std::string& api_key,
const std::string& client_id,
const std::string& client_secret) {
ApiKeyCache& cache = InitializeApiKeyCacheInstance();
cache.set_api_key(api_key);
for (size_t i = 0; i < google_apis::CLIENT_NUM_ITEMS; ++i) {
google_apis::OAuth2Client client =
static_cast<google_apis::OAuth2Client>(i);
cache.SetClientID(client, client_id);
cache.SetClientSecret(client, client_secret);
}
}
#endif // BUILDFLAG(IS_IOS)
base::ScopedClosureRunner SetScopedApiKeyCacheForTesting(
ApiKeyCache* api_key_cache) {
CHECK(api_key_cache) << "Overriding with nullptr is not allowed.";
ApiKeyCache* previous_value =
g_api_key_cache_instance.exchange(api_key_cache);
return base::ScopedClosureRunner(base::BindOnce(

@ -116,14 +116,6 @@ COMPONENT_EXPORT(GOOGLE_APIS) const std::string& GetFresnelAPIKey();
COMPONENT_EXPORT(GOOGLE_APIS) const std::string& GetBocaAPIKey();
#endif
#if BUILDFLAG(SUPPORT_EXTERNAL_GOOGLE_API_KEY)
// Sets the API key.
//
// Note: This function must be called before any call to GetAPIKey().
COMPONENT_EXPORT(GOOGLE_APIS)
void SetAPIKey(const std::string& api_key);
#endif
// Retrieves the key used to sign metrics (UMA/UKM) uploads.
COMPONENT_EXPORT(GOOGLE_APIS) const std::string& GetMetricsKey();
@ -155,23 +147,37 @@ const std::string& GetOAuth2ClientID(OAuth2Client client);
COMPONENT_EXPORT(GOOGLE_APIS)
const std::string& GetOAuth2ClientSecret(OAuth2Client client);
#if BUILDFLAG(IS_IOS)
// Sets the client id for the specified client. Should be called as early as
// possible before these ids are accessed.
COMPONENT_EXPORT(GOOGLE_APIS)
void SetOAuth2ClientID(OAuth2Client client, const std::string& client_id);
// Sets the client secret for the specified client. Should be called as early as
// possible before these secrets are accessed.
COMPONENT_EXPORT(GOOGLE_APIS)
void SetOAuth2ClientSecret(OAuth2Client client,
const std::string& client_secret);
#endif
// Returns if the API key using in the current build is the one for official
// Google Chrome.
COMPONENT_EXPORT(GOOGLE_APIS) bool IsGoogleChromeAPIKeyUsed();
#if BUILDFLAG(SUPPORT_EXTERNAL_GOOGLE_API_KEY)
// Initializes the API keys with default values and overrides the main APIKey
// with `api_key`.
//
// Note: Following this call, `GetApiKey()` and `GetAPIKey(channel)` will
// return `api_key`. This function does not override the other API keys
// or client IDS & client secrets.
COMPONENT_EXPORT(GOOGLE_APIS)
void InitializeAndOverrideAPIKey(const std::string& api_key);
#endif
#if BUILDFLAG(IS_IOS)
// Initializes the API keys with default values and overrides the `APIKey` with
// `api_key`, all the client IDs with `client_id` and all client secrets with
// `client_secret`.
//
// Note: Following this call, `GetApiKey()` and `GetAPIKey(channel)` will
// return `api_key`, `GetOAuth2ClientID(*)` will return 'client_id' and
// `GetOAuth2ClientSecret(*)` will return `client_secret`. This function does
// not override the other API keys.
COMPONENT_EXPORT(GOOGLE_APIS)
void InitializeAndOverrideAPIKeyAndOAuthClient(
const std::string& api_key,
const std::string& client_id,
const std::string& client_secret);
#endif
// Sets a testing global instance of `ApiKeyCache` and returns a scoped object
// that will restore the previous value once destroyed.
COMPONENT_EXPORT(GOOGLE_APIS)

@ -523,25 +523,10 @@ TEST_F(GoogleAPIKeysTest, OverrideAllKeysUsingSetters) {
google_apis::SetScopedApiKeyCacheForTesting(&api_key_cache);
std::string api_key("setter-API_KEY");
google_apis::SetAPIKey(api_key);
std::string id_main("setter-ID_MAIN");
std::string secret_main("setter-SECRET_MAIN");
google_apis::SetOAuth2ClientID(google_apis::CLIENT_MAIN, id_main);
google_apis::SetOAuth2ClientSecret(google_apis::CLIENT_MAIN, secret_main);
std::string id_remoting("setter-ID_REMOTING");
std::string secret_remoting("setter-SECRET_REMOTING");
google_apis::SetOAuth2ClientID(google_apis::CLIENT_REMOTING, id_remoting);
google_apis::SetOAuth2ClientSecret(google_apis::CLIENT_REMOTING,
secret_remoting);
std::string id_remoting_host("setter-ID_REMOTING_HOST");
std::string secret_remoting_host("setter-SECRET_REMOTING_HOST");
google_apis::SetOAuth2ClientID(google_apis::CLIENT_REMOTING_HOST,
id_remoting_host);
google_apis::SetOAuth2ClientSecret(google_apis::CLIENT_REMOTING_HOST,
secret_remoting_host);
std::string client_id("setter-CLIENT_ID");
std::string client_secret("setter-CLIENT_SECRET");
google_apis::InitializeAndOverrideAPIKeyAndOAuthClient(api_key, client_id,
client_secret);
EXPECT_TRUE(google_apis::HasAPIKeyConfigured());
EXPECT_TRUE(google_apis::HasOAuthClientConfigured());
@ -549,19 +534,20 @@ TEST_F(GoogleAPIKeysTest, OverrideAllKeysUsingSetters) {
EXPECT_EQ(api_key, google_apis::GetAPIKey(::version_info::Channel::STABLE));
EXPECT_EQ(api_key, google_apis::GetAPIKey());
EXPECT_EQ(id_main, google_apis::GetOAuth2ClientID(google_apis::CLIENT_MAIN));
EXPECT_EQ(secret_main,
EXPECT_EQ(client_id,
google_apis::GetOAuth2ClientID(google_apis::CLIENT_MAIN));
EXPECT_EQ(client_secret,
google_apis::GetOAuth2ClientSecret(google_apis::CLIENT_MAIN));
EXPECT_EQ(id_remoting,
EXPECT_EQ(client_id,
google_apis::GetOAuth2ClientID(google_apis::CLIENT_REMOTING));
EXPECT_EQ(secret_remoting,
EXPECT_EQ(client_secret,
google_apis::GetOAuth2ClientSecret(google_apis::CLIENT_REMOTING));
EXPECT_EQ(id_remoting_host,
EXPECT_EQ(client_id,
google_apis::GetOAuth2ClientID(google_apis::CLIENT_REMOTING_HOST));
EXPECT_EQ(secret_remoting_host, google_apis::GetOAuth2ClientSecret(
google_apis::CLIENT_REMOTING_HOST));
EXPECT_EQ(client_secret, google_apis::GetOAuth2ClientSecret(
google_apis::CLIENT_REMOTING_HOST));
}
#endif // BUILDFLAG(IS_IOS)

@ -521,16 +521,9 @@ WEB_STATE_USER_DATA_KEY_IMPL(WebViewHolder)
+ (void)setGoogleAPIKey:(NSString*)googleAPIKey
clientID:(NSString*)clientID
clientSecret:(NSString*)clientSecret {
google_apis::SetAPIKey(base::SysNSStringToUTF8(googleAPIKey));
std::string clientIDString = base::SysNSStringToUTF8(clientID);
std::string clientSecretString = base::SysNSStringToUTF8(clientSecret);
for (size_t i = 0; i < google_apis::CLIENT_NUM_ITEMS; ++i) {
google_apis::OAuth2Client client =
static_cast<google_apis::OAuth2Client>(i);
google_apis::SetOAuth2ClientID(client, clientIDString);
google_apis::SetOAuth2ClientSecret(client, clientSecretString);
}
google_apis::InitializeAndOverrideAPIKeyAndOAuthClient(
base::SysNSStringToUTF8(googleAPIKey), base::SysNSStringToUTF8(clientID),
base::SysNSStringToUTF8(clientSecret));
}
+ (CWVWebView*)webViewForWebState:(web::WebState*)webState {