1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "google_apis/gaia/ubertoken_fetcher.h"
9 #include "base/logging.h"
10 #include "base/rand_util.h"
11 #include "base/time/time.h"
12 #include "google_apis/gaia/gaia_auth_fetcher.h"
13 #include "google_apis/gaia/gaia_constants.h"
14 #include "google_apis/gaia/google_service_auth_error.h"
15 #include "google_apis/gaia/oauth2_token_service.h"
17 const int UbertokenFetcher::kMaxRetries
= 3;
19 UbertokenFetcher::UbertokenFetcher(
20 OAuth2TokenService
* token_service
,
21 UbertokenConsumer
* consumer
,
22 const std::string
& source
,
23 net::URLRequestContextGetter
* request_context
)
24 : OAuth2TokenService::Consumer("uber_token_fetcher"),
25 token_service_(token_service
),
28 request_context_(request_context
),
30 second_access_token_request_(false) {
31 DCHECK(token_service
);
33 DCHECK(request_context
);
36 UbertokenFetcher::~UbertokenFetcher() {
39 void UbertokenFetcher::StartFetchingToken(const std::string
& account_id
) {
40 DCHECK(!account_id
.empty());
41 account_id_
= account_id
;
42 second_access_token_request_
= false;
46 void UbertokenFetcher::OnUberAuthTokenSuccess(const std::string
& token
) {
47 consumer_
->OnUbertokenSuccess(token
);
50 void UbertokenFetcher::OnUberAuthTokenFailure(
51 const GoogleServiceAuthError
& error
) {
52 // Retry only transient errors.
54 error
.state() == GoogleServiceAuthError::CONNECTION_FAILED
||
55 error
.state() == GoogleServiceAuthError::SERVICE_UNAVAILABLE
;
57 if (retry_number_
< kMaxRetries
) {
58 // Calculate an exponential backoff with randomness of less than 1 sec.
59 double backoff
= base::RandDouble() + (1 << retry_number_
);
62 retry_timer_
.Start(FROM_HERE
,
63 base::TimeDelta::FromSecondsD(backoff
),
65 &UbertokenFetcher::ExchangeTokens
);
69 // The access token is invalid. Tell the token service.
70 OAuth2TokenService::ScopeSet scopes
;
71 scopes
.insert(GaiaConstants::kOAuth1LoginScope
);
72 token_service_
->InvalidateToken(account_id_
, scopes
, access_token_
);
74 // In case the access was just stale, try one more time.
75 if (!second_access_token_request_
) {
76 second_access_token_request_
= true;
82 consumer_
->OnUbertokenFailure(error
);
85 void UbertokenFetcher::OnGetTokenSuccess(
86 const OAuth2TokenService::Request
* request
,
87 const std::string
& access_token
,
88 const base::Time
& expiration_time
) {
89 DCHECK(!access_token
.empty());
90 access_token_
= access_token
;
91 access_token_request_
.reset();
95 void UbertokenFetcher::OnGetTokenFailure(
96 const OAuth2TokenService::Request
* request
,
97 const GoogleServiceAuthError
& error
) {
98 access_token_request_
.reset();
99 consumer_
->OnUbertokenFailure(error
);
102 void UbertokenFetcher::RequestAccessToken() {
104 gaia_auth_fetcher_
.reset();
107 OAuth2TokenService::ScopeSet scopes
;
108 scopes
.insert(GaiaConstants::kOAuth1LoginScope
);
109 access_token_request_
=
110 token_service_
->StartRequest(account_id_
, scopes
, this);
113 void UbertokenFetcher::ExchangeTokens() {
114 gaia_auth_fetcher_
.reset(new GaiaAuthFetcher(this,
117 gaia_auth_fetcher_
->StartTokenFetchForUberAuthExchange(access_token_
);