| Index: blimp/client/core/session/identity_source.cc
|
| diff --git a/blimp/client/core/session/identity_source.cc b/blimp/client/core/session/identity_source.cc
|
| index 48b96f4154863c698a969c928957f3fbc16b9537..fba87f01d0bff9e6d393eb59a35483143af85be8 100644
|
| --- a/blimp/client/core/session/identity_source.cc
|
| +++ b/blimp/client/core/session/identity_source.cc
|
| @@ -4,7 +4,9 @@
|
|
|
| #include "blimp/client/core/session/identity_source.h"
|
|
|
| +#include "base/command_line.h"
|
| #include "base/memory/ptr_util.h"
|
| +#include "blimp/client/core/blimp_client_switches.h"
|
|
|
| namespace blimp {
|
| namespace client {
|
| @@ -13,6 +15,9 @@ namespace {
|
| // OAuth2 token scope.
|
| const char kOAuth2TokenScope[] =
|
| "https://www.googleapis.com/auth/userinfo.email";
|
| +
|
| +// Max retry times when OAuth2 token request is canceled.
|
| +const int kTokenRequestCancelMaxRetry = 3;
|
| } // namespace
|
|
|
| IdentitySource::IdentitySource(BlimpClientContextDelegate* delegate,
|
| @@ -20,6 +25,7 @@ IdentitySource::IdentitySource(BlimpClientContextDelegate* delegate,
|
| : OAuth2TokenService::Consumer("blimp_client"),
|
| token_callback_(callback),
|
| is_fetching_token_(false),
|
| + retry_times_(0),
|
| delegate_(delegate) {
|
| DCHECK(delegate_);
|
|
|
| @@ -39,9 +45,16 @@ void IdentitySource::Connect() {
|
| return;
|
| }
|
|
|
| - const std::string& account_id = identity_provider_->GetActiveAccountId();
|
| + // Pass empty token to assignment source if we have command line switches.
|
| + if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEngineIP)) {
|
| + if (token_callback_) {
|
| + token_callback_.Run(std::string());
|
| + }
|
| + return;
|
| + }
|
|
|
| - // User must sign in first.
|
| + // User must sign in first to get an OAuth2 token.
|
| + const std::string& account_id = identity_provider_->GetActiveAccountId();
|
| if (account_id.empty()) {
|
| delegate_->OnAuthenticationError(
|
| BlimpClientContextDelegate::AuthError::NOT_SIGNED_IN);
|
| @@ -53,12 +66,25 @@ void IdentitySource::Connect() {
|
| FetchAuthToken();
|
| }
|
|
|
| +// Add sign in state observer.
|
| +void IdentitySource::AddObserver(IdentityProvider::Observer* observer) {
|
| + DCHECK(identity_provider_);
|
| + identity_provider_->AddObserver(observer);
|
| +}
|
| +
|
| +// Remove sign in state observer.
|
| +void IdentitySource::RemoveObserver(IdentityProvider::Observer* observer) {
|
| + DCHECK(identity_provider_);
|
| + identity_provider_->RemoveObserver(observer);
|
| +}
|
| +
|
| void IdentitySource::OnGetTokenSuccess(
|
| const OAuth2TokenService::Request* request,
|
| const std::string& access_token,
|
| const base::Time& expiration_time) {
|
| token_request_.reset();
|
| is_fetching_token_ = false;
|
| + retry_times_ = 0;
|
|
|
| if (token_callback_) {
|
| token_callback_.Run(access_token);
|
| @@ -70,8 +96,26 @@ void IdentitySource::OnGetTokenFailure(
|
| const OAuth2TokenService::Request* request,
|
| const GoogleServiceAuthError& error) {
|
| token_request_.reset();
|
| - is_fetching_token_ = false;
|
|
|
| + // Retry the request.
|
| + // The embedder can invalidate the refresh token at any time, this happens
|
| + // during application start up or when user switches account.
|
| + // OnGetTokenFailure will be called and the error code is REQUEST_CANCELED.
|
| + if (error.state() == GoogleServiceAuthError::State::REQUEST_CANCELED &&
|
| + retry_times_ < kTokenRequestCancelMaxRetry) {
|
| + retry_times_++;
|
| + VLOG(1) << "Retrying to get OAuth2 token due to request cancellation. "
|
| + "retry time = "
|
| + << retry_times_;
|
| + FetchAuthToken();
|
| + return;
|
| + }
|
| +
|
| + // If request failure was not caused by cancellation, or reached max retry
|
| + // times on request cancellation, propagate the error to embedder.
|
| + is_fetching_token_ = false;
|
| + retry_times_ = 0;
|
| + VLOG(1) << "OAuth2 token error: " << error.state();
|
| DCHECK(delegate_);
|
| delegate_->OnAuthenticationError(
|
| BlimpClientContextDelegate::AuthError::OAUTH_TOKEN_FAIL);
|
|
|