summaryrefslogtreecommitdiffstats
path: root/google_apis/gaia/account_tracker.h
blob: 41ebd2e60dca7ab60fb501e373497b745df63251 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef GOOGLE_APIS_GAIA_ACCOUNT_TRACKER_H_
#define GOOGLE_APIS_GAIA_ACCOUNT_TRACKER_H_

#include <map>
#include <string>
#include <vector>

#include "base/memory/scoped_ptr.h"
#include "base/observer_list.h"
#include "google_apis/gaia/gaia_oauth_client.h"
#include "google_apis/gaia/identity_provider.h"
#include "google_apis/gaia/oauth2_token_service.h"

class GoogleServiceAuthError;

namespace net {
class URLRequestContextGetter;
}

namespace gaia {

struct AccountIds {
  std::string account_key;  // The account ID used by OAuth2TokenService.
  std::string gaia;
  std::string email;
};

class AccountIdFetcher;

// The AccountTracker keeps track of what accounts exist on the
// profile and the state of their credentials. The tracker fetches the
// gaia ID of each account it knows about.
//
// The AccountTracker maintains these invariants:
// 1. Events are only fired after the gaia ID has been fetched.
// 2. Add/Remove and SignIn/SignOut pairs are always generated in order.
// 3. SignIn follows Add, and there will be a SignOut between SignIn & Remove.
// 4. If there is no primary account, there are no other accounts.
class AccountTracker : public OAuth2TokenService::Observer,
                       public IdentityProvider::Observer {
 public:
  AccountTracker(IdentityProvider* identity_provider,
                 net::URLRequestContextGetter* request_context_getter);
  ~AccountTracker() override;

  class Observer {
   public:
    virtual void OnAccountAdded(const AccountIds& ids) = 0;
    virtual void OnAccountRemoved(const AccountIds& ids) = 0;
    virtual void OnAccountSignInChanged(const AccountIds& ids,
                                        bool is_signed_in) = 0;
  };

  void Shutdown();

  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);

  // Returns the list of accounts that are signed in, and for which gaia IDs
  // have been fetched. The primary account for the profile will be first
  // in the vector. Additional accounts will be in order of their gaia IDs.
  std::vector<AccountIds> GetAccounts() const;
  AccountIds FindAccountIdsByGaiaId(const std::string& gaia_id);

  // OAuth2TokenService::Observer implementation.
  void OnRefreshTokenAvailable(const std::string& account_key) override;
  void OnRefreshTokenRevoked(const std::string& account_key) override;

  void OnUserInfoFetchSuccess(AccountIdFetcher* fetcher,
                              const std::string& gaia_id);
  void OnUserInfoFetchFailure(AccountIdFetcher* fetcher);

  // IdentityProvider::Observer implementation.
  void OnActiveAccountLogin() override;
  void OnActiveAccountLogout() override;

  // Sets the state of an account. Does not fire notifications.
  void SetAccountStateForTest(AccountIds ids, bool is_signed_in);

  IdentityProvider* identity_provider() { return identity_provider_; }

  // Indicates if all user information has been fetched. If the result is false,
  // there are still unfininshed fetchers.
  virtual bool IsAllUserInfoFetched() const;

 private:
  struct AccountState {
    AccountIds ids;
    bool is_signed_in;
  };

  void NotifyAccountAdded(const AccountState& account);
  void NotifyAccountRemoved(const AccountState& account);
  void NotifySignInChanged(const AccountState& account);

  void UpdateSignInState(const std::string account_key, bool is_signed_in);

  void StartTrackingAccount(const std::string account_key);
  void StopTrackingAccount(const std::string account_key);
  void StopTrackingAllAccounts();
  void StartFetchingUserInfo(const std::string account_key);
  void DeleteFetcher(AccountIdFetcher* fetcher);

  IdentityProvider* identity_provider_;  // Not owned.
  scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
  std::map<std::string, AccountIdFetcher*> user_info_requests_;
  std::map<std::string, AccountState> accounts_;
  ObserverList<Observer> observer_list_;
  bool shutdown_called_;
};

class AccountIdFetcher : public OAuth2TokenService::Consumer,
                         public gaia::GaiaOAuthClient::Delegate {
 public:
  AccountIdFetcher(OAuth2TokenService* token_service,
                   net::URLRequestContextGetter* request_context_getter,
                   AccountTracker* tracker,
                   const std::string& account_key);
  ~AccountIdFetcher() override;

  const std::string& account_key() { return account_key_; }

  void Start();

  // OAuth2TokenService::Consumer implementation.
  void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
                         const std::string& access_token,
                         const base::Time& expiration_time) override;
  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
                         const GoogleServiceAuthError& error) override;

  // gaia::GaiaOAuthClient::Delegate implementation.
  void OnGetUserIdResponse(const std::string& gaia_id) override;
  void OnOAuthError() override;
  void OnNetworkError(int response_code) override;

 private:
  OAuth2TokenService* token_service_;
  net::URLRequestContextGetter* request_context_getter_;
  AccountTracker* tracker_;
  const std::string account_key_;

  scoped_ptr<OAuth2TokenService::Request> login_token_request_;
  scoped_ptr<gaia::GaiaOAuthClient> gaia_oauth_client_;
};

}  // namespace extensions

#endif  // GOOGLE_APIS_GAIA_ACCOUNT_TRACKER_H_