OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/signin/core/browser/account_reconcilor.h" | 5 #include "components/signin/core/browser/account_reconcilor.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
11 #include "base/location.h" | 11 #include "base/location.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/single_thread_task_runner.h" | 13 #include "base/single_thread_task_runner.h" |
14 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
15 #include "base/thread_task_runner_handle.h" | 15 #include "base/thread_task_runner_handle.h" |
16 #include "components/signin/core/browser/profile_oauth2_token_service.h" | 16 #include "components/signin/core/browser/profile_oauth2_token_service.h" |
17 #include "components/signin/core/browser/signin_client.h" | 17 #include "components/signin/core/browser/signin_client.h" |
18 #include "components/signin/core/browser/signin_metrics.h" | 18 #include "components/signin/core/browser/signin_metrics.h" |
19 #include "components/signin/core/common/profile_management_switches.h" | 19 #include "components/signin/core/common/profile_management_switches.h" |
20 #include "google_apis/gaia/gaia_auth_util.h" | 20 #include "google_apis/gaia/gaia_auth_util.h" |
21 #include "google_apis/gaia/gaia_oauth_client.h" | 21 #include "google_apis/gaia/gaia_oauth_client.h" |
22 #include "google_apis/gaia/gaia_urls.h" | 22 #include "google_apis/gaia/gaia_urls.h" |
23 | 23 |
24 | 24 |
25 namespace { | 25 namespace { |
26 | 26 |
27 class EmailEqualToFunc : public std::equal_to<std::pair<std::string, bool> > { | 27 class EmailEqualToFunc : public std::equal_to<gaia::ListedAccount> { |
28 public: | 28 public: |
29 bool operator()(const std::pair<std::string, bool>& p1, | 29 bool operator()(const gaia::ListedAccount& p1, |
30 const std::pair<std::string, bool>& p2) const; | 30 const gaia::ListedAccount& p2) const; |
31 }; | 31 }; |
32 | 32 |
33 bool EmailEqualToFunc::operator()( | 33 bool EmailEqualToFunc::operator()( |
34 const std::pair<std::string, bool>& p1, | 34 const gaia::ListedAccount& p1, |
35 const std::pair<std::string, bool>& p2) const { | 35 const gaia::ListedAccount& p2) const { |
36 return p1.second == p2.second && gaia::AreEmailsSame(p1.first, p2.first); | 36 return p1.valid == p2.valid && gaia::AreEmailsSame(p1.email, p2.email); |
37 } | 37 } |
38 | 38 |
39 class AreEmailsSameFunc : public std::equal_to<std::string> { | 39 class AreEmailsSameFunc : public std::equal_to<std::string> { |
40 public: | 40 public: |
41 bool operator()(const std::string& p1, | 41 bool operator()(const std::string& p1, |
42 const std::string& p2) const; | 42 const std::string& p2) const; |
43 }; | 43 }; |
44 | 44 |
45 bool AreEmailsSameFunc::operator()( | 45 bool AreEmailsSameFunc::operator()( |
46 const std::string& p1, | 46 const std::string& p1, |
47 const std::string& p2) const { | 47 const std::string& p2) const { |
48 return gaia::AreEmailsSame(p1, p2); | 48 return gaia::AreEmailsSame(p1, p2); |
49 } | 49 } |
50 | 50 |
| 51 gaia::ListedAccount AccountFromEmail(const std::string& email) { |
| 52 gaia::ListedAccount account; |
| 53 account.email = email; |
| 54 account.gaia_id = std::string(); |
| 55 account.valid = true; |
| 56 return account; |
| 57 } |
| 58 |
51 } // namespace | 59 } // namespace |
52 | 60 |
53 | 61 |
54 AccountReconcilor::AccountReconcilor( | 62 AccountReconcilor::AccountReconcilor( |
55 ProfileOAuth2TokenService* token_service, | 63 ProfileOAuth2TokenService* token_service, |
56 SigninManagerBase* signin_manager, | 64 SigninManagerBase* signin_manager, |
57 SigninClient* client, | 65 SigninClient* client, |
58 GaiaCookieManagerService* cookie_manager_service) | 66 GaiaCookieManagerService* cookie_manager_service) |
59 : token_service_(token_service), | 67 : token_service_(token_service), |
60 signin_manager_(signin_manager), | 68 signin_manager_(signin_manager), |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 ValidateAccountsFromTokenService(); | 282 ValidateAccountsFromTokenService(); |
275 | 283 |
276 // Rely on the GCMS to manage calls to and responses from ListAccounts. | 284 // Rely on the GCMS to manage calls to and responses from ListAccounts. |
277 if (cookie_manager_service_->ListAccounts(&gaia_accounts_)) { | 285 if (cookie_manager_service_->ListAccounts(&gaia_accounts_)) { |
278 OnGaiaAccountsInCookieUpdated( | 286 OnGaiaAccountsInCookieUpdated( |
279 gaia_accounts_, GoogleServiceAuthError(GoogleServiceAuthError::NONE)); | 287 gaia_accounts_, GoogleServiceAuthError(GoogleServiceAuthError::NONE)); |
280 } | 288 } |
281 } | 289 } |
282 | 290 |
283 void AccountReconcilor::OnGaiaAccountsInCookieUpdated( | 291 void AccountReconcilor::OnGaiaAccountsInCookieUpdated( |
284 const std::vector<std::pair<std::string, bool> >& accounts, | 292 const std::vector<gaia::ListedAccount>& accounts, |
285 const GoogleServiceAuthError& error) { | 293 const GoogleServiceAuthError& error) { |
286 VLOG(1) << "AccountReconcilor::OnGaiaAccountsInCookieUpdated: " | 294 VLOG(1) << "AccountReconcilor::OnGaiaAccountsInCookieUpdated: " |
287 << "CookieJar " << accounts.size() << " accounts, " | 295 << "CookieJar " << accounts.size() << " accounts, " |
288 << "Reconcilor's state is " << is_reconcile_started_ << ", " | 296 << "Reconcilor's state is " << is_reconcile_started_ << ", " |
289 << "Error was " << error.ToString(); | 297 << "Error was " << error.ToString(); |
290 if (error.state() == GoogleServiceAuthError::NONE) { | 298 if (error.state() == GoogleServiceAuthError::NONE) { |
291 gaia_accounts_ = accounts; | 299 gaia_accounts_ = accounts; |
292 | 300 |
293 // It is possible that O2RT is not available at this moment. | 301 // It is possible that O2RT is not available at this moment. |
294 if (token_service_->GetAccounts().empty()) | 302 if (token_service_->GetAccounts().empty()) |
(...skipping 29 matching lines...) Expand all Loading... |
324 } else { | 332 } else { |
325 Shutdown(); | 333 Shutdown(); |
326 } | 334 } |
327 } | 335 } |
328 | 336 |
329 void AccountReconcilor::FinishReconcile() { | 337 void AccountReconcilor::FinishReconcile() { |
330 VLOG(1) << "AccountReconcilor::FinishReconcile"; | 338 VLOG(1) << "AccountReconcilor::FinishReconcile"; |
331 DCHECK(add_to_cookie_.empty()); | 339 DCHECK(add_to_cookie_.empty()); |
332 int number_gaia_accounts = gaia_accounts_.size(); | 340 int number_gaia_accounts = gaia_accounts_.size(); |
333 bool are_primaries_equal = number_gaia_accounts > 0 && | 341 bool are_primaries_equal = number_gaia_accounts > 0 && |
334 gaia::AreEmailsSame(primary_account_, gaia_accounts_[0].first); | 342 gaia::AreEmailsSame(primary_account_, gaia_accounts_[0].email); |
335 | 343 |
336 // If there are any accounts in the gaia cookie but not in chrome, then | 344 // If there are any accounts in the gaia cookie but not in chrome, then |
337 // those accounts need to be removed from the cookie. This means we need | 345 // those accounts need to be removed from the cookie. This means we need |
338 // to blow the cookie away. | 346 // to blow the cookie away. |
339 int removed_from_cookie = 0; | 347 int removed_from_cookie = 0; |
340 for (size_t i = 0; i < gaia_accounts_.size(); ++i) { | 348 for (size_t i = 0; i < gaia_accounts_.size(); ++i) { |
341 const std::string& gaia_account = gaia_accounts_[i].first; | 349 const std::string& gaia_account = gaia_accounts_[i].email; |
342 if (gaia_accounts_[i].second && | 350 if (gaia_accounts_[i].valid && |
343 chrome_accounts_.end() == | 351 chrome_accounts_.end() == |
344 std::find_if(chrome_accounts_.begin(), | 352 std::find_if(chrome_accounts_.begin(), |
345 chrome_accounts_.end(), | 353 chrome_accounts_.end(), |
346 std::bind1st(AreEmailsSameFunc(), gaia_account))) { | 354 std::bind1st(AreEmailsSameFunc(), gaia_account))) { |
347 ++removed_from_cookie; | 355 ++removed_from_cookie; |
348 } | 356 } |
349 } | 357 } |
350 | 358 |
351 bool rebuild_cookie = !are_primaries_equal || removed_from_cookie > 0; | 359 bool rebuild_cookie = !are_primaries_equal || removed_from_cookie > 0; |
352 std::vector<std::pair<std::string, bool> > original_gaia_accounts = | 360 std::vector<gaia::ListedAccount> original_gaia_accounts = |
353 gaia_accounts_; | 361 gaia_accounts_; |
354 if (rebuild_cookie) { | 362 if (rebuild_cookie) { |
355 VLOG(1) << "AccountReconcilor::FinishReconcile: rebuild cookie"; | 363 VLOG(1) << "AccountReconcilor::FinishReconcile: rebuild cookie"; |
356 // Really messed up state. Blow away the gaia cookie completely and | 364 // Really messed up state. Blow away the gaia cookie completely and |
357 // rebuild it, making sure the primary account as specified by the | 365 // rebuild it, making sure the primary account as specified by the |
358 // SigninManager is the first session in the gaia cookie. | 366 // SigninManager is the first session in the gaia cookie. |
359 PerformLogoutAllAccountsAction(); | 367 PerformLogoutAllAccountsAction(); |
360 gaia_accounts_.clear(); | 368 gaia_accounts_.clear(); |
361 } | 369 } |
362 | 370 |
(...skipping 10 matching lines...) Expand all Loading... |
373 // not already in the cookie jar or its state is invalid, or signal merge | 381 // not already in the cookie jar or its state is invalid, or signal merge |
374 // completed otherwise. Make a copy of |add_to_cookie_| since calls to | 382 // completed otherwise. Make a copy of |add_to_cookie_| since calls to |
375 // SignalComplete() will change the array. | 383 // SignalComplete() will change the array. |
376 std::vector<std::string> add_to_cookie_copy = add_to_cookie_; | 384 std::vector<std::string> add_to_cookie_copy = add_to_cookie_; |
377 int added_to_cookie = 0; | 385 int added_to_cookie = 0; |
378 for (size_t i = 0; i < add_to_cookie_copy.size(); ++i) { | 386 for (size_t i = 0; i < add_to_cookie_copy.size(); ++i) { |
379 if (gaia_accounts_.end() != | 387 if (gaia_accounts_.end() != |
380 std::find_if(gaia_accounts_.begin(), | 388 std::find_if(gaia_accounts_.begin(), |
381 gaia_accounts_.end(), | 389 gaia_accounts_.end(), |
382 std::bind1st(EmailEqualToFunc(), | 390 std::bind1st(EmailEqualToFunc(), |
383 std::make_pair(add_to_cookie_copy[i], | 391 AccountFromEmail(add_to_cookie_copy[i] |
384 true)))) { | 392 )))) { |
385 cookie_manager_service_->SignalComplete( | 393 cookie_manager_service_->SignalComplete( |
386 add_to_cookie_copy[i], | 394 add_to_cookie_copy[i], |
387 GoogleServiceAuthError::AuthErrorNone()); | 395 GoogleServiceAuthError::AuthErrorNone()); |
388 } else { | 396 } else { |
389 PerformMergeAction(add_to_cookie_copy[i]); | 397 PerformMergeAction(add_to_cookie_copy[i]); |
390 if (original_gaia_accounts.end() == | 398 if (original_gaia_accounts.end() == |
391 std::find_if(original_gaia_accounts.begin(), | 399 std::find_if(original_gaia_accounts.begin(), |
392 original_gaia_accounts.end(), | 400 original_gaia_accounts.end(), |
393 std::bind1st(EmailEqualToFunc(), | 401 std::bind1st(EmailEqualToFunc(), |
394 std::make_pair(add_to_cookie_copy[i], | 402 AccountFromEmail(add_to_cookie_copy[i] |
395 true)))) { | 403 )))) { |
396 added_to_cookie++; | 404 added_to_cookie++; |
397 } | 405 } |
398 } | 406 } |
399 } | 407 } |
400 | 408 |
401 signin_metrics::LogSigninAccountReconciliation(chrome_accounts_.size(), | 409 signin_metrics::LogSigninAccountReconciliation(chrome_accounts_.size(), |
402 added_to_cookie, | 410 added_to_cookie, |
403 removed_from_cookie, | 411 removed_from_cookie, |
404 are_primaries_equal, | 412 are_primaries_equal, |
405 first_execution_, | 413 first_execution_, |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 << "Account added: " << account_id << ", " | 464 << "Account added: " << account_id << ", " |
457 << "Error was " << error.ToString(); | 465 << "Error was " << error.ToString(); |
458 // Always listens to GaiaCookieManagerService. Only proceed if reconciling. | 466 // Always listens to GaiaCookieManagerService. Only proceed if reconciling. |
459 if (is_reconcile_started_ && MarkAccountAsAddedToCookie(account_id)) { | 467 if (is_reconcile_started_ && MarkAccountAsAddedToCookie(account_id)) { |
460 if (error.state() != GoogleServiceAuthError::State::NONE) | 468 if (error.state() != GoogleServiceAuthError::State::NONE) |
461 error_during_last_reconcile_ = true; | 469 error_during_last_reconcile_ = true; |
462 CalculateIfReconcileIsDone(); | 470 CalculateIfReconcileIsDone(); |
463 ScheduleStartReconcileIfChromeAccountsChanged(); | 471 ScheduleStartReconcileIfChromeAccountsChanged(); |
464 } | 472 } |
465 } | 473 } |
OLD | NEW |