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.
5 #include "google_apis/google_api_keys.h"
7 // If you add more includes to this list, you also need to add them to
8 // google_api_keys_unittest.cc.
9 #include "base/command_line.h"
10 #include "base/environment.h"
11 #include "base/lazy_instance.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/strings/stringize_macros.h"
15 #include "google_apis/gaia/gaia_switches.h"
17 #if defined(GOOGLE_CHROME_BUILD) || defined(USE_OFFICIAL_GOOGLE_API_KEYS)
18 #include "google_apis/internal/google_chrome_api_keys.h"
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"
25 #if !defined(GOOGLE_API_KEY)
26 #define GOOGLE_API_KEY DUMMY_API_TOKEN
29 #if !defined(GOOGLE_API_KEY_SAFESITES)
30 #define GOOGLE_API_KEY_SAFESITES DUMMY_API_TOKEN
33 #if !defined(GOOGLE_CLIENT_ID_MAIN)
34 #define GOOGLE_CLIENT_ID_MAIN DUMMY_API_TOKEN
37 #if !defined(GOOGLE_CLIENT_SECRET_MAIN)
38 #define GOOGLE_CLIENT_SECRET_MAIN DUMMY_API_TOKEN
41 #if !defined(GOOGLE_CLIENT_ID_CLOUD_PRINT)
42 #define GOOGLE_CLIENT_ID_CLOUD_PRINT DUMMY_API_TOKEN
45 #if !defined(GOOGLE_CLIENT_SECRET_CLOUD_PRINT)
46 #define GOOGLE_CLIENT_SECRET_CLOUD_PRINT DUMMY_API_TOKEN
49 #if !defined(GOOGLE_CLIENT_ID_REMOTING)
50 #define GOOGLE_CLIENT_ID_REMOTING DUMMY_API_TOKEN
53 #if !defined(GOOGLE_CLIENT_SECRET_REMOTING)
54 #define GOOGLE_CLIENT_SECRET_REMOTING DUMMY_API_TOKEN
57 #if !defined(GOOGLE_CLIENT_ID_REMOTING_HOST)
58 #define GOOGLE_CLIENT_ID_REMOTING_HOST DUMMY_API_TOKEN
61 #if !defined(GOOGLE_CLIENT_SECRET_REMOTING_HOST)
62 #define GOOGLE_CLIENT_SECRET_REMOTING_HOST DUMMY_API_TOKEN
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)
71 #define GOOGLE_DEFAULT_CLIENT_ID ""
73 #if !defined(GOOGLE_DEFAULT_CLIENT_SECRET)
74 #define GOOGLE_DEFAULT_CLIENT_SECRET ""
77 namespace google_apis
{
79 // This is used as a lazy instance to determine keys once and cache them.
83 scoped_ptr
<base::Environment
> environment(base::Environment::Create());
84 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
86 api_key_
= CalculateKeyValue(GOOGLE_API_KEY
,
87 STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY
),
94 CalculateKeyValue(GOOGLE_API_KEY_SAFESITES
,
95 STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_SAFESITES
),
101 std::string default_client_id
=
102 CalculateKeyValue(GOOGLE_DEFAULT_CLIENT_ID
,
103 STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_ID
),
108 std::string default_client_secret
=
109 CalculateKeyValue(GOOGLE_DEFAULT_CLIENT_SECRET
,
110 STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_SECRET
),
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
122 client_ids_
[CLIENT_MAIN
] = CalculateKeyValue(
123 GOOGLE_CLIENT_ID_MAIN
,
124 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_MAIN
),
125 switches::kOAuth2ClientID
,
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
,
137 client_ids_
[CLIENT_CLOUD_PRINT
] = CalculateKeyValue(
138 GOOGLE_CLIENT_ID_CLOUD_PRINT
,
139 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_CLOUD_PRINT
),
144 client_secrets_
[CLIENT_CLOUD_PRINT
] = CalculateKeyValue(
145 GOOGLE_CLIENT_SECRET_CLOUD_PRINT
,
146 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_CLOUD_PRINT
),
148 default_client_secret
,
152 client_ids_
[CLIENT_REMOTING
] = CalculateKeyValue(
153 GOOGLE_CLIENT_ID_REMOTING
,
154 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_REMOTING
),
159 client_secrets_
[CLIENT_REMOTING
] = CalculateKeyValue(
160 GOOGLE_CLIENT_SECRET_REMOTING
,
161 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_REMOTING
),
163 default_client_secret
,
167 client_ids_
[CLIENT_REMOTING_HOST
] = CalculateKeyValue(
168 GOOGLE_CLIENT_ID_REMOTING_HOST
,
169 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_REMOTING_HOST
),
174 client_secrets_
[CLIENT_REMOTING_HOST
] = CalculateKeyValue(
175 GOOGLE_CLIENT_SECRET_REMOTING_HOST
,
176 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_REMOTING_HOST
),
178 default_client_secret
,
183 std::string
api_key() const { return api_key_
; }
184 std::string
api_key_safesites() const { return api_key_safesites_
; }
186 std::string
GetClientID(OAuth2Client client
) const {
187 DCHECK_LT(client
, CLIENT_NUM_ITEMS
);
188 return client_ids_
[client
];
191 std::string
GetClientSecret(OAuth2Client client
) const {
192 DCHECK_LT(client
, CLIENT_NUM_ITEMS
);
193 return client_secrets_
[client
];
196 std::string
GetSpdyProxyAuthValue() {
197 #if defined(SPDY_PROXY_AUTH_VALUE)
198 return SPDY_PROXY_AUTH_VALUE
;
200 return std::string();
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
,
214 CommandLine
* command_line
) {
215 std::string key_value
= baked_in_value
;
217 if (environment
->GetVar(environment_variable_name
, &temp
)) {
219 VLOG(1) << "Overriding API key " << environment_variable_name
220 << " with value " << key_value
<< " from environment variable.";
223 if (command_line_switch
&& command_line
->HasSwitch(command_line_switch
)) {
224 key_value
= command_line
->GetSwitchValueASCII(command_line_switch
);
225 VLOG(1) << "Overriding API key " << environment_variable_name
226 << " with value " << key_value
<< " from command-line switch.";
229 if (key_value
== DUMMY_API_TOKEN
) {
230 #if defined(GOOGLE_CHROME_BUILD)
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.
236 if (default_if_unset
.size() > 0) {
237 VLOG(1) << "Using default value \"" << default_if_unset
238 << "\" for API key " << environment_variable_name
;
239 key_value
= default_if_unset
;
243 // This should remain a debug-only log.
244 DVLOG(1) << "API key " << environment_variable_name
<< "=" << key_value
;
249 std::string api_key_
;
250 std::string api_key_safesites_
;
251 std::string client_ids_
[CLIENT_NUM_ITEMS
];
252 std::string client_secrets_
[CLIENT_NUM_ITEMS
];
255 static base::LazyInstance
<APIKeyCache
> g_api_key_cache
=
256 LAZY_INSTANCE_INITIALIZER
;
258 bool HasKeysConfigured() {
259 if (GetAPIKey() == DUMMY_API_TOKEN
)
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
) {
273 std::string
GetAPIKey() {
274 return g_api_key_cache
.Get().api_key();
277 std::string
GetSafeSitesAPIKey() {
278 return g_api_key_cache
.Get().api_key_safesites();
281 std::string
GetOAuth2ClientID(OAuth2Client client
) {
282 return g_api_key_cache
.Get().GetClientID(client
);
285 std::string
GetOAuth2ClientSecret(OAuth2Client client
) {
286 return g_api_key_cache
.Get().GetClientSecret(client
);
289 std::string
GetSpdyProxyAuthValue() {
290 return g_api_key_cache
.Get().GetSpdyProxyAuthValue();
293 bool IsGoogleChromeAPIKeyUsed() {
294 #if defined(GOOGLE_CHROME_BUILD) || defined(USE_OFFICIAL_GOOGLE_API_KEYS)
301 } // namespace google_apis