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

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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 92
93 DCHECK(restore_strategy_ == RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN); 93 DCHECK(restore_strategy_ == RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN);
94 RestoreSessionFromSavedTokens(); 94 RestoreSessionFromSavedTokens();
95 } 95 }
96 96
97 void OAuth2LoginManager::RestoreSessionFromSavedTokens() { 97 void OAuth2LoginManager::RestoreSessionFromSavedTokens() {
98 ProfileOAuth2TokenService* token_service = GetTokenService(); 98 ProfileOAuth2TokenService* token_service = GetTokenService();
99 const std::string& primary_account_id = GetPrimaryAccountId(); 99 const std::string& primary_account_id = GetPrimaryAccountId();
100 if (token_service->RefreshTokenIsAvailable(primary_account_id)) { 100 if (token_service->RefreshTokenIsAvailable(primary_account_id)) {
101 LOG(WARNING) << "OAuth2 refresh token is already loaded."; 101 LOG(WARNING) << "OAuth2 refresh token is already loaded.";
102 RestoreSessionCookies(); 102 VerifySessionCookies();
103 } else { 103 } else {
104 LOG(WARNING) << "Loading OAuth2 refresh token from database."; 104 LOG(WARNING) << "Loading OAuth2 refresh token from database.";
105 105
106 // Flag user with unknown token status in case there are no saved tokens 106 // Flag user with unknown token status in case there are no saved tokens
107 // and OnRefreshTokenAvailable is not called. Flagging it here would 107 // and OnRefreshTokenAvailable is not called. Flagging it here would
108 // cause user to go through Gaia in next login to obtain a new refresh 108 // cause user to go through Gaia in next login to obtain a new refresh
109 // token. 109 // token.
110 UserManager::Get()->SaveUserOAuthStatus(primary_account_id, 110 UserManager::Get()->SaveUserOAuthStatus(primary_account_id,
111 User::OAUTH_TOKEN_STATUS_UNKNOWN); 111 User::OAUTH_TOKEN_STATUS_UNKNOWN);
112 112
(...skipping 25 matching lines...) Expand all
138 // oauth2 token. 138 // oauth2 token.
139 if (UserManager::Get()->IsLoggedInAsLocallyManagedUser()) { 139 if (UserManager::Get()->IsLoggedInAsLocallyManagedUser()) {
140 LOG(WARNING) << "Logged in as managed user, skip token validation."; 140 LOG(WARNING) << "Logged in as managed user, skip token validation.";
141 return; 141 return;
142 } 142 }
143 // Only restore session cookies for the primary account in the profile. 143 // Only restore session cookies for the primary account in the profile.
144 if (GetPrimaryAccountId() == account_id) { 144 if (GetPrimaryAccountId() == account_id) {
145 // Token is loaded. Undo the flagging before token loading. 145 // Token is loaded. Undo the flagging before token loading.
146 UserManager::Get()->SaveUserOAuthStatus(account_id, 146 UserManager::Get()->SaveUserOAuthStatus(account_id,
147 User::OAUTH2_TOKEN_STATUS_VALID); 147 User::OAUTH2_TOKEN_STATUS_VALID);
148 RestoreSessionCookies(); 148 VerifySessionCookies();
149 } 149 }
150 } 150 }
151 151
152 ProfileOAuth2TokenService* OAuth2LoginManager::GetTokenService() { 152 ProfileOAuth2TokenService* OAuth2LoginManager::GetTokenService() {
153 return ProfileOAuth2TokenServiceFactory::GetForProfile(user_profile_); 153 return ProfileOAuth2TokenServiceFactory::GetForProfile(user_profile_);
154 } 154 }
155 155
156 const std::string& OAuth2LoginManager::GetPrimaryAccountId() { 156 const std::string& OAuth2LoginManager::GetPrimaryAccountId() {
157 SigninManagerBase* signin_manager = 157 SigninManagerBase* signin_manager =
158 SigninManagerFactory::GetForProfile(user_profile_); 158 SigninManagerFactory::GetForProfile(user_profile_);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) { 236 const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) {
237 VLOG(1) << "OAuth2 tokens fetched"; 237 VLOG(1) << "OAuth2 tokens fetched";
238 DCHECK(refresh_token_.empty()); 238 DCHECK(refresh_token_.empty());
239 refresh_token_.assign(oauth2_tokens.refresh_token); 239 refresh_token_.assign(oauth2_tokens.refresh_token);
240 oauthlogin_access_token_ = oauth2_tokens.access_token; 240 oauthlogin_access_token_ = oauth2_tokens.access_token;
241 StoreOAuth2Token(); 241 StoreOAuth2Token();
242 } 242 }
243 243
244 void OAuth2LoginManager::OnOAuth2TokensFetchFailed() { 244 void OAuth2LoginManager::OnOAuth2TokensFetchFailed() {
245 LOG(ERROR) << "OAuth2 tokens fetch failed!"; 245 LOG(ERROR) << "OAuth2 tokens fetch failed!";
246 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", 246 RecordSessionRestoreOutcome(SESSION_RESTORE_TOKEN_FETCH_FAILED,
247 SESSION_RESTORE_TOKEN_FETCH_FAILED, 247 SESSION_RESTORE_FAILED);
248 SESSION_RESTORE_COUNT);
249 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_FAILED);
250 } 248 }
251 249
252 void OAuth2LoginManager::RestoreSessionCookies() { 250 void OAuth2LoginManager::VerifySessionCookies() {
253 DCHECK(!login_verifier_.get()); 251 DCHECK(!login_verifier_.get());
254 SetSessionRestoreState(SESSION_RESTORE_IN_PROGRESS);
255 login_verifier_.reset( 252 login_verifier_.reset(
256 new OAuth2LoginVerifier(this, 253 new OAuth2LoginVerifier(this,
257 g_browser_process->system_request_context(), 254 g_browser_process->system_request_context(),
258 user_profile_->GetRequestContext(), 255 user_profile_->GetRequestContext(),
259 oauthlogin_access_token_)); 256 oauthlogin_access_token_));
257
258 if (restore_strategy_ == RESTORE_FROM_SAVED_OAUTH2_REFRESH_TOKEN) {
259 login_verifier_->VerifyUserCookies(user_profile_);
260 return;
261 }
262
263 RestoreSessionCookies();
264 }
265
266 void OAuth2LoginManager::RestoreSessionCookies() {
267 SetSessionRestoreState(SESSION_RESTORE_IN_PROGRESS);
260 login_verifier_->VerifyProfileTokens(user_profile_); 268 login_verifier_->VerifyProfileTokens(user_profile_);
261 } 269 }
262 270
263 void OAuth2LoginManager::Shutdown() { 271 void OAuth2LoginManager::Shutdown() {
264 GetTokenService()->RemoveObserver(this); 272 GetTokenService()->RemoveObserver(this);
265 login_verifier_.reset(); 273 login_verifier_.reset();
266 oauth2_token_fetcher_.reset(); 274 oauth2_token_fetcher_.reset();
267 } 275 }
268 276
269 void OAuth2LoginManager::OnSessionMergeSuccess() { 277 void OAuth2LoginManager::OnSessionMergeSuccess() {
270 VLOG(1) << "OAuth2 refresh and/or GAIA token verification succeeded."; 278 VLOG(1) << "OAuth2 refresh and/or GAIA token verification succeeded.";
271 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", 279 RecordSessionRestoreOutcome(SESSION_RESTORE_SUCCESS,
272 SESSION_RESTORE_SUCCESS, 280 SESSION_RESTORE_DONE);
273 SESSION_RESTORE_COUNT);
274 SetSessionRestoreState(OAuth2LoginManager::SESSION_RESTORE_DONE);
275 } 281 }
276 282
277 void OAuth2LoginManager::OnSessionMergeFailure(bool connection_error) { 283 void OAuth2LoginManager::OnSessionMergeFailure(bool connection_error) {
278 LOG(ERROR) << "OAuth2 refresh and GAIA token verification failed!" 284 LOG(ERROR) << "OAuth2 refresh and GAIA token verification failed!"
279 << " connection_error: " << connection_error; 285 << " connection_error: " << connection_error;
280 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore", 286 RecordSessionRestoreOutcome(SESSION_RESTORE_MERGE_SESSION_FAILED,
281 SESSION_RESTORE_MERGE_SESSION_FAILED, 287 connection_error ?
282 SESSION_RESTORE_COUNT); 288 SESSION_RESTORE_CONNECTION_FAILED :
283 SetSessionRestoreState(connection_error ? 289 SESSION_RESTORE_FAILED);
284 OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED :
285 OAuth2LoginManager::SESSION_RESTORE_FAILED);
286 } 290 }
287 291
288 void OAuth2LoginManager::OnListAccountsSuccess(const std::string& data) { 292 void OAuth2LoginManager::OnListAccountsSuccess(const std::string& data) {
289 PostMergeVerificationOutcome outcome = POST_MERGE_SUCCESS; 293 MergeVerificationOutcome outcome = POST_MERGE_SUCCESS;
290 // Let's analyze which accounts we see logged in here: 294 // Let's analyze which accounts we see logged in here:
291 std::vector<std::string> accounts = gaia::ParseListAccountsData(data); 295 std::vector<std::string> accounts = gaia::ParseListAccountsData(data);
292 std::string user_email = gaia::CanonicalizeEmail(GetPrimaryAccountId()); 296 std::string user_email = gaia::CanonicalizeEmail(GetPrimaryAccountId());
293 if (!accounts.empty()) { 297 if (!accounts.empty()) {
294 bool found = false; 298 bool found = false;
295 bool first = true; 299 bool first = true;
296 for (std::vector<std::string>::const_iterator iter = accounts.begin(); 300 for (std::vector<std::string>::const_iterator iter = accounts.begin();
297 iter != accounts.end(); ++iter) { 301 iter != accounts.end(); ++iter) {
298 if (gaia::CanonicalizeEmail(*iter) == user_email) { 302 if (gaia::CanonicalizeEmail(*iter) == user_email) {
299 found = true; 303 found = true;
300 break; 304 break;
301 } 305 }
302 306
303 first = false; 307 first = false;
304 } 308 }
305 309
306 if (!found) 310 if (!found)
307 outcome = POST_MERGE_MISSING_PRIMARY_ACCOUNT; 311 outcome = POST_MERGE_MISSING_PRIMARY_ACCOUNT;
308 else if (!first) 312 else if (!first)
309 outcome = POST_MERGE_PRIMARY_NOT_FIRST_ACCOUNT; 313 outcome = POST_MERGE_PRIMARY_NOT_FIRST_ACCOUNT;
310 314
311 } else { 315 } else {
312 outcome = POST_MERGE_NO_ACCOUNTS; 316 outcome = POST_MERGE_NO_ACCOUNTS;
313 } 317 }
314 318
315 RecordPostMergeOutcome(outcome); 319 bool is_pre_merge = (state_ == SESSION_RESTORE_PREPARING);
320 RecordCookiesCheckOutcome(is_pre_merge, outcome);
321 // If the primary account is missing during the initial cookie freshness
322 // check, try to restore GAIA session cookies form the OAuth2 tokens.
323 if (is_pre_merge) {
324 if (outcome != POST_MERGE_SUCCESS &&
325 outcome != POST_MERGE_PRIMARY_NOT_FIRST_ACCOUNT) {
326 RestoreSessionCookies();
327 } else {
328 // We are done with this account, it's GAIA cookies are legit.
329 RecordSessionRestoreOutcome(SESSION_RESTORE_NOT_NEEDED,
330 SESSION_RESTORE_DONE);
331 }
332 }
316 } 333 }
317 334
318 void OAuth2LoginManager::OnListAccountsFailure(bool connection_error) { 335 void OAuth2LoginManager::OnListAccountsFailure(bool connection_error) {
319 RecordPostMergeOutcome(connection_error ? POST_MERGE_CONNECTION_FAILED : 336 bool is_pre_merge = (state_ == SESSION_RESTORE_PREPARING);
320 POST_MERGE_VERIFICATION_FAILED); 337 RecordCookiesCheckOutcome(
338 is_pre_merge,
339 connection_error ? POST_MERGE_CONNECTION_FAILED :
340 POST_MERGE_VERIFICATION_FAILED);
341 if (is_pre_merge) {
342 if (!connection_error) {
343 // If we failed to get account list, our cookies might be stale so we
344 // need to attempt to restore them.
345 RestoreSessionCookies();
346 } else {
347 RecordSessionRestoreOutcome(SESSION_RESTORE_LISTACCOUNTS_FAILED,
348 SESSION_RESTORE_CONNECTION_FAILED);
349 }
350 }
351 }
352
353 void OAuth2LoginManager::RecordSessionRestoreOutcome(
354 SessionRestoreOutcome outcome,
355 OAuth2LoginManager::SessionRestoreState state) {
356 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.SessionRestore",
357 outcome,
358 SESSION_RESTORE_COUNT);
359 SetSessionRestoreState(state);
321 } 360 }
322 361
323 // static 362 // static
324 void OAuth2LoginManager::RecordPostMergeOutcome( 363 void OAuth2LoginManager::RecordCookiesCheckOutcome(
325 PostMergeVerificationOutcome outcome) { 364 bool is_pre_merge,
326 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.PostMergeVerification", 365 MergeVerificationOutcome outcome) {
327 outcome, 366 if (is_pre_merge) {
328 POST_MERGE_COUNT); 367 UMA_HISTOGRAM_ENUMERATION(
368 "OAuth2Login.PreMergeVerification",
Alexei Svitkine (slow) 2014/01/29 17:41:22 Nit: Move this on the line above and align the oth
zel 2014/01/29 17:51:46 Done.
369 outcome,
370 POST_MERGE_COUNT);
371 } else {
372 UMA_HISTOGRAM_ENUMERATION(
373 "OAuth2Login.PostMergeVerification",
374 outcome,
375 POST_MERGE_COUNT);
376 }
329 } 377 }
330 378
331
332 void OAuth2LoginManager::SetSessionRestoreState( 379 void OAuth2LoginManager::SetSessionRestoreState(
333 OAuth2LoginManager::SessionRestoreState state) { 380 OAuth2LoginManager::SessionRestoreState state) {
334 if (state_ == state) 381 if (state_ == state)
335 return; 382 return;
336 383
337 state_ = state; 384 state_ = state;
338 if (state == OAuth2LoginManager::SESSION_RESTORE_FAILED) { 385 if (state == OAuth2LoginManager::SESSION_RESTORE_FAILED) {
339 UMA_HISTOGRAM_TIMES("OAuth2Login.SessionRestoreTimeToFailure", 386 UMA_HISTOGRAM_TIMES("OAuth2Login.SessionRestoreTimeToFailure",
340 base::Time::Now() - session_restore_start_); 387 base::Time::Now() - session_restore_start_);
341 } else if (state == OAuth2LoginManager::SESSION_RESTORE_DONE) { 388 } else if (state == OAuth2LoginManager::SESSION_RESTORE_DONE) {
342 UMA_HISTOGRAM_TIMES("OAuth2Login.SessionRestoreTimeToSuccess", 389 UMA_HISTOGRAM_TIMES("OAuth2Login.SessionRestoreTimeToSuccess",
343 base::Time::Now() - session_restore_start_); 390 base::Time::Now() - session_restore_start_);
344 } 391 }
345 392
346 FOR_EACH_OBSERVER(Observer, observer_list_, 393 FOR_EACH_OBSERVER(Observer, observer_list_,
347 OnSessionRestoreStateChanged(user_profile_, state_)); 394 OnSessionRestoreStateChanged(user_profile_, state_));
348 } 395 }
349 396
350 void OAuth2LoginManager::SetSessionRestoreStartForTesting( 397 void OAuth2LoginManager::SetSessionRestoreStartForTesting(
351 const base::Time& time) { 398 const base::Time& time) {
352 session_restore_start_ = time; 399 session_restore_start_ = time;
353 } 400 }
354 401
355 } // namespace chromeos 402 } // 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