Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(630)

Side by Side Diff: chrome/browser/chromeos/login/oauth2_login_manager.cc

Issue 148463004: Perform /ListAccounts check before session merge to see if there is a need for session merge at all. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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/chromeos/login/oauth2_login_manager.h" 5 #include "chrome/browser/chromeos/login/oauth2_login_manager.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 90
91 DCHECK(restore_strategy_ == RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN); 91 DCHECK(restore_strategy_ == RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN);
92 RestoreSessionFromSavedTokens(); 92 RestoreSessionFromSavedTokens();
93 } 93 }
94 94
95 void OAuth2LoginManager::RestoreSessionFromSavedTokens() { 95 void OAuth2LoginManager::RestoreSessionFromSavedTokens() {
96 ProfileOAuth2TokenService* token_service = GetTokenService(); 96 ProfileOAuth2TokenService* token_service = GetTokenService();
97 const std::string& primary_account_id = token_service->GetPrimaryAccountId(); 97 const std::string& primary_account_id = token_service->GetPrimaryAccountId();
98 if (token_service->RefreshTokenIsAvailable(primary_account_id)) { 98 if (token_service->RefreshTokenIsAvailable(primary_account_id)) {
99 LOG(WARNING) << "OAuth2 refresh token is already loaded."; 99 LOG(WARNING) << "OAuth2 refresh token is already loaded.";
100 RestoreSessionCookies(); 100 VerifySessionCookies();
101 } else { 101 } else {
102 LOG(WARNING) << "Loading OAuth2 refresh token from database."; 102 LOG(WARNING) << "Loading OAuth2 refresh token from database.";
103 103
104 // Flag user with unknown token status in case there are no saved tokens 104 // Flag user with unknown token status in case there are no saved tokens
105 // and OnRefreshTokenAvailable is not called. Flagging it here would 105 // and OnRefreshTokenAvailable is not called. Flagging it here would
106 // cause user to go through Gaia in next login to obtain a new refresh 106 // cause user to go through Gaia in next login to obtain a new refresh
107 // token. 107 // token.
108 UserManager::Get()->SaveUserOAuthStatus(primary_account_id, 108 UserManager::Get()->SaveUserOAuthStatus(primary_account_id,
109 User::OAUTH_TOKEN_STATUS_UNKNOWN); 109 User::OAUTH_TOKEN_STATUS_UNKNOWN);
110 110
(...skipping 25 matching lines...) Expand all
136 // oauth2 token. 136 // oauth2 token.
137 if (UserManager::Get()->IsLoggedInAsLocallyManagedUser()) { 137 if (UserManager::Get()->IsLoggedInAsLocallyManagedUser()) {
138 LOG(WARNING) << "Logged in as managed user, skip token validation."; 138 LOG(WARNING) << "Logged in as managed user, skip token validation.";
139 return; 139 return;
140 } 140 }
141 // Only restore session cookies for the primary account in the profile. 141 // Only restore session cookies for the primary account in the profile.
142 if (GetTokenService()->GetPrimaryAccountId() == account_id) { 142 if (GetTokenService()->GetPrimaryAccountId() == account_id) {
143 // Token is loaded. Undo the flagging before token loading. 143 // Token is loaded. Undo the flagging before token loading.
144 UserManager::Get()->SaveUserOAuthStatus(account_id, 144 UserManager::Get()->SaveUserOAuthStatus(account_id,
145 User::OAUTH2_TOKEN_STATUS_VALID); 145 User::OAUTH2_TOKEN_STATUS_VALID);
146 RestoreSessionCookies(); 146 VerifySessionCookies();
147 } 147 }
148 } 148 }
149 149
150 ProfileOAuth2TokenService* OAuth2LoginManager::GetTokenService() { 150 ProfileOAuth2TokenService* OAuth2LoginManager::GetTokenService() {
151 ProfileOAuth2TokenService* token_service = 151 ProfileOAuth2TokenService* token_service =
152 ProfileOAuth2TokenServiceFactory::GetForProfile(user_profile_); 152 ProfileOAuth2TokenServiceFactory::GetForProfile(user_profile_);
153 return token_service; 153 return token_service;
154 } 154 }
155 155
156 void OAuth2LoginManager::StoreOAuth2Token() { 156 void OAuth2LoginManager::StoreOAuth2Token() {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 } 237 }
238 238
239 void OAuth2LoginManager::OnOAuth2TokensFetchFailed() { 239 void OAuth2LoginManager::OnOAuth2TokensFetchFailed() {
240 LOG(ERROR) << "OAuth2 tokens fetch failed!"; 240 LOG(ERROR) << "OAuth2 tokens fetch failed!";
241 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", 241 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore",
242 SESSION_RESTORE_TOKEN_FETCH_FAILED, 242 SESSION_RESTORE_TOKEN_FETCH_FAILED,
243 SESSION_RESTORE_COUNT); 243 SESSION_RESTORE_COUNT);
244 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_FAILED); 244 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_FAILED);
245 } 245 }
246 246
247 void OAuth2LoginManager::RestoreSessionCookies() { 247 void OAuth2LoginManager::VerifySessionCookies() {
248 DCHECK(!login_verifier_.get()); 248 DCHECK(!login_verifier_.get());
249 SetSessionRestoreState(SESSION_RESTORE_IN_PROGRESS);
250 login_verifier_.reset( 249 login_verifier_.reset(
251 new OAuth2LoginVerifier(this, 250 new OAuth2LoginVerifier(this,
252 g_browser_process->system_request_context(), 251 g_browser_process->system_request_context(),
253 user_profile_->GetRequestContext(), 252 user_profile_->GetRequestContext(),
254 oauthlogin_access_token_)); 253 oauthlogin_access_token_));
254
255 if (restore_strategy_ == RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN) {
256 login_verifier_->VerifyUserCookies(user_profile_);
257 return;
258 }
259
260 RestoreSessionCookies();
261 }
262
263 void OAuth2LoginManager::RestoreSessionCookies() {
264 SetSessionRestoreState(SESSION_RESTORE_IN_PROGRESS);
255 login_verifier_->VerifyProfileTokens(user_profile_); 265 login_verifier_->VerifyProfileTokens(user_profile_);
256 } 266 }
257 267
258 void OAuth2LoginManager::Shutdown() { 268 void OAuth2LoginManager::Shutdown() {
259 GetTokenService()->RemoveObserver(this); 269 GetTokenService()->RemoveObserver(this);
260 login_verifier_.reset(); 270 login_verifier_.reset();
261 oauth2_token_fetcher_.reset(); 271 oauth2_token_fetcher_.reset();
262 } 272 }
263 273
264 void OAuth2LoginManager::OnSessionMergeSuccess() { 274 void OAuth2LoginManager::OnSessionMergeSuccess() {
265 VLOG(1) << "OAuth2 refresh and/or GAIA token verification succeeded."; 275 VLOG(1) << "OAuth2 refresh and/or GAIA token verification succeeded.";
266 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", 276 RecordSessionRestoreOutcome(SESSION_RESTORE_SUCCESS);
267 SESSION_RESTORE_SUCCESS,
268 SESSION_RESTORE_COUNT);
269 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_DONE);
270 } 277 }
271 278
272 void OAuth2LoginManager::OnSessionMergeFailure(bool connection_error) { 279 void OAuth2LoginManager::OnSessionMergeFailure(bool connection_error) {
273 LOG(ERROR) << "OAuth2 refresh and GAIA token verification failed!" 280 LOG(ERROR) << "OAuth2 refresh and GAIA token verification failed!"
274 << " connection_error: " << connection_error; 281 << " connection_error: " << connection_error;
275 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", 282 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore",
276 SESSION_RESTORE_MERGE_SESSION_FAILED, 283 SESSION_RESTORE_MERGE_SESSION_FAILED,
277 SESSION_RESTORE_COUNT); 284 SESSION_RESTORE_COUNT);
278 SetSessionRestoreState(connection_error ? 285 SetSessionRestoreState(connection_error ?
279 OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED : 286 OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED :
280 OAuth2LoginManager::SESSION_RESTORE_FAILED); 287 OAuth2LoginManager::SESSION_RESTORE_FAILED);
281 } 288 }
282 289
283 void OAuth2LoginManager::OnListAccountsSuccess(const std::string& data) { 290 void OAuth2LoginManager::OnListAccountsSuccess(const std::string& data) {
284 PostMergeVerificationOutcome outcome = POST_MERGE_SUCCESS; 291 MergeVerificationOutcome outcome = POST_MERGE_SUCCESS;
285 // Let's analyze which accounts we see logged in here: 292 // Let's analyze which accounts we see logged in here:
286 std::vector<std::string> accounts = gaia::ParseListAccountsData(data); 293 std::vector<std::string> accounts = gaia::ParseListAccountsData(data);
287 std::string user_email = gaia::CanonicalizeEmail( 294 std::string user_email = gaia::CanonicalizeEmail(
288 GetTokenService()->GetPrimaryAccountId()); 295 GetTokenService()->GetPrimaryAccountId());
289 if (!accounts.empty()) { 296 if (!accounts.empty()) {
290 bool found = false; 297 bool found = false;
291 bool first = true; 298 bool first = true;
292 for (std::vector<std::string>::const_iterator iter = accounts.begin(); 299 for (std::vector<std::string>::const_iterator iter = accounts.begin();
293 iter != accounts.end(); ++iter) { 300 iter != accounts.end(); ++iter) {
294 if (gaia::CanonicalizeEmail(*iter) == user_email) { 301 if (gaia::CanonicalizeEmail(*iter) == user_email) {
295 found = true; 302 found = true;
296 break; 303 break;
297 } 304 }
298 305
299 first = false; 306 first = false;
300 } 307 }
301 308
302 if (!found) 309 if (!found)
303 outcome = POST_MERGE_MISSING_PRIMARY_ACCOUNT; 310 outcome = POST_MERGE_MISSING_PRIMARY_ACCOUNT;
304 else if (!first) 311 else if (!first)
305 outcome = POST_MERGE_PRIMARY_NOT_FIRST_ACCOUNT; 312 outcome = POST_MERGE_PRIMARY_NOT_FIRST_ACCOUNT;
306 313
307 } else { 314 } else {
308 outcome = POST_MERGE_NO_ACCOUNTS; 315 outcome = POST_MERGE_NO_ACCOUNTS;
309 } 316 }
310 317
311 RecordPostMergeOutcome(outcome); 318 bool is_pre_merge = (state_ == SESSION_RESTORE_PREPARING);
319 RecordCookiesCheckOutcome(is_pre_merge, outcome);
320 // If the primary account is missing during the initial cookie freshness
321 // check, try to restore GAIA session cookies form the OAuth2 tokens.
322 if (is_pre_merge) {
323 if (outcome != POST_MERGE_SUCCESS &&
324 outcome != POST_MERGE_PRIMARY_NOT_FIRST_ACCOUNT) {
325 RestoreSessionCookies();
326 } else {
327 // We are done with this account, it's GAIA cookies are legit.
328 RecordSessionRestoreOutcome(SESSION_RESTORE_NOT_NEEDED);
329 }
330 }
312 } 331 }
313 332
314 void OAuth2LoginManager::OnListAccountsFailure(bool connection_error) { 333 void OAuth2LoginManager::OnListAccountsFailure(bool connection_error) {
315 RecordPostMergeOutcome(connection_error ? POST_MERGE_CONNECTION_FAILED : 334 RecordCookiesCheckOutcome(
316 POST_MERGE_VERIFICATION_FAILED); 335 state_ == SESSION_RESTORE_PREPARING, // is_pre_merge
336 connection_error ? POST_MERGE_CONNECTION_FAILED :
337 POST_MERGE_VERIFICATION_FAILED);
338 bool is_pre_merge = (state_ == SESSION_RESTORE_PREPARING);
xiyuan 2014/01/28 03:51:32 nit: Move this before RecordCookiesCheckOutcome an
zel 2014/01/29 02:15:34 Done.
339 if (is_pre_merge && !connection_error) {
xiyuan 2014/01/28 03:51:32 Should we schedule retry for connection failure? O
zel 2014/01/29 02:15:34 Fixed - good catch! No need to retrying since tha
340 // If we failed to get account list, our cookies might be stale so we
341 // need to attempt to restore them.
342 RestoreSessionCookies();
343 }
344 }
345
346 void OAuth2LoginManager::RecordSessionRestoreOutcome(
347 SessionRestoreOutcome outcome) {
348 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore",
349 outcome,
350 SESSION_RESTORE_COUNT);
351 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_DONE);
317 } 352 }
318 353
319 // static 354 // static
320 void OAuth2LoginManager::RecordPostMergeOutcome( 355 void OAuth2LoginManager::RecordCookiesCheckOutcome(
321 PostMergeVerificationOutcome outcome) { 356 bool is_pre_merge,
322 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.PostMergeVerification", 357 MergeVerificationOutcome outcome) {
323 outcome, 358 UMA_HISTOGRAM_ENUMERATION(
324 POST_MERGE_COUNT); 359 is_pre_merge ? "OAuth2Login.PreMergeVerification" :
360 "OAuth2Login.PostMergeVerification",
361 outcome,
362 POST_MERGE_COUNT);
325 } 363 }
326 364
327
328 void OAuth2LoginManager::SetSessionRestoreState( 365 void OAuth2LoginManager::SetSessionRestoreState(
329 OAuth2LoginManager::SessionRestoreState state) { 366 OAuth2LoginManager::SessionRestoreState state) {
330 if (state_ == state) 367 if (state_ == state)
331 return; 368 return;
332 369
333 state_ = state; 370 state_ = state;
334 if (state == OAuth2LoginManager::SESSION_RESTORE_FAILED) { 371 if (state == OAuth2LoginManager::SESSION_RESTORE_FAILED) {
335 UMA_HISTOGRAM_TIMES("OAuth2Login.SessionRestoreTimeToFailure", 372 UMA_HISTOGRAM_TIMES("OAuth2Login.SessionRestoreTimeToFailure",
336 base::Time::Now() - session_restore_start_); 373 base::Time::Now() - session_restore_start_);
337 } else if (state == OAuth2LoginManager::SESSION_RESTORE_DONE) { 374 } else if (state == OAuth2LoginManager::SESSION_RESTORE_DONE) {
338 UMA_HISTOGRAM_TIMES("OAuth2Login.SessionRestoreTimeToSuccess", 375 UMA_HISTOGRAM_TIMES("OAuth2Login.SessionRestoreTimeToSuccess",
339 base::Time::Now() - session_restore_start_); 376 base::Time::Now() - session_restore_start_);
340 } 377 }
341 378
342 FOR_EACH_OBSERVER(Observer, observer_list_, 379 FOR_EACH_OBSERVER(Observer, observer_list_,
343 OnSessionRestoreStateChanged(user_profile_, state_)); 380 OnSessionRestoreStateChanged(user_profile_, state_));
344 } 381 }
345 382
346 void OAuth2LoginManager::SetSessionRestoreStartForTesting( 383 void OAuth2LoginManager::SetSessionRestoreStartForTesting(
347 const base::Time& time) { 384 const base::Time& time) {
348 session_restore_start_ = time; 385 session_restore_start_ = time;
349 } 386 }
350 387
351 } // namespace chromeos 388 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/login/oauth2_login_manager.h ('k') | chrome/browser/chromeos/login/oauth2_login_verifier.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698