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_ACCOUNT_TRACKER_H_
6#define GOOGLE_APIS_GAIA_ACCOUNT_TRACKER_H_
7
8#include <map>
9#include <string>
10#include <vector>
11
12#include "base/memory/scoped_ptr.h"
13#include "base/observer_list.h"
14#include "google_apis/gaia/gaia_oauth_client.h"
15#include "google_apis/gaia/identity_provider.h"
16#include "google_apis/gaia/oauth2_token_service.h"
17
18class GoogleServiceAuthError;
19
20namespace net {
21class URLRequestContextGetter;
22}
23
24namespace gaia {
25
26struct AccountIds {
27  std::string account_key;  // The account ID used by OAuth2TokenService.
28  std::string gaia;
29  std::string email;
30};
31
32class AccountIdFetcher;
33
34// The AccountTracker keeps track of what accounts exist on the
35// profile and the state of their credentials. The tracker fetches the
36// gaia ID of each account it knows about.
37//
38// The AccountTracker maintains these invariants:
39// 1. Events are only fired after the gaia ID has been fetched.
40// 2. Add/Remove and SignIn/SignOut pairs are always generated in order.
41// 3. SignIn follows Add, and there will be a SignOut between SignIn & Remove.
42// 4. If there is no primary account, there are no other accounts.
43class AccountTracker : public OAuth2TokenService::Observer,
44                       public IdentityProvider::Observer {
45 public:
46  AccountTracker(IdentityProvider* identity_provider,
47                 net::URLRequestContextGetter* request_context_getter);
48  virtual ~AccountTracker();
49
50  class Observer {
51   public:
52    virtual void OnAccountAdded(const AccountIds& ids) = 0;
53    virtual void OnAccountRemoved(const AccountIds& ids) = 0;
54    virtual void OnAccountSignInChanged(const AccountIds& ids,
55                                        bool is_signed_in) = 0;
56  };
57
58  void Shutdown();
59
60  void AddObserver(Observer* observer);
61  void RemoveObserver(Observer* observer);
62
63  // Returns the list of accounts that are signed in, and for which gaia IDs
64  // have been fetched. The primary account for the profile will be first
65  // in the vector. Additional accounts will be in order of their gaia IDs.
66  std::vector<AccountIds> GetAccounts() const;
67  AccountIds FindAccountIdsByGaiaId(const std::string& gaia_id);
68
69  // OAuth2TokenService::Observer implementation.
70  virtual void OnRefreshTokenAvailable(const std::string& account_key) OVERRIDE;
71  virtual void OnRefreshTokenRevoked(const std::string& account_key) OVERRIDE;
72
73  void OnUserInfoFetchSuccess(AccountIdFetcher* fetcher,
74                              const std::string& gaia_id);
75  void OnUserInfoFetchFailure(AccountIdFetcher* fetcher);
76
77  // IdentityProvider::Observer implementation.
78  virtual void OnActiveAccountLogin() OVERRIDE;
79  virtual void OnActiveAccountLogout() OVERRIDE;
80
81  // Sets the state of an account. Does not fire notifications.
82  void SetAccountStateForTest(AccountIds ids, bool is_signed_in);
83
84  IdentityProvider* identity_provider() { return identity_provider_; }
85
86  // Indicates if all user information has been fetched. If the result is false,
87  // there are still unfininshed fetchers.
88  virtual bool IsAllUserInfoFetched() const;
89
90 private:
91  struct AccountState {
92    AccountIds ids;
93    bool is_signed_in;
94  };
95
96  void NotifyAccountAdded(const AccountState& account);
97  void NotifyAccountRemoved(const AccountState& account);
98  void NotifySignInChanged(const AccountState& account);
99
100  void UpdateSignInState(const std::string account_key, bool is_signed_in);
101
102  void StartTrackingAccount(const std::string account_key);
103  void StopTrackingAccount(const std::string account_key);
104  void StopTrackingAllAccounts();
105  void StartFetchingUserInfo(const std::string account_key);
106  void DeleteFetcher(AccountIdFetcher* fetcher);
107
108  IdentityProvider* identity_provider_;  // Not owned.
109  scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
110  std::map<std::string, AccountIdFetcher*> user_info_requests_;
111  std::map<std::string, AccountState> accounts_;
112  ObserverList<Observer> observer_list_;
113  bool shutdown_called_;
114};
115
116class AccountIdFetcher : public OAuth2TokenService::Consumer,
117                         public gaia::GaiaOAuthClient::Delegate {
118 public:
119  AccountIdFetcher(OAuth2TokenService* token_service,
120                   net::URLRequestContextGetter* request_context_getter,
121                   AccountTracker* tracker,
122                   const std::string& account_key);
123  virtual ~AccountIdFetcher();
124
125  const std::string& account_key() { return account_key_; }
126
127  void Start();
128
129  // OAuth2TokenService::Consumer implementation.
130  virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
131                                 const std::string& access_token,
132                                 const base::Time& expiration_time) OVERRIDE;
133  virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
134                                 const GoogleServiceAuthError& error) OVERRIDE;
135
136  // gaia::GaiaOAuthClient::Delegate implementation.
137  virtual void OnGetUserIdResponse(const std::string& gaia_id) OVERRIDE;
138  virtual void OnOAuthError() OVERRIDE;
139  virtual void OnNetworkError(int response_code) OVERRIDE;
140
141 private:
142  OAuth2TokenService* token_service_;
143  net::URLRequestContextGetter* request_context_getter_;
144  AccountTracker* tracker_;
145  const std::string account_key_;
146
147  scoped_ptr<OAuth2TokenService::Request> login_token_request_;
148  scoped_ptr<gaia::GaiaOAuthClient> gaia_oauth_client_;
149};
150
151}  // namespace extensions
152
153#endif  // GOOGLE_APIS_GAIA_ACCOUNT_TRACKER_H_
154