Commit 646f29b4 authored by Colin Blundell's avatar Colin Blundell Committed by Commit Bot

IdentityProvider: Provide explicit interface to fetch access tokens

One of IdentityProvider's clients' use cases is to fetch access tokens
for the active account. IdentityProvider currently provides no explicit
mechanism for this, instead letting clients directly interact with the
underlying OAuth2TokenService instance via GetTokenService(). However,
it's necessary to decouple IdentityProvider from OAuth2TokenService at
an interface level in order to allow for porting ProfileIdentityProvider
to be backed by IdentityManager.

This CL adds an explicit interface for clients of IdentityProvider to
request access tokens for the active account. This interface is
currently implemented directly in IdentityProvider itself, as it is
common to ProfileIdentityProvider and DeviceIdentityProvider. Before
porting ProfileIdentityProvider to be backed by IdentityManager we
will move this implementation out into those two derived classes,
temporarily duplicating it. However, we will only do that when we are
just at the point of porting ProfileIdentityProvider away from using
ProfileOAuth2TokenService.

Bug: 809452
Change-Id: I402af0cb19b5e0057edc3870ca2a8f564f4f8e10
Reviewed-on: https://chromium-review.googlesource.com/1089051Reviewed-by: default avatarPavel Yatsuk <pavely@chromium.org>
Commit-Queue: Colin Blundell <blundell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#565584}
parent 312c8aec
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
#include "components/gcm_driver/gcm_driver.h" #include "components/gcm_driver/gcm_driver.h"
#include "components/invalidation/impl/gcm_invalidation_bridge.h" #include "components/invalidation/impl/gcm_invalidation_bridge.h"
#include "components/invalidation/public/identity_provider.h"
#include "google_apis/gaia/gaia_constants.h" #include "google_apis/gaia/gaia_constants.h"
namespace invalidation { namespace invalidation {
...@@ -173,8 +172,7 @@ void GCMInvalidationBridge::Core::OnStoreReset() { ...@@ -173,8 +172,7 @@ void GCMInvalidationBridge::Core::OnStoreReset() {
GCMInvalidationBridge::GCMInvalidationBridge( GCMInvalidationBridge::GCMInvalidationBridge(
gcm::GCMDriver* gcm_driver, gcm::GCMDriver* gcm_driver,
IdentityProvider* identity_provider) IdentityProvider* identity_provider)
: OAuth2TokenService::Consumer("gcm_network_channel"), : gcm_driver_(gcm_driver),
gcm_driver_(gcm_driver),
identity_provider_(identity_provider), identity_provider_(identity_provider),
subscribed_for_incoming_messages_(false), subscribed_for_incoming_messages_(false),
weak_factory_(this) {} weak_factory_(this) {}
...@@ -205,7 +203,7 @@ void GCMInvalidationBridge::CoreInitializationDone( ...@@ -205,7 +203,7 @@ void GCMInvalidationBridge::CoreInitializationDone(
void GCMInvalidationBridge::RequestToken( void GCMInvalidationBridge::RequestToken(
syncer::GCMNetworkChannelDelegate::RequestTokenCallback callback) { syncer::GCMNetworkChannelDelegate::RequestTokenCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (access_token_request_ != nullptr) { if (access_token_fetcher_ != nullptr) {
// Report previous request as cancelled. // Report previous request as cancelled.
GoogleServiceAuthError error(GoogleServiceAuthError::REQUEST_CANCELED); GoogleServiceAuthError error(GoogleServiceAuthError::REQUEST_CANCELED);
std::string access_token; std::string access_token;
...@@ -220,41 +218,22 @@ void GCMInvalidationBridge::RequestToken( ...@@ -220,41 +218,22 @@ void GCMInvalidationBridge::RequestToken(
request_token_callback_ = callback; request_token_callback_ = callback;
OAuth2TokenService::ScopeSet scopes; OAuth2TokenService::ScopeSet scopes;
scopes.insert(GaiaConstants::kChromeSyncOAuth2Scope); scopes.insert(GaiaConstants::kChromeSyncOAuth2Scope);
access_token_request_ = identity_provider_->GetTokenService()->StartRequest( access_token_fetcher_ = identity_provider_->FetchAccessToken(
identity_provider_->GetActiveAccountId(), scopes, this); "gcm_network_channel", scopes,
base::BindOnce(&GCMInvalidationBridge::OnAccessTokenRequestCompleted,
base::Unretained(this)));
} }
void GCMInvalidationBridge::OnGetTokenSuccess( void GCMInvalidationBridge::OnAccessTokenRequestCompleted(
const OAuth2TokenService::Request* request, GoogleServiceAuthError error,
const std::string& access_token, std::string access_token) {
const base::Time& expiration_time) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_EQ(access_token_request_.get(), request);
core_thread_task_runner_->PostTask( core_thread_task_runner_->PostTask(
FROM_HERE, FROM_HERE,
base::Bind(&GCMInvalidationBridge::Core::RequestTokenFinished, base::Bind(&GCMInvalidationBridge::Core::RequestTokenFinished, core_,
core_, request_token_callback_, error, access_token));
request_token_callback_,
GoogleServiceAuthError::AuthErrorNone(),
access_token));
request_token_callback_.Reset();
access_token_request_.reset();
}
void GCMInvalidationBridge::OnGetTokenFailure(
const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_EQ(access_token_request_.get(), request);
core_thread_task_runner_->PostTask(
FROM_HERE,
base::Bind(&GCMInvalidationBridge::Core::RequestTokenFinished,
core_,
request_token_callback_,
error,
std::string()));
request_token_callback_.Reset(); request_token_callback_.Reset();
access_token_request_.reset(); access_token_fetcher_.reset();
} }
void GCMInvalidationBridge::InvalidateToken(const std::string& token) { void GCMInvalidationBridge::InvalidateToken(const std::string& token) {
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include "components/gcm_driver/gcm_client.h" #include "components/gcm_driver/gcm_client.h"
#include "components/gcm_driver/gcm_connection_observer.h" #include "components/gcm_driver/gcm_connection_observer.h"
#include "components/invalidation/impl/gcm_network_channel_delegate.h" #include "components/invalidation/impl/gcm_network_channel_delegate.h"
#include "google_apis/gaia/oauth2_token_service.h" #include "components/invalidation/public/identity_provider.h"
namespace base { namespace base {
class SingleThreadTaskRunner; class SingleThreadTaskRunner;
...@@ -36,8 +36,7 @@ class IdentityProvider; ...@@ -36,8 +36,7 @@ class IdentityProvider;
// all function calls to GCMInvalidationBridge which does actual work to perform // all function calls to GCMInvalidationBridge which does actual work to perform
// them. // them.
class GCMInvalidationBridge : public gcm::GCMAppHandler, class GCMInvalidationBridge : public gcm::GCMAppHandler,
public gcm::GCMConnectionObserver, public gcm::GCMConnectionObserver {
public OAuth2TokenService::Consumer {
public: public:
class Core; class Core;
...@@ -45,12 +44,8 @@ class GCMInvalidationBridge : public gcm::GCMAppHandler, ...@@ -45,12 +44,8 @@ class GCMInvalidationBridge : public gcm::GCMAppHandler,
IdentityProvider* identity_provider); IdentityProvider* identity_provider);
~GCMInvalidationBridge() override; ~GCMInvalidationBridge() override;
// OAuth2TokenService::Consumer implementation. void OnAccessTokenRequestCompleted(GoogleServiceAuthError error,
void OnGetTokenSuccess(const OAuth2TokenService::Request* request, std::string access_token);
const std::string& access_token,
const base::Time& expiration_time) override;
void OnGetTokenFailure(const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) override;
// gcm::GCMAppHandler implementation. // gcm::GCMAppHandler implementation.
void ShutdownHandler() override; void ShutdownHandler() override;
...@@ -99,7 +94,7 @@ class GCMInvalidationBridge : public gcm::GCMAppHandler, ...@@ -99,7 +94,7 @@ class GCMInvalidationBridge : public gcm::GCMAppHandler,
scoped_refptr<base::SingleThreadTaskRunner> core_thread_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> core_thread_task_runner_;
// Fields related to RequestToken function. // Fields related to RequestToken function.
std::unique_ptr<OAuth2TokenService::Request> access_token_request_; std::unique_ptr<ActiveAccountAccessTokenFetcher> access_token_fetcher_;
syncer::GCMNetworkChannelDelegate::RequestTokenCallback syncer::GCMNetworkChannelDelegate::RequestTokenCallback
request_token_callback_; request_token_callback_;
bool subscribed_for_incoming_messages_; bool subscribed_for_incoming_messages_;
......
...@@ -61,8 +61,7 @@ TiclInvalidationService::TiclInvalidationService( ...@@ -61,8 +61,7 @@ TiclInvalidationService::TiclInvalidationService(
std::unique_ptr<TiclSettingsProvider> settings_provider, std::unique_ptr<TiclSettingsProvider> settings_provider,
gcm::GCMDriver* gcm_driver, gcm::GCMDriver* gcm_driver,
const scoped_refptr<net::URLRequestContextGetter>& request_context) const scoped_refptr<net::URLRequestContextGetter>& request_context)
: OAuth2TokenService::Consumer("ticl_invalidation"), : user_agent_(user_agent),
user_agent_(user_agent),
identity_provider_(std::move(identity_provider)), identity_provider_(std::move(identity_provider)),
settings_provider_(std::move(settings_provider)), settings_provider_(std::move(settings_provider)),
invalidator_registrar_(new syncer::InvalidatorRegistrar()), invalidator_registrar_(new syncer::InvalidatorRegistrar()),
...@@ -182,7 +181,7 @@ void TiclInvalidationService::RequestDetailedStatus( ...@@ -182,7 +181,7 @@ void TiclInvalidationService::RequestDetailedStatus(
void TiclInvalidationService::RequestAccessToken() { void TiclInvalidationService::RequestAccessToken() {
// Only one active request at a time. // Only one active request at a time.
if (access_token_request_ != nullptr) if (access_token_fetcher_ != nullptr)
return; return;
request_access_token_retry_timer_.Stop(); request_access_token_retry_timer_.Stop();
OAuth2TokenService::ScopeSet oauth2_scopes; OAuth2TokenService::ScopeSet oauth2_scopes;
...@@ -195,16 +194,24 @@ void TiclInvalidationService::RequestAccessToken() { ...@@ -195,16 +194,24 @@ void TiclInvalidationService::RequestAccessToken() {
token_service->InvalidateAccessToken(account_id, oauth2_scopes, token_service->InvalidateAccessToken(account_id, oauth2_scopes,
access_token_); access_token_);
access_token_.clear(); access_token_.clear();
access_token_request_ = access_token_fetcher_ = identity_provider_->FetchAccessToken(
token_service->StartRequest(account_id, oauth2_scopes, this); "ticl_invalidation", oauth2_scopes,
base::BindOnce(&TiclInvalidationService::OnAccessTokenRequestCompleted,
base::Unretained(this)));
} }
void TiclInvalidationService::OnGetTokenSuccess( void TiclInvalidationService::OnAccessTokenRequestCompleted(
const OAuth2TokenService::Request* request, GoogleServiceAuthError error,
const std::string& access_token, std::string access_token) {
const base::Time& expiration_time) { access_token_fetcher_.reset();
DCHECK_EQ(access_token_request_.get(), request); if (error.state() == GoogleServiceAuthError::NONE)
access_token_request_.reset(); OnAccessTokenRequestSucceeded(access_token);
else
OnAccessTokenRequestFailed(error);
}
void TiclInvalidationService::OnAccessTokenRequestSucceeded(
std::string access_token) {
// Reset backoff time after successful response. // Reset backoff time after successful response.
request_access_token_backoff_.Reset(); request_access_token_backoff_.Reset();
access_token_ = access_token; access_token_ = access_token;
...@@ -215,12 +222,9 @@ void TiclInvalidationService::OnGetTokenSuccess( ...@@ -215,12 +222,9 @@ void TiclInvalidationService::OnGetTokenSuccess(
} }
} }
void TiclInvalidationService::OnGetTokenFailure( void TiclInvalidationService::OnAccessTokenRequestFailed(
const OAuth2TokenService::Request* request, GoogleServiceAuthError error) {
const GoogleServiceAuthError& error) {
DCHECK_EQ(access_token_request_.get(), request);
DCHECK_NE(error.state(), GoogleServiceAuthError::NONE); DCHECK_NE(error.state(), GoogleServiceAuthError::NONE);
access_token_request_.reset();
switch (error.state()) { switch (error.state()) {
case GoogleServiceAuthError::CONNECTION_FAILED: case GoogleServiceAuthError::CONNECTION_FAILED:
case GoogleServiceAuthError::SERVICE_UNAVAILABLE: { case GoogleServiceAuthError::SERVICE_UNAVAILABLE: {
...@@ -262,7 +266,7 @@ void TiclInvalidationService::OnActiveAccountRefreshTokenRemoved() { ...@@ -262,7 +266,7 @@ void TiclInvalidationService::OnActiveAccountRefreshTokenRemoved() {
} }
void TiclInvalidationService::OnActiveAccountLogout() { void TiclInvalidationService::OnActiveAccountLogout() {
access_token_request_.reset(); access_token_fetcher_.reset();
request_access_token_retry_timer_.Stop(); request_access_token_retry_timer_.Stop();
if (gcm_invalidation_bridge_) if (gcm_invalidation_bridge_)
......
...@@ -43,7 +43,6 @@ class GCMInvalidationBridge; ...@@ -43,7 +43,6 @@ class GCMInvalidationBridge;
// This InvalidationService wraps the C++ Invalidation Client (TICL) library. // This InvalidationService wraps the C++ Invalidation Client (TICL) library.
// It provides invalidations for desktop platforms (Win, Mac, Linux). // It provides invalidations for desktop platforms (Win, Mac, Linux).
class TiclInvalidationService : public InvalidationService, class TiclInvalidationService : public InvalidationService,
public OAuth2TokenService::Consumer,
public IdentityProvider::Observer, public IdentityProvider::Observer,
public TiclSettingsProvider::Observer, public TiclSettingsProvider::Observer,
public syncer::InvalidationHandler { public syncer::InvalidationHandler {
...@@ -84,12 +83,10 @@ class TiclInvalidationService : public InvalidationService, ...@@ -84,12 +83,10 @@ class TiclInvalidationService : public InvalidationService,
void RequestAccessToken(); void RequestAccessToken();
// OAuth2TokenService::Consumer implementation void OnAccessTokenRequestCompleted(GoogleServiceAuthError error,
void OnGetTokenSuccess(const OAuth2TokenService::Request* request, std::string access_token);
const std::string& access_token, void OnAccessTokenRequestSucceeded(std::string access_token);
const base::Time& expiration_time) override; void OnAccessTokenRequestFailed(GoogleServiceAuthError error);
void OnGetTokenFailure(const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) override;
// IdentityProvider::Observer implementation. // IdentityProvider::Observer implementation.
void OnActiveAccountRefreshTokenUpdated() override; void OnActiveAccountRefreshTokenUpdated() override;
...@@ -137,9 +134,9 @@ class TiclInvalidationService : public InvalidationService, ...@@ -137,9 +134,9 @@ class TiclInvalidationService : public InvalidationService,
// invalidate it with OAuth2TokenService. // invalidate it with OAuth2TokenService.
std::string access_token_; std::string access_token_;
// TiclInvalidationService needs to hold reference to access_token_request_ // TiclInvalidationService needs to hold reference to access_token_fetcher_
// for the duration of request in order to receive callbacks. // for the duration of request in order to receive callbacks.
std::unique_ptr<OAuth2TokenService::Request> access_token_request_; std::unique_ptr<ActiveAccountAccessTokenFetcher> access_token_fetcher_;
base::OneShotTimer request_access_token_retry_timer_; base::OneShotTimer request_access_token_retry_timer_;
net::BackoffEntry request_access_token_backoff_; net::BackoffEntry request_access_token_backoff_;
......
...@@ -6,10 +6,88 @@ ...@@ -6,10 +6,88 @@
namespace invalidation { namespace invalidation {
class ActiveAccountAccessTokenFetcherImpl
: public ActiveAccountAccessTokenFetcher,
OAuth2TokenService::Consumer {
public:
ActiveAccountAccessTokenFetcherImpl(
const std::string& active_account_id,
const std::string& oauth_consumer_name,
OAuth2TokenService* token_service,
const OAuth2TokenService::ScopeSet& scopes,
ActiveAccountAccessTokenCallback callback);
~ActiveAccountAccessTokenFetcherImpl() override = default;
private:
// 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;
// Invokes |callback_| with (|access_token|, |error|).
void HandleTokenRequestCompletion(const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error,
const std::string& access_token);
ActiveAccountAccessTokenCallback callback_;
std::unique_ptr<OAuth2TokenService::Request> access_token_request_;
DISALLOW_COPY_AND_ASSIGN(ActiveAccountAccessTokenFetcherImpl);
};
ActiveAccountAccessTokenFetcherImpl::ActiveAccountAccessTokenFetcherImpl(
const std::string& active_account_id,
const std::string& oauth_consumer_name,
OAuth2TokenService* token_service,
const OAuth2TokenService::ScopeSet& scopes,
ActiveAccountAccessTokenCallback callback)
: OAuth2TokenService::Consumer(oauth_consumer_name),
callback_(std::move(callback)) {
access_token_request_ =
token_service->StartRequest(active_account_id, scopes, this);
}
void ActiveAccountAccessTokenFetcherImpl::OnGetTokenSuccess(
const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) {
HandleTokenRequestCompletion(request, GoogleServiceAuthError::AuthErrorNone(),
access_token);
}
void ActiveAccountAccessTokenFetcherImpl::OnGetTokenFailure(
const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) {
HandleTokenRequestCompletion(request, error, std::string());
}
void ActiveAccountAccessTokenFetcherImpl::HandleTokenRequestCompletion(
const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error,
const std::string& access_token) {
DCHECK_EQ(request, access_token_request_.get());
std::unique_ptr<OAuth2TokenService::Request> request_deleter(
std::move(access_token_request_));
std::move(callback_).Run(error, access_token);
}
IdentityProvider::Observer::~Observer() {} IdentityProvider::Observer::~Observer() {}
IdentityProvider::~IdentityProvider() {} IdentityProvider::~IdentityProvider() {}
std::unique_ptr<ActiveAccountAccessTokenFetcher>
IdentityProvider::FetchAccessToken(const std::string& oauth_consumer_name,
const OAuth2TokenService::ScopeSet& scopes,
ActiveAccountAccessTokenCallback callback) {
return std::make_unique<ActiveAccountAccessTokenFetcherImpl>(
GetActiveAccountId(), oauth_consumer_name, GetTokenService(), scopes,
std::move(callback));
}
void IdentityProvider::AddObserver(Observer* observer) { void IdentityProvider::AddObserver(Observer* observer) {
// See the comment on |num_observers_| in the .h file for why this addition // See the comment on |num_observers_| in the .h file for why this addition
// must happen here. // must happen here.
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <string> #include <string>
#include "base/callback.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/observer_list.h" #include "base/observer_list.h"
...@@ -14,6 +15,18 @@ ...@@ -14,6 +15,18 @@
namespace invalidation { namespace invalidation {
// An opaque object that clients can use to control the lifetime of access
// token requests.
class ActiveAccountAccessTokenFetcher {
public:
ActiveAccountAccessTokenFetcher() = default;
virtual ~ActiveAccountAccessTokenFetcher() = default;
};
using ActiveAccountAccessTokenCallback =
base::OnceCallback<void(GoogleServiceAuthError error,
std::string access_token)>;
// Helper class that provides access to information about the "active GAIA // Helper class that provides access to information about the "active GAIA
// account" with which invalidation should interact. The definition of the // account" with which invalidation should interact. The definition of the
// "active Gaia account is context-dependent": the purpose of this abstraction // "active Gaia account is context-dependent": the purpose of this abstraction
...@@ -58,6 +71,15 @@ class IdentityProvider : public OAuth2TokenService::Observer { ...@@ -58,6 +71,15 @@ class IdentityProvider : public OAuth2TokenService::Observer {
// Gets the token service vending OAuth tokens for all logged-in accounts. // Gets the token service vending OAuth tokens for all logged-in accounts.
virtual OAuth2TokenService* GetTokenService() = 0; virtual OAuth2TokenService* GetTokenService() = 0;
// Starts an access token request for |oauth_consumer_name| and |scopes|. When
// the request completes, |callback| will be invoked with the access token
// or error. To cancel the request, destroy the returned TokenFetcher.
std::unique_ptr<ActiveAccountAccessTokenFetcher> FetchAccessToken(
const std::string& oauth_consumer_name,
const OAuth2TokenService::ScopeSet& scopes,
ActiveAccountAccessTokenCallback callback);
void AddObserver(Observer* observer); void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer); void RemoveObserver(Observer* observer);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment