- add sources.
[platform/framework/web/crosswalk.git] / src / google_apis / google_api_keys.cc
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.
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.
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
16 #if defined(GOOGLE_CHROME_BUILD) || defined(USE_OFFICIAL_GOOGLE_API_KEYS)
17 #include "google_apis/internal/google_chrome_api_keys.h"
18 #endif
19
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"
23
24 #if !defined(GOOGLE_API_KEY)
25 #define GOOGLE_API_KEY DUMMY_API_TOKEN
26 #endif
27
28 #if !defined(GOOGLE_CLIENT_ID_MAIN)
29 #define GOOGLE_CLIENT_ID_MAIN DUMMY_API_TOKEN
30 #endif
31
32 #if !defined(GOOGLE_CLIENT_SECRET_MAIN)
33 #define GOOGLE_CLIENT_SECRET_MAIN DUMMY_API_TOKEN
34 #endif
35
36 #if !defined(GOOGLE_CLIENT_ID_CLOUD_PRINT)
37 #define GOOGLE_CLIENT_ID_CLOUD_PRINT DUMMY_API_TOKEN
38 #endif
39
40 #if !defined(GOOGLE_CLIENT_SECRET_CLOUD_PRINT)
41 #define GOOGLE_CLIENT_SECRET_CLOUD_PRINT DUMMY_API_TOKEN
42 #endif
43
44 #if !defined(GOOGLE_CLIENT_ID_REMOTING)
45 #define GOOGLE_CLIENT_ID_REMOTING DUMMY_API_TOKEN
46 #endif
47
48 #if !defined(GOOGLE_CLIENT_SECRET_REMOTING)
49 #define GOOGLE_CLIENT_SECRET_REMOTING DUMMY_API_TOKEN
50 #endif
51
52 #if !defined(GOOGLE_CLIENT_ID_REMOTING_HOST)
53 #define GOOGLE_CLIENT_ID_REMOTING_HOST DUMMY_API_TOKEN
54 #endif
55
56 #if !defined(GOOGLE_CLIENT_SECRET_REMOTING_HOST)
57 #define GOOGLE_CLIENT_SECRET_REMOTING_HOST DUMMY_API_TOKEN
58 #endif
59
60 // These are used as shortcuts for developers and users providing
61 // OAuth credentials via preprocessor defines or environment
62 // variables.  If set, they will be used to replace any of the client
63 // IDs and secrets above that have not been set (and only those; they
64 // will not override already-set values).
65 #if !defined(GOOGLE_DEFAULT_CLIENT_ID)
66 #define GOOGLE_DEFAULT_CLIENT_ID ""
67 #endif
68 #if !defined(GOOGLE_DEFAULT_CLIENT_SECRET)
69 #define GOOGLE_DEFAULT_CLIENT_SECRET ""
70 #endif
71
72 namespace switches {
73
74 // Specifies custom OAuth2 client id for testing purposes.
75 const char kOAuth2ClientID[] = "oauth2-client-id";
76
77 // Specifies custom OAuth2 client secret for testing purposes.
78 const char kOAuth2ClientSecret[] = "oauth2-client-secret";
79
80 }  // namespace switches
81
82 namespace google_apis {
83
84 // This is used as a lazy instance to determine keys once and cache them.
85 class APIKeyCache {
86  public:
87   APIKeyCache() {
88     scoped_ptr<base::Environment> environment(base::Environment::Create());
89     CommandLine* command_line = CommandLine::ForCurrentProcess();
90
91     api_key_ = CalculateKeyValue(GOOGLE_API_KEY,
92                                  STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY),
93                                  NULL,
94                                  std::string(),
95                                  environment.get(),
96                                  command_line);
97
98     std::string default_client_id =
99         CalculateKeyValue(GOOGLE_DEFAULT_CLIENT_ID,
100                           STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_ID),
101                           NULL,
102                           std::string(),
103                           environment.get(),
104                           command_line);
105     std::string default_client_secret =
106         CalculateKeyValue(GOOGLE_DEFAULT_CLIENT_SECRET,
107                           STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_SECRET),
108                           NULL,
109                           std::string(),
110                           environment.get(),
111                           command_line);
112
113     // We currently only allow overriding the baked-in values for the
114     // default OAuth2 client ID and secret using a command-line
115     // argument, since that is useful to enable testing against
116     // staging servers, and since that was what was possible and
117     // likely practiced by the QA team before this implementation was
118     // written.
119     client_ids_[CLIENT_MAIN] = CalculateKeyValue(
120         GOOGLE_CLIENT_ID_MAIN,
121         STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_MAIN),
122         switches::kOAuth2ClientID,
123         default_client_id,
124         environment.get(),
125         command_line);
126     client_secrets_[CLIENT_MAIN] = CalculateKeyValue(
127         GOOGLE_CLIENT_SECRET_MAIN,
128         STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_MAIN),
129         switches::kOAuth2ClientSecret,
130         default_client_secret,
131         environment.get(),
132         command_line);
133
134     client_ids_[CLIENT_CLOUD_PRINT] = CalculateKeyValue(
135         GOOGLE_CLIENT_ID_CLOUD_PRINT,
136         STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_CLOUD_PRINT),
137         NULL,
138         default_client_id,
139         environment.get(),
140         command_line);
141     client_secrets_[CLIENT_CLOUD_PRINT] = CalculateKeyValue(
142         GOOGLE_CLIENT_SECRET_CLOUD_PRINT,
143         STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_CLOUD_PRINT),
144         NULL,
145         default_client_secret,
146         environment.get(),
147         command_line);
148
149     client_ids_[CLIENT_REMOTING] = CalculateKeyValue(
150         GOOGLE_CLIENT_ID_REMOTING,
151         STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_REMOTING),
152         NULL,
153         default_client_id,
154         environment.get(),
155         command_line);
156     client_secrets_[CLIENT_REMOTING] = CalculateKeyValue(
157         GOOGLE_CLIENT_SECRET_REMOTING,
158         STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_REMOTING),
159         NULL,
160         default_client_secret,
161         environment.get(),
162         command_line);
163
164     client_ids_[CLIENT_REMOTING_HOST] = CalculateKeyValue(
165         GOOGLE_CLIENT_ID_REMOTING_HOST,
166         STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_REMOTING_HOST),
167         NULL,
168         default_client_id,
169         environment.get(),
170         command_line);
171     client_secrets_[CLIENT_REMOTING_HOST] = CalculateKeyValue(
172         GOOGLE_CLIENT_SECRET_REMOTING_HOST,
173         STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_REMOTING_HOST),
174         NULL,
175         default_client_secret,
176         environment.get(),
177         command_line);
178   }
179
180   std::string api_key() const { return api_key_; }
181
182   std::string GetClientID(OAuth2Client client) const {
183     DCHECK_LT(client, CLIENT_NUM_ITEMS);
184     return client_ids_[client];
185   }
186
187   std::string GetClientSecret(OAuth2Client client) const {
188     DCHECK_LT(client, CLIENT_NUM_ITEMS);
189     return client_secrets_[client];
190   }
191
192  private:
193   // Gets a value for a key.  In priority order, this will be the value
194   // provided via a command-line switch, the value provided via an
195   // environment variable, or finally a value baked into the build.
196   // |command_line_switch| may be NULL.
197   static std::string CalculateKeyValue(const char* baked_in_value,
198                                        const char* environment_variable_name,
199                                        const char* command_line_switch,
200                                        const std::string& default_if_unset,
201                                        base::Environment* environment,
202                                        CommandLine* command_line) {
203     std::string key_value = baked_in_value;
204     std::string temp;
205     if (environment->GetVar(environment_variable_name, &temp)) {
206       key_value = temp;
207       LOG(INFO) << "Overriding API key " << environment_variable_name
208                 << " with value " << key_value << " from environment variable.";
209     }
210
211     if (command_line_switch && command_line->HasSwitch(command_line_switch)) {
212       key_value = command_line->GetSwitchValueASCII(command_line_switch);
213       LOG(INFO) << "Overriding API key " << environment_variable_name
214                 << " with value " << key_value << " from command-line switch.";
215     }
216
217     if (key_value == DUMMY_API_TOKEN) {
218 #if defined(GOOGLE_CHROME_BUILD)
219       // No key should be unset in an official build except the
220       // GOOGLE_DEFAULT_* keys.  The default keys don't trigger this
221       // check as their "unset" value is not DUMMY_API_TOKEN.
222       CHECK(false);
223 #endif
224       if (default_if_unset.size() > 0) {
225         LOG(INFO) << "Using default value \"" << default_if_unset
226                   << "\" for API key " << environment_variable_name;
227         key_value = default_if_unset;
228       }
229     }
230
231     // This should remain a debug-only log.
232     DVLOG(1) << "API key " << environment_variable_name << "=" << key_value;
233
234     return key_value;
235   }
236
237   std::string api_key_;
238   std::string client_ids_[CLIENT_NUM_ITEMS];
239   std::string client_secrets_[CLIENT_NUM_ITEMS];
240 };
241
242 static base::LazyInstance<APIKeyCache> g_api_key_cache =
243     LAZY_INSTANCE_INITIALIZER;
244
245 bool HasKeysConfigured() {
246   if (GetAPIKey() == DUMMY_API_TOKEN)
247     return false;
248
249   for (size_t client_id = 0; client_id < CLIENT_NUM_ITEMS; ++client_id) {
250     OAuth2Client client = static_cast<OAuth2Client>(client_id);
251     if (GetOAuth2ClientID(client) == DUMMY_API_TOKEN ||
252         GetOAuth2ClientSecret(client) == DUMMY_API_TOKEN) {
253       return false;
254     }
255   }
256
257   return true;
258 }
259
260 std::string GetAPIKey() {
261   return g_api_key_cache.Get().api_key();
262 }
263
264 std::string GetOAuth2ClientID(OAuth2Client client) {
265   return g_api_key_cache.Get().GetClientID(client);
266 }
267
268 std::string GetOAuth2ClientSecret(OAuth2Client client) {
269   return g_api_key_cache.Get().GetClientSecret(client);
270 }
271
272 }  // namespace google_apis