Blink roll 154909:154938
[chromium-blink-merge.git] / google_apis / google_api_keys.cc
blobfc4b54735b44042eb79c7845028b37020491ac63
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 // Used to indicate an unset key/id/secret. This works better with
21 // various unit tests than leaving the token empty.
22 #define DUMMY_API_TOKEN "dummytoken"
24 #if !defined(GOOGLE_API_KEY)
25 #define GOOGLE_API_KEY DUMMY_API_TOKEN
26 #endif
28 #if !defined(GOOGLE_CLIENT_ID_MAIN)
29 #define GOOGLE_CLIENT_ID_MAIN DUMMY_API_TOKEN
30 #endif
32 #if !defined(GOOGLE_CLIENT_SECRET_MAIN)
33 #define GOOGLE_CLIENT_SECRET_MAIN DUMMY_API_TOKEN
34 #endif
36 #if !defined(GOOGLE_CLIENT_ID_CLOUD_PRINT)
37 #define GOOGLE_CLIENT_ID_CLOUD_PRINT DUMMY_API_TOKEN
38 #endif
40 #if !defined(GOOGLE_CLIENT_SECRET_CLOUD_PRINT)
41 #define GOOGLE_CLIENT_SECRET_CLOUD_PRINT DUMMY_API_TOKEN
42 #endif
44 #if !defined(GOOGLE_CLIENT_ID_REMOTING)
45 #define GOOGLE_CLIENT_ID_REMOTING DUMMY_API_TOKEN
46 #endif
48 #if !defined(GOOGLE_CLIENT_SECRET_REMOTING)
49 #define GOOGLE_CLIENT_SECRET_REMOTING DUMMY_API_TOKEN
50 #endif
52 // These are used as shortcuts for developers and users providing
53 // OAuth credentials via preprocessor defines or environment
54 // variables. If set, they will be used to replace any of the client
55 // IDs and secrets above that have not been set (and only those; they
56 // will not override already-set values).
57 #if !defined(GOOGLE_DEFAULT_CLIENT_ID)
58 #define GOOGLE_DEFAULT_CLIENT_ID ""
59 #endif
60 #if !defined(GOOGLE_DEFAULT_CLIENT_SECRET)
61 #define GOOGLE_DEFAULT_CLIENT_SECRET ""
62 #endif
64 namespace switches {
66 // Specifies custom OAuth2 client id for testing purposes.
67 const char kOAuth2ClientID[] = "oauth2-client-id";
69 // Specifies custom OAuth2 client secret for testing purposes.
70 const char kOAuth2ClientSecret[] = "oauth2-client-secret";
72 } // namespace switches
74 namespace google_apis {
76 // This is used as a lazy instance to determine keys once and cache them.
77 class APIKeyCache {
78 public:
79 APIKeyCache() {
80 scoped_ptr<base::Environment> environment(base::Environment::Create());
81 CommandLine* command_line = CommandLine::ForCurrentProcess();
83 api_key_ = CalculateKeyValue(GOOGLE_API_KEY,
84 STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY),
85 NULL,
86 std::string(),
87 environment.get(),
88 command_line);
90 std::string default_client_id =
91 CalculateKeyValue(GOOGLE_DEFAULT_CLIENT_ID,
92 STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_ID),
93 NULL,
94 std::string(),
95 environment.get(),
96 command_line);
97 std::string default_client_secret =
98 CalculateKeyValue(GOOGLE_DEFAULT_CLIENT_SECRET,
99 STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_SECRET),
100 NULL,
101 std::string(),
102 environment.get(),
103 command_line);
105 // We currently only allow overriding the baked-in values for the
106 // default OAuth2 client ID and secret using a command-line
107 // argument, since that is useful to enable testing against
108 // staging servers, and since that was what was possible and
109 // likely practiced by the QA team before this implementation was
110 // written.
111 client_ids_[CLIENT_MAIN] = CalculateKeyValue(
112 GOOGLE_CLIENT_ID_MAIN,
113 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_MAIN),
114 switches::kOAuth2ClientID,
115 default_client_id,
116 environment.get(),
117 command_line);
118 client_secrets_[CLIENT_MAIN] = CalculateKeyValue(
119 GOOGLE_CLIENT_SECRET_MAIN,
120 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_MAIN),
121 switches::kOAuth2ClientSecret,
122 default_client_secret,
123 environment.get(),
124 command_line);
126 client_ids_[CLIENT_CLOUD_PRINT] = CalculateKeyValue(
127 GOOGLE_CLIENT_ID_CLOUD_PRINT,
128 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_CLOUD_PRINT),
129 NULL,
130 default_client_id,
131 environment.get(),
132 command_line);
133 client_secrets_[CLIENT_CLOUD_PRINT] = CalculateKeyValue(
134 GOOGLE_CLIENT_SECRET_CLOUD_PRINT,
135 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_CLOUD_PRINT),
136 NULL,
137 default_client_secret,
138 environment.get(),
139 command_line);
141 client_ids_[CLIENT_REMOTING] = CalculateKeyValue(
142 GOOGLE_CLIENT_ID_REMOTING,
143 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_REMOTING),
144 NULL,
145 default_client_id,
146 environment.get(),
147 command_line);
148 client_secrets_[CLIENT_REMOTING] = CalculateKeyValue(
149 GOOGLE_CLIENT_SECRET_REMOTING,
150 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_REMOTING),
151 NULL,
152 default_client_secret,
153 environment.get(),
154 command_line);
157 std::string api_key() const { return api_key_; }
159 std::string GetClientID(OAuth2Client client) const {
160 DCHECK_LT(client, CLIENT_NUM_ITEMS);
161 return client_ids_[client];
164 std::string GetClientSecret(OAuth2Client client) const {
165 DCHECK_LT(client, CLIENT_NUM_ITEMS);
166 return client_secrets_[client];
169 private:
170 // Gets a value for a key. In priority order, this will be the value
171 // provided via a command-line switch, the value provided via an
172 // environment variable, or finally a value baked into the build.
173 // |command_line_switch| may be NULL.
174 static std::string CalculateKeyValue(const char* baked_in_value,
175 const char* environment_variable_name,
176 const char* command_line_switch,
177 const std::string& default_if_unset,
178 base::Environment* environment,
179 CommandLine* command_line) {
180 std::string key_value = baked_in_value;
181 std::string temp;
182 if (environment->GetVar(environment_variable_name, &temp)) {
183 key_value = temp;
184 LOG(INFO) << "Overriding API key " << environment_variable_name
185 << " with value " << key_value << " from environment variable.";
188 if (command_line_switch && command_line->HasSwitch(command_line_switch)) {
189 key_value = command_line->GetSwitchValueASCII(command_line_switch);
190 LOG(INFO) << "Overriding API key " << environment_variable_name
191 << " with value " << key_value << " from command-line switch.";
194 if (key_value == DUMMY_API_TOKEN) {
195 #if defined(GOOGLE_CHROME_BUILD)
196 // No key should be unset in an official build except the
197 // GOOGLE_DEFAULT_* keys. The default keys don't trigger this
198 // check as their "unset" value is not DUMMY_API_TOKEN.
199 CHECK(false);
200 #endif
201 if (default_if_unset.size() > 0) {
202 LOG(INFO) << "Using default value \"" << default_if_unset
203 << "\" for API key " << environment_variable_name;
204 key_value = default_if_unset;
208 // This should remain a debug-only log.
209 DVLOG(1) << "API key " << environment_variable_name << "=" << key_value;
211 return key_value;
214 std::string api_key_;
215 std::string client_ids_[CLIENT_NUM_ITEMS];
216 std::string client_secrets_[CLIENT_NUM_ITEMS];
219 static base::LazyInstance<APIKeyCache> g_api_key_cache =
220 LAZY_INSTANCE_INITIALIZER;
222 bool HasKeysConfigured() {
223 if (GetAPIKey() == DUMMY_API_TOKEN)
224 return false;
226 for (size_t client_id = 0; client_id < CLIENT_NUM_ITEMS; ++client_id) {
227 OAuth2Client client = static_cast<OAuth2Client>(client_id);
228 if (GetOAuth2ClientID(client) == DUMMY_API_TOKEN ||
229 GetOAuth2ClientSecret(client) == DUMMY_API_TOKEN) {
230 return false;
234 return true;
237 std::string GetAPIKey() {
238 return g_api_key_cache.Get().api_key();
241 std::string GetOAuth2ClientID(OAuth2Client client) {
242 return g_api_key_cache.Get().GetClientID(client);
245 std::string GetOAuth2ClientSecret(OAuth2Client client) {
246 return g_api_key_cache.Get().GetClientSecret(client);
249 } // namespace google_apis