1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef GOOGLE_APIS_GAIA_MERGE_SESSION_HELPER_H_ 6 #define GOOGLE_APIS_GAIA_MERGE_SESSION_HELPER_H_ 7 8 #include <deque> 9 10 #include "base/observer_list.h" 11 #include "base/timer/timer.h" 12 #include "google_apis/gaia/gaia_auth_consumer.h" 13 #include "google_apis/gaia/ubertoken_fetcher.h" 14 #include "net/url_request/url_fetcher_delegate.h" 15 16 class GaiaAuthFetcher; 17 class GoogleServiceAuthError; 18 class OAuth2TokenService; 19 20 namespace net { 21 class URLFetcher; 22 class URLRequestContextGetter; 23 } 24 25 // Merges a Google account known to Chrome into the cookie jar. When merging 26 // multiple accounts, one instance of the helper is better than multiple 27 // instances if there is the possibility that they run concurrently, since 28 // changes to the cookie must be serialized. 29 // 30 // By default instances of MergeSessionHelper delete themselves when done. 31 class MergeSessionHelper : public GaiaAuthConsumer, 32 public UbertokenConsumer, 33 public net::URLFetcherDelegate { 34 public: 35 class Observer { 36 public: 37 // Called whenever a merge session is completed. The account that was 38 // merged is given by |account_id|. If |error| is equal to 39 // GoogleServiceAuthError::AuthErrorNone() then the merge succeeeded. 40 virtual void MergeSessionCompleted(const std::string& account_id, 41 const GoogleServiceAuthError& error) = 0; 42 protected: ~Observer()43 virtual ~Observer() {} 44 }; 45 46 // Class to retrieve the external connection check results from gaia. 47 // Declared publicly for unit tests. 48 class ExternalCcResultFetcher : public GaiaAuthConsumer, 49 public net::URLFetcherDelegate { 50 public: 51 // Maps connection URLs, as returned by StartGetCheckConnectionInfo() to 52 // token and URLFetcher used to fetch the URL. 53 typedef std::map<GURL, std::pair<std::string, net::URLFetcher*> > 54 URLToTokenAndFetcher; 55 56 // Maps tokens to the fetched result for that token. 57 typedef std::map<std::string, std::string> ResultMap; 58 59 ExternalCcResultFetcher(MergeSessionHelper* helper); 60 virtual ~ExternalCcResultFetcher(); 61 62 // Gets the current value of the external connection check result string. 63 std::string GetExternalCcResult(); 64 65 // Start fetching the external CC result. If a fetch is already in progress 66 // it is canceled. 67 void Start(); 68 69 // Are external URLs still being checked? 70 bool IsRunning(); 71 72 // Returns a copy of the internal token to fetcher map. get_fetcher_map_for_testing()73 URLToTokenAndFetcher get_fetcher_map_for_testing() { 74 return fetchers_; 75 } 76 77 // Simulate a timeout for tests. 78 void TimeoutForTests(); 79 80 private: 81 // Overridden from GaiaAuthConsumer. 82 virtual void OnGetCheckConnectionInfoSuccess( 83 const std::string& data) OVERRIDE; 84 85 // Creates and initializes a URL fetcher for doing a connection check. 86 net::URLFetcher* CreateFetcher(const GURL& url); 87 88 // Overridden from URLFetcherDelgate. 89 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 90 91 // Any fetches still ongoing after this call are considered timed out. 92 void Timeout(); 93 94 void CleanupTransientState(); 95 96 MergeSessionHelper* helper_; 97 base::OneShotTimer<ExternalCcResultFetcher> timer_; 98 scoped_ptr<GaiaAuthFetcher> gaia_auth_fetcher_; 99 URLToTokenAndFetcher fetchers_; 100 ResultMap results_; 101 102 DISALLOW_COPY_AND_ASSIGN(ExternalCcResultFetcher); 103 }; 104 105 MergeSessionHelper(OAuth2TokenService* token_service, 106 net::URLRequestContextGetter* request_context, 107 Observer* observer); 108 virtual ~MergeSessionHelper(); 109 110 void LogIn(const std::string& account_id); 111 112 // Add or remove observers of this helper. 113 void AddObserver(Observer* observer); 114 void RemoveObserver(Observer* observer); 115 116 // Cancel all login requests. 117 void CancelAll(); 118 119 // Signout of |account_id| given a list of accounts already signed in. 120 // Since this involves signing out of all accounts and resigning back in, 121 // the order which |accounts| are given is important as it will dictate 122 // the sign in order. |account_id| does not have to be in |accounts|. 123 void LogOut(const std::string& account_id, 124 const std::vector<std::string>& accounts); 125 126 // Signout all accounts. 127 void LogOutAllAccounts(); 128 129 // Call observers when merge session completes. This public so that callers 130 // that know that a given account is already in the cookie jar can simply 131 // inform the observers. 132 void SignalComplete(const std::string& account_id, 133 const GoogleServiceAuthError& error); 134 135 // Returns true of there are pending log ins or outs. is_running()136 bool is_running() const { return accounts_.size() > 0; } 137 138 // Start the process of fetching the external check connection result so that 139 // its ready when we try to perform a merge session. 140 void StartFetchingExternalCcResult(); 141 142 // Returns true if the helper is still fetching external check connection 143 // results. 144 bool StillFetchingExternalCcResult(); 145 146 private: request_context()147 net::URLRequestContextGetter* request_context() { return request_context_; } 148 149 // Overridden from UbertokenConsumer. 150 virtual void OnUbertokenSuccess(const std::string& token) OVERRIDE; 151 virtual void OnUbertokenFailure(const GoogleServiceAuthError& error) OVERRIDE; 152 153 // Overridden from GaiaAuthConsumer. 154 virtual void OnMergeSessionSuccess(const std::string& data) OVERRIDE; 155 virtual void OnMergeSessionFailure(const GoogleServiceAuthError& error) 156 OVERRIDE; 157 158 void LogOutInternal(const std::string& account_id, 159 const std::vector<std::string>& accounts); 160 161 // Starts the proess of fetching the uber token and performing a merge session 162 // for the next account. Virtual so that it can be overriden in tests. 163 virtual void StartFetching(); 164 165 // Virtual for testing purpose. 166 virtual void StartLogOutUrlFetch(); 167 168 // Start the next merge session, if needed. 169 void HandleNextAccount(); 170 171 // Overridden from URLFetcherDelgate. 172 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 173 174 OAuth2TokenService* token_service_; 175 net::URLRequestContextGetter* request_context_; 176 scoped_ptr<GaiaAuthFetcher> gaia_auth_fetcher_; 177 scoped_ptr<UbertokenFetcher> uber_token_fetcher_; 178 ExternalCcResultFetcher result_fetcher_; 179 180 // A worklist for this class. Accounts names are stored here if 181 // we are pending a signin action for that account. Empty strings 182 // represent a signout request. 183 std::deque<std::string> accounts_; 184 185 // List of observers to notify when merge session completes. 186 // Makes sure list is empty on destruction. 187 ObserverList<Observer, true> observer_list_; 188 189 DISALLOW_COPY_AND_ASSIGN(MergeSessionHelper); 190 }; 191 192 #endif // GOOGLE_APIS_GAIA_MERGE_SESSION_HELPER_H_ 193