OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/net/gaia/token_service.h" | 5 #include "chrome/browser/net/gaia/token_service.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
9 #include "chrome/browser/profiles/profile.h" | 9 #include "chrome/browser/profiles/profile.h" |
10 #include "chrome/common/chrome_notification_types.h" | 10 #include "chrome/common/chrome_notification_types.h" |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
153 if (web_data_service_.get()) | 153 if (web_data_service_.get()) |
154 web_data_service_->SetTokenForService(service, auth_token); | 154 web_data_service_->SetTokenForService(service, auth_token); |
155 } | 155 } |
156 | 156 |
157 void TokenService::EraseTokensFromDB() { | 157 void TokenService::EraseTokensFromDB() { |
158 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 158 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
159 if (web_data_service_.get()) | 159 if (web_data_service_.get()) |
160 web_data_service_->RemoveAllTokens(); | 160 web_data_service_->RemoveAllTokens(); |
161 } | 161 } |
162 | 162 |
163 // static | |
164 int TokenService::GetServiceIndex(const std::string& service) { | |
165 for (int i = 0; i < kNumServices; ++i) { | |
166 if (kServices[i] == service) | |
167 return i; | |
168 } | |
169 return -1; | |
170 } | |
171 | |
163 bool TokenService::AreCredentialsValid() const { | 172 bool TokenService::AreCredentialsValid() const { |
164 return !credentials_.lsid.empty() && !credentials_.sid.empty(); | 173 return !credentials_.lsid.empty() && !credentials_.sid.empty(); |
165 } | 174 } |
166 | 175 |
167 bool TokenService::HasLsid() const { | 176 bool TokenService::HasLsid() const { |
168 return !credentials_.lsid.empty(); | 177 return !credentials_.lsid.empty(); |
169 } | 178 } |
170 | 179 |
171 const std::string& TokenService::GetLsid() const { | 180 const std::string& TokenService::GetLsid() const { |
172 return credentials_.lsid; | 181 return credentials_.lsid; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
232 const std::string& TokenService::GetTokenForService( | 241 const std::string& TokenService::GetTokenForService( |
233 const char* const service) const { | 242 const char* const service) const { |
234 | 243 |
235 if (token_map_.count(service) > 0) { | 244 if (token_map_.count(service) > 0) { |
236 // Note map[key] is not const. | 245 // Note map[key] is not const. |
237 return (*token_map_.find(service)).second; | 246 return (*token_map_.find(service)).second; |
238 } | 247 } |
239 return EmptyString(); | 248 return EmptyString(); |
240 } | 249 } |
241 | 250 |
251 bool TokenService::HasOAuthLoginToken() const { | |
Rick Campbell
2011/11/28 22:51:07
See comment in header. I recommend removing these
Munjal (Google)
2011/11/28 23:41:14
Replied there.
| |
252 return HasTokenForService(GaiaConstants::kGaiaOAuth2LoginRefreshToken); | |
253 } | |
254 | |
255 const std::string& TokenService::GetOAuth2LoginRefreshToken() const { | |
256 return GetTokenForService(GaiaConstants::kGaiaOAuth2LoginRefreshToken); | |
257 } | |
258 | |
259 const std::string& TokenService::GetOAuth2LoginAccessToken() const { | |
260 return GetTokenForService(GaiaConstants::kGaiaOAuth2LoginAccessToken); | |
261 } | |
262 | |
242 // Note that this can fire twice or more for any given service. | 263 // Note that this can fire twice or more for any given service. |
243 // It can fire once from the DB read, and then once from the initial | 264 // It can fire once from the DB read, and then once from the initial |
244 // fetcher. Future fetches can cause more notification firings. | 265 // fetcher. Future fetches can cause more notification firings. |
245 // The DB read will not however fire a notification if the fetcher | 266 // The DB read will not however fire a notification if the fetcher |
246 // returned first. So it's always safe to use the latest notification. | 267 // returned first. So it's always safe to use the latest notification. |
247 void TokenService::FireTokenAvailableNotification( | 268 void TokenService::FireTokenAvailableNotification( |
248 const std::string& service, | 269 const std::string& service, |
249 const std::string& auth_token) { | 270 const std::string& auth_token) { |
250 | 271 |
251 TokenAvailableDetails details(service, auth_token); | 272 TokenAvailableDetails details(service, auth_token); |
(...skipping 20 matching lines...) Expand all Loading... | |
272 FireTokenAvailableNotification(service, auth_token); | 293 FireTokenAvailableNotification(service, auth_token); |
273 } | 294 } |
274 | 295 |
275 void TokenService::OnIssueAuthTokenSuccess(const std::string& service, | 296 void TokenService::OnIssueAuthTokenSuccess(const std::string& service, |
276 const std::string& auth_token) { | 297 const std::string& auth_token) { |
277 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 298 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
278 VLOG(1) << "Got an authorization token for " << service; | 299 VLOG(1) << "Got an authorization token for " << service; |
279 token_map_[service] = auth_token; | 300 token_map_[service] = auth_token; |
280 FireTokenAvailableNotification(service, auth_token); | 301 FireTokenAvailableNotification(service, auth_token); |
281 SaveAuthTokenToDB(service, auth_token); | 302 SaveAuthTokenToDB(service, auth_token); |
303 if (service == GaiaConstants::kLSOService) { | |
Rick Campbell
2011/11/28 22:51:07
Is there another way to accomplish this? Splicing
Munjal (Google)
2011/11/28 23:41:14
I thought about that but decided that this was the
| |
304 int index = GetServiceIndex(service); | |
305 DCHECK_NE(-1, index); | |
306 fetchers_[index]->StartOAuthLoginTokenFetch(auth_token); | |
307 } | |
282 } | 308 } |
283 | 309 |
284 void TokenService::OnIssueAuthTokenFailure(const std::string& service, | 310 void TokenService::OnIssueAuthTokenFailure(const std::string& service, |
285 const GoogleServiceAuthError& error) { | 311 const GoogleServiceAuthError& error) { |
286 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 312 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
287 LOG(WARNING) << "Auth token issuing failed for service:" << service; | 313 LOG(WARNING) << "Auth token issuing failed for service:" << service; |
288 FireTokenRequestFailedNotification(service, error); | 314 FireTokenRequestFailedNotification(service, error); |
289 } | 315 } |
290 | 316 |
317 void TokenService::OnOAuthLoginTokenSuccess(const std::string& refresh_token, | |
318 const std::string& access_token, | |
319 int expires_in_secs) { | |
320 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
321 VLOG(1) << "Got OAuth2 login token pair"; | |
322 token_map_[GaiaConstants::kGaiaOAuth2LoginRefreshToken] = refresh_token; | |
323 token_map_[GaiaConstants::kGaiaOAuth2LoginAccessToken] = access_token; | |
324 SaveAuthTokenToDB(GaiaConstants::kGaiaOAuth2LoginRefreshToken, | |
325 refresh_token); | |
326 SaveAuthTokenToDB(GaiaConstants::kGaiaOAuth2LoginAccessToken, | |
327 access_token); | |
328 // We don't save expiration information for now. | |
329 | |
330 FireTokenAvailableNotification(GaiaConstants::kGaiaOAuth2LoginRefreshToken, | |
331 refresh_token); | |
332 } | |
333 | |
334 void TokenService::OnOAuthLoginTokenFailure( | |
335 const GoogleServiceAuthError& error) { | |
336 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
337 LOG(WARNING) << "OAuth2 login token pair fetch failed:"; | |
338 FireTokenRequestFailedNotification( | |
339 GaiaConstants::kGaiaOAuth2LoginRefreshToken, error); | |
340 } | |
341 | |
291 void TokenService::OnOAuthGetAccessTokenSuccess(const std::string& token, | 342 void TokenService::OnOAuthGetAccessTokenSuccess(const std::string& token, |
292 const std::string& secret) { | 343 const std::string& secret) { |
293 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 344 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
294 VLOG(1) << "TokenService::OnOAuthGetAccessTokenSuccess"; | 345 VLOG(1) << "TokenService::OnOAuthGetAccessTokenSuccess"; |
295 SaveAuthTokenToDB(GaiaConstants::kGaiaOAuthToken, token); | 346 SaveAuthTokenToDB(GaiaConstants::kGaiaOAuthToken, token); |
296 SaveAuthTokenToDB(GaiaConstants::kGaiaOAuthSecret, secret); | 347 SaveAuthTokenToDB(GaiaConstants::kGaiaOAuthSecret, secret); |
297 UpdateOAuthCredentials(token, secret); | 348 UpdateOAuthCredentials(token, secret); |
298 } | 349 } |
299 | 350 |
300 void TokenService::OnOAuthGetAccessTokenFailure( | 351 void TokenService::OnOAuthGetAccessTokenFailure( |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
341 content::Source<TokenService>(this), | 392 content::Source<TokenService>(this), |
342 content::NotificationService::NoDetails()); | 393 content::NotificationService::NoDetails()); |
343 } | 394 } |
344 | 395 |
345 // Load tokens from the db_token map into the in memory token map. | 396 // Load tokens from the db_token map into the in memory token map. |
346 void TokenService::LoadTokensIntoMemory( | 397 void TokenService::LoadTokensIntoMemory( |
347 const std::map<std::string, std::string>& db_tokens, | 398 const std::map<std::string, std::string>& db_tokens, |
348 std::map<std::string, std::string>* in_memory_tokens) { | 399 std::map<std::string, std::string>* in_memory_tokens) { |
349 | 400 |
350 for (int i = 0; i < kNumServices; i++) { | 401 for (int i = 0; i < kNumServices; i++) { |
351 // OnIssueAuthTokenSuccess should come from the same thread. | 402 LoadSingleTokenIntoMemory(db_tokens, in_memory_tokens, kServices[i]); |
352 // If a token is already present in the map, it could only have | |
353 // come from a DB read or from IssueAuthToken. Since we should never | |
354 // fetch from the DB twice in a browser session, it must be from | |
355 // OnIssueAuthTokenSuccess, which is a live fetcher. | |
356 // | |
357 // Network fetched tokens take priority over DB tokens, so exclude tokens | |
358 // which have already been loaded by the fetcher. | |
359 if (!in_memory_tokens->count(kServices[i]) && | |
360 db_tokens.count(kServices[i])) { | |
361 std::string db_token = db_tokens.find(kServices[i])->second; | |
362 if (!db_token.empty()) { | |
363 VLOG(1) << "Loading " << kServices[i] << " token from DB: " << db_token; | |
364 (*in_memory_tokens)[kServices[i]] = db_token; | |
365 FireTokenAvailableNotification(kServices[i], db_token); | |
366 // Failures are only for network errors. | |
367 } | |
368 } | |
369 } | 403 } |
404 LoadSingleTokenIntoMemory(db_tokens, in_memory_tokens, | |
405 GaiaConstants::kGaiaOAuth2LoginRefreshToken); | |
406 LoadSingleTokenIntoMemory(db_tokens, in_memory_tokens, | |
407 GaiaConstants::kGaiaOAuth2LoginAccessToken); | |
370 | 408 |
371 if (credentials_.lsid.empty() && credentials_.sid.empty()) { | 409 if (credentials_.lsid.empty() && credentials_.sid.empty()) { |
372 // Look for GAIA SID and LSID tokens. If we have both, and the current | 410 // Look for GAIA SID and LSID tokens. If we have both, and the current |
373 // crendentials are empty, update the credentials. | 411 // crendentials are empty, update the credentials. |
374 std::string lsid; | 412 std::string lsid; |
375 std::string sid; | 413 std::string sid; |
376 | 414 |
377 if (db_tokens.count(GaiaConstants::kGaiaLsid) > 0) | 415 if (db_tokens.count(GaiaConstants::kGaiaLsid) > 0) |
378 lsid = db_tokens.find(GaiaConstants::kGaiaLsid)->second; | 416 lsid = db_tokens.find(GaiaConstants::kGaiaLsid)->second; |
379 | 417 |
380 if (db_tokens.count(GaiaConstants::kGaiaSid) > 0) | 418 if (db_tokens.count(GaiaConstants::kGaiaSid) > 0) |
381 sid = db_tokens.find(GaiaConstants::kGaiaSid)->second; | 419 sid = db_tokens.find(GaiaConstants::kGaiaSid)->second; |
382 | 420 |
383 if (!lsid.empty() && !sid.empty()) { | 421 if (!lsid.empty() && !sid.empty()) { |
384 UpdateCredentials(GaiaAuthConsumer::ClientLoginResult(sid, | 422 UpdateCredentials(GaiaAuthConsumer::ClientLoginResult(sid, |
385 lsid, | 423 lsid, |
386 std::string(), | 424 std::string(), |
387 std::string())); | 425 std::string())); |
388 } | 426 } |
389 } | 427 } |
390 | 428 |
391 for (int i = 0; i < kNumOAuthServices; i++) { | 429 for (int i = 0; i < kNumOAuthServices; i++) { |
392 // OnIssueAuthTokenSuccess should come from the same thread. | 430 LoadSingleTokenIntoMemory(db_tokens, in_memory_tokens, kOAuthServices[i]); |
393 // If a token is already present in the map, it could only have | |
394 // come from a DB read or from IssueAuthToken. Since we should never | |
395 // fetch from the DB twice in a browser session, it must be from | |
396 // OnIssueAuthTokenSuccess, which is a live fetcher. | |
397 // | |
398 // Network fetched tokens take priority over DB tokens, so exclude tokens | |
399 // which have already been loaded by the fetcher. | |
400 if (!in_memory_tokens->count(kOAuthServices[i]) && | |
401 db_tokens.count(kOAuthServices[i])) { | |
402 std::string db_token = db_tokens.find(kOAuthServices[i])->second; | |
403 if (!db_token.empty()) { | |
404 VLOG(1) << "Loading " << kOAuthServices[i] << " OAuth token from DB: " | |
405 << db_token; | |
406 (*in_memory_tokens)[kOAuthServices[i]] = db_token; | |
407 FireTokenAvailableNotification(kOAuthServices[i], db_token); | |
408 // Failures are only for network errors. | |
409 } | |
410 } | |
411 } | 431 } |
412 | 432 |
413 if (oauth_token_.empty() && oauth_secret_.empty()) { | 433 if (oauth_token_.empty() && oauth_secret_.empty()) { |
414 // Look for GAIA OAuth1 access token and secret. If we have both, and the | 434 // Look for GAIA OAuth1 access token and secret. If we have both, and the |
415 // current crendentials are empty, update the credentials. | 435 // current crendentials are empty, update the credentials. |
416 std::string oauth_token; | 436 std::string oauth_token; |
417 std::string oauth_secret; | 437 std::string oauth_secret; |
418 | 438 |
419 if (db_tokens.count(GaiaConstants::kGaiaOAuthToken) > 0) | 439 if (db_tokens.count(GaiaConstants::kGaiaOAuthToken) > 0) |
420 oauth_token = db_tokens.find(GaiaConstants::kGaiaOAuthToken)->second; | 440 oauth_token = db_tokens.find(GaiaConstants::kGaiaOAuthToken)->second; |
421 | 441 |
422 if (db_tokens.count(GaiaConstants::kGaiaOAuthSecret) > 0) | 442 if (db_tokens.count(GaiaConstants::kGaiaOAuthSecret) > 0) |
423 oauth_secret = db_tokens.find(GaiaConstants::kGaiaOAuthSecret)->second; | 443 oauth_secret = db_tokens.find(GaiaConstants::kGaiaOAuthSecret)->second; |
424 | 444 |
425 if (!oauth_token.empty() && !oauth_secret.empty()) { | 445 if (!oauth_token.empty() && !oauth_secret.empty()) { |
426 UpdateOAuthCredentials(oauth_token, oauth_secret); | 446 UpdateOAuthCredentials(oauth_token, oauth_secret); |
427 } | 447 } |
428 } | 448 } |
429 } | 449 } |
430 | 450 |
451 void TokenService::LoadSingleTokenIntoMemory( | |
452 const std::map<std::string, std::string>& db_tokens, | |
453 std::map<std::string, std::string>* in_memory_tokens, | |
454 const std::string& service) { | |
455 // OnIssueAuthTokenSuccess should come from the same thread. | |
456 // If a token is already present in the map, it could only have | |
457 // come from a DB read or from IssueAuthToken. Since we should never | |
458 // fetch from the DB twice in a browser session, it must be from | |
459 // OnIssueAuthTokenSuccess, which is a live fetcher. | |
460 // | |
461 // Network fetched tokens take priority over DB tokens, so exclude tokens | |
462 // which have already been loaded by the fetcher. | |
463 if (!in_memory_tokens->count(service) && db_tokens.count(service)) { | |
464 std::string db_token = db_tokens.find(service)->second; | |
465 if (!db_token.empty()) { | |
466 VLOG(1) << "Loading " << service << " token from DB: " << db_token; | |
467 (*in_memory_tokens)[service] = db_token; | |
468 FireTokenAvailableNotification(service, db_token); | |
469 // Failures are only for network errors. | |
470 } | |
471 } | |
472 } | |
473 | |
431 void TokenService::Observe(int type, | 474 void TokenService::Observe(int type, |
432 const content::NotificationSource& source, | 475 const content::NotificationSource& source, |
433 const content::NotificationDetails& details) { | 476 const content::NotificationDetails& details) { |
434 DCHECK_EQ(type, chrome::NOTIFICATION_TOKEN_UPDATED); | 477 DCHECK_EQ(type, chrome::NOTIFICATION_TOKEN_UPDATED); |
435 TokenAvailableDetails* tok_details = | 478 TokenAvailableDetails* tok_details = |
436 content::Details<TokenAvailableDetails>(details).ptr(); | 479 content::Details<TokenAvailableDetails>(details).ptr(); |
437 OnIssueAuthTokenSuccess(tok_details->service(), tok_details->token()); | 480 OnIssueAuthTokenSuccess(tok_details->service(), tok_details->token()); |
438 } | 481 } |
OLD | NEW |