1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/net/gaia/token_service.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/command_line.h" 83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_util.h" 921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/chrome_switches.h" 114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/common/net/gaia/gaia_auth_fetcher.h" 123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/net/gaia/gaia_constants.h" 13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h" 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/url_request/url_request_context_getter.h" 163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Unfortunately kNumServices must be defined in the .h. 183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// TODO(chron): Sync doesn't use the TalkToken anymore so we can stop 193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// requesting it. 20513209b27ff55e2841eac0e4120199c23acce758Ben Murdochconst char* TokenService::kServices[] = { 21513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GaiaConstants::kGaiaService, 22513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GaiaConstants::kSyncService, 23513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GaiaConstants::kTalkService, 24513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch GaiaConstants::kDeviceManagementService 25513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}; 26513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 273345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTokenService::TokenService() 283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : token_loading_query_(0) { 29731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 323345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTokenService::~TokenService() { 33731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ResetCredentialsInMemory(); 353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TokenService::Initialize(const char* const source, 383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Profile* profile) { 393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 40731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!source_.empty()) { 423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Already initialized. 433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return; 443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick getter_ = profile->GetRequestContext(); 463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Since the user can create a bookmark in incognito, sync may be running. 473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Thus we have to go for explicit access. 483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick web_data_service_ = profile->GetWebDataService(Profile::EXPLICIT_ACCESS); 493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick source_ = std::string(source); 503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#ifndef NDEBUG 523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick CommandLine* cmd_line = CommandLine::ForCurrentProcess(); 533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Allow the token service to be cleared from the command line. 543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (cmd_line->HasSwitch(switches::kClearTokenService)) 553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EraseTokensFromDB(); 563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Allow a token to be injected from the command line. 583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (cmd_line->HasSwitch(switches::kSetToken)) { 593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string value = cmd_line->GetSwitchValueASCII(switches::kSetToken); 603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int separator = value.find(':'); 613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string service = value.substr(0, separator); 623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string token = value.substr(separator + 1); 633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick token_map_[service] = token; 643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SaveAuthTokenToDB(service, token); 653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif 673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick registrar_.Add(this, 693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NotificationType::TOKEN_UPDATED, 703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NotificationService::AllSources()); 713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TokenService::ResetCredentialsInMemory() { 74731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Terminate any running fetchers. Callbacks will not return. 773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int i = 0; i < kNumServices; i++) { 783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick fetchers_[i].reset(); 793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Cancel pending loads. Callbacks will not return. 823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (token_loading_query_) { 833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick web_data_service_->CancelRequest(token_loading_query_); 843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick token_loading_query_ = 0; 853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick token_map_.clear(); 883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick credentials_ = GaiaAuthConsumer::ClientLoginResult(); 893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TokenService::UpdateCredentials( 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const GaiaAuthConsumer::ClientLoginResult& credentials) { 93731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch credentials_ = credentials; 953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Cancels any currently running requests. 973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int i = 0; i < kNumServices; i++) { 984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch fetchers_[i].reset(new GaiaAuthFetcher(this, source_, getter_)); 993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TokenService::LoadTokensFromDB() { 103731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick token_loading_query_ = web_data_service_->GetAllTokens(this); 1053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TokenService::SaveAuthTokenToDB(const std::string& service, 1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& auth_token) { 109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick web_data_service_->SetTokenForService(service, auth_token); 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TokenService::EraseTokensFromDB() { 114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick web_data_service_->RemoveAllTokens(); 1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool TokenService::AreCredentialsValid() const { 1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return !credentials_.lsid.empty() && !credentials_.sid.empty(); 1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool TokenService::HasLsid() const { 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return !credentials_.lsid.empty(); 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst std::string& TokenService::GetLsid() const { 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return credentials_.lsid; 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TokenService::StartFetchingTokens() { 131731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(AreCredentialsValid()); 1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int i = 0; i < kNumServices; i++) { 1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick fetchers_[i]->StartIssueAuthToken(credentials_.sid, 1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick credentials_.lsid, 1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick kServices[i]); 1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Services dependent on a token will check if a token is available. 1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// If it isn't, they'll go to sleep until they get a token event. 1423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool TokenService::HasTokenForService(const char* const service) const { 1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return token_map_.count(service) > 0; 1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst std::string& TokenService::GetTokenForService( 1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* const service) const { 1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (token_map_.count(service) > 0) { 1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Note map[key] is not const. 1513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return (*token_map_.find(service)).second; 1523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return EmptyString(); 1543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Note that this can fire twice or more for any given service. 1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// It can fire once from the DB read, and then once from the initial 1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// fetcher. Future fetches can cause more notification firings. 1593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// The DB read will not however fire a notification if the fetcher 1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// returned first. So it's always safe to use the latest notification. 1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TokenService::FireTokenAvailableNotification( 1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& service, 1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& auth_token) { 1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TokenAvailableDetails details(service, auth_token); 1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NotificationService::current()->Notify( 1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NotificationType::TOKEN_AVAILABLE, 1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Source<TokenService>(this), 1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Details<const TokenAvailableDetails>(&details)); 1703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TokenService::FireTokenRequestFailedNotification( 1733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& service, 1743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const GoogleServiceAuthError& error) { 1753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TokenRequestFailedDetails details(service, error); 1773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NotificationService::current()->Notify( 1783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NotificationType::TOKEN_REQUEST_FAILED, 1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Source<TokenService>(this), 1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Details<const TokenRequestFailedDetails>(&details)); 1813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TokenService::IssueAuthTokenForTest(const std::string& service, 1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& auth_token) { 1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick token_map_[service] = auth_token; 1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FireTokenAvailableNotification(service, auth_token); 1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TokenService::OnIssueAuthTokenSuccess(const std::string& service, 1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& auth_token) { 191731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 192513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch VLOG(1) << "Got an authorization token for " << service; 1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick token_map_[service] = auth_token; 1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FireTokenAvailableNotification(service, auth_token); 1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SaveAuthTokenToDB(service, auth_token); 1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TokenService::OnIssueAuthTokenFailure(const std::string& service, 1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const GoogleServiceAuthError& error) { 200731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LOG(WARNING) << "Auth token issuing failed for service:" << service; 2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FireTokenRequestFailedNotification(service, error); 2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TokenService::OnWebDataServiceRequestDone(WebDataService::Handle h, 2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const WDTypedResult* result) { 207731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(token_loading_query_); 2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick token_loading_query_ = 0; 2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // If the fetch failed, there will be no result. In that case, we just don't 2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // load any tokens at all from the DB. 2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (result) { 2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(result->GetType() == TOKEN_RESULT); 2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const WDResult<std::map<std::string, std::string> > * token_result = 2163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick static_cast<const WDResult<std::map<std::string, std::string> > * > ( 2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick result); 2183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick LoadTokensIntoMemory(token_result->GetValue(), &token_map_); 2193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NotificationService::current()->Notify( 2223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NotificationType::TOKEN_LOADING_FINISHED, 2233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Source<TokenService>(this), 2243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick NotificationService::NoDetails()); 2253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Load tokens from the db_token map into the in memory token map. 2283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TokenService::LoadTokensIntoMemory( 2293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::map<std::string, std::string>& db_tokens, 2303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::map<std::string, std::string>* in_memory_tokens) { 2313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int i = 0; i < kNumServices; i++) { 2333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // OnIssueAuthTokenSuccess should come from the same thread. 2343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // If a token is already present in the map, it could only have 2353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // come from a DB read or from IssueAuthToken. Since we should never 2363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // fetch from the DB twice in a browser session, it must be from 2373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // OnIssueAuthTokenSuccess, which is a live fetcher. 2383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // 2393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Network fetched tokens take priority over DB tokens, so exclude tokens 2403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // which have already been loaded by the fetcher. 2413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!in_memory_tokens->count(kServices[i]) && 2423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick db_tokens.count(kServices[i])) { 2433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string db_token = db_tokens.find(kServices[i])->second; 2443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!db_token.empty()) { 245513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch VLOG(1) << "Loading " << kServices[i] << "token from DB: " << db_token; 2463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick (*in_memory_tokens)[kServices[i]] = db_token; 2473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FireTokenAvailableNotification(kServices[i], db_token); 2483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Failures are only for network errors. 2493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TokenService::Observe(NotificationType type, 2553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const NotificationSource& source, 2563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const NotificationDetails& details) { 2573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick DCHECK(type == NotificationType::TOKEN_UPDATED); 2583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick TokenAvailableDetails* tok_details = 2593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Details<TokenAvailableDetails>(details).ptr(); 2603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick OnIssueAuthTokenSuccess(tok_details->service(), tok_details->token()); 2613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 262