Home | History | Annotate | Download | only in gaia
      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:
     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.
     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.
    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:
    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