account_reconcilor.cc revision c5cede9ae108bb15f6b7a8aea21c7e1fefa2834c
1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 28bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 38bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// found in the LICENSE file. 48bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "components/signin/core/browser/account_reconcilor.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <algorithm> 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/bind.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/json/json_reader.h" 111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/logging.h" 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/message_loop/message_loop.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string_number_conversions.h" 151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/time/time.h" 16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/browser/profile_oauth2_token_service.h" 17e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "components/signin/core/browser/signin_client.h" 18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "components/signin/core/browser/signin_oauth_helper.h" 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "google_apis/gaia/gaia_auth_fetcher.h" 20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "google_apis/gaia/gaia_auth_util.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "google_apis/gaia/gaia_constants.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "google_apis/gaia/gaia_oauth_client.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "google_apis/gaia/gaia_urls.h" 24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "net/cookies/canonical_cookie.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Fetches a refresh token from the given session in the GAIA cookie. This is 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// a best effort only. If it should fail, another reconcile action will occur 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// shortly anyway. 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class AccountReconcilor::RefreshTokenFetcher 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : public SigninOAuthHelper, 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) public SigninOAuthHelper::Consumer { 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RefreshTokenFetcher(AccountReconcilor* reconcilor, 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& account_id, 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int session_index); 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~RefreshTokenFetcher() {} 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Overridden from GaiaAuthConsumer: 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnSigninOAuthInformationAvailable( 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& email, 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& display_email, 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& refresh_token) OVERRIDE; 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Called when an error occurs while getting the information. 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual void OnSigninOAuthInformationFailure( 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GoogleServiceAuthError& error) OVERRIDE; 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AccountReconcilor* reconcilor_; 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string account_id_; 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int session_index_; 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(RefreshTokenFetcher); 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)AccountReconcilor::RefreshTokenFetcher::RefreshTokenFetcher( 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AccountReconcilor* reconcilor, 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& account_id, 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int session_index) 60c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : SigninOAuthHelper(reconcilor->client()->GetURLRequestContext(), 61c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::IntToString(session_index), 62c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch this), 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) reconcilor_(reconcilor), 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) account_id_(account_id), 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session_index_(session_index) { 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(reconcilor_); 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!account_id.empty()); 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccountReconcilor::RefreshTokenFetcher::OnSigninOAuthInformationAvailable( 71c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const std::string& email, 72c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const std::string& display_email, 73c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const std::string& refresh_token) { 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "RefreshTokenFetcher::OnSigninOAuthInformationAvailable:" 75c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch << " account=" << account_id_ << " email=" << email 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << " displayEmail=" << display_email; 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // TODO(rogerta): because of the problem with email vs displayEmail and 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // emails that have been canonicalized, the argument |email| is used here 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // to make sure the correct string is used when calling the token service. 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This will be cleaned up when chrome moves to using gaia obfuscated id. 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) reconcilor_->HandleRefreshTokenFetched(email, refresh_token); 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccountReconcilor::RefreshTokenFetcher::OnSigninOAuthInformationFailure( 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GoogleServiceAuthError& error) { 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "RefreshTokenFetcher::OnSigninOAuthInformationFailure:" 88c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch << " account=" << account_id_ << " session_index=" << session_index_; 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) reconcilor_->HandleRefreshTokenFetched(account_id_, std::string()); 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool AccountReconcilor::EmailLessFunc::operator()(const std::string& s1, 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& s2) const { 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return gaia::CanonicalizeEmail(s1) < gaia::CanonicalizeEmail(s2); 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class AccountReconcilor::UserIdFetcher 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : public gaia::GaiaOAuthClient::Delegate { 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UserIdFetcher(AccountReconcilor* reconcilor, 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& access_token, 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& account_id); 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Returns the scopes needed by the UserIdFetcher. 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static OAuth2TokenService::ScopeSet GetScopes(); 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Overriden from gaia::GaiaOAuthClient::Delegate. 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnGetUserIdResponse(const std::string& user_id) OVERRIDE; 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnOAuthError() OVERRIDE; 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void OnNetworkError(int response_code) OVERRIDE; 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AccountReconcilor* const reconcilor_; 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string account_id_; 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string access_token_; 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gaia::GaiaOAuthClient gaia_auth_client_; 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(UserIdFetcher); 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)AccountReconcilor::UserIdFetcher::UserIdFetcher(AccountReconcilor* reconcilor, 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& access_token, 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& account_id) 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : reconcilor_(reconcilor), 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) account_id_(account_id), 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) access_token_(access_token), 127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gaia_auth_client_(reconcilor_->client()->GetURLRequestContext()) { 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(reconcilor_); 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!account_id_.empty()); 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const int kMaxRetries = 5; 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gaia_auth_client_.GetUserId(access_token_, kMaxRetries, this); 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)OAuth2TokenService::ScopeSet AccountReconcilor::UserIdFetcher::GetScopes() { 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OAuth2TokenService::ScopeSet scopes; 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scopes.insert("https://www.googleapis.com/auth/userinfo.profile"); 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return scopes; 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::UserIdFetcher::OnGetUserIdResponse( 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& user_id) { 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::OnGetUserIdResponse: " << account_id_; 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // HandleSuccessfulAccountIdCheck() may delete |this|, so call it last. 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) reconcilor_->HandleSuccessfulAccountIdCheck(account_id_); 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::UserIdFetcher::OnOAuthError() { 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::OnOAuthError: " << account_id_; 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Invalidate the access token to force a refetch next time. 154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch reconcilor_->token_service()->InvalidateToken( 155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch account_id_, GetScopes(), access_token_); 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // HandleFailedAccountIdCheck() may delete |this|, so call it last. 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) reconcilor_->HandleFailedAccountIdCheck(account_id_); 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::UserIdFetcher::OnNetworkError(int response_code) { 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::OnNetworkError: " << account_id_ 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << " response_code=" << response_code; 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(rogerta): some response error should not be treated like 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // permanent errors. Figure out appropriate ones. 167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // HandleFailedAccountIdCheck() may delete |this|, so call it last. 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) reconcilor_->HandleFailedAccountIdCheck(account_id_); 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochAccountReconcilor::AccountReconcilor(ProfileOAuth2TokenService* token_service, 172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch SigninManagerBase* signin_manager, 173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch SigninClient* client) 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : OAuth2TokenService::Consumer("account_reconcilor"), 175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch token_service_(token_service), 176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch signin_manager_(signin_manager), 177e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch client_(client), 178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch merge_session_helper_(token_service_, 179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch client->GetURLRequestContext(), 180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch this), 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registered_with_token_service_(false), 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) is_reconcile_started_(false), 183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) are_gaia_accounts_set_(false), 184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) requests_(NULL) { 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::AccountReconcilor"; 1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)AccountReconcilor::~AccountReconcilor() { 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "AccountReconcilor::~AccountReconcilor"; 190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Make sure shutdown was called first. 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!registered_with_token_service_); 192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!reconciliation_timer_.IsRunning()); 193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!requests_); 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(0u, user_id_fetchers_.size()); 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(0u, refresh_token_fetchers_.size()); 196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccountReconcilor::Initialize(bool start_reconcile_if_tokens_available) { 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "AccountReconcilor::Initialize"; 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RegisterWithSigninManager(); 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 202c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // If this user is not signed in, the reconcilor should do nothing but 203c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // wait for signin. 204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (IsProfileConnected()) { 205e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch RegisterForCookieChanges(); 206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RegisterWithTokenService(); 207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StartPeriodicReconciliation(); 208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Start a reconcile if the tokens are already loaded. 210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (start_reconcile_if_tokens_available && 211c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch token_service_->GetAccounts().size() > 0) { 212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StartReconcile(); 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AccountReconcilor::Shutdown() { 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::Shutdown"; 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) merge_session_helper_.CancelAll(); 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) merge_session_helper_.RemoveObserver(this); 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gaia_fetcher_.reset(); 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeleteFetchers(); 223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UnregisterWithSigninManager(); 224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UnregisterWithTokenService(); 225e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch UnregisterForCookieChanges(); 226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) StopPeriodicReconciliation(); 227f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::AddMergeSessionObserver( 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MergeSessionHelper::Observer* observer) { 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) merge_session_helper_.AddObserver(observer); 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::RemoveMergeSessionObserver( 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MergeSessionHelper::Observer* observer) { 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) merge_session_helper_.RemoveObserver(observer); 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::DeleteFetchers() { 240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) delete[] requests_; 241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) requests_ = NULL; 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) user_id_fetchers_.clear(); 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) refresh_token_fetchers_.clear(); 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool AccountReconcilor::AreAllRefreshTokensChecked() const { 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return chrome_accounts_.size() == 249c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch (valid_chrome_accounts_.size() + invalid_chrome_accounts_.size()); 250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 252e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid AccountReconcilor::RegisterForCookieChanges() { 253e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // First clear any existing registration to avoid DCHECKs that can otherwise 254e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // go off in some embedders on reauth (e.g., ChromeSigninClient). 255e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch UnregisterForCookieChanges(); 256e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch client_->SetCookieChangedCallback( 257e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::Bind(&AccountReconcilor::OnCookieChanged, base::Unretained(this))); 2581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 260e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid AccountReconcilor::UnregisterForCookieChanges() { 261e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch client_->SetCookieChangedCallback(SigninClient::CookieChangedCallback()); 2621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccountReconcilor::RegisterWithSigninManager() { 265c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch signin_manager_->AddObserver(this); 2661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccountReconcilor::UnregisterWithSigninManager() { 269c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch signin_manager_->RemoveObserver(this); 2701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccountReconcilor::RegisterWithTokenService() { 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::RegisterWithTokenService"; 2744ad1aa43a48567659193a298fad74f55e00b3dd9Ben Murdoch // During re-auth, the reconcilor will get a callback about successful signin 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // even when the profile is already connected. Avoid re-registering 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // with the token service since this will DCHECK. 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (registered_with_token_service_) 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 280c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch token_service_->AddObserver(this); 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registered_with_token_service_ = true; 2821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 2841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccountReconcilor::UnregisterWithTokenService() { 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!registered_with_token_service_) 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 288c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch token_service_->RemoveObserver(this); 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registered_with_token_service_ = false; 2901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 2911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool AccountReconcilor::IsProfileConnected() { 293c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return !signin_manager_->GetAuthenticatedUsername().empty(); 294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccountReconcilor::StartPeriodicReconciliation() { 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::StartPeriodicReconciliation"; 2981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // TODO(rogerta): pick appropriate thread and timeout value. 299c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch reconciliation_timer_.Start(FROM_HERE, 300c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::TimeDelta::FromSeconds(300), 301c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch this, 302c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch &AccountReconcilor::PeriodicReconciliation); 3031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccountReconcilor::StopPeriodicReconciliation() { 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::StopPeriodicReconciliation"; 3071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) reconciliation_timer_.Stop(); 3081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccountReconcilor::PeriodicReconciliation() { 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::PeriodicReconciliation"; 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StartReconcile(); 3131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 315e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid AccountReconcilor::OnCookieChanged(const net::CanonicalCookie* cookie) { 316e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (cookie->Name() == "LSID" && 317e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch cookie->Domain() == GaiaUrls::GetInstance()->gaia_url().host() && 318e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch cookie->IsSecure() && cookie->IsHttpOnly()) { 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::OnCookieChanged: LSID changed"; 320e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#ifdef OS_CHROMEOS 321e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // On Chrome OS it is possible that O2RT is not available at this moment 322e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // because profile data transfer is still in progress. 323c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!token_service_->GetAccounts().size()) { 324e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch VLOG(1) << "AccountReconcilor::OnCookieChanged: cookie change is ingored" 325e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch "because profile data transfer is in progress."; 326e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return; 327e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 328e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#endif 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StartReconcile(); 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccountReconcilor::OnRefreshTokenAvailable(const std::string& account_id) { 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::OnRefreshTokenAvailable: " << account_id; 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StartReconcile(); 3361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccountReconcilor::OnRefreshTokenRevoked(const std::string& account_id) { 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::OnRefreshTokenRevoked: " << account_id; 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StartRemoveAction(account_id); 3411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccountReconcilor::OnRefreshTokensLoaded() {} 3448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 345c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid AccountReconcilor::GoogleSigninSucceeded(const std::string& username, 346c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const std::string& password) { 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::GoogleSigninSucceeded: signed in"; 348e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch RegisterForCookieChanges(); 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RegisterWithTokenService(); 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StartPeriodicReconciliation(); 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::GoogleSignedOut(const std::string& username) { 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::GoogleSignedOut: signed out"; 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UnregisterWithTokenService(); 356e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch UnregisterForCookieChanges(); 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StopPeriodicReconciliation(); 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void AccountReconcilor::PerformMergeAction(const std::string& account_id) { 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::PerformMergeAction: " << account_id; 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) merge_session_helper_.LogIn(account_id); 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::StartRemoveAction(const std::string& account_id) { 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::StartRemoveAction: " << account_id; 367c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GetAccountsFromCookie(base::Bind(&AccountReconcilor::FinishRemoveAction, 368c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Unretained(this), 369c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch account_id)); 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::FinishRemoveAction( 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& account_id, 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GoogleServiceAuthError& error, 375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::vector<std::pair<std::string, bool> >& accounts) { 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::FinishRemoveAction:" 377c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch << " account=" << account_id << " error=" << error.ToString(); 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error.state() == GoogleServiceAuthError::NONE) { 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AbortReconcile(); 380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<std::string> accounts_only; 381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (std::vector<std::pair<std::string, bool> >::const_iterator i = 382c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch accounts.begin(); 383c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch i != accounts.end(); 384c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ++i) { 385a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) accounts_only.push_back(i->first); 386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) merge_session_helper_.LogOut(account_id, accounts_only); 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Wait for the next ReconcileAction if there is an error. 3901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 3911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 392c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid AccountReconcilor::PerformAddToChromeAction(const std::string& account_id, 393c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int session_index) { 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::PerformAddToChromeAction:" 395c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch << " account=" << account_id << " session_index=" << session_index; 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined(OS_ANDROID) && !defined(OS_IOS) 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) refresh_token_fetchers_.push_back( 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new RefreshTokenFetcher(this, account_id, session_index)); 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 4011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 4021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::PerformLogoutAllAccountsAction() { 4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::PerformLogoutAllAccountsAction"; 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) merge_session_helper_.LogOutAllAccounts(); 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::StartReconcile() { 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!IsProfileConnected() || is_reconcile_started_) 410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 411f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) is_reconcile_started_ = true; 4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 414f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Reset state for validating gaia cookie. 415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) are_gaia_accounts_set_ = false; 416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gaia_accounts_.clear(); 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetAccountsFromCookie(base::Bind( 4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &AccountReconcilor::ContinueReconcileActionAfterGetGaiaAccounts, 419c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Unretained(this))); 420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Reset state for validating oauth2 tokens. 422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) primary_account_.clear(); 423f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) chrome_accounts_.clear(); 4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeleteFetchers(); 425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) valid_chrome_accounts_.clear(); 426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) invalid_chrome_accounts_.clear(); 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_to_cookie_.clear(); 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_to_chrome_.clear(); 429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ValidateAccountsFromTokenService(); 4301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 4311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::GetAccountsFromCookie( 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GetAccountsFromCookieCallback callback) { 4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) get_gaia_accounts_callbacks_.push_back(callback); 4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!gaia_fetcher_) { 4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // There is no list account request in flight. 437c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gaia_fetcher_.reset(new GaiaAuthFetcher( 438c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch this, GaiaConstants::kChromeSource, client_->GetURLRequestContext())); 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gaia_fetcher_->StartListAccounts(); 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 4421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AccountReconcilor::OnListAccountsSuccess(const std::string& data) { 444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gaia_fetcher_.reset(); 445f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 446f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Get account information from response data. 447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<std::pair<std::string, bool> > gaia_accounts; 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool valid_json = gaia::ParseListAccountsData(data, &gaia_accounts); 4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!valid_json) { 4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: parsing error"; 4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else if (gaia_accounts.size() > 0) { 4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: " 4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "Gaia " << gaia_accounts.size() << " accounts, " 454a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "Primary is '" << gaia_accounts[0].first << "'"; 455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: No accounts"; 457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // There must be at least one callback waiting for result. 4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!get_gaia_accounts_callbacks_.empty()); 4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 462c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GoogleServiceAuthError error = 463c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch !valid_json ? GoogleServiceAuthError( 464c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE) 465c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : GoogleServiceAuthError::AuthErrorNone(); 4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) get_gaia_accounts_callbacks_.front().Run(error, gaia_accounts); 4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) get_gaia_accounts_callbacks_.pop_front(); 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MayBeDoNextListAccounts(); 470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AccountReconcilor::OnListAccountsFailure( 473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const GoogleServiceAuthError& error) { 474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) gaia_fetcher_.reset(); 4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::OnListAccountsFailure: " << error.ToString(); 476a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<std::pair<std::string, bool> > empty_accounts; 4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // There must be at least one callback waiting for result. 4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!get_gaia_accounts_callbacks_.empty()); 4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) get_gaia_accounts_callbacks_.front().Run(error, empty_accounts); 4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) get_gaia_accounts_callbacks_.pop_front(); 483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MayBeDoNextListAccounts(); 4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::MayBeDoNextListAccounts() { 4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!get_gaia_accounts_callbacks_.empty()) { 489c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gaia_fetcher_.reset(new GaiaAuthFetcher( 490c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch this, GaiaConstants::kChromeSource, client_->GetURLRequestContext())); 4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gaia_fetcher_->StartListAccounts(); 4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::ContinueReconcileActionAfterGetGaiaAccounts( 4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GoogleServiceAuthError& error, 497a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::vector<std::pair<std::string, bool> >& accounts) { 4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (error.state() == GoogleServiceAuthError::NONE) { 4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gaia_accounts_ = accounts; 5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) are_gaia_accounts_set_ = true; 5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FinishReconcile(); 5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AbortReconcile(); 5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AccountReconcilor::ValidateAccountsFromTokenService() { 508c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch primary_account_ = signin_manager_->GetAuthenticatedUsername(); 509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!primary_account_.empty()); 510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 511c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch chrome_accounts_ = token_service_->GetAccounts(); 512a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_GT(chrome_accounts_.size(), 0u); 513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::ValidateAccountsFromTokenService: " 5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "Chrome " << chrome_accounts_.size() << " accounts, " 5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "Primary is '" << primary_account_ << "'"; 517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!requests_); 519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) requests_ = 520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) new scoped_ptr<OAuth2TokenService::Request>[chrome_accounts_.size()]; 5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const OAuth2TokenService::ScopeSet scopes = 5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AccountReconcilor::UserIdFetcher::GetScopes(); 523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 0; i < chrome_accounts_.size(); ++i) { 524c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch requests_[i] = 525c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch token_service_->StartRequest(chrome_accounts_[i], scopes, this); 526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(0u, user_id_fetchers_.size()); 5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) user_id_fetchers_.resize(chrome_accounts_.size()); 530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AccountReconcilor::OnGetTokenSuccess( 533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const OAuth2TokenService::Request* request, 534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& access_token, 535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const base::Time& expiration_time) { 5365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t index; 5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (index = 0; index < chrome_accounts_.size(); ++index) { 5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (request == requests_[index].get()) 5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(index < chrome_accounts_.size()); 5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& account_id = chrome_accounts_[index]; 5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::OnGetTokenSuccess: valid " << account_id; 5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!user_id_fetchers_[index]); 548c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch user_id_fetchers_[index] = new UserIdFetcher(this, access_token, account_id); 549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AccountReconcilor::OnGetTokenFailure( 552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const OAuth2TokenService::Request* request, 553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const GoogleServiceAuthError& error) { 5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t index; 5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (index = 0; index < chrome_accounts_.size(); ++index) { 5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (request == requests_[index].get()) 5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(index < chrome_accounts_.size()); 5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& account_id = chrome_accounts_[index]; 5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 563c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch VLOG(1) << "AccountReconcilor::OnGetTokenFailure: invalid " << account_id; 5645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) HandleFailedAccountIdCheck(account_id); 565f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 566f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::FinishReconcile() { 568f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Make sure that the process of validating the gaia cookie and the oauth2 569f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // tokens individually is done before proceeding with reconciliation. 5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!are_gaia_accounts_set_ || !AreAllRefreshTokensChecked()) 571f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 572f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::FinishReconcile"; 574f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeleteFetchers(); 5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(add_to_cookie_.empty()); 5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(add_to_chrome_.empty()); 579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool are_primaries_equal = 580a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gaia_accounts_.size() > 0 && 581a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) gaia::AreEmailsSame(primary_account_, gaia_accounts_[0].first); 5825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (are_primaries_equal) { 5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Determine if we need to merge accounts from gaia cookie to chrome. 585f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 0; i < gaia_accounts_.size(); ++i) { 586a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& gaia_account = gaia_accounts_[i].first; 587a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (gaia_accounts_[i].second && 588c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch valid_chrome_accounts_.find(gaia_account) == 589c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch valid_chrome_accounts_.end()) { 5905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_to_chrome_.push_back(std::make_pair(gaia_account, i)); 591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 592f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 5935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Determine if we need to merge accounts from chrome into gaia cookie. 595a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (EmailSet::const_iterator i = valid_chrome_accounts_.begin(); 596c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch i != valid_chrome_accounts_.end(); 597c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ++i) { 598a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool add_to_cookie = true; 599a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (size_t j = 0; j < gaia_accounts_.size(); ++j) { 600a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (gaia::AreEmailsSame(gaia_accounts_[j].first, *i)) { 601a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) add_to_cookie = !gaia_accounts_[j].second; 602a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) break; 603a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 6045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 605a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (add_to_cookie) 606a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) add_to_cookie_.push_back(*i); 6075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 6095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::FinishReconcile: rebuild cookie"; 6105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Really messed up state. Blow away the gaia cookie completely and 6115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // rebuild it, making sure the primary account as specified by the 6125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // SigninManager is the first session in the gaia cookie. 6135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PerformLogoutAllAccountsAction(); 6145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_to_cookie_.push_back(primary_account_); 615a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (EmailSet::const_iterator i = valid_chrome_accounts_.begin(); 616c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch i != valid_chrome_accounts_.end(); 617c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ++i) { 6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (*i != primary_account_) 6195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_to_cookie_.push_back(*i); 6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // For each account known to chrome but not in the gaia cookie, 6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // PerformMergeAction(). 6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i < add_to_cookie_.size(); ++i) 6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PerformMergeAction(add_to_cookie_[i]); 6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // For each account in the gaia cookie not known to chrome, 6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // PerformAddToChromeAction. 6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (std::vector<std::pair<std::string, int> >::const_iterator i = 631c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch add_to_chrome_.begin(); 632c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch i != add_to_chrome_.end(); 633c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ++i) { 6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PerformAddToChromeAction(i->first, i->second); 6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CalculateIfReconcileIsDone(); 638a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScheduleStartReconcileIfChromeAccountsChanged(); 6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::AbortReconcile() { 6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::AbortReconcile: we'll try again later"; 6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DeleteFetchers(); 6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_to_cookie_.clear(); 6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_to_chrome_.clear(); 6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CalculateIfReconcileIsDone(); 6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::CalculateIfReconcileIsDone() { 6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) is_reconcile_started_ = !add_to_cookie_.empty() || !add_to_chrome_.empty(); 6515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!is_reconcile_started_) 6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::CalculateIfReconcileIsDone: done"; 6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 655a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AccountReconcilor::ScheduleStartReconcileIfChromeAccountsChanged() { 656a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (is_reconcile_started_) 657a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 658a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 659a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Start a reconcile as the token accounts have changed. 660a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) VLOG(1) << "AccountReconcilor::StartReconcileIfChromeAccountsChanged"; 661a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<std::string> reconciled_accounts(chrome_accounts_); 662c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::vector<std::string> new_chrome_accounts(token_service_->GetAccounts()); 663a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::sort(reconciled_accounts.begin(), reconciled_accounts.end()); 664a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::sort(new_chrome_accounts.begin(), new_chrome_accounts.end()); 665a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (reconciled_accounts != new_chrome_accounts) { 666a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::MessageLoop::current()->PostTask( 667a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) FROM_HERE, 668a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&AccountReconcilor::StartReconcile, base::Unretained(this))); 669a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 670a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 671a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 6725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::MergeSessionCompleted( 6735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& account_id, 6745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GoogleServiceAuthError& error) { 6755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) VLOG(1) << "AccountReconcilor::MergeSessionCompleted: account_id=" 6765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << account_id; 6775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Remove the account from the list that is being merged. 6795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (std::vector<std::string>::iterator i = add_to_cookie_.begin(); 680c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch i != add_to_cookie_.end(); 681c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ++i) { 6825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (account_id == *i) { 6835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_to_cookie_.erase(i); 6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CalculateIfReconcileIsDone(); 689a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ScheduleStartReconcileIfChromeAccountsChanged(); 6905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::HandleSuccessfulAccountIdCheck( 6935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& account_id) { 6945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) valid_chrome_accounts_.insert(account_id); 6955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FinishReconcile(); 6965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::HandleFailedAccountIdCheck( 6995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& account_id) { 7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) invalid_chrome_accounts_.insert(account_id); 7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FinishReconcile(); 7025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AccountReconcilor::HandleRefreshTokenFetched( 7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& account_id, 7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::string& refresh_token) { 7075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!refresh_token.empty()) { 708c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch token_service_->UpdateCredentials(account_id, refresh_token); 709f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 710f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Remove the account from the list that is being updated. 7125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (std::vector<std::pair<std::string, int> >::iterator i = 7135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_to_chrome_.begin(); 714c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch i != add_to_chrome_.end(); 715c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ++i) { 716a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (gaia::AreEmailsSame(account_id, i->first)) { 7175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_to_chrome_.erase(i); 7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 720f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 7215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CalculateIfReconcileIsDone(); 7231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 724