| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/string_util.h" | 7 #include "base/string_util.h" |
| 8 #include "chrome/browser/chrome_thread.h" | 8 #include "chrome/browser/chrome_thread.h" |
| 9 #include "chrome/browser/profile.h" | 9 #include "chrome/browser/profile.h" |
| 10 #include "chrome/common/net/gaia/gaia_authenticator2.h" | 10 #include "chrome/common/net/gaia/gaia_authenticator2.h" |
| 11 #include "chrome/common/net/gaia/gaia_constants.h" | 11 #include "chrome/common/net/gaia/gaia_constants.h" |
| 12 #include "chrome/common/net/url_request_context_getter.h" | 12 #include "chrome/common/net/url_request_context_getter.h" |
| 13 #include "chrome/common/notification_service.h" | 13 #include "chrome/common/notification_service.h" |
| 14 | 14 |
| 15 // Unfortunately kNumServices must be defined in the .h. | 15 // Unfortunately kNumServices must be defined in the .h. |
| 16 // TODO(chron): Sync doesn't use the TalkToken anymore so we can stop |
| 17 // requesting it. |
| 16 const char* TokenService::kServices[] = {GaiaConstants::kSyncService, | 18 const char* TokenService::kServices[] = {GaiaConstants::kSyncService, |
| 17 GaiaConstants::kTalkService}; | 19 GaiaConstants::kTalkService}; |
| 18 TokenService::TokenService() | 20 TokenService::TokenService() |
| 19 : token_loading_query_(NULL) { | 21 : token_loading_query_(NULL) { |
| 20 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | 22 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
| 21 } | 23 } |
| 22 | 24 |
| 23 TokenService::~TokenService() { | 25 TokenService::~TokenService() { |
| 24 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | 26 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
| 25 ResetCredentialsInMemory(); | 27 ResetCredentialsInMemory(); |
| 26 } | 28 } |
| 27 | 29 |
| 28 void TokenService::Initialize(const char* const source, | 30 void TokenService::Initialize(const char* const source, |
| 29 Profile* profile) { | 31 Profile* profile) { |
| 30 | 32 |
| 31 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | 33 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
| 32 | 34 if (!source_.empty()) { |
| 35 // Already initialized. |
| 36 return; |
| 37 } |
| 33 getter_ = profile->GetRequestContext(); | 38 getter_ = profile->GetRequestContext(); |
| 34 // Since the user can create a bookmark in incognito, sync may be running. | 39 // Since the user can create a bookmark in incognito, sync may be running. |
| 35 // Thus we have to go for explicit access. | 40 // Thus we have to go for explicit access. |
| 36 web_data_service_ = profile->GetWebDataService(Profile::EXPLICIT_ACCESS); | 41 web_data_service_ = profile->GetWebDataService(Profile::EXPLICIT_ACCESS); |
| 37 source_ = std::string(source); | 42 source_ = std::string(source); |
| 43 registrar_.Add(this, |
| 44 NotificationType::TOKEN_UPDATED, |
| 45 NotificationService::AllSources()); |
| 38 } | 46 } |
| 39 | 47 |
| 40 void TokenService::ResetCredentialsInMemory() { | 48 void TokenService::ResetCredentialsInMemory() { |
| 41 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | 49 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
| 42 | 50 |
| 43 // Terminate any running fetchers. Callbacks will not return. | 51 // Terminate any running fetchers. Callbacks will not return. |
| 44 for (int i = 0; i < kNumServices; i++) { | 52 for (int i = 0; i < kNumServices; i++) { |
| 45 fetchers_[i].reset(); | 53 fetchers_[i].reset(); |
| 46 } | 54 } |
| 47 | 55 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 const std::string& service, | 148 const std::string& service, |
| 141 const GoogleServiceAuthError& error) { | 149 const GoogleServiceAuthError& error) { |
| 142 | 150 |
| 143 TokenRequestFailedDetails details(service, error); | 151 TokenRequestFailedDetails details(service, error); |
| 144 NotificationService::current()->Notify( | 152 NotificationService::current()->Notify( |
| 145 NotificationType::TOKEN_REQUEST_FAILED, | 153 NotificationType::TOKEN_REQUEST_FAILED, |
| 146 Source<TokenService>(this), | 154 Source<TokenService>(this), |
| 147 Details<const TokenRequestFailedDetails>(&details)); | 155 Details<const TokenRequestFailedDetails>(&details)); |
| 148 } | 156 } |
| 149 | 157 |
| 158 void TokenService::IssueAuthTokenForTest(const std::string& service, |
| 159 const std::string& auth_token) { |
| 160 token_map_[service] = auth_token; |
| 161 FireTokenAvailableNotification(service, auth_token); |
| 162 } |
| 163 |
| 150 void TokenService::OnIssueAuthTokenSuccess(const std::string& service, | 164 void TokenService::OnIssueAuthTokenSuccess(const std::string& service, |
| 151 const std::string& auth_token) { | 165 const std::string& auth_token) { |
| 152 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); | 166 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); |
| 153 LOG(INFO) << "Got an authorization token for " << service; | 167 LOG(INFO) << "Got an authorization token for " << service; |
| 154 token_map_[service] = auth_token; | 168 token_map_[service] = auth_token; |
| 155 FireTokenAvailableNotification(service, auth_token); | 169 FireTokenAvailableNotification(service, auth_token); |
| 156 SaveAuthTokenToDB(service, auth_token); | 170 SaveAuthTokenToDB(service, auth_token); |
| 157 } | 171 } |
| 158 | 172 |
| 159 void TokenService::OnIssueAuthTokenFailure(const std::string& service, | 173 void TokenService::OnIssueAuthTokenFailure(const std::string& service, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 171 | 185 |
| 172 // If the fetch failed, there will be no result. In that case, we just don't | 186 // If the fetch failed, there will be no result. In that case, we just don't |
| 173 // load any tokens at all from the DB. | 187 // load any tokens at all from the DB. |
| 174 if (result) { | 188 if (result) { |
| 175 DCHECK(result->GetType() == TOKEN_RESULT); | 189 DCHECK(result->GetType() == TOKEN_RESULT); |
| 176 const WDResult<std::map<std::string, std::string> > * token_result = | 190 const WDResult<std::map<std::string, std::string> > * token_result = |
| 177 static_cast<const WDResult<std::map<std::string, std::string> > * > ( | 191 static_cast<const WDResult<std::map<std::string, std::string> > * > ( |
| 178 result); | 192 result); |
| 179 LoadTokensIntoMemory(token_result->GetValue(), &token_map_); | 193 LoadTokensIntoMemory(token_result->GetValue(), &token_map_); |
| 180 } | 194 } |
| 195 |
| 196 NotificationService::current()->Notify( |
| 197 NotificationType::TOKEN_LOADING_FINISHED, |
| 198 Source<TokenService>(this), |
| 199 NotificationService::NoDetails()); |
| 181 } | 200 } |
| 182 | 201 |
| 183 // Load tokens from the db_token map into the in memory token map. | 202 // Load tokens from the db_token map into the in memory token map. |
| 184 void TokenService::LoadTokensIntoMemory( | 203 void TokenService::LoadTokensIntoMemory( |
| 185 const std::map<std::string, std::string>& db_tokens, | 204 const std::map<std::string, std::string>& db_tokens, |
| 186 std::map<std::string, std::string>* in_memory_tokens) { | 205 std::map<std::string, std::string>* in_memory_tokens) { |
| 187 | 206 |
| 188 for (int i = 0; i < kNumServices; i++) { | 207 for (int i = 0; i < kNumServices; i++) { |
| 189 // OnIssueAuthTokenSuccess should come from the same thread. | 208 // OnIssueAuthTokenSuccess should come from the same thread. |
| 190 // If a token is already present in the map, it could only have | 209 // If a token is already present in the map, it could only have |
| 191 // come from a DB read or from IssueAuthToken. Since we should never | 210 // come from a DB read or from IssueAuthToken. Since we should never |
| 192 // fetch from the DB twice in a browser session, it must be from | 211 // fetch from the DB twice in a browser session, it must be from |
| 193 // OnIssueAuthTokenSuccess, which is a live fetcher. | 212 // OnIssueAuthTokenSuccess, which is a live fetcher. |
| 194 // | 213 // |
| 195 // Network fetched tokens take priority over DB tokens, so exclude tokens | 214 // Network fetched tokens take priority over DB tokens, so exclude tokens |
| 196 // which have already been loaded by the fetcher. | 215 // which have already been loaded by the fetcher. |
| 197 if (!in_memory_tokens->count(kServices[i]) && | 216 if (!in_memory_tokens->count(kServices[i]) && |
| 198 db_tokens.count(kServices[i])) { | 217 db_tokens.count(kServices[i])) { |
| 199 std::string db_token = db_tokens.find(kServices[i])->second; | 218 std::string db_token = db_tokens.find(kServices[i])->second; |
| 200 if (!db_token.empty()) { | 219 if (!db_token.empty()) { |
| 201 LOG(INFO) << "Loading " << kServices[i] << "token from DB:" | 220 LOG(INFO) << "Loading " << kServices[i] << "token from DB:" |
| 202 << db_token; | 221 << db_token; |
| 203 (*in_memory_tokens)[kServices[i]] = db_token; | 222 (*in_memory_tokens)[kServices[i]] = db_token; |
| 204 FireTokenAvailableNotification(kServices[i], db_token); | 223 FireTokenAvailableNotification(kServices[i], db_token); |
| 205 // Failures are only for network errors. | 224 // Failures are only for network errors. |
| 206 } | 225 } |
| 207 } | 226 } |
| 208 } | 227 } |
| 209 } | 228 } |
| 229 |
| 230 void TokenService::Observe(NotificationType type, |
| 231 const NotificationSource& source, |
| 232 const NotificationDetails& details) { |
| 233 DCHECK(type == NotificationType::TOKEN_UPDATED); |
| 234 TokenAvailableDetails* tok_details = |
| 235 Details<TokenAvailableDetails>(details).ptr(); |
| 236 OnIssueAuthTokenSuccess(tok_details->service(), tok_details->token()); |
| 237 } |
| OLD | NEW |