account_reconcilor.cc revision 010d83a9304c5a91596085d917d248abff47903a
124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Copyright 2014 The Chromium Authors. All rights reserved. 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Use of this source code is governed by a BSD-style license that can be 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// found in the LICENSE file. 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "components/signin/core/browser/account_reconcilor.h" 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <algorithm> 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "base/bind.h" 1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "base/json/json_reader.h" 1152fd984f7e67c3a0ab18d5565f40356bcfa84822Greg Clayton#include "base/logging.h" 1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "base/message_loop/message_loop.h" 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "base/message_loop/message_loop_proxy.h" 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "base/strings/string_number_conversions.h" 1590df56354288b44e5b6c2844c52f1e0eefd5509bGreg Clayton#include "base/time/time.h" 16a39fa4b8c67886e0d7df0752fe176ad7723e305fJim Ingham#include "components/signin/core/browser/profile_oauth2_token_service.h" 178da92a74478ff2465e092aea92ce29ad7ad6ddddGreg Clayton#include "components/signin/core/browser/signin_client.h" 18a39fa4b8c67886e0d7df0752fe176ad7723e305fJim Ingham#include "components/signin/core/browser/signin_oauth_helper.h" 1914ef59fe5728d862c040cf5a6b99c384229a34eeGreg Clayton#include "google_apis/gaia/gaia_auth_fetcher.h" 20a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham#include "google_apis/gaia/gaia_auth_util.h" 218da92a74478ff2465e092aea92ce29ad7ad6ddddGreg Clayton#include "google_apis/gaia/gaia_constants.h" 2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "google_apis/gaia/gaia_oauth_client.h" 23e9ca3a4130bfb76765256549e01c759da8ec2f1dCaroline Tice#include "google_apis/gaia/gaia_urls.h" 2422defe8b06df5b1f09b53bda255ef07513abc04cGreg Clayton#include "net/cookies/canonical_cookie.h" 2522defe8b06df5b1f09b53bda255ef07513abc04cGreg Clayton 26e9ca3a4130bfb76765256549e01c759da8ec2f1dCaroline Tice 272f28ece553d2ef0d7b3e8d1419020591ec3818f9Greg Claytonnamespace { 285f54ac373b119a4c6693e4875c48aa761fba0c86Greg Clayton 2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass EmailEqualToFunc : public std::equal_to<std::pair<std::string, bool> > { 3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner public: 3149ce8969d3154e1560106cfe530444c09410f217Greg Clayton bool operator()(const std::pair<std::string, bool>& p1, 3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const std::pair<std::string, bool>& p2) const; 33eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice}; 3452fd984f7e67c3a0ab18d5565f40356bcfa84822Greg Clayton 3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool EmailEqualToFunc::operator()( 3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const std::pair<std::string, bool>& p1, 3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const std::pair<std::string, bool>& p2) const { 3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return p1.second == p2.second && gaia::AreEmailsSame(p1.first, p2.first); 3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} // namespace 4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 44ff44ab42e9f5d8e4d550e11d1b69413e0bc75b71Greg Clayton// Fetches a refresh token from the given session in the GAIA cookie. This is 4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// a best effort only. If it should fail, another reconcile action will occur 4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// shortly anyway. 4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass AccountReconcilor::RefreshTokenFetcher 4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner : public SigninOAuthHelper, 4914ef59fe5728d862c040cf5a6b99c384229a34eeGreg Clayton public SigninOAuthHelper::Consumer { 508da92a74478ff2465e092aea92ce29ad7ad6ddddGreg Clayton public: 5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner RefreshTokenFetcher(AccountReconcilor* reconcilor, 5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const std::string& account_id, 5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner int session_index); 5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual ~RefreshTokenFetcher() {} 5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner private: 57a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham // Overridden from GaiaAuthConsumer: 58a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham virtual void OnSigninOAuthInformationAvailable( 59a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham const std::string& email, 60a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham const std::string& display_email, 61a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham const std::string& refresh_token) OVERRIDE; 6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Called when an error occurs while getting the information. 6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner virtual void OnSigninOAuthInformationFailure( 6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const GoogleServiceAuthError& error) OVERRIDE; 6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner AccountReconcilor* reconcilor_; 6882cfaed47126a17b4fa21e42e05546e7a041b9e3Greg Clayton const std::string account_id_; 6982cfaed47126a17b4fa21e42e05546e7a041b9e3Greg Clayton int session_index_; 70a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham 71a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham DISALLOW_COPY_AND_ASSIGN(RefreshTokenFetcher); 72a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham}; 73a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham 74a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim InghamAccountReconcilor::RefreshTokenFetcher::RefreshTokenFetcher( 7554e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton AccountReconcilor* reconcilor, 76a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham const std::string& account_id, 77a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham int session_index) 7882cfaed47126a17b4fa21e42e05546e7a041b9e3Greg Clayton : SigninOAuthHelper(reconcilor->client()->GetURLRequestContext(), 7982cfaed47126a17b4fa21e42e05546e7a041b9e3Greg Clayton base::IntToString(session_index), 8082cfaed47126a17b4fa21e42e05546e7a041b9e3Greg Clayton this), 8182cfaed47126a17b4fa21e42e05546e7a041b9e3Greg Clayton reconcilor_(reconcilor), 8282cfaed47126a17b4fa21e42e05546e7a041b9e3Greg Clayton account_id_(account_id), 83a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham session_index_(session_index) { 84a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham DCHECK(reconcilor_); 85a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham DCHECK(!account_id.empty()); 86b1a9862ba1ceb219b6042ff3f8c6ff591867ae26Greg Clayton} 87a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham 88a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Inghamvoid AccountReconcilor::RefreshTokenFetcher::OnSigninOAuthInformationAvailable( 89a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham const std::string& email, 9054e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton const std::string& display_email, 91a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham const std::string& refresh_token) { 92a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham VLOG(1) << "RefreshTokenFetcher::OnSigninOAuthInformationAvailable:" 93b1a9862ba1ceb219b6042ff3f8c6ff591867ae26Greg Clayton << " account=" << account_id_ << " email=" << email 94b1a9862ba1ceb219b6042ff3f8c6ff591867ae26Greg Clayton << " displayEmail=" << display_email; 95a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham 96a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham // TODO(rogerta): because of the problem with email vs displayEmail and 97b1a9862ba1ceb219b6042ff3f8c6ff591867ae26Greg Clayton // emails that have been canonicalized, the argument |email| is used here 98b1a9862ba1ceb219b6042ff3f8c6ff591867ae26Greg Clayton // to make sure the correct string is used when calling the token service. 99a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham // This will be cleaned up when chrome moves to using gaia obfuscated id. 100a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham reconcilor_->HandleRefreshTokenFetched(email, refresh_token); 101a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham} 1029c3cfe397d6040a46677e201c2682cc2a5163fe9Eli Friedman 103a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Inghamvoid AccountReconcilor::RefreshTokenFetcher::OnSigninOAuthInformationFailure( 104a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham const GoogleServiceAuthError& error) { 105a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham VLOG(1) << "RefreshTokenFetcher::OnSigninOAuthInformationFailure:" 106a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham << " account=" << account_id_ << " session_index=" << session_index_; 107a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham reconcilor_->HandleRefreshTokenFetched(account_id_, std::string()); 108a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham} 109a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham 110a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Inghambool AccountReconcilor::EmailLessFunc::operator()(const std::string& s1, 111a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham const std::string& s2) const { 112a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham return gaia::CanonicalizeEmail(s1) < gaia::CanonicalizeEmail(s2); 11336da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton} 114b1a9862ba1ceb219b6042ff3f8c6ff591867ae26Greg Clayton 115a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Inghamclass AccountReconcilor::UserIdFetcher 116a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham : public gaia::GaiaOAuthClient::Delegate { 117a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham public: 118b1a9862ba1ceb219b6042ff3f8c6ff591867ae26Greg Clayton UserIdFetcher(AccountReconcilor* reconcilor, 119a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham const std::string& access_token, 120b1a9862ba1ceb219b6042ff3f8c6ff591867ae26Greg Clayton const std::string& account_id); 121a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham 122a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham // Returns the scopes needed by the UserIdFetcher. 123a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham static OAuth2TokenService::ScopeSet GetScopes(); 124a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham 125a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham private: 12654e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton // Overriden from gaia::GaiaOAuthClient::Delegate. 127a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham virtual void OnGetUserIdResponse(const std::string& user_id) OVERRIDE; 128a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham virtual void OnOAuthError() OVERRIDE; 129a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham virtual void OnNetworkError(int response_code) OVERRIDE; 130a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham 131a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham AccountReconcilor* const reconcilor_; 132a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham const std::string account_id_; 133a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham const std::string access_token_; 134b1a9862ba1ceb219b6042ff3f8c6ff591867ae26Greg Clayton gaia::GaiaOAuthClient gaia_auth_client_; 135a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham 136a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham DISALLOW_COPY_AND_ASSIGN(UserIdFetcher); 137a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham}; 138a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham 139a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim InghamAccountReconcilor::UserIdFetcher::UserIdFetcher(AccountReconcilor* reconcilor, 140a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham const std::string& access_token, 141a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham const std::string& account_id) 142a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham : reconcilor_(reconcilor), 14382cfaed47126a17b4fa21e42e05546e7a041b9e3Greg Clayton account_id_(account_id), 14482cfaed47126a17b4fa21e42e05546e7a041b9e3Greg Clayton access_token_(access_token), 14582cfaed47126a17b4fa21e42e05546e7a041b9e3Greg Clayton gaia_auth_client_(reconcilor_->client()->GetURLRequestContext()) { 14682cfaed47126a17b4fa21e42e05546e7a041b9e3Greg Clayton DCHECK(reconcilor_); 147a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham DCHECK(!account_id_.empty()); 148a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham 14954e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton const int kMaxRetries = 5; 150158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham gaia_auth_client_.GetUserId(access_token_, kMaxRetries, this); 151158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham} 152158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham 153158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham// static 154158842ca982c53aca6c5ad7345d7b261e309292dJim InghamOAuth2TokenService::ScopeSet AccountReconcilor::UserIdFetcher::GetScopes() { 155158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham OAuth2TokenService::ScopeSet scopes; 156158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham scopes.insert("https://www.googleapis.com/auth/userinfo.profile"); 157158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham return scopes; 158158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham} 159158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham 160158842ca982c53aca6c5ad7345d7b261e309292dJim Inghamvoid AccountReconcilor::UserIdFetcher::OnGetUserIdResponse( 161158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham const std::string& user_id) { 162158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham VLOG(1) << "AccountReconcilor::OnGetUserIdResponse: " << account_id_; 163158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham 164158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham // HandleSuccessfulAccountIdCheck() may delete |this|, so call it last. 165158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham reconcilor_->HandleSuccessfulAccountIdCheck(account_id_); 166158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham} 167158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham 168158842ca982c53aca6c5ad7345d7b261e309292dJim Inghamvoid AccountReconcilor::UserIdFetcher::OnOAuthError() { 169158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham VLOG(1) << "AccountReconcilor::OnOAuthError: " << account_id_; 170158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham 171158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham // Invalidate the access token to force a refetch next time. 172158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham reconcilor_->token_service()->InvalidateToken( 173158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham account_id_, GetScopes(), access_token_); 174158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham 175158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham // HandleFailedAccountIdCheck() may delete |this|, so call it last. 176158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham reconcilor_->HandleFailedAccountIdCheck(account_id_); 177158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham} 178158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham 179158842ca982c53aca6c5ad7345d7b261e309292dJim Inghamvoid AccountReconcilor::UserIdFetcher::OnNetworkError(int response_code) { 180158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham VLOG(1) << "AccountReconcilor::OnNetworkError: " << account_id_ 181158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham << " response_code=" << response_code; 182158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham 183158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham // TODO(rogerta): some response error should not be treated like 184158842ca982c53aca6c5ad7345d7b261e309292dJim Ingham // permanent errors. Figure out appropriate ones. 18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // HandleFailedAccountIdCheck() may delete |this|, so call it last. 18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner reconcilor_->HandleFailedAccountIdCheck(account_id_); 18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerAccountReconcilor::AccountReconcilor(ProfileOAuth2TokenService* token_service, 19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SigninManagerBase* signin_manager, 19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner SigninClient* client) 19214ef59fe5728d862c040cf5a6b99c384229a34eeGreg Clayton : OAuth2TokenService::Consumer("account_reconcilor"), 193a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham token_service_(token_service), 194a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham signin_manager_(signin_manager), 19554e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton client_(client), 196a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham merge_session_helper_(token_service_, 197a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham client->GetURLRequestContext(), 198a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham this), 199a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham registered_with_token_service_(false), 200a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham is_reconcile_started_(false), 201a30baf5b257c7a62c5888679e7c1ac8eb47ca6d7Jim Ingham are_gaia_accounts_set_(false), 20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner requests_(NULL) { 20314ef59fe5728d862c040cf5a6b99c384229a34eeGreg Clayton VLOG(1) << "AccountReconcilor::AccountReconcilor"; 2048da92a74478ff2465e092aea92ce29ad7ad6ddddGreg Clayton} 2058da92a74478ff2465e092aea92ce29ad7ad6ddddGreg Clayton 2068da92a74478ff2465e092aea92ce29ad7ad6ddddGreg ClaytonAccountReconcilor::~AccountReconcilor() { 20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::~AccountReconcilor"; 20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Make sure shutdown was called first. 20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DCHECK(!registered_with_token_service_); 21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DCHECK(!reconciliation_timer_.IsRunning()); 21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DCHECK(!requests_); 21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DCHECK_EQ(0u, user_id_fetchers_.size()); 21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DCHECK_EQ(0u, refresh_token_fetchers_.size()); 21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::Initialize(bool start_reconcile_if_tokens_available) { 21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::Initialize"; 21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner RegisterWithSigninManager(); 21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // If this user is not signed in, the reconcilor should do nothing but 22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // wait for signin. 22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (IsProfileConnected()) { 22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner RegisterForCookieChanges(); 22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner RegisterWithTokenService(); 22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StartPeriodicReconciliation(); 22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Start a reconcile if the tokens are already loaded. 22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (start_reconcile_if_tokens_available && 22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner token_service_->GetAccounts().size() > 0) { 23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StartReconcile(); 23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 232c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham } 233c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham} 234d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton 235d6d806ceff943ca26c008f704013f18920685cfdGreg Claytonvoid AccountReconcilor::Shutdown() { 236c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham VLOG(1) << "AccountReconcilor::Shutdown"; 237c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham merge_session_helper_.CancelAll(); 238c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham merge_session_helper_.RemoveObserver(this); 239c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham gaia_fetcher_.reset(); 240c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham DeleteFetchers(); 241c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham UnregisterWithSigninManager(); 24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner UnregisterWithTokenService(); 24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner UnregisterForCookieChanges(); 24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StopPeriodicReconciliation(); 24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 246d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton 247d6d806ceff943ca26c008f704013f18920685cfdGreg Claytonvoid AccountReconcilor::AddMergeSessionObserver( 24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner MergeSessionHelper::Observer* observer) { 24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner merge_session_helper_.AddObserver(observer); 25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::RemoveMergeSessionObserver( 25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner MergeSessionHelper::Observer* observer) { 25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner merge_session_helper_.RemoveObserver(observer); 25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::DeleteFetchers() { 25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner delete[] requests_; 25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner requests_ = NULL; 26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner user_id_fetchers_.clear(); 26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner refresh_token_fetchers_.clear(); 26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool AccountReconcilor::AreAllRefreshTokensChecked() const { 26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return chrome_accounts_.size() == 26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner (valid_chrome_accounts_.size() + invalid_chrome_accounts_.size()); 26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::RegisterForCookieChanges() { 27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // First clear any existing registration to avoid DCHECKs that can otherwise 27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // go off in some embedders on reauth (e.g., ChromeSigninClient). 27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner UnregisterForCookieChanges(); 27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner client_->SetCookieChangedCallback( 27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner base::Bind(&AccountReconcilor::OnCookieChanged, base::Unretained(this))); 27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::UnregisterForCookieChanges() { 279d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton client_->SetCookieChangedCallback(SigninClient::CookieChangedCallback()); 28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::RegisterWithSigninManager() { 28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner signin_manager_->AddObserver(this); 28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::UnregisterWithSigninManager() { 28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner signin_manager_->RemoveObserver(this); 28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 290d6d806ceff943ca26c008f704013f18920685cfdGreg Claytonvoid AccountReconcilor::RegisterWithTokenService() { 29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::RegisterWithTokenService"; 29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // During re-auth, the reconcilor will get a callback about successful signin 29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // even when the profile is already connected. Avoid re-registering 294d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton // with the token service since this will DCHECK. 29524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (registered_with_token_service_) 29624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return; 29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 29824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner token_service_->AddObserver(this); 299c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham registered_with_token_service_ = true; 300c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham} 301c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham 302c4547c59f2e8390bdbf92484c851be06395b8e77Jim Inghamvoid AccountReconcilor::UnregisterWithTokenService() { 303c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham if (!registered_with_token_service_) 304d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton return; 305c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham 306c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham token_service_->RemoveObserver(this); 307c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham registered_with_token_service_ = false; 308d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton} 309d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton 310d6d806ceff943ca26c008f704013f18920685cfdGreg Claytonbool AccountReconcilor::IsProfileConnected() { 311c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham return !signin_manager_->GetAuthenticatedUsername().empty(); 312c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham} 313d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton 314c4547c59f2e8390bdbf92484c851be06395b8e77Jim Inghamvoid AccountReconcilor::StartPeriodicReconciliation() { 31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::StartPeriodicReconciliation"; 316c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham // TODO(rogerta): pick appropriate thread and timeout value. 317c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham reconciliation_timer_.Start(FROM_HERE, 31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner base::TimeDelta::FromSeconds(300), 31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner this, 32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner &AccountReconcilor::PeriodicReconciliation); 32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 32324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::StopPeriodicReconciliation() { 32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::StopPeriodicReconciliation"; 32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner reconciliation_timer_.Stop(); 32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::PeriodicReconciliation() { 32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::PeriodicReconciliation"; 33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StartReconcile(); 33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::OnCookieChanged(const net::CanonicalCookie* cookie) { 33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (cookie->Name() == "LSID" && 33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner cookie->Domain() == GaiaUrls::GetInstance()->gaia_url().host() && 33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner cookie->IsSecure() && cookie->IsHttpOnly()) { 33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::OnCookieChanged: LSID changed"; 33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifdef OS_CHROMEOS 33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // On Chrome OS it is possible that O2RT is not available at this moment 34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // because profile data transfer is still in progress. 34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!token_service_->GetAccounts().size()) { 34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::OnCookieChanged: cookie change is ingored" 34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner "because profile data transfer is in progress."; 34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return; 34524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif 34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StartReconcile(); 34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 34924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::OnRefreshTokenAvailable(const std::string& account_id) { 35224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::OnRefreshTokenAvailable: " << account_id; 35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StartReconcile(); 35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 35524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::OnRefreshTokenRevoked(const std::string& account_id) { 35731cf0e7c5ff8233eccef28ca22d025d7b490cb7aGreg Clayton VLOG(1) << "AccountReconcilor::OnRefreshTokenRevoked: " << account_id; 35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StartRemoveAction(account_id); 35931cf0e7c5ff8233eccef28ca22d025d7b490cb7aGreg Clayton} 36024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::OnRefreshTokensLoaded() {} 36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::GoogleSigninSucceeded(const std::string& username, 36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const std::string& password) { 36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::GoogleSigninSucceeded: signed in"; 36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner RegisterForCookieChanges(); 36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner RegisterWithTokenService(); 36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StartPeriodicReconciliation(); 36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 37124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::GoogleSignedOut(const std::string& username) { 37224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::GoogleSignedOut: signed out"; 37324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner UnregisterWithTokenService(); 37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner UnregisterForCookieChanges(); 37524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner StopPeriodicReconciliation(); 37624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 37824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::PerformMergeAction(const std::string& account_id) { 37924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::PerformMergeAction: " << account_id; 38024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner merge_session_helper_.LogIn(account_id); 381d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton} 382d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton 383d6d806ceff943ca26c008f704013f18920685cfdGreg Claytonvoid AccountReconcilor::StartRemoveAction(const std::string& account_id) { 384d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton VLOG(1) << "AccountReconcilor::StartRemoveAction: " << account_id; 385d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton GetAccountsFromCookie(base::Bind(&AccountReconcilor::FinishRemoveAction, 386d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton base::Unretained(this), 387d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton account_id)); 388d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton} 389d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton 390d6d806ceff943ca26c008f704013f18920685cfdGreg Claytonvoid AccountReconcilor::FinishRemoveAction( 391d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton const std::string& account_id, 392d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton const GoogleServiceAuthError& error, 393d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton const std::vector<std::pair<std::string, bool> >& accounts) { 394d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton VLOG(1) << "AccountReconcilor::FinishRemoveAction:" 395d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton << " account=" << account_id << " error=" << error.ToString(); 396d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton if (error.state() == GoogleServiceAuthError::NONE) { 397d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton AbortReconcile(); 398d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton std::vector<std::string> accounts_only; 399d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton for (std::vector<std::pair<std::string, bool> >::const_iterator i = 400d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton accounts.begin(); 401d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton i != accounts.end(); 402d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton ++i) { 403d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton accounts_only.push_back(i->first); 404d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton } 405d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton merge_session_helper_.LogOut(account_id, accounts_only); 406d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton } 407d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton // Wait for the next ReconcileAction if there is an error. 408d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton} 409d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton 410d6d806ceff943ca26c008f704013f18920685cfdGreg Claytonvoid AccountReconcilor::PerformAddToChromeAction(const std::string& account_id, 411d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton int session_index) { 412d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton VLOG(1) << "AccountReconcilor::PerformAddToChromeAction:" 413d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton << " account=" << account_id << " session_index=" << session_index; 414d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton 415d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton#if !defined(OS_ANDROID) && !defined(OS_IOS) 416d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton refresh_token_fetchers_.push_back( 417d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton new RefreshTokenFetcher(this, account_id, session_index)); 418d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton#endif 419d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton} 420d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton 421d6d806ceff943ca26c008f704013f18920685cfdGreg Claytonvoid AccountReconcilor::PerformLogoutAllAccountsAction() { 422d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton VLOG(1) << "AccountReconcilor::PerformLogoutAllAccountsAction"; 4239b8550ee5ca4bb85b67352e1c63a1abf7f4a3809Jim Ingham merge_session_helper_.LogOutAllAccounts(); 424d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton} 425d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton 426d6d806ceff943ca26c008f704013f18920685cfdGreg Claytonvoid AccountReconcilor::StartReconcile() { 427d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton if (!IsProfileConnected() || is_reconcile_started_) 428d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton return; 429d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton 430d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton is_reconcile_started_ = true; 431d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton 432d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton // Reset state for validating gaia cookie. 433d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton are_gaia_accounts_set_ = false; 434d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton gaia_accounts_.clear(); 43524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner GetAccountsFromCookie(base::Bind( 43624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner &AccountReconcilor::ContinueReconcileActionAfterGetGaiaAccounts, 43724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner base::Unretained(this))); 43824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 43924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Reset state for validating oauth2 tokens. 44024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner primary_account_.clear(); 44124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner chrome_accounts_.clear(); 44224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DeleteFetchers(); 443d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton valid_chrome_accounts_.clear(); 44424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner invalid_chrome_accounts_.clear(); 44524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner add_to_cookie_.clear(); 44624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner add_to_chrome_.clear(); 44724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ValidateAccountsFromTokenService(); 44824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 44924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 45024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::GetAccountsFromCookie( 45124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner GetAccountsFromCookieCallback callback) { 45224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner get_gaia_accounts_callbacks_.push_back(callback); 45324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!gaia_fetcher_) { 45424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // There is no list account request in flight. 45524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner gaia_fetcher_.reset(new GaiaAuthFetcher( 45624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner this, GaiaConstants::kChromeSource, client_->GetURLRequestContext())); 45724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner gaia_fetcher_->StartListAccounts(); 45824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 45924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 46024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 46124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::OnListAccountsSuccess(const std::string& data) { 46224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner gaia_fetcher_.reset(); 46324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 46424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Get account information from response data. 46524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::vector<std::pair<std::string, bool> > gaia_accounts; 46624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner bool valid_json = gaia::ParseListAccountsData(data, &gaia_accounts); 46724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!valid_json) { 46824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: parsing error"; 46924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } else if (gaia_accounts.size() > 0) { 47024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: " 47124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner << "Gaia " << gaia_accounts.size() << " accounts, " 47224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner << "Primary is '" << gaia_accounts[0].first << "'"; 47324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } else { 47424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: No accounts"; 47524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 47624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 47724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // There must be at least one callback waiting for result. 47824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DCHECK(!get_gaia_accounts_callbacks_.empty()); 47924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 48024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner GoogleServiceAuthError error = 48124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner !valid_json ? GoogleServiceAuthError( 48224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE) 48324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner : GoogleServiceAuthError::AuthErrorNone(); 48424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner get_gaia_accounts_callbacks_.front().Run(error, gaia_accounts); 48524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner get_gaia_accounts_callbacks_.pop_front(); 48624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 48724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner MayBeDoNextListAccounts(); 48824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 48924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 49024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::OnListAccountsFailure( 49124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const GoogleServiceAuthError& error) { 49224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner gaia_fetcher_.reset(); 49324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::OnListAccountsFailure: " << error.ToString(); 49424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::vector<std::pair<std::string, bool> > empty_accounts; 49524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 49624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // There must be at least one callback waiting for result. 49724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DCHECK(!get_gaia_accounts_callbacks_.empty()); 49824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 49924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner get_gaia_accounts_callbacks_.front().Run(error, empty_accounts); 50024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner get_gaia_accounts_callbacks_.pop_front(); 50124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 50224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner MayBeDoNextListAccounts(); 50324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 50424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 50524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::MayBeDoNextListAccounts() { 50624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!get_gaia_accounts_callbacks_.empty()) { 50724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner gaia_fetcher_.reset(new GaiaAuthFetcher( 50824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner this, GaiaConstants::kChromeSource, client_->GetURLRequestContext())); 50924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner gaia_fetcher_->StartListAccounts(); 51024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 511d6d47976b71187907c1cdeea86fabf7d5534314fJim Ingham} 51224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 513d6d47976b71187907c1cdeea86fabf7d5534314fJim Inghamvoid AccountReconcilor::ContinueReconcileActionAfterGetGaiaAccounts( 514d6d47976b71187907c1cdeea86fabf7d5534314fJim Ingham const GoogleServiceAuthError& error, 51524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const std::vector<std::pair<std::string, bool> >& accounts) { 51624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (error.state() == GoogleServiceAuthError::NONE) { 51724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner gaia_accounts_ = accounts; 51824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner are_gaia_accounts_set_ = true; 51924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FinishReconcile(); 52024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } else { 52124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner AbortReconcile(); 52224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 52324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 52424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 52524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::ValidateAccountsFromTokenService() { 52624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner primary_account_ = signin_manager_->GetAuthenticatedUsername(); 527fb2d05b85d8185f06d97d2c5444652fa74c246c3Enrico Granata DCHECK(!primary_account_.empty()); 528fb2d05b85d8185f06d97d2c5444652fa74c246c3Enrico Granata 529fb2d05b85d8185f06d97d2c5444652fa74c246c3Enrico Granata chrome_accounts_ = token_service_->GetAccounts(); 530fb2d05b85d8185f06d97d2c5444652fa74c246c3Enrico Granata DCHECK_GT(chrome_accounts_.size(), 0u); 531fb2d05b85d8185f06d97d2c5444652fa74c246c3Enrico Granata 532fb2d05b85d8185f06d97d2c5444652fa74c246c3Enrico Granata VLOG(1) << "AccountReconcilor::ValidateAccountsFromTokenService: " 533fb2d05b85d8185f06d97d2c5444652fa74c246c3Enrico Granata << "Chrome " << chrome_accounts_.size() << " accounts, " 53424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner << "Primary is '" << primary_account_ << "'"; 53524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 53624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DCHECK(!requests_); 53724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner requests_ = 53824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner new scoped_ptr<OAuth2TokenService::Request>[chrome_accounts_.size()]; 53924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const OAuth2TokenService::ScopeSet scopes = 54024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner AccountReconcilor::UserIdFetcher::GetScopes(); 54124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (size_t i = 0; i < chrome_accounts_.size(); ++i) { 54224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner requests_[i] = 54324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner token_service_->StartRequest(chrome_accounts_[i], scopes, this); 544eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice } 545eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice 546eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice DCHECK_EQ(0u, user_id_fetchers_.size()); 547eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice user_id_fetchers_.resize(chrome_accounts_.size()); 548eddffe93d2c9ebb575e7b03fe1c5e71f9ecaf9f1Caroline Tice} 549537a7a86687683fd403ce652d178fbc89e06ef9fGreg Clayton 550e9ca3a4130bfb76765256549e01c759da8ec2f1dCaroline Ticevoid AccountReconcilor::OnGetTokenSuccess( 55127345db7bc4167078014798032137b0452f4cab9Greg Clayton const OAuth2TokenService::Request* request, 55227345db7bc4167078014798032137b0452f4cab9Greg Clayton const std::string& access_token, 553e9ca3a4130bfb76765256549e01c759da8ec2f1dCaroline Tice const base::Time& expiration_time) { 55427345db7bc4167078014798032137b0452f4cab9Greg Clayton size_t index; 55527345db7bc4167078014798032137b0452f4cab9Greg Clayton for (index = 0; index < chrome_accounts_.size(); ++index) { 55627345db7bc4167078014798032137b0452f4cab9Greg Clayton if (request == requests_[index].get()) 55727345db7bc4167078014798032137b0452f4cab9Greg Clayton break; 55827345db7bc4167078014798032137b0452f4cab9Greg Clayton } 55927345db7bc4167078014798032137b0452f4cab9Greg Clayton DCHECK(index < chrome_accounts_.size()); 560e9ca3a4130bfb76765256549e01c759da8ec2f1dCaroline Tice 56127345db7bc4167078014798032137b0452f4cab9Greg Clayton const std::string& account_id = chrome_accounts_[index]; 56227345db7bc4167078014798032137b0452f4cab9Greg Clayton 56327345db7bc4167078014798032137b0452f4cab9Greg Clayton VLOG(1) << "AccountReconcilor::OnGetTokenSuccess: valid " << account_id; 56427345db7bc4167078014798032137b0452f4cab9Greg Clayton 56527345db7bc4167078014798032137b0452f4cab9Greg Clayton DCHECK(!user_id_fetchers_[index]); 56627345db7bc4167078014798032137b0452f4cab9Greg Clayton user_id_fetchers_[index] = new UserIdFetcher(this, access_token, account_id); 567e9ca3a4130bfb76765256549e01c759da8ec2f1dCaroline Tice} 56827345db7bc4167078014798032137b0452f4cab9Greg Clayton 56927345db7bc4167078014798032137b0452f4cab9Greg Claytonvoid AccountReconcilor::OnGetTokenFailure( 57027345db7bc4167078014798032137b0452f4cab9Greg Clayton const OAuth2TokenService::Request* request, 57127345db7bc4167078014798032137b0452f4cab9Greg Clayton const GoogleServiceAuthError& error) { 57227345db7bc4167078014798032137b0452f4cab9Greg Clayton size_t index; 57327345db7bc4167078014798032137b0452f4cab9Greg Clayton for (index = 0; index < chrome_accounts_.size(); ++index) { 57427345db7bc4167078014798032137b0452f4cab9Greg Clayton if (request == requests_[index].get()) 57527345db7bc4167078014798032137b0452f4cab9Greg Clayton break; 57627345db7bc4167078014798032137b0452f4cab9Greg Clayton } 57727345db7bc4167078014798032137b0452f4cab9Greg Clayton DCHECK(index < chrome_accounts_.size()); 578e9ca3a4130bfb76765256549e01c759da8ec2f1dCaroline Tice 579e9ca3a4130bfb76765256549e01c759da8ec2f1dCaroline Tice const std::string& account_id = chrome_accounts_[index]; 580e9ca3a4130bfb76765256549e01c759da8ec2f1dCaroline Tice 581e9ca3a4130bfb76765256549e01c759da8ec2f1dCaroline Tice VLOG(1) << "AccountReconcilor::OnGetTokenFailure: invalid " << account_id; 582e9ca3a4130bfb76765256549e01c759da8ec2f1dCaroline Tice HandleFailedAccountIdCheck(account_id); 583e9ca3a4130bfb76765256549e01c759da8ec2f1dCaroline Tice} 584c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham 585c4547c59f2e8390bdbf92484c851be06395b8e77Jim Inghamvoid AccountReconcilor::FinishReconcile() { 586c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham // Make sure that the process of validating the gaia cookie and the oauth2 587c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham // tokens individually is done before proceeding with reconciliation. 588c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham if (!are_gaia_accounts_set_ || !AreAllRefreshTokensChecked()) 589d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton return; 590d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton 591d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton VLOG(1) << "AccountReconcilor::FinishReconcile"; 592d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton 593c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham DeleteFetchers(); 594c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham 595d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton DCHECK(add_to_cookie_.empty()); 596c4547c59f2e8390bdbf92484c851be06395b8e77Jim Ingham DCHECK(add_to_chrome_.empty()); 597d6d806ceff943ca26c008f704013f18920685cfdGreg Clayton bool are_primaries_equal = 59824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner gaia_accounts_.size() > 0 && 59924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner gaia::AreEmailsSame(primary_account_, gaia_accounts_[0].first); 60024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 60124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (are_primaries_equal) { 60224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Determine if we need to merge accounts from gaia cookie to chrome. 60324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (size_t i = 0; i < gaia_accounts_.size(); ++i) { 60424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const std::string& gaia_account = gaia_accounts_[i].first; 60524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (gaia_accounts_[i].second && 60624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner valid_chrome_accounts_.find(gaia_account) == 60724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner valid_chrome_accounts_.end()) { 60824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner add_to_chrome_.push_back(std::make_pair(gaia_account, i)); 60924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 61024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 61124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } else { 61224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::FinishReconcile: rebuild cookie"; 61324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Really messed up state. Blow away the gaia cookie completely and 61424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // rebuild it, making sure the primary account as specified by the 61524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // SigninManager is the first session in the gaia cookie. 61624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner PerformLogoutAllAccountsAction(); 61724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner gaia_accounts_.clear(); 61824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 61924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 62024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Create a list of accounts that need to be added to the gaia cookie. 62124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // The primary account must be first to make sure it becomes the default 62224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // account in the case where chrome is completely rebuilding the cookie. 62324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner add_to_cookie_.push_back(primary_account_); 62424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (EmailSet::const_iterator i = valid_chrome_accounts_.begin(); 62524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner i != valid_chrome_accounts_.end(); 62652fd984f7e67c3a0ab18d5565f40356bcfa84822Greg Clayton ++i) { 62724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (*i != primary_account_) 62824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner add_to_cookie_.push_back(*i); 62924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 63024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 63124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // For each account known to chrome, PerformMergeAction() if the account is 63224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // not already in the cookie jar or its state is invalid, or signal merge 63324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // completed otherwise. Make a copy of |add_to_cookie_| since calls to 63424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // SignalComplete() will change the array. 63524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::vector<std::string> add_to_cookie_copy = add_to_cookie_; 63624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (size_t i = 0; i < add_to_cookie_copy.size(); ++i) { 637b586901fb633b898e19bdfc8d605b4e89a3ab5b8Eli Friedman if (gaia_accounts_.end() != 63824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::find_if(gaia_accounts_.begin(), 63924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner gaia_accounts_.end(), 64024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::bind1st(EmailEqualToFunc(), 64124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::make_pair(add_to_cookie_copy[i], 64224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner true)))) { 64324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner merge_session_helper_.SignalComplete( 64424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner add_to_cookie_copy[i], 64524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner GoogleServiceAuthError::AuthErrorNone()); 64624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } else { 64724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner PerformMergeAction(add_to_cookie_copy[i]); 64824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 64924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 65024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 65124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // For each account in the gaia cookie not known to chrome, 65224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // PerformAddToChromeAction. 65324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (std::vector<std::pair<std::string, int> >::const_iterator i = 65424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner add_to_chrome_.begin(); 65524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner i != add_to_chrome_.end(); 65624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ++i) { 65724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner PerformAddToChromeAction(i->first, i->second); 65824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 65924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 66024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner CalculateIfReconcileIsDone(); 66124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ScheduleStartReconcileIfChromeAccountsChanged(); 66224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 66324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 66424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::AbortReconcile() { 66524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::AbortReconcile: we'll try again later"; 66624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner DeleteFetchers(); 66724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner add_to_cookie_.clear(); 66824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner add_to_chrome_.clear(); 66924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner CalculateIfReconcileIsDone(); 67024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 67124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 67224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::CalculateIfReconcileIsDone() { 67324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner is_reconcile_started_ = !add_to_cookie_.empty() || !add_to_chrome_.empty(); 67424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (!is_reconcile_started_) 67524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner VLOG(1) << "AccountReconcilor::CalculateIfReconcileIsDone: done"; 67624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 67724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 67824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::ScheduleStartReconcileIfChromeAccountsChanged() { 67924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (is_reconcile_started_) 68024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return; 68124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 68249ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton // Start a reconcile as the token accounts have changed. 68349ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton VLOG(1) << "AccountReconcilor::StartReconcileIfChromeAccountsChanged"; 68424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::vector<std::string> reconciled_accounts(chrome_accounts_); 68549ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton std::vector<std::string> new_chrome_accounts(token_service_->GetAccounts()); 68624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner std::sort(reconciled_accounts.begin(), reconciled_accounts.end()); 68749ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton std::sort(new_chrome_accounts.begin(), new_chrome_accounts.end()); 68849ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton if (reconciled_accounts != new_chrome_accounts) { 68924b48ff28b7c60dd4598212c3e77935a0fc1142dGreg Clayton base::MessageLoop::current()->PostTask( 69024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner FROM_HERE, 69124b48ff28b7c60dd4598212c3e77935a0fc1142dGreg Clayton base::Bind(&AccountReconcilor::StartReconcile, base::Unretained(this))); 69249ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton } 69324b48ff28b7c60dd4598212c3e77935a0fc1142dGreg Clayton} 69449ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton 69524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid AccountReconcilor::MergeSessionCompleted( 69624b48ff28b7c60dd4598212c3e77935a0fc1142dGreg Clayton const std::string& account_id, 69724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner const GoogleServiceAuthError& error) { 69849ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton VLOG(1) << "AccountReconcilor::MergeSessionCompleted: account_id=" 69924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner << account_id; 70024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 70159df36f99b76e33852e6848a162f5c2851074ea2Enrico Granata // Remove the account from the list that is being merged. 70259df36f99b76e33852e6848a162f5c2851074ea2Enrico Granata for (std::vector<std::string>::iterator i = add_to_cookie_.begin(); 70349ce682dfa7993d31206cea19ce7006cd3f3077eGreg Clayton i != add_to_cookie_.end(); 70424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ++i) { 70524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (account_id == *i) { 70659df36f99b76e33852e6848a162f5c2851074ea2Enrico Granata add_to_cookie_.erase(i); 70759df36f99b76e33852e6848a162f5c2851074ea2Enrico Granata break; 70859df36f99b76e33852e6848a162f5c2851074ea2Enrico Granata } 70949ce8969d3154e1560106cfe530444c09410f217Greg Clayton } 71049ce8969d3154e1560106cfe530444c09410f217Greg Clayton 71149ce8969d3154e1560106cfe530444c09410f217Greg Clayton CalculateIfReconcileIsDone(); 71249ce8969d3154e1560106cfe530444c09410f217Greg Clayton ScheduleStartReconcileIfChromeAccountsChanged(); 71349ce8969d3154e1560106cfe530444c09410f217Greg Clayton} 71449ce8969d3154e1560106cfe530444c09410f217Greg Clayton 71549ce8969d3154e1560106cfe530444c09410f217Greg Claytonvoid AccountReconcilor::HandleSuccessfulAccountIdCheck( 71649ce8969d3154e1560106cfe530444c09410f217Greg Clayton const std::string& account_id) { 71759df36f99b76e33852e6848a162f5c2851074ea2Enrico Granata valid_chrome_accounts_.insert(account_id); 71859df36f99b76e33852e6848a162f5c2851074ea2Enrico Granata FinishReconcile(); 71959df36f99b76e33852e6848a162f5c2851074ea2Enrico Granata} 72059df36f99b76e33852e6848a162f5c2851074ea2Enrico Granata 72159df36f99b76e33852e6848a162f5c2851074ea2Enrico Granatavoid AccountReconcilor::HandleFailedAccountIdCheck( 72259df36f99b76e33852e6848a162f5c2851074ea2Enrico Granata const std::string& account_id) { 72359df36f99b76e33852e6848a162f5c2851074ea2Enrico Granata invalid_chrome_accounts_.insert(account_id); 72459df36f99b76e33852e6848a162f5c2851074ea2Enrico Granata FinishReconcile(); 72559df36f99b76e33852e6848a162f5c2851074ea2Enrico Granata} 726cbed99955c9a7cadc457fd8af2ec6946124fa9a1Johnny Chen 72759df36f99b76e33852e6848a162f5c2851074ea2Enrico Granatavoid AccountReconcilor::HandleRefreshTokenFetched( 72859df36f99b76e33852e6848a162f5c2851074ea2Enrico Granata const std::string& account_id, 72959df36f99b76e33852e6848a162f5c2851074ea2Enrico Granata const std::string& refresh_token) { 73059df36f99b76e33852e6848a162f5c2851074ea2Enrico Granata if (!refresh_token.empty()) { 73159df36f99b76e33852e6848a162f5c2851074ea2Enrico Granata token_service_->UpdateCredentials(account_id, refresh_token); 73259df36f99b76e33852e6848a162f5c2851074ea2Enrico Granata } 73324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 73424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Remove the account from the list that is being updated. 73524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner for (std::vector<std::pair<std::string, int> >::iterator i = 73624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner add_to_chrome_.begin(); 73724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner i != add_to_chrome_.end(); 73824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner ++i) { 73924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner if (gaia::AreEmailsSame(account_id, i->first)) { 74024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner add_to_chrome_.erase(i); 74124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner break; 74224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 74324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner } 74424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 74524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner CalculateIfReconcileIsDone(); 74624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} 74724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner