blob: f879979bc78a49baafabf0ac192f96bb68c95ea0 [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
29#if !defined(GOOGLE_CLIENT_ID_MAIN)
[email protected]fc2212d2012-09-17 17:33:2030#define GOOGLE_CLIENT_ID_MAIN DUMMY_API_TOKEN
[email protected]e5e894ff2012-09-06 02:18:4731#endif
32
33#if !defined(GOOGLE_CLIENT_SECRET_MAIN)
[email protected]fc2212d2012-09-17 17:33:2034#define GOOGLE_CLIENT_SECRET_MAIN DUMMY_API_TOKEN
[email protected]e5e894ff2012-09-06 02:18:4735#endif
36
37#if !defined(GOOGLE_CLIENT_ID_CLOUD_PRINT)
[email protected]fc2212d2012-09-17 17:33:2038#define GOOGLE_CLIENT_ID_CLOUD_PRINT DUMMY_API_TOKEN
[email protected]e5e894ff2012-09-06 02:18:4739#endif
40
41#if !defined(GOOGLE_CLIENT_SECRET_CLOUD_PRINT)
[email protected]fc2212d2012-09-17 17:33:2042#define GOOGLE_CLIENT_SECRET_CLOUD_PRINT DUMMY_API_TOKEN
[email protected]e5e894ff2012-09-06 02:18:4743#endif
44
45#if !defined(GOOGLE_CLIENT_ID_REMOTING)
[email protected]fc2212d2012-09-17 17:33:2046#define GOOGLE_CLIENT_ID_REMOTING DUMMY_API_TOKEN
[email protected]e5e894ff2012-09-06 02:18:4747#endif
48
49#if !defined(GOOGLE_CLIENT_SECRET_REMOTING)
[email protected]fc2212d2012-09-17 17:33:2050#define GOOGLE_CLIENT_SECRET_REMOTING DUMMY_API_TOKEN
[email protected]e5e894ff2012-09-06 02:18:4751#endif
52
[email protected]d66d81742013-08-16 05:18:3853#if !defined(GOOGLE_CLIENT_ID_REMOTING_HOST)
54#define GOOGLE_CLIENT_ID_REMOTING_HOST DUMMY_API_TOKEN
55#endif
56
57#if !defined(GOOGLE_CLIENT_SECRET_REMOTING_HOST)
58#define GOOGLE_CLIENT_SECRET_REMOTING_HOST DUMMY_API_TOKEN
59#endif
60
[email protected]e5e894ff2012-09-06 02:18:4761// These are used as shortcuts for developers and users providing
62// OAuth credentials via preprocessor defines or environment
63// variables. If set, they will be used to replace any of the client
64// IDs and secrets above that have not been set (and only those; they
65// will not override already-set values).
66#if !defined(GOOGLE_DEFAULT_CLIENT_ID)
[email protected]1abac7a2013-01-31 14:01:2567#define GOOGLE_DEFAULT_CLIENT_ID ""
[email protected]e5e894ff2012-09-06 02:18:4768#endif
69#if !defined(GOOGLE_DEFAULT_CLIENT_SECRET)
[email protected]1abac7a2013-01-31 14:01:2570#define GOOGLE_DEFAULT_CLIENT_SECRET ""
[email protected]e5e894ff2012-09-06 02:18:4771#endif
72
[email protected]e5e894ff2012-09-06 02:18:4773namespace google_apis {
74
[email protected]e5e894ff2012-09-06 02:18:4775// This is used as a lazy instance to determine keys once and cache them.
76class APIKeyCache {
77 public:
78 APIKeyCache() {
79 scoped_ptr<base::Environment> environment(base::Environment::Create());
80 CommandLine* command_line = CommandLine::ForCurrentProcess();
81
82 api_key_ = CalculateKeyValue(GOOGLE_API_KEY,
83 STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY),
[email protected]007b3f82013-04-09 08:46:4584 NULL,
85 std::string(),
[email protected]e5e894ff2012-09-06 02:18:4786 environment.get(),
87 command_line);
88
[email protected]007b3f82013-04-09 08:46:4589 std::string default_client_id =
90 CalculateKeyValue(GOOGLE_DEFAULT_CLIENT_ID,
91 STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_ID),
92 NULL,
93 std::string(),
94 environment.get(),
95 command_line);
96 std::string default_client_secret =
97 CalculateKeyValue(GOOGLE_DEFAULT_CLIENT_SECRET,
98 STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_SECRET),
99 NULL,
100 std::string(),
101 environment.get(),
102 command_line);
[email protected]e5e894ff2012-09-06 02:18:47103
104 // We currently only allow overriding the baked-in values for the
105 // default OAuth2 client ID and secret using a command-line
106 // argument, since that is useful to enable testing against
107 // staging servers, and since that was what was possible and
108 // likely practiced by the QA team before this implementation was
109 // written.
110 client_ids_[CLIENT_MAIN] = CalculateKeyValue(
111 GOOGLE_CLIENT_ID_MAIN,
112 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_MAIN),
113 switches::kOAuth2ClientID,
114 default_client_id,
115 environment.get(),
116 command_line);
117 client_secrets_[CLIENT_MAIN] = CalculateKeyValue(
118 GOOGLE_CLIENT_SECRET_MAIN,
119 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_MAIN),
120 switches::kOAuth2ClientSecret,
121 default_client_secret,
122 environment.get(),
123 command_line);
124
125 client_ids_[CLIENT_CLOUD_PRINT] = CalculateKeyValue(
126 GOOGLE_CLIENT_ID_CLOUD_PRINT,
127 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_CLOUD_PRINT),
128 NULL,
129 default_client_id,
130 environment.get(),
131 command_line);
132 client_secrets_[CLIENT_CLOUD_PRINT] = CalculateKeyValue(
133 GOOGLE_CLIENT_SECRET_CLOUD_PRINT,
134 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_CLOUD_PRINT),
135 NULL,
136 default_client_secret,
137 environment.get(),
138 command_line);
139
140 client_ids_[CLIENT_REMOTING] = CalculateKeyValue(
141 GOOGLE_CLIENT_ID_REMOTING,
142 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_REMOTING),
143 NULL,
144 default_client_id,
145 environment.get(),
146 command_line);
147 client_secrets_[CLIENT_REMOTING] = CalculateKeyValue(
148 GOOGLE_CLIENT_SECRET_REMOTING,
149 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_REMOTING),
150 NULL,
151 default_client_secret,
152 environment.get(),
153 command_line);
[email protected]d66d81742013-08-16 05:18:38154
155 client_ids_[CLIENT_REMOTING_HOST] = CalculateKeyValue(
156 GOOGLE_CLIENT_ID_REMOTING_HOST,
157 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_REMOTING_HOST),
158 NULL,
159 default_client_id,
160 environment.get(),
161 command_line);
162 client_secrets_[CLIENT_REMOTING_HOST] = CalculateKeyValue(
163 GOOGLE_CLIENT_SECRET_REMOTING_HOST,
164 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_REMOTING_HOST),
165 NULL,
166 default_client_secret,
167 environment.get(),
168 command_line);
[email protected]e5e894ff2012-09-06 02:18:47169 }
170
171 std::string api_key() const { return api_key_; }
172
173 std::string GetClientID(OAuth2Client client) const {
174 DCHECK_LT(client, CLIENT_NUM_ITEMS);
175 return client_ids_[client];
176 }
177
178 std::string GetClientSecret(OAuth2Client client) const {
179 DCHECK_LT(client, CLIENT_NUM_ITEMS);
180 return client_secrets_[client];
181 }
182
183 private:
184 // Gets a value for a key. In priority order, this will be the value
185 // provided via a command-line switch, the value provided via an
186 // environment variable, or finally a value baked into the build.
187 // |command_line_switch| may be NULL.
188 static std::string CalculateKeyValue(const char* baked_in_value,
189 const char* environment_variable_name,
190 const char* command_line_switch,
191 const std::string& default_if_unset,
192 base::Environment* environment,
193 CommandLine* command_line) {
194 std::string key_value = baked_in_value;
195 std::string temp;
[email protected]b08bf822012-09-11 21:50:38196 if (environment->GetVar(environment_variable_name, &temp)) {
[email protected]e5e894ff2012-09-06 02:18:47197 key_value = temp;
[email protected]94305332013-11-25 22:32:05198 VLOG(1) << "Overriding API key " << environment_variable_name
199 << " with value " << key_value << " from environment variable.";
[email protected]b08bf822012-09-11 21:50:38200 }
201
202 if (command_line_switch && command_line->HasSwitch(command_line_switch)) {
[email protected]e5e894ff2012-09-06 02:18:47203 key_value = command_line->GetSwitchValueASCII(command_line_switch);
[email protected]94305332013-11-25 22:32:05204 VLOG(1) << "Overriding API key " << environment_variable_name
205 << " with value " << key_value << " from command-line switch.";
[email protected]b08bf822012-09-11 21:50:38206 }
[email protected]e5e894ff2012-09-06 02:18:47207
[email protected]2b113652012-09-17 17:01:39208 if (key_value == DUMMY_API_TOKEN) {
[email protected]e5e894ff2012-09-06 02:18:47209#if defined(GOOGLE_CHROME_BUILD)
[email protected]2b113652012-09-17 17:01:39210 // No key should be unset in an official build except the
211 // GOOGLE_DEFAULT_* keys. The default keys don't trigger this
212 // check as their "unset" value is not DUMMY_API_TOKEN.
213 CHECK(false);
[email protected]e5e894ff2012-09-06 02:18:47214#endif
[email protected]2b113652012-09-17 17:01:39215 if (default_if_unset.size() > 0) {
[email protected]94305332013-11-25 22:32:05216 VLOG(1) << "Using default value \"" << default_if_unset
217 << "\" for API key " << environment_variable_name;
[email protected]2b113652012-09-17 17:01:39218 key_value = default_if_unset;
219 }
[email protected]e5e894ff2012-09-06 02:18:47220 }
221
[email protected]b08bf822012-09-11 21:50:38222 // This should remain a debug-only log.
223 DVLOG(1) << "API key " << environment_variable_name << "=" << key_value;
[email protected]e5e894ff2012-09-06 02:18:47224
[email protected]b08bf822012-09-11 21:50:38225 return key_value;
[email protected]e5e894ff2012-09-06 02:18:47226 }
227
228 std::string api_key_;
229 std::string client_ids_[CLIENT_NUM_ITEMS];
230 std::string client_secrets_[CLIENT_NUM_ITEMS];
231};
232
233static base::LazyInstance<APIKeyCache> g_api_key_cache =
234 LAZY_INSTANCE_INITIALIZER;
235
[email protected]e7dd7892013-05-16 19:10:40236bool HasKeysConfigured() {
237 if (GetAPIKey() == DUMMY_API_TOKEN)
238 return false;
239
240 for (size_t client_id = 0; client_id < CLIENT_NUM_ITEMS; ++client_id) {
241 OAuth2Client client = static_cast<OAuth2Client>(client_id);
242 if (GetOAuth2ClientID(client) == DUMMY_API_TOKEN ||
243 GetOAuth2ClientSecret(client) == DUMMY_API_TOKEN) {
244 return false;
245 }
246 }
247
248 return true;
249}
250
[email protected]e5e894ff2012-09-06 02:18:47251std::string GetAPIKey() {
252 return g_api_key_cache.Get().api_key();
253}
254
255std::string GetOAuth2ClientID(OAuth2Client client) {
256 return g_api_key_cache.Get().GetClientID(client);
257}
258
259std::string GetOAuth2ClientSecret(OAuth2Client client) {
260 return g_api_key_cache.Get().GetClientSecret(client);
261}
262
[email protected]e4b54e32014-01-17 13:55:20263bool IsGoogleChromeAPIKeyUsed() {
264#if defined(GOOGLE_CHROME_BUILD) || defined(USE_OFFICIAL_GOOGLE_API_KEYS)
265 return true;
266#else
267 return false;
268#endif
269}
270
[email protected]e5e894ff2012-09-06 02:18:47271} // namespace google_apis