123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- // 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_SYNC_DRIVER_SYNC_AUTH_MANAGER_H_
- #define COMPONENTS_SYNC_DRIVER_SYNC_AUTH_MANAGER_H_
- #include <memory>
- #include <string>
- #include "base/callback.h"
- #include "base/memory/raw_ptr.h"
- #include "base/memory/weak_ptr.h"
- #include "base/time/time.h"
- #include "base/timer/timer.h"
- #include "components/signin/public/identity_manager/account_info.h"
- #include "components/signin/public/identity_manager/identity_manager.h"
- #include "components/sync/driver/sync_auth_util.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"
- namespace signin {
- class AccessTokenFetcher;
- struct AccessTokenInfo;
- } // namespace signin
- namespace syncer {
- struct SyncCredentials;
- // 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 signin::IdentityManager::Observer {
- public:
- // 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, or if the existing account's |is_primary| bit
- // changed. 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;
- // |identity_manager| may be null (this is the case if local Sync is enabled),
- // but if non-null, must outlive this object.
- SyncAuthManager(signin::IdentityManager* identity_manager,
- const AccountStateChangedCallback& account_state_changed,
- const CredentialsChangedCallback& credentials_changed);
- SyncAuthManager(const SyncAuthManager&) = delete;
- SyncAuthManager& operator=(const SyncAuthManager&) = delete;
- ~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 whether all relevant account information as returned by
- // GetActiveAccountInfo() has been fully loaded.
- bool IsActiveAccountInfoFullyLoaded() const;
- // 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;
- // Returns the last auth error that was encountered. The error could have come
- // from the Sync server or from the IdentityManager.
- GoogleServiceAuthError GetLastAuthError() const;
- // Returns the time at which the last auth error was set.
- base::Time GetLastAuthErrorTime() const;
- // Returns whether we are in the "Sync paused" state. That means there is a
- // primary account, but the user signed out in the content area, and so we
- // don't have credentials for it anymore.
- bool IsSyncPaused() const;
- // Returns the credentials to be passed to the SyncEngine.
- 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.
- SyncTokenStatus GetSyncTokenStatus() const;
- // Called by SyncServiceImpl when Sync starts up and will try talking to
- // the server soon. This initiates fetching an access token.
- void ConnectionOpened();
- // Called by SyncServiceImpl when the status of the connection to the Sync
- // server changed. Updates auth error state accordingly.
- void ConnectionStatusChanged(ConnectionStatus status);
- // Called by SyncServiceImpl when the connection to the Sync server is
- // closed (due to Sync being shut down). Clears all related state (such as
- // cached access token, error from the server, etc).
- void ConnectionClosed();
- // signin::IdentityManager::Observer implementation.
- void OnPrimaryAccountChanged(
- const signin::PrimaryAccountChangeEvent& event) override;
- void OnRefreshTokenUpdatedForAccount(
- const CoreAccountInfo& account_info) override;
- void OnRefreshTokenRemovedForAccount(
- const CoreAccountId& account_id) override;
- void OnRefreshTokensLoaded() override;
- // Test-only methods for inspecting/modifying internal state.
- bool IsRetryingAccessTokenFetchForTest() const;
- void ResetRequestAccessTokenBackoffForTest();
- private:
- 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.
- // Returns whether the syncing account was updated.
- bool UpdateSyncAccountIfNecessary();
- // Invalidates any current access token, which means invalidating it with the
- // IdentityManager and also dropping our own cached copy. Meant to be called
- // when we know the current token is invalid (e.g. expired). Does not do
- // anything about any scheduled or ongoing request.
- void InvalidateAccessToken();
- // Clears any access token we have, and cancels any pending or scheduled
- // request for one.
- void ClearAccessTokenAndRequest();
- // Schedules a request for an access token according to the current
- // |request_access_token_backoff_|. Usually called after some transient error.
- void ScheduleAccessTokenRequest();
- // Immediately starts an access token request, unless one is already ongoing.
- // If another request is scheduled for later, it is canceled. Any access token
- // we currently have is invalidated.
- void RequestAccessToken();
- // Callback for |ongoing_access_token_fetch_|.
- void AccessTokenFetched(GoogleServiceAuthError error,
- signin::AccessTokenInfo access_token_info);
- void SetLastAuthError(const GoogleServiceAuthError& error);
- const raw_ptr<signin::IdentityManager> 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 from
- // Chrome's identity/token management system.
- GoogleServiceAuthError last_auth_error_;
- base::Time last_auth_error_time_;
- // Whether Sync is currently connected to the server, i.e. ConnectionOpened()
- // has been called, but ConnectionClosed() hasn't. While this is false, we
- // don't try to get an access token. While it's true, we will *usually* have
- // either an access token or a pending/scheduled request for one, but this is
- // not guaranteed (e.g. in the case of a persistent auth error).
- bool connection_open_ = false;
- // 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<signin::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.
- // "Partial" because this instance is not fully populated - in particular,
- // |has_token| and |next_token_request_time| get computed on demand.
- SyncTokenStatus partial_token_status_;
- // Whether there was a retry done to fetch the access token when the request
- // was cancelled for the first time. This works around an issue that can only
- // happen once during browser startup, so it's sufficient to have a single
- // retry (i.e. not per request).
- bool access_token_retried_ = false;
- base::WeakPtrFactory<SyncAuthManager> weak_ptr_factory_{this};
- };
- } // namespace syncer
- #endif // COMPONENTS_SYNC_DRIVER_SYNC_AUTH_MANAGER_H_
|