[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | 6386cf5 | 2012-09-07 04:26:37 | [diff] [blame] | 5 | #include "google_apis/google_api_keys.h" |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 6 | |
[email protected] | e03604b | 2013-01-10 23:38:22 | [diff] [blame] | 7 | // If you add more includes to this list, you also need to add them to |
| 8 | // google_api_keys_unittest.cc. |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 9 | #include "base/command_line.h" |
| 10 | #include "base/environment.h" |
| 11 | #include "base/lazy_instance.h" |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame] | 12 | #include "base/logging.h" |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 13 | #include "base/memory/scoped_ptr.h" |
[email protected] | 8edbebd | 2013-01-31 19:45:02 | [diff] [blame] | 14 | #include "base/strings/stringize_macros.h" |
[email protected] | 850b353e | 2014-02-11 15:56:28 | [diff] [blame] | 15 | #include "google_apis/gaia/gaia_switches.h" |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 16 | |
[email protected] | d647e28 | 2012-09-13 13:10:10 | [diff] [blame] | 17 | #if defined(GOOGLE_CHROME_BUILD) || defined(USE_OFFICIAL_GOOGLE_API_KEYS) |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame] | 18 | #include "google_apis/internal/google_chrome_api_keys.h" |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 19 | #endif |
| 20 | |
[email protected] | d647e28 | 2012-09-13 13:10:10 | [diff] [blame] | 21 | // Used to indicate an unset key/id/secret. This works better with |
| 22 | // various unit tests than leaving the token empty. |
| 23 | #define DUMMY_API_TOKEN "dummytoken" |
| 24 | |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 25 | #if !defined(GOOGLE_API_KEY) |
[email protected] | 1abac7a | 2013-01-31 14:01:25 | [diff] [blame] | 26 | #define GOOGLE_API_KEY DUMMY_API_TOKEN |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 27 | #endif |
| 28 | |
treib | e81fd0f | 2014-11-24 12:35:48 | [diff] [blame] | 29 | #if !defined(GOOGLE_API_KEY_SAFESITES) |
| 30 | #define GOOGLE_API_KEY_SAFESITES DUMMY_API_TOKEN |
| 31 | #endif |
| 32 | |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 33 | #if !defined(GOOGLE_CLIENT_ID_MAIN) |
[email protected] | fc2212d | 2012-09-17 17:33:20 | [diff] [blame] | 34 | #define GOOGLE_CLIENT_ID_MAIN DUMMY_API_TOKEN |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 35 | #endif |
| 36 | |
| 37 | #if !defined(GOOGLE_CLIENT_SECRET_MAIN) |
[email protected] | fc2212d | 2012-09-17 17:33:20 | [diff] [blame] | 38 | #define GOOGLE_CLIENT_SECRET_MAIN DUMMY_API_TOKEN |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 39 | #endif |
| 40 | |
| 41 | #if !defined(GOOGLE_CLIENT_ID_CLOUD_PRINT) |
[email protected] | fc2212d | 2012-09-17 17:33:20 | [diff] [blame] | 42 | #define GOOGLE_CLIENT_ID_CLOUD_PRINT DUMMY_API_TOKEN |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 43 | #endif |
| 44 | |
| 45 | #if !defined(GOOGLE_CLIENT_SECRET_CLOUD_PRINT) |
[email protected] | fc2212d | 2012-09-17 17:33:20 | [diff] [blame] | 46 | #define GOOGLE_CLIENT_SECRET_CLOUD_PRINT DUMMY_API_TOKEN |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 47 | #endif |
| 48 | |
| 49 | #if !defined(GOOGLE_CLIENT_ID_REMOTING) |
[email protected] | fc2212d | 2012-09-17 17:33:20 | [diff] [blame] | 50 | #define GOOGLE_CLIENT_ID_REMOTING DUMMY_API_TOKEN |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 51 | #endif |
| 52 | |
| 53 | #if !defined(GOOGLE_CLIENT_SECRET_REMOTING) |
[email protected] | fc2212d | 2012-09-17 17:33:20 | [diff] [blame] | 54 | #define GOOGLE_CLIENT_SECRET_REMOTING DUMMY_API_TOKEN |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 55 | #endif |
| 56 | |
[email protected] | d66d8174 | 2013-08-16 05:18:38 | [diff] [blame] | 57 | #if !defined(GOOGLE_CLIENT_ID_REMOTING_HOST) |
| 58 | #define GOOGLE_CLIENT_ID_REMOTING_HOST DUMMY_API_TOKEN |
| 59 | #endif |
| 60 | |
| 61 | #if !defined(GOOGLE_CLIENT_SECRET_REMOTING_HOST) |
| 62 | #define GOOGLE_CLIENT_SECRET_REMOTING_HOST DUMMY_API_TOKEN |
| 63 | #endif |
| 64 | |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 65 | // These are used as shortcuts for developers and users providing |
| 66 | // OAuth credentials via preprocessor defines or environment |
| 67 | // variables. If set, they will be used to replace any of the client |
| 68 | // IDs and secrets above that have not been set (and only those; they |
| 69 | // will not override already-set values). |
| 70 | #if !defined(GOOGLE_DEFAULT_CLIENT_ID) |
[email protected] | 1abac7a | 2013-01-31 14:01:25 | [diff] [blame] | 71 | #define GOOGLE_DEFAULT_CLIENT_ID "" |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 72 | #endif |
| 73 | #if !defined(GOOGLE_DEFAULT_CLIENT_SECRET) |
[email protected] | 1abac7a | 2013-01-31 14:01:25 | [diff] [blame] | 74 | #define GOOGLE_DEFAULT_CLIENT_SECRET "" |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 75 | #endif |
| 76 | |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 77 | namespace google_apis { |
| 78 | |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 79 | // This is used as a lazy instance to determine keys once and cache them. |
| 80 | class APIKeyCache { |
| 81 | public: |
| 82 | APIKeyCache() { |
| 83 | scoped_ptr<base::Environment> environment(base::Environment::Create()); |
avi | 9ab03720 | 2014-12-22 23:49:53 | [diff] [blame] | 84 | base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 85 | |
| 86 | api_key_ = CalculateKeyValue(GOOGLE_API_KEY, |
| 87 | STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY), |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 88 | NULL, |
| 89 | std::string(), |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 90 | environment.get(), |
| 91 | command_line); |
| 92 | |
treib | e81fd0f | 2014-11-24 12:35:48 | [diff] [blame] | 93 | api_key_safesites_ = |
| 94 | CalculateKeyValue(GOOGLE_API_KEY_SAFESITES, |
| 95 | STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_SAFESITES), |
| 96 | NULL, |
| 97 | std::string(), |
| 98 | environment.get(), |
| 99 | command_line); |
| 100 | |
[email protected] | 007b3f8 | 2013-04-09 08:46:45 | [diff] [blame] | 101 | std::string default_client_id = |
| 102 | CalculateKeyValue(GOOGLE_DEFAULT_CLIENT_ID, |
| 103 | STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_ID), |
| 104 | NULL, |
| 105 | std::string(), |
| 106 | environment.get(), |
| 107 | command_line); |
| 108 | std::string default_client_secret = |
| 109 | CalculateKeyValue(GOOGLE_DEFAULT_CLIENT_SECRET, |
| 110 | STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_SECRET), |
| 111 | NULL, |
| 112 | std::string(), |
| 113 | environment.get(), |
| 114 | command_line); |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 115 | |
| 116 | // We currently only allow overriding the baked-in values for the |
| 117 | // default OAuth2 client ID and secret using a command-line |
| 118 | // argument, since that is useful to enable testing against |
| 119 | // staging servers, and since that was what was possible and |
| 120 | // likely practiced by the QA team before this implementation was |
| 121 | // written. |
| 122 | client_ids_[CLIENT_MAIN] = CalculateKeyValue( |
| 123 | GOOGLE_CLIENT_ID_MAIN, |
| 124 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_MAIN), |
| 125 | switches::kOAuth2ClientID, |
| 126 | default_client_id, |
| 127 | environment.get(), |
| 128 | command_line); |
| 129 | client_secrets_[CLIENT_MAIN] = CalculateKeyValue( |
| 130 | GOOGLE_CLIENT_SECRET_MAIN, |
| 131 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_MAIN), |
| 132 | switches::kOAuth2ClientSecret, |
| 133 | default_client_secret, |
| 134 | environment.get(), |
| 135 | command_line); |
| 136 | |
| 137 | client_ids_[CLIENT_CLOUD_PRINT] = CalculateKeyValue( |
| 138 | GOOGLE_CLIENT_ID_CLOUD_PRINT, |
| 139 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_CLOUD_PRINT), |
| 140 | NULL, |
| 141 | default_client_id, |
| 142 | environment.get(), |
| 143 | command_line); |
| 144 | client_secrets_[CLIENT_CLOUD_PRINT] = CalculateKeyValue( |
| 145 | GOOGLE_CLIENT_SECRET_CLOUD_PRINT, |
| 146 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_CLOUD_PRINT), |
| 147 | NULL, |
| 148 | default_client_secret, |
| 149 | environment.get(), |
| 150 | command_line); |
| 151 | |
| 152 | client_ids_[CLIENT_REMOTING] = CalculateKeyValue( |
| 153 | GOOGLE_CLIENT_ID_REMOTING, |
| 154 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_REMOTING), |
| 155 | NULL, |
| 156 | default_client_id, |
| 157 | environment.get(), |
| 158 | command_line); |
| 159 | client_secrets_[CLIENT_REMOTING] = CalculateKeyValue( |
| 160 | GOOGLE_CLIENT_SECRET_REMOTING, |
| 161 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_REMOTING), |
| 162 | NULL, |
| 163 | default_client_secret, |
| 164 | environment.get(), |
| 165 | command_line); |
[email protected] | d66d8174 | 2013-08-16 05:18:38 | [diff] [blame] | 166 | |
| 167 | client_ids_[CLIENT_REMOTING_HOST] = CalculateKeyValue( |
| 168 | GOOGLE_CLIENT_ID_REMOTING_HOST, |
| 169 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_REMOTING_HOST), |
| 170 | NULL, |
| 171 | default_client_id, |
| 172 | environment.get(), |
| 173 | command_line); |
| 174 | client_secrets_[CLIENT_REMOTING_HOST] = CalculateKeyValue( |
| 175 | GOOGLE_CLIENT_SECRET_REMOTING_HOST, |
| 176 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_REMOTING_HOST), |
| 177 | NULL, |
| 178 | default_client_secret, |
| 179 | environment.get(), |
| 180 | command_line); |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 181 | } |
| 182 | |
| 183 | std::string api_key() const { return api_key_; } |
treib | e81fd0f | 2014-11-24 12:35:48 | [diff] [blame] | 184 | std::string api_key_safesites() const { return api_key_safesites_; } |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 185 | |
| 186 | std::string GetClientID(OAuth2Client client) const { |
| 187 | DCHECK_LT(client, CLIENT_NUM_ITEMS); |
| 188 | return client_ids_[client]; |
| 189 | } |
| 190 | |
| 191 | std::string GetClientSecret(OAuth2Client client) const { |
| 192 | DCHECK_LT(client, CLIENT_NUM_ITEMS); |
| 193 | return client_secrets_[client]; |
| 194 | } |
| 195 | |
kundaji | 033fb6ec | 2014-10-15 19:11:08 | [diff] [blame] | 196 | std::string GetSpdyProxyAuthValue() { |
| 197 | #if defined(SPDY_PROXY_AUTH_VALUE) |
| 198 | return SPDY_PROXY_AUTH_VALUE; |
Antoine Labour | e2bda94f | 2014-10-27 19:04:36 | [diff] [blame] | 199 | #else |
kundaji | 033fb6ec | 2014-10-15 19:11:08 | [diff] [blame] | 200 | return std::string(); |
Antoine Labour | e2bda94f | 2014-10-27 19:04:36 | [diff] [blame] | 201 | #endif |
kundaji | 033fb6ec | 2014-10-15 19:11:08 | [diff] [blame] | 202 | } |
| 203 | |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 204 | private: |
| 205 | // Gets a value for a key. In priority order, this will be the value |
| 206 | // provided via a command-line switch, the value provided via an |
| 207 | // environment variable, or finally a value baked into the build. |
| 208 | // |command_line_switch| may be NULL. |
| 209 | static std::string CalculateKeyValue(const char* baked_in_value, |
| 210 | const char* environment_variable_name, |
| 211 | const char* command_line_switch, |
| 212 | const std::string& default_if_unset, |
| 213 | base::Environment* environment, |
avi | 9ab03720 | 2014-12-22 23:49:53 | [diff] [blame] | 214 | base::CommandLine* command_line) { |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 215 | std::string key_value = baked_in_value; |
| 216 | std::string temp; |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame] | 217 | if (environment->GetVar(environment_variable_name, &temp)) { |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 218 | key_value = temp; |
[email protected] | 9430533 | 2013-11-25 22:32:05 | [diff] [blame] | 219 | VLOG(1) << "Overriding API key " << environment_variable_name |
| 220 | << " with value " << key_value << " from environment variable."; |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame] | 221 | } |
| 222 | |
| 223 | if (command_line_switch && command_line->HasSwitch(command_line_switch)) { |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 224 | key_value = command_line->GetSwitchValueASCII(command_line_switch); |
[email protected] | 9430533 | 2013-11-25 22:32:05 | [diff] [blame] | 225 | VLOG(1) << "Overriding API key " << environment_variable_name |
| 226 | << " with value " << key_value << " from command-line switch."; |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame] | 227 | } |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 228 | |
[email protected] | 2b11365 | 2012-09-17 17:01:39 | [diff] [blame] | 229 | if (key_value == DUMMY_API_TOKEN) { |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 230 | #if defined(GOOGLE_CHROME_BUILD) |
[email protected] | 2b11365 | 2012-09-17 17:01:39 | [diff] [blame] | 231 | // No key should be unset in an official build except the |
| 232 | // GOOGLE_DEFAULT_* keys. The default keys don't trigger this |
| 233 | // check as their "unset" value is not DUMMY_API_TOKEN. |
| 234 | CHECK(false); |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 235 | #endif |
[email protected] | 2b11365 | 2012-09-17 17:01:39 | [diff] [blame] | 236 | if (default_if_unset.size() > 0) { |
[email protected] | 9430533 | 2013-11-25 22:32:05 | [diff] [blame] | 237 | VLOG(1) << "Using default value \"" << default_if_unset |
| 238 | << "\" for API key " << environment_variable_name; |
[email protected] | 2b11365 | 2012-09-17 17:01:39 | [diff] [blame] | 239 | key_value = default_if_unset; |
| 240 | } |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 241 | } |
| 242 | |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame] | 243 | // This should remain a debug-only log. |
| 244 | DVLOG(1) << "API key " << environment_variable_name << "=" << key_value; |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 245 | |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame] | 246 | return key_value; |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 247 | } |
| 248 | |
| 249 | std::string api_key_; |
treib | e81fd0f | 2014-11-24 12:35:48 | [diff] [blame] | 250 | std::string api_key_safesites_; |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 251 | std::string client_ids_[CLIENT_NUM_ITEMS]; |
| 252 | std::string client_secrets_[CLIENT_NUM_ITEMS]; |
| 253 | }; |
| 254 | |
| 255 | static base::LazyInstance<APIKeyCache> g_api_key_cache = |
| 256 | LAZY_INSTANCE_INITIALIZER; |
| 257 | |
[email protected] | e7dd789 | 2013-05-16 19:10:40 | [diff] [blame] | 258 | bool HasKeysConfigured() { |
| 259 | if (GetAPIKey() == DUMMY_API_TOKEN) |
| 260 | return false; |
| 261 | |
| 262 | for (size_t client_id = 0; client_id < CLIENT_NUM_ITEMS; ++client_id) { |
| 263 | OAuth2Client client = static_cast<OAuth2Client>(client_id); |
| 264 | if (GetOAuth2ClientID(client) == DUMMY_API_TOKEN || |
| 265 | GetOAuth2ClientSecret(client) == DUMMY_API_TOKEN) { |
| 266 | return false; |
| 267 | } |
| 268 | } |
| 269 | |
| 270 | return true; |
| 271 | } |
| 272 | |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 273 | std::string GetAPIKey() { |
| 274 | return g_api_key_cache.Get().api_key(); |
| 275 | } |
| 276 | |
treib | e81fd0f | 2014-11-24 12:35:48 | [diff] [blame] | 277 | std::string GetSafeSitesAPIKey() { |
| 278 | return g_api_key_cache.Get().api_key_safesites(); |
| 279 | } |
| 280 | |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 281 | std::string GetOAuth2ClientID(OAuth2Client client) { |
| 282 | return g_api_key_cache.Get().GetClientID(client); |
| 283 | } |
| 284 | |
| 285 | std::string GetOAuth2ClientSecret(OAuth2Client client) { |
| 286 | return g_api_key_cache.Get().GetClientSecret(client); |
| 287 | } |
| 288 | |
kundaji | 033fb6ec | 2014-10-15 19:11:08 | [diff] [blame] | 289 | std::string GetSpdyProxyAuthValue() { |
| 290 | return g_api_key_cache.Get().GetSpdyProxyAuthValue(); |
| 291 | } |
| 292 | |
[email protected] | e4b54e3 | 2014-01-17 13:55:20 | [diff] [blame] | 293 | bool IsGoogleChromeAPIKeyUsed() { |
| 294 | #if defined(GOOGLE_CHROME_BUILD) || defined(USE_OFFICIAL_GOOGLE_API_KEYS) |
| 295 | return true; |
| 296 | #else |
| 297 | return false; |
| 298 | #endif |
| 299 | } |
| 300 | |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 301 | } // namespace google_apis |