Blink roll 148954:148987
[chromium-blink-merge.git] / google_apis / google_api_keys.cc
blobc05435e8dd411f754c77001fa3df0e5bb2b109dd
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"
16 #if defined(GOOGLE_CHROME_BUILD) || defined(USE_OFFICIAL_GOOGLE_API_KEYS)
17 #include "google_apis/internal/google_chrome_api_keys.h"
18 #endif
20 // TODO(joi): Can we enable this warning without having it treated as
21 // an error? We don't want to fail builds, just warn, but all warnings
22 // from the preprocessor are currently treated as errors, at least in
23 // Linux builds.
24 #if 0
25 #if !defined(GOOGLE_API_KEY) && ( \
26 (!defined(GOOGLE_DEFAULT_CLIENT_ID) && \
27 !defined(GOOGLE_DEFAULT_CLIENT_SECRET)) \
28 || \
29 (!defined(GOOGLE_CLIENT_ID_MAIN) && \
30 !defined(GOOGLE_CLIENT_SECRET_MAIN)))
31 #warning You have not specified API keys; some features may not work.
32 #warning See www.chromium.org/developers/how-tos/api-keys for details.
33 #endif // (API keys unset)
34 #endif // 0
36 // Used to indicate an unset key/id/secret. This works better with
37 // various unit tests than leaving the token empty.
38 #define DUMMY_API_TOKEN "dummytoken"
40 #if !defined(GOOGLE_API_KEY)
41 #define GOOGLE_API_KEY DUMMY_API_TOKEN
42 #endif
44 #if !defined(GOOGLE_CLIENT_ID_MAIN)
45 #define GOOGLE_CLIENT_ID_MAIN DUMMY_API_TOKEN
46 #endif
48 #if !defined(GOOGLE_CLIENT_SECRET_MAIN)
49 #define GOOGLE_CLIENT_SECRET_MAIN DUMMY_API_TOKEN
50 #endif
52 #if !defined(GOOGLE_CLIENT_ID_CLOUD_PRINT)
53 #define GOOGLE_CLIENT_ID_CLOUD_PRINT DUMMY_API_TOKEN
54 #endif
56 #if !defined(GOOGLE_CLIENT_SECRET_CLOUD_PRINT)
57 #define GOOGLE_CLIENT_SECRET_CLOUD_PRINT DUMMY_API_TOKEN
58 #endif
60 #if !defined(GOOGLE_CLIENT_ID_REMOTING)
61 #define GOOGLE_CLIENT_ID_REMOTING DUMMY_API_TOKEN
62 #endif
64 #if !defined(GOOGLE_CLIENT_SECRET_REMOTING)
65 #define GOOGLE_CLIENT_SECRET_REMOTING DUMMY_API_TOKEN
66 #endif
68 // These are used as shortcuts for developers and users providing
69 // OAuth credentials via preprocessor defines or environment
70 // variables. If set, they will be used to replace any of the client
71 // IDs and secrets above that have not been set (and only those; they
72 // will not override already-set values).
73 #if !defined(GOOGLE_DEFAULT_CLIENT_ID)
74 #define GOOGLE_DEFAULT_CLIENT_ID ""
75 #endif
76 #if !defined(GOOGLE_DEFAULT_CLIENT_SECRET)
77 #define GOOGLE_DEFAULT_CLIENT_SECRET ""
78 #endif
80 namespace switches {
82 // Specifies custom OAuth2 client id for testing purposes.
83 const char kOAuth2ClientID[] = "oauth2-client-id";
85 // Specifies custom OAuth2 client secret for testing purposes.
86 const char kOAuth2ClientSecret[] = "oauth2-client-secret";
88 } // namespace switches
90 namespace google_apis {
92 // This is used as a lazy instance to determine keys once and cache them.
93 class APIKeyCache {
94 public:
95 APIKeyCache() {
96 scoped_ptr<base::Environment> environment(base::Environment::Create());
97 CommandLine* command_line = CommandLine::ForCurrentProcess();
99 api_key_ = CalculateKeyValue(GOOGLE_API_KEY,
100 STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY),
101 NULL,
102 std::string(),
103 environment.get(),
104 command_line);
106 std::string default_client_id =
107 CalculateKeyValue(GOOGLE_DEFAULT_CLIENT_ID,
108 STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_ID),
109 NULL,
110 std::string(),
111 environment.get(),
112 command_line);
113 std::string default_client_secret =
114 CalculateKeyValue(GOOGLE_DEFAULT_CLIENT_SECRET,
115 STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_SECRET),
116 NULL,
117 std::string(),
118 environment.get(),
119 command_line);
121 // We currently only allow overriding the baked-in values for the
122 // default OAuth2 client ID and secret using a command-line
123 // argument, since that is useful to enable testing against
124 // staging servers, and since that was what was possible and
125 // likely practiced by the QA team before this implementation was
126 // written.
127 client_ids_[CLIENT_MAIN] = CalculateKeyValue(
128 GOOGLE_CLIENT_ID_MAIN,
129 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_MAIN),
130 switches::kOAuth2ClientID,
131 default_client_id,
132 environment.get(),
133 command_line);
134 client_secrets_[CLIENT_MAIN] = CalculateKeyValue(
135 GOOGLE_CLIENT_SECRET_MAIN,
136 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_MAIN),
137 switches::kOAuth2ClientSecret,
138 default_client_secret,
139 environment.get(),
140 command_line);
142 client_ids_[CLIENT_CLOUD_PRINT] = CalculateKeyValue(
143 GOOGLE_CLIENT_ID_CLOUD_PRINT,
144 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_CLOUD_PRINT),
145 NULL,
146 default_client_id,
147 environment.get(),
148 command_line);
149 client_secrets_[CLIENT_CLOUD_PRINT] = CalculateKeyValue(
150 GOOGLE_CLIENT_SECRET_CLOUD_PRINT,
151 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_CLOUD_PRINT),
152 NULL,
153 default_client_secret,
154 environment.get(),
155 command_line);
157 client_ids_[CLIENT_REMOTING] = CalculateKeyValue(
158 GOOGLE_CLIENT_ID_REMOTING,
159 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_REMOTING),
160 NULL,
161 default_client_id,
162 environment.get(),
163 command_line);
164 client_secrets_[CLIENT_REMOTING] = CalculateKeyValue(
165 GOOGLE_CLIENT_SECRET_REMOTING,
166 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_REMOTING),
167 NULL,
168 default_client_secret,
169 environment.get(),
170 command_line);
173 std::string api_key() const { return api_key_; }
175 std::string GetClientID(OAuth2Client client) const {
176 DCHECK_LT(client, CLIENT_NUM_ITEMS);
177 return client_ids_[client];
180 std::string GetClientSecret(OAuth2Client client) const {
181 DCHECK_LT(client, CLIENT_NUM_ITEMS);
182 return client_secrets_[client];
185 private:
186 // Gets a value for a key. In priority order, this will be the value
187 // provided via a command-line switch, the value provided via an
188 // environment variable, or finally a value baked into the build.
189 // |command_line_switch| may be NULL.
190 static std::string CalculateKeyValue(const char* baked_in_value,
191 const char* environment_variable_name,
192 const char* command_line_switch,
193 const std::string& default_if_unset,
194 base::Environment* environment,
195 CommandLine* command_line) {
196 std::string key_value = baked_in_value;
197 std::string temp;
198 if (environment->GetVar(environment_variable_name, &temp)) {
199 key_value = temp;
200 LOG(INFO) << "Overriding API key " << environment_variable_name
201 << " with value " << key_value << " from environment variable.";
204 if (command_line_switch && command_line->HasSwitch(command_line_switch)) {
205 key_value = command_line->GetSwitchValueASCII(command_line_switch);
206 LOG(INFO) << "Overriding API key " << environment_variable_name
207 << " with value " << key_value << " from command-line switch.";
210 if (key_value == DUMMY_API_TOKEN) {
211 #if defined(GOOGLE_CHROME_BUILD)
212 // No key should be unset in an official build except the
213 // GOOGLE_DEFAULT_* keys. The default keys don't trigger this
214 // check as their "unset" value is not DUMMY_API_TOKEN.
215 CHECK(false);
216 #endif
217 if (default_if_unset.size() > 0) {
218 LOG(INFO) << "Using default value \"" << default_if_unset
219 << "\" for API key " << environment_variable_name;
220 key_value = default_if_unset;
224 // This should remain a debug-only log.
225 DVLOG(1) << "API key " << environment_variable_name << "=" << key_value;
227 return key_value;
230 std::string api_key_;
231 std::string client_ids_[CLIENT_NUM_ITEMS];
232 std::string client_secrets_[CLIENT_NUM_ITEMS];
235 static base::LazyInstance<APIKeyCache> g_api_key_cache =
236 LAZY_INSTANCE_INITIALIZER;
238 std::string GetAPIKey() {
239 return g_api_key_cache.Get().api_key();
242 std::string GetOAuth2ClientID(OAuth2Client client) {
243 return g_api_key_cache.Get().GetClientID(client);
246 std::string GetOAuth2ClientSecret(OAuth2Client client) {
247 return g_api_key_cache.Get().GetClientSecret(client);
250 } // namespace google_apis