Add a basic settings page with a Polymer paper element which loads at chrome://md...
[chromium-blink-merge.git] / google_apis / gaia / ubertoken_fetcher.cc
blob15e5932bed620498fe8ede7fc2cd6ad2369c987d
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"
7 #include <vector>
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),
26 consumer_(consumer),
27 source_(source),
28 request_context_(request_context),
29 retry_number_(0),
30 second_access_token_request_(false) {
31 DCHECK(token_service);
32 DCHECK(consumer);
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;
43 RequestAccessToken();
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.
53 bool should_retry =
54 error.state() == GoogleServiceAuthError::CONNECTION_FAILED ||
55 error.state() == GoogleServiceAuthError::SERVICE_UNAVAILABLE;
56 if (should_retry) {
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_);
60 ++retry_number_;
61 retry_timer_.Stop();
62 retry_timer_.Start(FROM_HERE,
63 base::TimeDelta::FromSecondsD(backoff),
64 this,
65 &UbertokenFetcher::ExchangeTokens);
66 return;
68 } else {
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;
77 RequestAccessToken();
78 return;
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();
92 ExchangeTokens();
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() {
103 retry_number_ = 0;
104 gaia_auth_fetcher_.reset();
105 retry_timer_.Stop();
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,
115 source_,
116 request_context_));
117 gaia_auth_fetcher_->StartTokenFetchForUberAuthExchange(access_token_);