blob: 610818676f9f0d8f7ab907083d20c3418b52aa86 [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
7#include "base/command_line.h"
8#include "base/environment.h"
9#include "base/lazy_instance.h"
[email protected]b08bf822012-09-11 21:50:3810#include "base/logging.h"
[email protected]e5e894ff2012-09-06 02:18:4711#include "base/memory/scoped_ptr.h"
12#include "base/stringize_macros.h"
13
14#if defined(GOOGLE_CHROME_BUILD)
[email protected]b08bf822012-09-11 21:50:3815#include "google_apis/internal/google_chrome_api_keys.h"
[email protected]e5e894ff2012-09-06 02:18:4716#endif
17
18#if !defined(GOOGLE_API_KEY)
[email protected]b08bf822012-09-11 21:50:3819// TODO(joi): Make this blank once it is set via include.gypi.
[email protected]e5e894ff2012-09-06 02:18:4720#define GOOGLE_API_KEY "abcNOTREALKEYxyz"
21#endif
22
23#if !defined(GOOGLE_CLIENT_ID_MAIN)
[email protected]b08bf822012-09-11 21:50:3824// TODO(joi): Make this blank once it is set via include.gypi.
[email protected]e5e894ff2012-09-06 02:18:4725#define GOOGLE_CLIENT_ID_MAIN "77185425430.apps.googleusercontent.com"
26#endif
27
28#if !defined(GOOGLE_CLIENT_SECRET_MAIN)
[email protected]b08bf822012-09-11 21:50:3829// TODO(joi): Make this blank once it is set via include.gypi.
[email protected]e5e894ff2012-09-06 02:18:4730#define GOOGLE_CLIENT_SECRET_MAIN "OTJgUOQcT7lO7GsGZq2G4IlT"
31#endif
32
33#if !defined(GOOGLE_CLIENT_ID_CLOUD_PRINT)
[email protected]b08bf822012-09-11 21:50:3834// TODO(joi): Make this blank once it is set via include.gypi.
[email protected]e5e894ff2012-09-06 02:18:4735#define GOOGLE_CLIENT_ID_CLOUD_PRINT "551556820943.apps.googleusercontent.com"
36#endif
37
38#if !defined(GOOGLE_CLIENT_SECRET_CLOUD_PRINT)
[email protected]b08bf822012-09-11 21:50:3839// TODO(joi): Make this blank once it is set via include.gypi.
[email protected]e5e894ff2012-09-06 02:18:4740#define GOOGLE_CLIENT_SECRET_CLOUD_PRINT "u3/mp8CgLFxh4uiX1855/MHe"
41#endif
42
43#if !defined(GOOGLE_CLIENT_ID_REMOTING)
[email protected]b08bf822012-09-11 21:50:3844// TODO(joi): Make this blank once it is set via include.gypi.
[email protected]e5e894ff2012-09-06 02:18:4745#define GOOGLE_CLIENT_ID_REMOTING \
46 "440925447803-avn2sj1kc099s0r7v62je5s339mu0am1.apps.googleusercontent.com"
47#endif
48
49#if !defined(GOOGLE_CLIENT_SECRET_REMOTING)
[email protected]b08bf822012-09-11 21:50:3850// TODO(joi): Make this blank once it is set via include.gypi.
[email protected]e5e894ff2012-09-06 02:18:4751#define GOOGLE_CLIENT_SECRET_REMOTING "Bgur6DFiOMM1h8x-AQpuTQlK"
52#endif
53
54// These are used as shortcuts for developers and users providing
55// OAuth credentials via preprocessor defines or environment
56// variables. If set, they will be used to replace any of the client
57// IDs and secrets above that have not been set (and only those; they
58// will not override already-set values).
59#if !defined(GOOGLE_DEFAULT_CLIENT_ID)
60#define GOOGLE_DEFAULT_CLIENT_ID ""
61#endif
62#if !defined(GOOGLE_DEFAULT_CLIENT_SECRET)
63#define GOOGLE_DEFAULT_CLIENT_SECRET ""
64#endif
65
66namespace switches {
67
68// Specifies custom OAuth2 client id for testing purposes.
69const char kOAuth2ClientID[] = "oauth2-client-id";
70
71// Specifies custom OAuth2 client secret for testing purposes.
72const char kOAuth2ClientSecret[] = "oauth2-client-secret";
73
74} // namespace switches
75
76namespace google_apis {
77
78namespace {
79
80// This is used as a lazy instance to determine keys once and cache them.
81class APIKeyCache {
82 public:
83 APIKeyCache() {
84 scoped_ptr<base::Environment> environment(base::Environment::Create());
85 CommandLine* command_line = CommandLine::ForCurrentProcess();
86
87 api_key_ = CalculateKeyValue(GOOGLE_API_KEY,
88 STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY),
89 NULL, "",
90 environment.get(),
91 command_line);
92
93 std::string default_client_id = CalculateKeyValue(
94 GOOGLE_DEFAULT_CLIENT_ID,
95 STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_ID),
96 NULL, "",
97 environment.get(),
98 command_line);
99 std::string default_client_secret = CalculateKeyValue(
100 GOOGLE_DEFAULT_CLIENT_SECRET,
101 STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_SECRET),
102 NULL, "",
103 environment.get(),
104 command_line);
105
106 // We currently only allow overriding the baked-in values for the
107 // default OAuth2 client ID and secret using a command-line
108 // argument, since that is useful to enable testing against
109 // staging servers, and since that was what was possible and
110 // likely practiced by the QA team before this implementation was
111 // written.
112 client_ids_[CLIENT_MAIN] = CalculateKeyValue(
113 GOOGLE_CLIENT_ID_MAIN,
114 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_MAIN),
115 switches::kOAuth2ClientID,
116 default_client_id,
117 environment.get(),
118 command_line);
119 client_secrets_[CLIENT_MAIN] = CalculateKeyValue(
120 GOOGLE_CLIENT_SECRET_MAIN,
121 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_MAIN),
122 switches::kOAuth2ClientSecret,
123 default_client_secret,
124 environment.get(),
125 command_line);
126
127 client_ids_[CLIENT_CLOUD_PRINT] = CalculateKeyValue(
128 GOOGLE_CLIENT_ID_CLOUD_PRINT,
129 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_CLOUD_PRINT),
130 NULL,
131 default_client_id,
132 environment.get(),
133 command_line);
134 client_secrets_[CLIENT_CLOUD_PRINT] = CalculateKeyValue(
135 GOOGLE_CLIENT_SECRET_CLOUD_PRINT,
136 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_CLOUD_PRINT),
137 NULL,
138 default_client_secret,
139 environment.get(),
140 command_line);
141
142 client_ids_[CLIENT_REMOTING] = CalculateKeyValue(
143 GOOGLE_CLIENT_ID_REMOTING,
144 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_REMOTING),
145 NULL,
146 default_client_id,
147 environment.get(),
148 command_line);
149 client_secrets_[CLIENT_REMOTING] = CalculateKeyValue(
150 GOOGLE_CLIENT_SECRET_REMOTING,
151 STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_REMOTING),
152 NULL,
153 default_client_secret,
154 environment.get(),
155 command_line);
156 }
157
158 std::string api_key() const { return api_key_; }
159
160 std::string GetClientID(OAuth2Client client) const {
161 DCHECK_LT(client, CLIENT_NUM_ITEMS);
162 return client_ids_[client];
163 }
164
165 std::string GetClientSecret(OAuth2Client client) const {
166 DCHECK_LT(client, CLIENT_NUM_ITEMS);
167 return client_secrets_[client];
168 }
169
170 private:
171 // Gets a value for a key. In priority order, this will be the value
172 // provided via a command-line switch, the value provided via an
173 // environment variable, or finally a value baked into the build.
174 // |command_line_switch| may be NULL.
175 static std::string CalculateKeyValue(const char* baked_in_value,
176 const char* environment_variable_name,
177 const char* command_line_switch,
178 const std::string& default_if_unset,
179 base::Environment* environment,
180 CommandLine* command_line) {
181 std::string key_value = baked_in_value;
182 std::string temp;
[email protected]b08bf822012-09-11 21:50:38183 if (environment->GetVar(environment_variable_name, &temp)) {
[email protected]e5e894ff2012-09-06 02:18:47184 key_value = temp;
[email protected]b08bf822012-09-11 21:50:38185 LOG(INFO) << "Overriding API key " << environment_variable_name
186 << " with value " << key_value << " from environment variable.";
187 }
188
189 if (command_line_switch && command_line->HasSwitch(command_line_switch)) {
[email protected]e5e894ff2012-09-06 02:18:47190 key_value = command_line->GetSwitchValueASCII(command_line_switch);
[email protected]b08bf822012-09-11 21:50:38191 LOG(INFO) << "Overriding API key " << environment_variable_name
192 << " with value " << key_value << " from command-line switch.";
193 }
[email protected]e5e894ff2012-09-06 02:18:47194
195 if (key_value.size() == 0) {
196#if defined(GOOGLE_CHROME_BUILD)
197 // No key should be empty in an official build, except the
198 // default keys themselves, which will have an empty default.
199 CHECK(default_if_unset.size() == 0);
200#endif
[email protected]b08bf822012-09-11 21:50:38201 LOG(INFO) << "Using default value \"" << default_if_unset
202 << "\" for API key " << environment_variable_name;
[email protected]e5e894ff2012-09-06 02:18:47203 key_value = default_if_unset;
204 }
205
[email protected]b08bf822012-09-11 21:50:38206 // This should remain a debug-only log.
207 DVLOG(1) << "API key " << environment_variable_name << "=" << key_value;
[email protected]e5e894ff2012-09-06 02:18:47208
[email protected]b08bf822012-09-11 21:50:38209 return key_value;
[email protected]e5e894ff2012-09-06 02:18:47210 }
211
212 std::string api_key_;
213 std::string client_ids_[CLIENT_NUM_ITEMS];
214 std::string client_secrets_[CLIENT_NUM_ITEMS];
215};
216
217static base::LazyInstance<APIKeyCache> g_api_key_cache =
218 LAZY_INSTANCE_INITIALIZER;
219
220} // namespace
221
222std::string GetAPIKey() {
223 return g_api_key_cache.Get().api_key();
224}
225
226std::string GetOAuth2ClientID(OAuth2Client client) {
227 return g_api_key_cache.Get().GetClientID(client);
228}
229
230std::string GetOAuth2ClientSecret(OAuth2Client client) {
231 return g_api_key_cache.Get().GetClientSecret(client);
232}
233
234} // namespace google_apis