Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / chromeos / policy / policy_oauth2_token_fetcher.cc
blob45b96c3317c96a23147622454e1483e93c232b89
1 // Copyright (c) 2013 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 "chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.h"
7 #include <vector>
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "base/strings/string_util.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "google_apis/gaia/gaia_auth_fetcher.h"
14 #include "google_apis/gaia/gaia_constants.h"
15 #include "google_apis/gaia/gaia_urls.h"
16 #include "google_apis/gaia/google_service_auth_error.h"
17 #include "google_apis/gaia/oauth2_access_token_fetcher_impl.h"
18 #include "net/url_request/url_request_context_getter.h"
20 using content::BrowserThread;
22 namespace policy {
24 namespace {
26 // Max retry count for token fetching requests.
27 const int kMaxRequestAttemptCount = 5;
29 // OAuth token request retry delay in milliseconds.
30 const int kRequestRestartDelay = 3000;
32 } // namespace
34 PolicyOAuth2TokenFetcher::PolicyOAuth2TokenFetcher() {
37 PolicyOAuth2TokenFetcher::~PolicyOAuth2TokenFetcher() {
40 void PolicyOAuth2TokenFetcher::StartWithSigninContext(
41 net::URLRequestContextGetter* auth_context_getter,
42 net::URLRequestContextGetter* system_context_getter,
43 const TokenCallback& callback) {
44 DCHECK(!refresh_token_fetcher_ && !access_token_fetcher_);
46 auth_context_getter_ = auth_context_getter;
47 system_context_getter_ = system_context_getter;
48 callback_ = callback;
49 StartFetchingRefreshToken();
52 void PolicyOAuth2TokenFetcher::StartWithAuthCode(
53 const std::string& auth_code,
54 net::URLRequestContextGetter* system_context_getter,
55 const TokenCallback& callback) {
56 DCHECK(!refresh_token_fetcher_ && !access_token_fetcher_);
58 auth_code_ = auth_code;
59 system_context_getter_ = system_context_getter;
60 callback_ = callback;
61 StartFetchingRefreshToken();
64 void PolicyOAuth2TokenFetcher::StartWithRefreshToken(
65 const std::string& oauth2_refresh_token,
66 net::URLRequestContextGetter* system_context_getter,
67 const TokenCallback& callback) {
68 DCHECK(!refresh_token_fetcher_ && !access_token_fetcher_);
70 oauth2_refresh_token_ = oauth2_refresh_token;
71 system_context_getter_ = system_context_getter;
72 callback_ = callback;
73 StartFetchingAccessToken();
76 void PolicyOAuth2TokenFetcher::StartFetchingRefreshToken() {
77 if (auth_code_.empty()) {
78 refresh_token_fetcher_.reset(new GaiaAuthFetcher(
79 this, GaiaConstants::kChromeSource, auth_context_getter_.get()));
80 refresh_token_fetcher_->StartCookieForOAuthLoginTokenExchange(
81 std::string());
82 } else {
83 refresh_token_fetcher_.reset(new GaiaAuthFetcher(
84 this, GaiaConstants::kChromeSource, system_context_getter_.get()));
85 refresh_token_fetcher_->StartAuthCodeForOAuth2TokenExchange(auth_code_);
89 void PolicyOAuth2TokenFetcher::StartFetchingAccessToken() {
90 std::vector<std::string> scopes;
91 scopes.push_back(GaiaConstants::kDeviceManagementServiceOAuth);
92 scopes.push_back(GaiaConstants::kOAuthWrapBridgeUserInfoScope);
93 access_token_fetcher_.reset(
94 new OAuth2AccessTokenFetcherImpl(this,
95 system_context_getter_.get(),
96 oauth2_refresh_token_));
97 access_token_fetcher_->Start(
98 GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
99 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
100 scopes);
103 void PolicyOAuth2TokenFetcher::OnClientOAuthSuccess(
104 const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) {
105 VLOG(1) << "OAuth2 tokens for policy fetching succeeded.";
106 oauth2_refresh_token_ = oauth2_tokens.refresh_token;
107 retry_count_ = 0;
108 StartFetchingAccessToken();
111 void PolicyOAuth2TokenFetcher::OnClientOAuthFailure(
112 const GoogleServiceAuthError& error) {
113 VLOG(1) << "OAuth2 tokens fetch for policy fetch failed!";
114 RetryOnError(error,
115 base::Bind(&PolicyOAuth2TokenFetcher::StartFetchingRefreshToken,
116 AsWeakPtr()));
119 void PolicyOAuth2TokenFetcher::OnGetTokenSuccess(
120 const std::string& access_token,
121 const base::Time& expiration_time) {
122 VLOG(1) << "OAuth2 access token (device management) fetching succeeded.";
123 oauth2_access_token_ = access_token;
124 ForwardPolicyToken(access_token,
125 GoogleServiceAuthError(GoogleServiceAuthError::NONE));
128 void PolicyOAuth2TokenFetcher::OnGetTokenFailure(
129 const GoogleServiceAuthError& error) {
130 LOG(ERROR) << "OAuth2 access token (device management) fetching failed!";
131 RetryOnError(error,
132 base::Bind(&PolicyOAuth2TokenFetcher::StartFetchingAccessToken,
133 AsWeakPtr()));
136 void PolicyOAuth2TokenFetcher::RetryOnError(const GoogleServiceAuthError& error,
137 const base::Closure& task) {
138 DCHECK_CURRENTLY_ON(BrowserThread::UI);
139 if (error.IsTransientError() && retry_count_ < kMaxRequestAttemptCount) {
140 retry_count_++;
141 BrowserThread::PostDelayedTask(
142 BrowserThread::UI, FROM_HERE, task,
143 base::TimeDelta::FromMilliseconds(kRequestRestartDelay));
144 return;
146 LOG(ERROR) << "Unrecoverable error or retry count max reached.";
147 failed_ = true;
148 // Invoking the |callback_| signals to the owner of this object that it has
149 // completed, and the owner may delete this object on the callback method.
150 // So don't rely on |this| still being valid after ForwardPolicyToken()
151 // returns i.e. don't write to |failed_| or other fields.
152 ForwardPolicyToken(std::string(), error);
155 void PolicyOAuth2TokenFetcher::ForwardPolicyToken(
156 const std::string& token,
157 const GoogleServiceAuthError& error) {
158 if (!callback_.is_null())
159 callback_.Run(token, error);
162 } // namespace policy