blob: 6a2dd3de904fdd7e10463fd049d4f4ae98bf621b [file] [log] [blame]
[email protected]e5e894ff2012-09-06 02:18:471// 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]6386cf52012-09-07 04:26:375#include "google_apis/google_api_keys.h"
[email protected]e5e894ff2012-09-06 02:18:476
[email protected]e03604b2013-01-10 23:38:227// If you add more includes to this list, you also need to add them to
8// google_api_keys_unittest.cc.
[email protected]e5e894ff2012-09-06 02:18:479#include "base/command_line.h"
10#include "base/environment.h"
11#include "base/lazy_instance.h"
[email protected]b08bf822012-09-11 21:50:3812#include "base/logging.h"
[email protected]e5e894ff2012-09-06 02:18:4713#include "base/memory/scoped_ptr.h"
[email protected]8edbebd2013-01-31 19:45:0214#include "base/strings/stringize_macros.h"
[email protected]850b353e2014-02-11 15:56:2815#include "google_apis/gaia/gaia_switches.h"
[email protected]e5e894ff2012-09-06 02:18:4716
[email protected]d647e282012-09-13 13:10:1017#if defined(GOOGLE_CHROME_BUILD) || defined(USE_OFFICIAL_GOOGLE_API_KEYS)
[email protected]b08bf822012-09-11 21:50:3818#include "google_apis/internal/google_chrome_api_keys.h"
[email protected]e5e894ff2012-09-06 02:18:4719#endif
20
[email protected]d647e282012-09-13 13:10:1021// 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]e5e894ff2012-09-06 02:18:4725#if !defined(GOOGLE_API_KEY)
[email protected]1abac7a2013-01-31 14:01:2526#define GOOGLE_API_KEY DUMMY_API_TOKEN
[email protected]e5e894ff2012-09-06 02:18:4727#endif
28
treibe81fd0f2014-11-24 12:35:4829#if !defined(GOOGLE_API_KEY_SAFESITES)
30#define GOOGLE_API_KEY_SAFESITES DUMMY_API_TOKEN
31#endif
32
[email protected]e5e894ff2012-09-06 02:18:4733#if !defined(GOOGLE_CLIENT_ID_MAIN)
[email protected]fc2212d2012-09-17 17:33:2034#define GOOGLE_CLIENT_ID_MAIN DUMMY_API_TOKEN
[email protected]e5e894ff2012-09-06 02:18:4735#endif
36
37#if !defined(GOOGLE_CLIENT_SECRET_MAIN)
[email protected]fc2212d2012-09-17 17:33:2038#define GOOGLE_CLIENT_SECRET_MAIN DUMMY_API_TOKEN
[email protected]e5e894ff2012-09-06 02:18:4739#endif
40
41#if !defined(GOOGLE_CLIENT_ID_CLOUD_PRINT)
[email protected]fc2212d2012-09-17 17:33:2042#define GOOGLE_CLIENT_ID_CLOUD_PRINT DUMMY_API_TOKEN
[email protected]e5e894ff2012-09-06 02:18:4743#endif
44
45#if !defined(GOOGLE_CLIENT_SECRET_CLOUD_PRINT)
[email protected]fc2212d2012-09-17 17:33:2046#define GOOGLE_CLIENT_SECRET_CLOUD_PRINT DUMMY_API_TOKEN
[email protected]e5e894ff2012-09-06 02:18:4747#endif
48
49#if !defined(GOOGLE_CLIENT_ID_REMOTING)
[email protected]fc2212d2012-09-17 17:33:2050#define GOOGLE_CLIENT_ID_REMOTING DUMMY_API_TOKEN
[email protected]e5e894ff2012-09-06 02:18:4751#endif
52
53#if !defined(GOOGLE_CLIENT_SECRET_REMOTING)
[email protected]fc2212d2012-09-17 17:33:2054#define GOOGLE_CLIENT_SECRET_REMOTING DUMMY_API_TOKEN
[email protected]e5e894ff2012-09-06 02:18:4755#endif
56
[email protected]d66d81742013-08-16 05:18:3857#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]e5e894ff2012-09-06 02:18:4765// 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]1abac7a2013-01-31 14:01:2571#define GOOGLE_DEFAULT_CLIENT_ID ""
[email protected]e5e894ff2012-09-06 02:18:4772#endif
73#if !defined(GOOGLE_DEFAULT_CLIENT_SECRET)
[email protected]1abac7a2013-01-31 14:01:2574#define GOOGLE_DEFAULT_CLIENT_SECRET ""
[email protected]e5e894ff2012-09-06 02:18:4775#endif
76
[email protected]e5e894ff2012-09-06 02:18:4777namespace google_apis {
78
[email protected]e5e894ff2012-09-06 02:18:4779// This is used as a lazy instance to determine keys once and cache them.
80class APIKeyCache {
81 public:
82 APIKeyCache() {
83 scoped_ptr<base::Environment> environment(base::Environment::Create());
avi9ab037202014-12-22 23:49:5384 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
[email protected]e5e894ff2012-09-06 02:18:4785
86 api_key_ = CalculateKeyValue(GOOGLE_API_KEY,
87 STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY),
[email protected]007b3f82013-04-09 08:46:4588 NULL,
89 std::string(),
[email protected]e5e894ff2012-09-06 02:18:4790 environment.get(),
91 command_line);
92
treibe81fd0f2014-11-24 12:35:4893 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]007b3f82013-04-09 08:46:45101 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]e5e894ff2012-09-06 02:18:47115
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]d66d81742013-08-16 05:18:38166
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]e5e894ff2012-09-06 02:18:47181 }
182
183 std::string api_key() const { return api_key_; }
treibe81fd0f2014-11-24 12:35:48184 std::string api_key_safesites() const { return api_key_safesites_; }
[email protected]e5e894ff2012-09-06 02:18:47185
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
kundaji033fb6ec2014-10-15 19:11:08196 std::string GetSpdyProxyAuthValue() {
197#if defined(SPDY_PROXY_AUTH_VALUE)
198 return SPDY_PROXY_AUTH_VALUE;
Antoine Laboure2bda94f2014-10-27 19:04:36199#else
kundaji033fb6ec2014-10-15 19:11:08200 return std::string();
Antoine Laboure2bda94f2014-10-27 19:04:36201#endif
kundaji033fb6ec2014-10-15 19:11:08202 }
203
[email protected]e5e894ff2012-09-06 02:18:47204 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,
avi9ab037202014-12-22 23:49:53214 base::CommandLine* command_line) {
[email protected]e5e894ff2012-09-06 02:18:47215 std::string key_value = baked_in_value;
216 std::string temp;
[email protected]b08bf822012-09-11 21:50:38217 if (environment->GetVar(environment_variable_name, &temp)) {
[email protected]e5e894ff2012-09-06 02:18:47218 key_value = temp;
[email protected]94305332013-11-25 22:32:05219 VLOG(1) << "Overriding API key " << environment_variable_name
220 << " with value " << key_value << " from environment variable.";
[email protected]b08bf822012-09-11 21:50:38221 }
222
223 if (command_line_switch && command_line->HasSwitch(command_line_switch)) {
[email protected]e5e894ff2012-09-06 02:18:47224 key_value = command_line->GetSwitchValueASCII(command_line_switch);
[email protected]94305332013-11-25 22:32:05225 VLOG(1) << "Overriding API key " << environment_variable_name
226 << " with value " << key_value << " from command-line switch.";
[email protected]b08bf822012-09-11 21:50:38227 }
[email protected]e5e894ff2012-09-06 02:18:47228
[email protected]2b113652012-09-17 17:01:39229 if (key_value == DUMMY_API_TOKEN) {
[email protected]e5e894ff2012-09-06 02:18:47230#if defined(GOOGLE_CHROME_BUILD)
[email protected]2b113652012-09-17 17:01:39231 // 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]e5e894ff2012-09-06 02:18:47235#endif
[email protected]2b113652012-09-17 17:01:39236 if (default_if_unset.size() > 0) {
[email protected]94305332013-11-25 22:32:05237 VLOG(1) << "Using default value \"" << default_if_unset
238 << "\" for API key " << environment_variable_name;
[email protected]2b113652012-09-17 17:01:39239 key_value = default_if_unset;
240 }
[email protected]e5e894ff2012-09-06 02:18:47241 }
242
[email protected]b08bf822012-09-11 21:50:38243 // This should remain a debug-only log.
244 DVLOG(1) << "API key " << environment_variable_name << "=" << key_value;
[email protected]e5e894ff2012-09-06 02:18:47245
[email protected]b08bf822012-09-11 21:50:38246 return key_value;
[email protected]e5e894ff2012-09-06 02:18:47247 }
248
249 std::string api_key_;
treibe81fd0f2014-11-24 12:35:48250 std::string api_key_safesites_;
[email protected]e5e894ff2012-09-06 02:18:47251 std::string client_ids_[CLIENT_NUM_ITEMS];
252 std::string client_secrets_[CLIENT_NUM_ITEMS];
253};
254
255static base::LazyInstance<APIKeyCache> g_api_key_cache =
256 LAZY_INSTANCE_INITIALIZER;
257
[email protected]e7dd7892013-05-16 19:10:40258bool 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]e5e894ff2012-09-06 02:18:47273std::string GetAPIKey() {
274 return g_api_key_cache.Get().api_key();
275}
276
treibe81fd0f2014-11-24 12:35:48277std::string GetSafeSitesAPIKey() {
278 return g_api_key_cache.Get().api_key_safesites();
279}
280
[email protected]e5e894ff2012-09-06 02:18:47281std::string GetOAuth2ClientID(OAuth2Client client) {
282 return g_api_key_cache.Get().GetClientID(client);
283}
284
285std::string GetOAuth2ClientSecret(OAuth2Client client) {
286 return g_api_key_cache.Get().GetClientSecret(client);
287}
288
kundaji033fb6ec2014-10-15 19:11:08289std::string GetSpdyProxyAuthValue() {
290 return g_api_key_cache.Get().GetSpdyProxyAuthValue();
291}
292
[email protected]e4b54e32014-01-17 13:55:20293bool 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]e5e894ff2012-09-06 02:18:47301} // namespace google_apis