• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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