| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "google_apis/google_api_keys.h" |
| |
| #include "base/command_line.h" |
| #include "base/environment.h" |
| #include "base/lazy_instance.h" |
| #include "base/logging.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/stringize_macros.h" |
| |
| #if defined(GOOGLE_CHROME_BUILD) || defined(USE_OFFICIAL_GOOGLE_API_KEYS) |
| #include "google_apis/internal/google_chrome_api_keys.h" |
| #endif |
| |
| // TODO(joi): Can we enable this warning without having it treated as |
| // an error? We don't want to fail builds, just warn, but all warnings |
| // from the preprocessor are currently treated as errors, at least in |
| // Linux builds. |
| #if 0 |
| #if !defined(GOOGLE_API_KEY) && ( \ |
| (!defined(GOOGLE_DEFAULT_CLIENT_ID) && \ |
| !defined(GOOGLE_DEFAULT_CLIENT_SECRET)) \ |
| || \ |
| (!defined(GOOGLE_CLIENT_ID_MAIN) && \ |
| !defined(GOOGLE_CLIENT_SECRET_MAIN))) |
| #warning You have not specified API keys; some features may not work. |
| #warning See www.chromium.org/developers/how-tos/api-keys for details. |
| #endif // (API keys unset) |
| #endif // 0 |
| |
| // Used to indicate an unset key/id/secret. This works better with |
| // various unit tests than leaving the token empty. |
| #define DUMMY_API_TOKEN "dummytoken" |
| |
| #if !defined(GOOGLE_API_KEY) |
| // TODO(joi): This is temporary; switch to DUMMY_API_TOKEN once people |
| // have had some time to install API keys per |
| // http://chromium.org/developers/how-tos/api-keys |
| #define GOOGLE_API_KEY "AIzaSyBHDrl33hwRp4rMQY0ziRbj8K9LPA6vUCY" |
| #endif |
| |
| #if !defined(GOOGLE_CLIENT_ID_MAIN) |
| #define GOOGLE_CLIENT_ID_MAIN DUMMY_API_TOKEN |
| #endif |
| |
| #if !defined(GOOGLE_CLIENT_SECRET_MAIN) |
| #define GOOGLE_CLIENT_SECRET_MAIN DUMMY_API_TOKEN |
| #endif |
| |
| #if !defined(GOOGLE_CLIENT_ID_CLOUD_PRINT) |
| #define GOOGLE_CLIENT_ID_CLOUD_PRINT DUMMY_API_TOKEN |
| #endif |
| |
| #if !defined(GOOGLE_CLIENT_SECRET_CLOUD_PRINT) |
| #define GOOGLE_CLIENT_SECRET_CLOUD_PRINT DUMMY_API_TOKEN |
| #endif |
| |
| #if !defined(GOOGLE_CLIENT_ID_REMOTING) |
| #define GOOGLE_CLIENT_ID_REMOTING DUMMY_API_TOKEN |
| #endif |
| |
| #if !defined(GOOGLE_CLIENT_SECRET_REMOTING) |
| #define GOOGLE_CLIENT_SECRET_REMOTING DUMMY_API_TOKEN |
| #endif |
| |
| // These are used as shortcuts for developers and users providing |
| // OAuth credentials via preprocessor defines or environment |
| // variables. If set, they will be used to replace any of the client |
| // IDs and secrets above that have not been set (and only those; they |
| // will not override already-set values). |
| // |
| // TODO(joi): This is temporary; make both blank once people have had |
| // some time to install API keys per |
| // http://chromium.org/developers/how-tos/api-keys |
| #if !defined(GOOGLE_DEFAULT_CLIENT_ID) |
| #define GOOGLE_DEFAULT_CLIENT_ID "609716072145.apps.googleusercontent.com" |
| #endif |
| #if !defined(GOOGLE_DEFAULT_CLIENT_SECRET) |
| #define GOOGLE_DEFAULT_CLIENT_SECRET "WF4uG3gJzEH0KLpS7OuFBDux" |
| #endif |
| |
| namespace switches { |
| |
| // Specifies custom OAuth2 client id for testing purposes. |
| const char kOAuth2ClientID[] = "oauth2-client-id"; |
| |
| // Specifies custom OAuth2 client secret for testing purposes. |
| const char kOAuth2ClientSecret[] = "oauth2-client-secret"; |
| |
| } // namespace switches |
| |
| namespace google_apis { |
| |
| // This is used as a lazy instance to determine keys once and cache them. |
| class APIKeyCache { |
| public: |
| APIKeyCache() { |
| scoped_ptr<base::Environment> environment(base::Environment::Create()); |
| CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| |
| api_key_ = CalculateKeyValue(GOOGLE_API_KEY, |
| STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY), |
| NULL, "", |
| environment.get(), |
| command_line); |
| |
| std::string default_client_id = CalculateKeyValue( |
| GOOGLE_DEFAULT_CLIENT_ID, |
| STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_ID), |
| NULL, "", |
| environment.get(), |
| command_line); |
| std::string default_client_secret = CalculateKeyValue( |
| GOOGLE_DEFAULT_CLIENT_SECRET, |
| STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_SECRET), |
| NULL, "", |
| environment.get(), |
| command_line); |
| |
| // We currently only allow overriding the baked-in values for the |
| // default OAuth2 client ID and secret using a command-line |
| // argument, since that is useful to enable testing against |
| // staging servers, and since that was what was possible and |
| // likely practiced by the QA team before this implementation was |
| // written. |
| client_ids_[CLIENT_MAIN] = CalculateKeyValue( |
| GOOGLE_CLIENT_ID_MAIN, |
| STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_MAIN), |
| switches::kOAuth2ClientID, |
| default_client_id, |
| environment.get(), |
| command_line); |
| client_secrets_[CLIENT_MAIN] = CalculateKeyValue( |
| GOOGLE_CLIENT_SECRET_MAIN, |
| STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_MAIN), |
| switches::kOAuth2ClientSecret, |
| default_client_secret, |
| environment.get(), |
| command_line); |
| |
| client_ids_[CLIENT_CLOUD_PRINT] = CalculateKeyValue( |
| GOOGLE_CLIENT_ID_CLOUD_PRINT, |
| STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_CLOUD_PRINT), |
| NULL, |
| default_client_id, |
| environment.get(), |
| command_line); |
| client_secrets_[CLIENT_CLOUD_PRINT] = CalculateKeyValue( |
| GOOGLE_CLIENT_SECRET_CLOUD_PRINT, |
| STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_CLOUD_PRINT), |
| NULL, |
| default_client_secret, |
| environment.get(), |
| command_line); |
| |
| client_ids_[CLIENT_REMOTING] = CalculateKeyValue( |
| GOOGLE_CLIENT_ID_REMOTING, |
| STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_REMOTING), |
| NULL, |
| default_client_id, |
| environment.get(), |
| command_line); |
| client_secrets_[CLIENT_REMOTING] = CalculateKeyValue( |
| GOOGLE_CLIENT_SECRET_REMOTING, |
| STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_REMOTING), |
| NULL, |
| default_client_secret, |
| environment.get(), |
| command_line); |
| } |
| |
| std::string api_key() const { return api_key_; } |
| |
| std::string GetClientID(OAuth2Client client) const { |
| DCHECK_LT(client, CLIENT_NUM_ITEMS); |
| return client_ids_[client]; |
| } |
| |
| std::string GetClientSecret(OAuth2Client client) const { |
| DCHECK_LT(client, CLIENT_NUM_ITEMS); |
| return client_secrets_[client]; |
| } |
| |
| private: |
| // Gets a value for a key. In priority order, this will be the value |
| // provided via a command-line switch, the value provided via an |
| // environment variable, or finally a value baked into the build. |
| // |command_line_switch| may be NULL. |
| static std::string CalculateKeyValue(const char* baked_in_value, |
| const char* environment_variable_name, |
| const char* command_line_switch, |
| const std::string& default_if_unset, |
| base::Environment* environment, |
| CommandLine* command_line) { |
| std::string key_value = baked_in_value; |
| std::string temp; |
| if (environment->GetVar(environment_variable_name, &temp)) { |
| key_value = temp; |
| LOG(INFO) << "Overriding API key " << environment_variable_name |
| << " with value " << key_value << " from environment variable."; |
| } |
| |
| if (command_line_switch && command_line->HasSwitch(command_line_switch)) { |
| key_value = command_line->GetSwitchValueASCII(command_line_switch); |
| LOG(INFO) << "Overriding API key " << environment_variable_name |
| << " with value " << key_value << " from command-line switch."; |
| } |
| |
| if (key_value == DUMMY_API_TOKEN) { |
| #if defined(GOOGLE_CHROME_BUILD) |
| // No key should be unset in an official build except the |
| // GOOGLE_DEFAULT_* keys. The default keys don't trigger this |
| // check as their "unset" value is not DUMMY_API_TOKEN. |
| CHECK(false); |
| #endif |
| if (default_if_unset.size() > 0) { |
| LOG(INFO) << "Using default value \"" << default_if_unset |
| << "\" for API key " << environment_variable_name; |
| key_value = default_if_unset; |
| } |
| } |
| |
| // This should remain a debug-only log. |
| DVLOG(1) << "API key " << environment_variable_name << "=" << key_value; |
| |
| return key_value; |
| } |
| |
| std::string api_key_; |
| std::string client_ids_[CLIENT_NUM_ITEMS]; |
| std::string client_secrets_[CLIENT_NUM_ITEMS]; |
| }; |
| |
| static base::LazyInstance<APIKeyCache> g_api_key_cache = |
| LAZY_INSTANCE_INITIALIZER; |
| |
| std::string GetAPIKey() { |
| return g_api_key_cache.Get().api_key(); |
| } |
| |
| std::string GetOAuth2ClientID(OAuth2Client client) { |
| return g_api_key_cache.Get().GetClientID(client); |
| } |
| |
| std::string GetOAuth2ClientSecret(OAuth2Client client) { |
| return g_api_key_cache.Get().GetClientSecret(client); |
| } |
| |
| } // namespace google_apis |