diff --git a/google_apis/google_api_keys.cc b/google_apis/google_api_keys.cc index 06a53e2476f568..ab92d1e4dccf74 100644 --- a/google_apis/google_api_keys.cc +++ b/google_apis/google_api_keys.cc @@ -206,6 +206,9 @@ class APIKeyCache { } std::string api_key() const { return api_key_; } +#if defined(OS_IOS) + void set_api_key(const std::string& api_key) { api_key_ = api_key; } +#endif std::string api_key_non_stable() const { return api_key_non_stable_; } std::string api_key_remoting() const { return api_key_remoting_; } @@ -214,11 +217,23 @@ class APIKeyCache { return client_ids_[client]; } +#if defined(OS_IOS) + void SetClientID(OAuth2Client client, const std::string& client_id) { + client_ids_[client] = client_id; + } +#endif + std::string GetClientSecret(OAuth2Client client) const { DCHECK_LT(client, CLIENT_NUM_ITEMS); return client_secrets_[client]; } +#if defined(OS_IOS) + void SetClientSecret(OAuth2Client client, const std::string& client_secret) { + client_secrets_[client] = client_secret; + } +#endif + std::string GetSpdyProxyAuthValue() { #if defined(SPDY_PROXY_AUTH_VALUE) return SPDY_PROXY_AUTH_VALUE; @@ -319,6 +334,12 @@ std::string GetRemotingAPIKey() { return g_api_key_cache.Get().api_key_remoting(); } +#if defined(OS_IOS) +void SetAPIKey(const std::string& api_key) { + g_api_key_cache.Get().set_api_key(api_key); +} +#endif + std::string GetOAuth2ClientID(OAuth2Client client) { return g_api_key_cache.Get().GetClientID(client); } @@ -327,6 +348,17 @@ std::string GetOAuth2ClientSecret(OAuth2Client client) { return g_api_key_cache.Get().GetClientSecret(client); } +#if defined(OS_IOS) +void SetOAuth2ClientID(OAuth2Client client, const std::string& client_id) { + g_api_key_cache.Get().SetClientID(client, client_id); +} + +void SetOAuth2ClientSecret(OAuth2Client client, + const std::string& client_secret) { + g_api_key_cache.Get().SetClientSecret(client, client_secret); +} +#endif + std::string GetSpdyProxyAuthValue() { return g_api_key_cache.Get().GetSpdyProxyAuthValue(); } diff --git a/google_apis/google_api_keys.h b/google_apis/google_api_keys.h index e10078c330a142..fb928680c03cb1 100644 --- a/google_apis/google_api_keys.h +++ b/google_apis/google_api_keys.h @@ -73,6 +73,12 @@ std::string GetNonStableAPIKey(); std::string GetRemotingAPIKey(); +#if defined(OS_IOS) +// Sets the API key. This should be called as early as possible before this +// API key is even accessed. +void SetAPIKey(const std::string& api_key); +#endif + // Represents the different sets of client IDs and secrets in use. enum OAuth2Client { CLIENT_MAIN, // Several different features use this. @@ -97,6 +103,16 @@ std::string GetOAuth2ClientID(OAuth2Client client); // in, e.g. URL-escaped if you use it in a URL. std::string GetOAuth2ClientSecret(OAuth2Client client); +#if defined(OS_IOS) +// Sets the client id for the specified client. Should be called as early as +// possible before these ids are accessed. +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. +void SetOAuth2ClientSecret(OAuth2Client client, + const std::string& client_secret); +#endif // Returns the auth token for the data reduction proxy. std::string GetSpdyProxyAuthValue(); diff --git a/google_apis/google_api_keys_unittest.cc b/google_apis/google_api_keys_unittest.cc index 5ce1fb31622d45..74765ecaefe274 100644 --- a/google_apis/google_api_keys_unittest.cc +++ b/google_apis/google_api_keys_unittest.cc @@ -481,4 +481,94 @@ TEST_F(GoogleAPIKeysTest, OverrideAllKeysUsingEnvironment) { EXPECT_EQ("env-SECRET_REMOTING_HOST", secret_remoting_host); } +#if defined(OS_IOS) +// Override all keys using both preprocessor defines and setters. +// Setters should win. +namespace override_all_keys_setters { + +// We start every test by creating a clean environment for the +// preprocessor defines used in google_api_keys.cc +#undef DUMMY_API_TOKEN +#undef GOOGLE_API_KEY +#undef GOOGLE_CLIENT_ID_MAIN +#undef GOOGLE_CLIENT_SECRET_MAIN +#undef GOOGLE_CLIENT_ID_CLOUD_PRINT +#undef GOOGLE_CLIENT_SECRET_CLOUD_PRINT +#undef GOOGLE_CLIENT_ID_REMOTING +#undef GOOGLE_CLIENT_SECRET_REMOTING +#undef GOOGLE_CLIENT_ID_REMOTING_HOST +#undef GOOGLE_CLIENT_SECRET_REMOTING_HOST +#undef GOOGLE_DEFAULT_CLIENT_ID +#undef GOOGLE_DEFAULT_CLIENT_SECRET + +#define GOOGLE_API_KEY "API_KEY" +#define GOOGLE_CLIENT_ID_MAIN "ID_MAIN" +#define GOOGLE_CLIENT_SECRET_MAIN "SECRET_MAIN" +#define GOOGLE_CLIENT_ID_CLOUD_PRINT "ID_CLOUD_PRINT" +#define GOOGLE_CLIENT_SECRET_CLOUD_PRINT "SECRET_CLOUD_PRINT" +#define GOOGLE_CLIENT_ID_REMOTING "ID_REMOTING" +#define GOOGLE_CLIENT_SECRET_REMOTING "SECRET_REMOTING" +#define GOOGLE_CLIENT_ID_REMOTING_HOST "ID_REMOTING_HOST" +#define GOOGLE_CLIENT_SECRET_REMOTING_HOST "SECRET_REMOTING_HOST" + +// Undef include guard so things get defined again, within this namespace. +#undef GOOGLE_APIS_GOOGLE_API_KEYS_H_ +#undef GOOGLE_APIS_INTERNAL_GOOGLE_CHROME_API_KEYS_ +#include "google_apis/google_api_keys.cc" + +} // namespace override_all_keys_setters + +TEST_F(GoogleAPIKeysTest, OverrideAllKeysUsingSetters) { + namespace testcase = override_all_keys_setters::google_apis; + + std::string api_key("setter-API_KEY"); + testcase::SetAPIKey(api_key); + + std::string id_main("setter-ID_MAIN"); + std::string secret_main("setter-SECRET_MAIN"); + testcase::SetOAuth2ClientID(testcase::CLIENT_MAIN, id_main); + testcase::SetOAuth2ClientSecret(testcase::CLIENT_MAIN, secret_main); + + std::string id_cloud_print("setter-ID_CLOUD_PRINT"); + std::string secret_cloud_print("setter-SECRET_CLOUD_PRINT"); + testcase::SetOAuth2ClientID(testcase::CLIENT_CLOUD_PRINT, id_cloud_print); + testcase::SetOAuth2ClientSecret(testcase::CLIENT_CLOUD_PRINT, + secret_cloud_print); + + std::string id_remoting("setter-ID_REMOTING"); + std::string secret_remoting("setter-SECRET_REMOTING"); + testcase::SetOAuth2ClientID(testcase::CLIENT_REMOTING, id_remoting); + testcase::SetOAuth2ClientSecret(testcase::CLIENT_REMOTING, secret_remoting); + + std::string id_remoting_host("setter-ID_REMOTING_HOST"); + std::string secret_remoting_host("setter-SECRET_REMOTING_HOST"); + testcase::SetOAuth2ClientID(testcase::CLIENT_REMOTING_HOST, id_remoting_host); + testcase::SetOAuth2ClientSecret(testcase::CLIENT_REMOTING_HOST, + secret_remoting_host); + + EXPECT_TRUE(testcase::HasKeysConfigured()); + + EXPECT_EQ(api_key, testcase::GetAPIKey()); + + EXPECT_EQ(id_main, testcase::GetOAuth2ClientID(testcase::CLIENT_MAIN)); + EXPECT_EQ(secret_main, + testcase::GetOAuth2ClientSecret(testcase::CLIENT_MAIN)); + + EXPECT_EQ(id_cloud_print, + testcase::GetOAuth2ClientID(testcase::CLIENT_CLOUD_PRINT)); + EXPECT_EQ(secret_cloud_print, + testcase::GetOAuth2ClientSecret(testcase::CLIENT_CLOUD_PRINT)); + + EXPECT_EQ(id_remoting, + testcase::GetOAuth2ClientID(testcase::CLIENT_REMOTING)); + EXPECT_EQ(secret_remoting, + testcase::GetOAuth2ClientSecret(testcase::CLIENT_REMOTING)); + + EXPECT_EQ(id_remoting_host, + testcase::GetOAuth2ClientID(testcase::CLIENT_REMOTING_HOST)); + EXPECT_EQ(secret_remoting_host, + testcase::GetOAuth2ClientSecret(testcase::CLIENT_REMOTING_HOST)); +} +#endif // defined(OS_IOS) + #endif // defined(OS_LINUX) || defined(OS_MACOSX) diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn index 147177498ebead..9d053cdd619ab1 100644 --- a/ios/web_view/BUILD.gn +++ b/ios/web_view/BUILD.gn @@ -88,6 +88,7 @@ ios_web_view_deps = [ "//components/translate/core/browser", "//components/translate/core/common", "//components/translate/ios/browser", + "//google_apis", "//ios/net", "//ios/net", "//ios/web", diff --git a/ios/web_view/internal/DEPS b/ios/web_view/internal/DEPS index 1068058f861059..b749fbfaa2e10e 100644 --- a/ios/web_view/internal/DEPS +++ b/ios/web_view/internal/DEPS @@ -7,6 +7,7 @@ include_rules = [ "+components/prefs", "+components/translate/core", "+components/translate/ios", + "+google_apis", "+ios/net", "+ios/web/public", "+ios/web_view", diff --git a/ios/web_view/internal/cwv_web_view.mm b/ios/web_view/internal/cwv_web_view.mm index 157ed90a02db58..da06b5577e3364 100644 --- a/ios/web_view/internal/cwv_web_view.mm +++ b/ios/web_view/internal/cwv_web_view.mm @@ -10,6 +10,7 @@ #import "base/ios/weak_nsobject.h" #include "base/memory/ptr_util.h" #include "base/strings/sys_string_conversions.h" +#include "google_apis/google_api_keys.h" #import "ios/web/public/navigation_manager.h" #include "ios/web/public/referrer.h" #include "ios/web/public/reload_type.h" @@ -93,6 +94,21 @@ + (void)setUserAgentProduct:(NSString*)product { gUserAgentProduct = [product copy]; } ++ (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(i); + google_apis::SetOAuth2ClientID(client, clientIDString); + google_apis::SetOAuth2ClientSecret(client, clientSecretString); + } +} + - (instancetype)initWithFrame:(CGRect)frame configuration:(CWVWebViewConfiguration*)configuration { self = [super initWithFrame:frame]; diff --git a/ios/web_view/public/cwv_web_view.h b/ios/web_view/public/cwv_web_view.h index 54bf295018f370..9f608525ca89d6 100644 --- a/ios/web_view/public/cwv_web_view.h +++ b/ios/web_view/public/cwv_web_view.h @@ -69,6 +69,15 @@ CWV_EXPORT // depending upon their internal state. + (void)setUserAgentProduct:(NSString*)product; +// Use this method to set the necessary credentials used to communicate with +// the Google API for features such as translate. See this link for more info: +// https://support.google.com/googleapi/answer/6158857 +// This method must be called before any |CWVWebViews| are instantiated for +// the keys to be used. ++ (void)setGoogleAPIKey:(NSString*)googleAPIKey + clientID:(NSString*)clientID + clientSecret:(NSString*)clientSecret; + // |configuration| must not be null - (instancetype)initWithFrame:(CGRect)frame configuration:(CWVWebViewConfiguration*)configuration