[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 | |
| 7 | #include "base/command_line.h" |
| 8 | #include "base/environment.h" |
| 9 | #include "base/lazy_instance.h" |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame^] | 10 | #include "base/logging.h" |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 11 | #include "base/memory/scoped_ptr.h" |
| 12 | #include "base/stringize_macros.h" |
| 13 | |
| 14 | #if defined(GOOGLE_CHROME_BUILD) |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame^] | 15 | #include "google_apis/internal/google_chrome_api_keys.h" |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 16 | #endif |
| 17 | |
| 18 | #if !defined(GOOGLE_API_KEY) |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame^] | 19 | // TODO(joi): Make this blank once it is set via include.gypi. |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 20 | #define GOOGLE_API_KEY "abcNOTREALKEYxyz" |
| 21 | #endif |
| 22 | |
| 23 | #if !defined(GOOGLE_CLIENT_ID_MAIN) |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame^] | 24 | // TODO(joi): Make this blank once it is set via include.gypi. |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 25 | #define GOOGLE_CLIENT_ID_MAIN "77185425430.apps.googleusercontent.com" |
| 26 | #endif |
| 27 | |
| 28 | #if !defined(GOOGLE_CLIENT_SECRET_MAIN) |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame^] | 29 | // TODO(joi): Make this blank once it is set via include.gypi. |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 30 | #define GOOGLE_CLIENT_SECRET_MAIN "OTJgUOQcT7lO7GsGZq2G4IlT" |
| 31 | #endif |
| 32 | |
| 33 | #if !defined(GOOGLE_CLIENT_ID_CLOUD_PRINT) |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame^] | 34 | // TODO(joi): Make this blank once it is set via include.gypi. |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 35 | #define GOOGLE_CLIENT_ID_CLOUD_PRINT "551556820943.apps.googleusercontent.com" |
| 36 | #endif |
| 37 | |
| 38 | #if !defined(GOOGLE_CLIENT_SECRET_CLOUD_PRINT) |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame^] | 39 | // TODO(joi): Make this blank once it is set via include.gypi. |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 40 | #define GOOGLE_CLIENT_SECRET_CLOUD_PRINT "u3/mp8CgLFxh4uiX1855/MHe" |
| 41 | #endif |
| 42 | |
| 43 | #if !defined(GOOGLE_CLIENT_ID_REMOTING) |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame^] | 44 | // TODO(joi): Make this blank once it is set via include.gypi. |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 45 | #define GOOGLE_CLIENT_ID_REMOTING \ |
| 46 | "440925447803-avn2sj1kc099s0r7v62je5s339mu0am1.apps.googleusercontent.com" |
| 47 | #endif |
| 48 | |
| 49 | #if !defined(GOOGLE_CLIENT_SECRET_REMOTING) |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame^] | 50 | // TODO(joi): Make this blank once it is set via include.gypi. |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 51 | #define GOOGLE_CLIENT_SECRET_REMOTING "Bgur6DFiOMM1h8x-AQpuTQlK" |
| 52 | #endif |
| 53 | |
| 54 | // These are used as shortcuts for developers and users providing |
| 55 | // OAuth credentials via preprocessor defines or environment |
| 56 | // variables. If set, they will be used to replace any of the client |
| 57 | // IDs and secrets above that have not been set (and only those; they |
| 58 | // will not override already-set values). |
| 59 | #if !defined(GOOGLE_DEFAULT_CLIENT_ID) |
| 60 | #define GOOGLE_DEFAULT_CLIENT_ID "" |
| 61 | #endif |
| 62 | #if !defined(GOOGLE_DEFAULT_CLIENT_SECRET) |
| 63 | #define GOOGLE_DEFAULT_CLIENT_SECRET "" |
| 64 | #endif |
| 65 | |
| 66 | namespace switches { |
| 67 | |
| 68 | // Specifies custom OAuth2 client id for testing purposes. |
| 69 | const char kOAuth2ClientID[] = "oauth2-client-id"; |
| 70 | |
| 71 | // Specifies custom OAuth2 client secret for testing purposes. |
| 72 | const char kOAuth2ClientSecret[] = "oauth2-client-secret"; |
| 73 | |
| 74 | } // namespace switches |
| 75 | |
| 76 | namespace google_apis { |
| 77 | |
| 78 | namespace { |
| 79 | |
| 80 | // This is used as a lazy instance to determine keys once and cache them. |
| 81 | class APIKeyCache { |
| 82 | public: |
| 83 | APIKeyCache() { |
| 84 | scoped_ptr<base::Environment> environment(base::Environment::Create()); |
| 85 | CommandLine* command_line = CommandLine::ForCurrentProcess(); |
| 86 | |
| 87 | api_key_ = CalculateKeyValue(GOOGLE_API_KEY, |
| 88 | STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY), |
| 89 | NULL, "", |
| 90 | environment.get(), |
| 91 | command_line); |
| 92 | |
| 93 | std::string default_client_id = CalculateKeyValue( |
| 94 | GOOGLE_DEFAULT_CLIENT_ID, |
| 95 | STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_ID), |
| 96 | NULL, "", |
| 97 | environment.get(), |
| 98 | command_line); |
| 99 | std::string default_client_secret = CalculateKeyValue( |
| 100 | GOOGLE_DEFAULT_CLIENT_SECRET, |
| 101 | STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_SECRET), |
| 102 | NULL, "", |
| 103 | environment.get(), |
| 104 | command_line); |
| 105 | |
| 106 | // We currently only allow overriding the baked-in values for the |
| 107 | // default OAuth2 client ID and secret using a command-line |
| 108 | // argument, since that is useful to enable testing against |
| 109 | // staging servers, and since that was what was possible and |
| 110 | // likely practiced by the QA team before this implementation was |
| 111 | // written. |
| 112 | client_ids_[CLIENT_MAIN] = CalculateKeyValue( |
| 113 | GOOGLE_CLIENT_ID_MAIN, |
| 114 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_MAIN), |
| 115 | switches::kOAuth2ClientID, |
| 116 | default_client_id, |
| 117 | environment.get(), |
| 118 | command_line); |
| 119 | client_secrets_[CLIENT_MAIN] = CalculateKeyValue( |
| 120 | GOOGLE_CLIENT_SECRET_MAIN, |
| 121 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_MAIN), |
| 122 | switches::kOAuth2ClientSecret, |
| 123 | default_client_secret, |
| 124 | environment.get(), |
| 125 | command_line); |
| 126 | |
| 127 | client_ids_[CLIENT_CLOUD_PRINT] = CalculateKeyValue( |
| 128 | GOOGLE_CLIENT_ID_CLOUD_PRINT, |
| 129 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_CLOUD_PRINT), |
| 130 | NULL, |
| 131 | default_client_id, |
| 132 | environment.get(), |
| 133 | command_line); |
| 134 | client_secrets_[CLIENT_CLOUD_PRINT] = CalculateKeyValue( |
| 135 | GOOGLE_CLIENT_SECRET_CLOUD_PRINT, |
| 136 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_CLOUD_PRINT), |
| 137 | NULL, |
| 138 | default_client_secret, |
| 139 | environment.get(), |
| 140 | command_line); |
| 141 | |
| 142 | client_ids_[CLIENT_REMOTING] = CalculateKeyValue( |
| 143 | GOOGLE_CLIENT_ID_REMOTING, |
| 144 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_REMOTING), |
| 145 | NULL, |
| 146 | default_client_id, |
| 147 | environment.get(), |
| 148 | command_line); |
| 149 | client_secrets_[CLIENT_REMOTING] = CalculateKeyValue( |
| 150 | GOOGLE_CLIENT_SECRET_REMOTING, |
| 151 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_REMOTING), |
| 152 | NULL, |
| 153 | default_client_secret, |
| 154 | environment.get(), |
| 155 | command_line); |
| 156 | } |
| 157 | |
| 158 | std::string api_key() const { return api_key_; } |
| 159 | |
| 160 | std::string GetClientID(OAuth2Client client) const { |
| 161 | DCHECK_LT(client, CLIENT_NUM_ITEMS); |
| 162 | return client_ids_[client]; |
| 163 | } |
| 164 | |
| 165 | std::string GetClientSecret(OAuth2Client client) const { |
| 166 | DCHECK_LT(client, CLIENT_NUM_ITEMS); |
| 167 | return client_secrets_[client]; |
| 168 | } |
| 169 | |
| 170 | private: |
| 171 | // Gets a value for a key. In priority order, this will be the value |
| 172 | // provided via a command-line switch, the value provided via an |
| 173 | // environment variable, or finally a value baked into the build. |
| 174 | // |command_line_switch| may be NULL. |
| 175 | static std::string CalculateKeyValue(const char* baked_in_value, |
| 176 | const char* environment_variable_name, |
| 177 | const char* command_line_switch, |
| 178 | const std::string& default_if_unset, |
| 179 | base::Environment* environment, |
| 180 | CommandLine* command_line) { |
| 181 | std::string key_value = baked_in_value; |
| 182 | std::string temp; |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame^] | 183 | if (environment->GetVar(environment_variable_name, &temp)) { |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 184 | key_value = temp; |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame^] | 185 | LOG(INFO) << "Overriding API key " << environment_variable_name |
| 186 | << " with value " << key_value << " from environment variable."; |
| 187 | } |
| 188 | |
| 189 | if (command_line_switch && command_line->HasSwitch(command_line_switch)) { |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 190 | key_value = command_line->GetSwitchValueASCII(command_line_switch); |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame^] | 191 | LOG(INFO) << "Overriding API key " << environment_variable_name |
| 192 | << " with value " << key_value << " from command-line switch."; |
| 193 | } |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 194 | |
| 195 | if (key_value.size() == 0) { |
| 196 | #if defined(GOOGLE_CHROME_BUILD) |
| 197 | // No key should be empty in an official build, except the |
| 198 | // default keys themselves, which will have an empty default. |
| 199 | CHECK(default_if_unset.size() == 0); |
| 200 | #endif |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame^] | 201 | LOG(INFO) << "Using default value \"" << default_if_unset |
| 202 | << "\" for API key " << environment_variable_name; |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 203 | key_value = default_if_unset; |
| 204 | } |
| 205 | |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame^] | 206 | // This should remain a debug-only log. |
| 207 | DVLOG(1) << "API key " << environment_variable_name << "=" << key_value; |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 208 | |
[email protected] | b08bf82 | 2012-09-11 21:50:38 | [diff] [blame^] | 209 | return key_value; |
[email protected] | e5e894ff | 2012-09-06 02:18:47 | [diff] [blame] | 210 | } |
| 211 | |
| 212 | std::string api_key_; |
| 213 | std::string client_ids_[CLIENT_NUM_ITEMS]; |
| 214 | std::string client_secrets_[CLIENT_NUM_ITEMS]; |
| 215 | }; |
| 216 | |
| 217 | static base::LazyInstance<APIKeyCache> g_api_key_cache = |
| 218 | LAZY_INSTANCE_INITIALIZER; |
| 219 | |
| 220 | } // namespace |
| 221 | |
| 222 | std::string GetAPIKey() { |
| 223 | return g_api_key_cache.Get().api_key(); |
| 224 | } |
| 225 | |
| 226 | std::string GetOAuth2ClientID(OAuth2Client client) { |
| 227 | return g_api_key_cache.Get().GetClientID(client); |
| 228 | } |
| 229 | |
| 230 | std::string GetOAuth2ClientSecret(OAuth2Client client) { |
| 231 | return g_api_key_cache.Get().GetClientSecret(client); |
| 232 | } |
| 233 | |
| 234 | } // namespace google_apis |