File: sync_auth_manager.h

package info (click to toggle)
chromium-browser 70.0.3538.110-1~deb9u1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 1,619,476 kB
  • sloc: cpp: 13,024,755; ansic: 1,349,823; python: 916,672; xml: 314,489; java: 280,047; asm: 276,936; perl: 75,771; objc: 66,634; sh: 45,860; cs: 28,354; php: 11,064; makefile: 10,911; yacc: 9,109; tcl: 8,403; ruby: 4,065; lex: 1,779; pascal: 1,411; lisp: 1,055; awk: 41; jsp: 39; sed: 17; sql: 3
file content (177 lines) | stat: -rw-r--r-- 7,248 bytes parent folder | download
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
// Copyright 2018 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 COMPONENTS_BROWSER_SYNC_SYNC_AUTH_MANAGER_H_
#define COMPONENTS_BROWSER_SYNC_SYNC_AUTH_MANAGER_H_

#include <memory>
#include <string>
#include <vector>

#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "components/signin/core/browser/account_info.h"
#include "components/sync/driver/sync_token_status.h"
#include "components/sync/engine/connection_status.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "net/base/backoff_entry.h"
#include "services/identity/public/cpp/identity_manager.h"

namespace identity {
class AccessTokenFetcher;
}

namespace syncer {
struct SyncCredentials;
class SyncPrefs;
}  // namespace syncer

namespace browser_sync {

// SyncAuthManager tracks the account to be used for Sync and its authentication
// state. Note that this account may or may not be the primary account (as per
// IdentityManager::GetPrimaryAccountInfo() etc).
class SyncAuthManager : public identity::IdentityManager::Observer {
 public:
  struct SyncAccountInfo {
    SyncAccountInfo();
    SyncAccountInfo(const AccountInfo& account_info, bool is_primary);

    AccountInfo account_info;
    bool is_primary = false;
  };

  // Called when the existence of an authenticated account changes. It's
  // guaranteed that this is only called for going from "no account" to "have
  // account" or vice versa, i.e. SyncAuthManager will never directly switch
  // from one account to a different one. Call GetActiveAccountInfo to get the
  // new state.
  using AccountStateChangedCallback = base::RepeatingClosure;
  // Called when the credential state changes, i.e. an access token was
  // added/changed/removed. Call GetCredentials to get the new state.
  using CredentialsChangedCallback = base::RepeatingClosure;

  // |sync_prefs| must not be null and must outlive this.
  // |identity_manager| may be null (this is the case if local Sync is enabled),
  // but if non-null, must outlive this object.
  SyncAuthManager(syncer::SyncPrefs* sync_prefs,
                  identity::IdentityManager* identity_manager,
                  const AccountStateChangedCallback& account_state_changed,
                  const CredentialsChangedCallback& credentials_changed);
  ~SyncAuthManager() override;

  // Tells the tracker to start listening for changes to the account/sign-in
  // status. This gets called during SyncService initialization, except in the
  // case of local Sync. Before this is called, GetActiveAccountInfo will always
  // return an empty AccountInfo. Note that this will *not* trigger any
  // callbacks, even if there is an active account afterwards.
  void RegisterForAuthNotifications();

  // Returns the account which should be used when communicating with the Sync
  // server. Note that this account may not be blessed for Sync-the-feature.
  SyncAccountInfo GetActiveAccountInfo() const;

  const GoogleServiceAuthError& GetLastAuthError() const {
    return last_auth_error_;
  }

  // Returns the credentials to be passed to the SyncEngine.
  syncer::SyncCredentials GetCredentials() const;

  const std::string& access_token() const { return access_token_; }

  // Returns the state of the access token and token request, for display in
  // internals UI.
  const syncer::SyncTokenStatus& GetSyncTokenStatus() const;

  // Called by ProfileSyncService when the status of the connection to the Sync
  // server changed. Updates auth error state accordingly.
  void ConnectionStatusChanged(syncer::ConnectionStatus status);

  // Clears all auth-related state (error, cached access token etc). Called
  // when Sync is turned off.
  void Clear();

  // identity::IdentityManager::Observer implementation.
  void OnPrimaryAccountSet(const AccountInfo& primary_account_info) override;
  void OnPrimaryAccountCleared(
      const AccountInfo& previous_primary_account_info) override;
  void OnRefreshTokenUpdatedForAccount(const AccountInfo& account_info,
                                       bool is_valid) override;
  void OnRefreshTokenRemovedForAccount(
      const AccountInfo& account_info) override;
  void OnAccountsInCookieUpdated(
      const std::vector<AccountInfo>& accounts) override;

  // Test-only methods for inspecting/modifying internal state.
  bool IsRetryingAccessTokenFetchForTest() const;
  void ResetRequestAccessTokenBackoffForTest();

 private:
  // Determines which account should be used for Sync and returns the
  // corresponding AccountInfo.
  SyncAccountInfo DetermineAccountToUse() const;

  // Updates |sync_account_| to the appropriate account (i.e.
  // DetermineAccountToUse) if necessary, and notifies observers of any changes
  // (sign-in/sign-out/"primary" bit change). Note that changing from one
  // account to another is exposed to observers as a sign-out + sign-in.
  bool UpdateSyncAccountIfNecessary();

  void ClearAccessTokenAndRequest();

  void RequestAccessToken();

  void AccessTokenFetched(GoogleServiceAuthError error,
                          identity::AccessTokenInfo access_token_info);

  syncer::SyncPrefs* const sync_prefs_;
  identity::IdentityManager* const identity_manager_;

  const AccountStateChangedCallback account_state_changed_callback_;
  const CredentialsChangedCallback credentials_changed_callback_;

  bool registered_for_auth_notifications_ = false;

  // The account which we are using to sync. If this is non-empty, that does
  // *not* necessarily imply that Sync is actually running, e.g. because of
  // delayed startup.
  SyncAccountInfo sync_account_;

  // This is a cache of the last authentication response we received either
  // from the sync server or from Chrome's identity/token management system.
  // TODO(crbug.com/839834): Differentiate between these types of auth errors,
  // since their semantics and lifetimes are quite different: e.g. the former
  // can only exist while the Sync engine is initialized; the latter exists
  // independent of Sync state, and probably shouldn't get reset in Clear().
  GoogleServiceAuthError last_auth_error_;

  // The current access token. This is mutually exclusive with
  // |ongoing_access_token_fetch_| and |request_access_token_retry_timer_|:
  // We have at most one of a) an access token OR b) a pending request OR c) a
  // pending retry i.e. a scheduled request.
  std::string access_token_;

  // Pending request for an access token. Non-null iff there is a request
  // ongoing.
  std::unique_ptr<identity::AccessTokenFetcher> ongoing_access_token_fetch_;

  // If RequestAccessToken fails with transient error then retry requesting
  // access token with exponential backoff.
  base::OneShotTimer request_access_token_retry_timer_;
  net::BackoffEntry request_access_token_backoff_;

  // Info about the state of our access token, for display in the internals UI.
  syncer::SyncTokenStatus token_status_;

  base::WeakPtrFactory<SyncAuthManager> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(SyncAuthManager);
};

}  // namespace browser_sync

#endif  // COMPONENTS_BROWSER_SYNC_SYNC_AUTH_MANAGER_H_