fixup! [M108 Migration][API] Bring up autofill
[platform/framework/web/chromium-efl.git] / google_apis / google_api_keys.cc
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "google_apis/google_api_keys.h"
6
7 // If you add more includes to this list, you also need to add them to
8 // google_api_keys_unittest.cc and google_api_keys_mac_unittest.mm.
9
10 #include <stddef.h>
11
12 #include <memory>
13 #include <string>
14
15 #include "base/command_line.h"
16 #include "base/environment.h"
17 #include "base/lazy_instance.h"
18 #include "base/logging.h"
19 #include "base/strings/stringize_macros.h"
20 #include "build/branding_buildflags.h"
21 #include "google_apis/buildflags.h"
22 #include "google_apis/gaia/gaia_config.h"
23 #include "google_apis/gaia/gaia_switches.h"
24
25 #if BUILDFLAG(IS_APPLE)
26 #include "google_apis/google_api_keys_mac.h"
27 #endif
28
29 #if defined(USE_OFFICIAL_GOOGLE_API_KEYS)
30 #include "google_apis/internal/google_chrome_api_keys.h"
31 #include "google_apis/internal/metrics_signing_key.h"
32 #endif
33
34 // Used to indicate an unset key/id/secret.  This works better with
35 // various unit tests than leaving the token empty.
36 #define DUMMY_API_TOKEN "dummytoken"
37
38 #if !defined(GOOGLE_API_KEY)
39 #define GOOGLE_API_KEY DUMMY_API_TOKEN
40 #endif
41
42 #if !defined(GOOGLE_METRICS_SIGNING_KEY)
43 #define GOOGLE_METRICS_SIGNING_KEY DUMMY_API_TOKEN
44 #endif
45
46 #if !defined(GOOGLE_CLIENT_ID_MAIN)
47 #define GOOGLE_CLIENT_ID_MAIN DUMMY_API_TOKEN
48 #endif
49
50 #if !defined(GOOGLE_CLIENT_SECRET_MAIN)
51 #define GOOGLE_CLIENT_SECRET_MAIN DUMMY_API_TOKEN
52 #endif
53
54 #if !defined(GOOGLE_CLIENT_ID_REMOTING)
55 #define GOOGLE_CLIENT_ID_REMOTING DUMMY_API_TOKEN
56 #endif
57
58 #if !defined(GOOGLE_CLIENT_SECRET_REMOTING)
59 #define GOOGLE_CLIENT_SECRET_REMOTING DUMMY_API_TOKEN
60 #endif
61
62 #if !defined(GOOGLE_CLIENT_ID_REMOTING_HOST)
63 #define GOOGLE_CLIENT_ID_REMOTING_HOST DUMMY_API_TOKEN
64 #endif
65
66 #if !defined(GOOGLE_CLIENT_SECRET_REMOTING_HOST)
67 #define GOOGLE_CLIENT_SECRET_REMOTING_HOST DUMMY_API_TOKEN
68 #endif
69
70 #if !defined(GOOGLE_API_KEY_ANDROID_NON_STABLE)
71 #define GOOGLE_API_KEY_ANDROID_NON_STABLE DUMMY_API_TOKEN
72 #endif
73
74 #if !defined(GOOGLE_API_KEY_REMOTING)
75 #define GOOGLE_API_KEY_REMOTING DUMMY_API_TOKEN
76 #endif
77
78 // API key for SharingService.
79 #if !defined(GOOGLE_API_KEY_SHARING)
80 #define GOOGLE_API_KEY_SHARING DUMMY_API_TOKEN
81 #endif
82
83 // API key for the Speech On-Device API (SODA).
84 #if !defined(GOOGLE_API_KEY_SODA)
85 #define GOOGLE_API_KEY_SODA DUMMY_API_TOKEN
86 #endif
87
88 // API key for the ReadAloud API.
89 #if !defined(GOOGLE_API_KEY_READ_ALOUD)
90 #define GOOGLE_API_KEY_READ_ALOUD DUMMY_API_TOKEN
91 #endif
92
93 // API key for the Fresnel API.
94 #if !defined(GOOGLE_API_KEY_FRESNEL)
95 #define GOOGLE_API_KEY_FRESNEL DUMMY_API_TOKEN
96 #endif
97
98 // These are used as shortcuts for developers and users providing
99 // OAuth credentials via preprocessor defines or environment
100 // variables.  If set, they will be used to replace any of the client
101 // IDs and secrets above that have not been set (and only those; they
102 // will not override already-set values).
103 #if !defined(GOOGLE_DEFAULT_CLIENT_ID)
104 #define GOOGLE_DEFAULT_CLIENT_ID ""
105 #endif
106 #if !defined(GOOGLE_DEFAULT_CLIENT_SECRET)
107 #define GOOGLE_DEFAULT_CLIENT_SECRET ""
108 #endif
109
110 namespace google_apis {
111
112 const char kAPIKeysDevelopersHowToURL[] =
113     "https://www.chromium.org/developers/how-tos/api-keys";
114
115 // This is used as a lazy instance to determine keys once and cache them.
116 class APIKeyCache {
117  public:
118   APIKeyCache() {
119     std::unique_ptr<base::Environment> environment(base::Environment::Create());
120     base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
121     GaiaConfig* gaia_config = GaiaConfig::GetInstance();
122
123     api_key_ = CalculateKeyValue(
124         GOOGLE_API_KEY, STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY), nullptr,
125         std::string(), environment.get(), command_line, gaia_config);
126
127 // A special non-stable key is at the moment defined only for Android Chrome.
128 #if BUILDFLAG(IS_ANDROID)
129     api_key_non_stable_ = CalculateKeyValue(
130         GOOGLE_API_KEY_ANDROID_NON_STABLE,
131         STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_ANDROID_NON_STABLE), nullptr,
132         std::string(), environment.get(), command_line, gaia_config);
133 #else
134     api_key_non_stable_ = api_key_;
135 #endif
136
137     api_key_remoting_ = CalculateKeyValue(
138         GOOGLE_API_KEY_REMOTING,
139         STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_REMOTING), nullptr, std::string(),
140         environment.get(), command_line, gaia_config);
141
142     api_key_sharing_ = CalculateKeyValue(
143         GOOGLE_API_KEY_SHARING, STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_SHARING),
144         nullptr, std::string(), environment.get(), command_line, gaia_config);
145
146     api_key_soda_ = CalculateKeyValue(
147         GOOGLE_API_KEY_SODA, STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_SODA),
148         nullptr, std::string(), environment.get(), command_line, gaia_config);
149
150     api_key_read_aloud_ = CalculateKeyValue(
151         GOOGLE_API_KEY_READ_ALOUD,
152         STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_READ_ALOUD), nullptr,
153         std::string(), environment.get(), command_line, gaia_config);
154
155     api_key_fresnel_ = CalculateKeyValue(
156         GOOGLE_API_KEY_FRESNEL, STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_FRESNEL),
157         nullptr, std::string(), environment.get(), command_line, gaia_config);
158
159     metrics_key_ = CalculateKeyValue(
160         GOOGLE_METRICS_SIGNING_KEY,
161         STRINGIZE_NO_EXPANSION(GOOGLE_METRICS_SIGNING_KEY), nullptr,
162         std::string(), environment.get(), command_line, gaia_config);
163
164     std::string default_client_id = CalculateKeyValue(
165         GOOGLE_DEFAULT_CLIENT_ID,
166         STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_ID), nullptr,
167         std::string(), environment.get(), command_line, gaia_config);
168     std::string default_client_secret = CalculateKeyValue(
169         GOOGLE_DEFAULT_CLIENT_SECRET,
170         STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_SECRET), nullptr,
171         std::string(), environment.get(), command_line, gaia_config);
172
173     // We currently only allow overriding the baked-in values for the
174     // default OAuth2 client ID and secret using a command-line
175     // argument and gaia config, since that is useful to enable testing against
176     // staging servers, and since that was what was possible and
177     // likely practiced by the QA team before this implementation was
178     // written.
179     client_ids_[CLIENT_MAIN] = CalculateKeyValue(
180         GOOGLE_CLIENT_ID_MAIN, STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_MAIN),
181         ::switches::kOAuth2ClientID, default_client_id, environment.get(),
182         command_line, gaia_config);
183     client_secrets_[CLIENT_MAIN] = CalculateKeyValue(
184         GOOGLE_CLIENT_SECRET_MAIN,
185         STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_MAIN),
186         ::switches::kOAuth2ClientSecret, default_client_secret,
187         environment.get(), command_line, gaia_config);
188
189     client_ids_[CLIENT_REMOTING] = CalculateKeyValue(
190         GOOGLE_CLIENT_ID_REMOTING,
191         STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_REMOTING), nullptr,
192         default_client_id, environment.get(), command_line, gaia_config);
193     client_secrets_[CLIENT_REMOTING] = CalculateKeyValue(
194         GOOGLE_CLIENT_SECRET_REMOTING,
195         STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_REMOTING), nullptr,
196         default_client_secret, environment.get(), command_line, gaia_config);
197
198     client_ids_[CLIENT_REMOTING_HOST] = CalculateKeyValue(
199         GOOGLE_CLIENT_ID_REMOTING_HOST,
200         STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_REMOTING_HOST), nullptr,
201         default_client_id, environment.get(), command_line, gaia_config);
202     client_secrets_[CLIENT_REMOTING_HOST] = CalculateKeyValue(
203         GOOGLE_CLIENT_SECRET_REMOTING_HOST,
204         STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_REMOTING_HOST), nullptr,
205         default_client_secret, environment.get(), command_line, gaia_config);
206   }
207
208   std::string api_key() const { return api_key_; }
209 #if BUILDFLAG(SUPPORT_EXTERNAL_GOOGLE_API_KEY)
210   void set_api_key(const std::string& api_key) { api_key_ = api_key; }
211 #endif
212   std::string api_key_non_stable() const { return api_key_non_stable_; }
213   std::string api_key_remoting() const { return api_key_remoting_; }
214   std::string api_key_sharing() const { return api_key_sharing_; }
215   std::string api_key_soda() const { return api_key_soda_; }
216   std::string api_key_read_aloud() const { return api_key_read_aloud_; }
217   std::string api_key_fresnel() const { return api_key_fresnel_; }
218
219   std::string metrics_key() const { return metrics_key_; }
220
221   std::string GetClientID(OAuth2Client client) const {
222     DCHECK_LT(client, CLIENT_NUM_ITEMS);
223     return client_ids_[client];
224   }
225
226 #if BUILDFLAG(IS_IOS)
227   void SetClientID(OAuth2Client client, const std::string& client_id) {
228     client_ids_[client] = client_id;
229   }
230 #endif
231
232   std::string GetClientSecret(OAuth2Client client) const {
233     DCHECK_LT(client, CLIENT_NUM_ITEMS);
234     return client_secrets_[client];
235   }
236
237 #if BUILDFLAG(IS_IOS)
238   void SetClientSecret(OAuth2Client client, const std::string& client_secret) {
239     client_secrets_[client] = client_secret;
240   }
241 #endif
242
243   std::string GetSpdyProxyAuthValue() {
244 #if defined(SPDY_PROXY_AUTH_VALUE)
245     return SPDY_PROXY_AUTH_VALUE;
246 #else
247     return std::string();
248 #endif
249   }
250
251  private:
252   // Gets a value for a key.  In priority order, this will be the value
253   // provided via:
254   // 1. Command-line switch
255   // 2. Config file
256   // 3. Environment variable
257   // 4. Baked into the build
258   // |command_line_switch| may be NULL. Official Google Chrome builds will not
259   // use the value provided by an environment variable.
260   static std::string CalculateKeyValue(const char* baked_in_value,
261                                        const char* environment_variable_name,
262                                        const char* command_line_switch,
263                                        const std::string& default_if_unset,
264                                        base::Environment* environment,
265                                        base::CommandLine* command_line,
266                                        GaiaConfig* gaia_config) {
267     std::string key_value = baked_in_value;
268     std::string temp;
269 #if BUILDFLAG(IS_APPLE)
270     // macOS and iOS can also override the API key with a value from the
271     // Info.plist.
272     temp = ::google_apis::GetAPIKeyFromInfoPlist(environment_variable_name);
273     if (!temp.empty()) {
274       key_value = temp;
275       VLOG(1) << "Overriding API key " << environment_variable_name
276               << " with value " << key_value << " from Info.plist.";
277     }
278 #endif
279
280 #if !BUILDFLAG(GOOGLE_CHROME_BRANDING)
281     // Don't allow using the environment to override API keys for official
282     // Google Chrome builds. There have been reports of mangled environments
283     // affecting users (crbug.com/710575).
284     if (environment->GetVar(environment_variable_name, &temp)) {
285       key_value = temp;
286       VLOG(1) << "Overriding API key " << environment_variable_name
287               << " with value " << key_value << " from environment variable.";
288     }
289 #endif
290
291     if (gaia_config &&
292         gaia_config->GetAPIKeyIfExists(environment_variable_name, &temp)) {
293       key_value = temp;
294       VLOG(1) << "Overriding API key " << environment_variable_name
295               << " with value " << key_value << " from gaia config.";
296     }
297
298     if (command_line_switch && command_line->HasSwitch(command_line_switch)) {
299       key_value = command_line->GetSwitchValueASCII(command_line_switch);
300       VLOG(1) << "Overriding API key " << environment_variable_name
301               << " with value " << key_value << " from command-line switch.";
302     }
303
304     if (key_value == DUMMY_API_TOKEN) {
305 // TODO(crbug.com/1294915): Rewrite this condition using
306 // BUILDFLAG(SUPPORT_EXTERNAL_GOOGLE_API_KEY).
307 #if BUILDFLAG(GOOGLE_CHROME_BRANDING) && !BUILDFLAG(IS_FUCHSIA)
308       // No key should be unset in an official build except the
309       // GOOGLE_DEFAULT_* keys.  The default keys don't trigger this
310       // check as their "unset" value is not DUMMY_API_TOKEN.
311       CHECK(false);
312 #endif
313       if (default_if_unset.size() > 0) {
314         VLOG(1) << "Using default value \"" << default_if_unset
315                 << "\" for API key " << environment_variable_name;
316         key_value = default_if_unset;
317       }
318     }
319
320     // This should remain a debug-only log.
321     DVLOG(1) << "API key " << environment_variable_name << "=" << key_value;
322
323     return key_value;
324   }
325
326   std::string api_key_;
327   std::string api_key_non_stable_;
328   std::string api_key_remoting_;
329   std::string api_key_sharing_;
330   std::string api_key_soda_;
331   std::string api_key_read_aloud_;
332   std::string api_key_fresnel_;
333   std::string metrics_key_;
334   std::string client_ids_[CLIENT_NUM_ITEMS];
335   std::string client_secrets_[CLIENT_NUM_ITEMS];
336 };
337
338 static base::LazyInstance<APIKeyCache>::DestructorAtExit g_api_key_cache =
339     LAZY_INSTANCE_INITIALIZER;
340
341 bool HasAPIKeyConfigured() {
342   return GetAPIKey() != DUMMY_API_TOKEN;
343 }
344
345 std::string GetAPIKey() {
346   return g_api_key_cache.Get().api_key();
347 }
348
349 std::string GetNonStableAPIKey() {
350   return g_api_key_cache.Get().api_key_non_stable();
351 }
352
353 std::string GetRemotingAPIKey() {
354   return g_api_key_cache.Get().api_key_remoting();
355 }
356
357 std::string GetSharingAPIKey() {
358   return g_api_key_cache.Get().api_key_sharing();
359 }
360
361 std::string GetSodaAPIKey() {
362   return g_api_key_cache.Get().api_key_soda();
363 }
364
365 std::string GetReadAloudAPIKey() {
366   return g_api_key_cache.Get().api_key_read_aloud();
367 }
368
369 std::string GetFresnelAPIKey() {
370   return g_api_key_cache.Get().api_key_fresnel();
371 }
372
373 #if BUILDFLAG(SUPPORT_EXTERNAL_GOOGLE_API_KEY)
374 void SetAPIKey(const std::string& api_key) {
375   g_api_key_cache.Get().set_api_key(api_key);
376 }
377 #endif
378
379 std::string GetMetricsKey() {
380   return g_api_key_cache.Get().metrics_key();
381 }
382
383 bool HasOAuthClientConfigured() {
384   for (size_t client_id = 0; client_id < CLIENT_NUM_ITEMS; ++client_id) {
385     OAuth2Client client = static_cast<OAuth2Client>(client_id);
386     if (GetOAuth2ClientID(client) == DUMMY_API_TOKEN ||
387         GetOAuth2ClientSecret(client) == DUMMY_API_TOKEN) {
388       return false;
389     }
390   }
391
392   return true;
393 }
394
395 std::string GetOAuth2ClientID(OAuth2Client client) {
396   return g_api_key_cache.Get().GetClientID(client);
397 }
398
399 std::string GetOAuth2ClientSecret(OAuth2Client client) {
400   return g_api_key_cache.Get().GetClientSecret(client);
401 }
402
403 #if BUILDFLAG(IS_IOS)
404 void SetOAuth2ClientID(OAuth2Client client, const std::string& client_id) {
405   g_api_key_cache.Get().SetClientID(client, client_id);
406 }
407
408 void SetOAuth2ClientSecret(OAuth2Client client,
409                            const std::string& client_secret) {
410   g_api_key_cache.Get().SetClientSecret(client, client_secret);
411 }
412 #endif
413
414 std::string GetSpdyProxyAuthValue() {
415   return g_api_key_cache.Get().GetSpdyProxyAuthValue();
416 }
417
418 bool IsGoogleChromeAPIKeyUsed() {
419 #if defined(USE_OFFICIAL_GOOGLE_API_KEYS)
420   return true;
421 #else
422   return false;
423 #endif
424 }
425
426 }  // namespace google_apis