policy_oauth2_token_fetcher.cc revision f2477e01787aa58f445919b809d89e252beef54f
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. 4 5#include "chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.h" 6 7#include <vector> 8 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.h" 18#include "net/url_request/url_request_context_getter.h" 19 20using content::BrowserThread; 21 22namespace policy { 23 24namespace { 25 26// Max retry count for token fetching requests. 27const int kMaxRequestAttemptCount = 5; 28 29// OAuth token request retry delay in milliseconds. 30const int kRequestRestartDelay = 3000; 31 32} // namespace 33 34PolicyOAuth2TokenFetcher::PolicyOAuth2TokenFetcher( 35 net::URLRequestContextGetter* auth_context_getter, 36 net::URLRequestContextGetter* system_context_getter, 37 const TokenCallback& callback) 38 : auth_context_getter_(auth_context_getter), 39 system_context_getter_(system_context_getter), 40 retry_count_(0), 41 failed_(false), 42 callback_(callback) {} 43 44PolicyOAuth2TokenFetcher::~PolicyOAuth2TokenFetcher() {} 45 46void PolicyOAuth2TokenFetcher::Start() { 47 retry_count_ = 0; 48 StartFetchingRefreshToken(); 49} 50 51void PolicyOAuth2TokenFetcher::StartFetchingRefreshToken() { 52 refresh_token_fetcher_.reset(new GaiaAuthFetcher( 53 this, GaiaConstants::kChromeSource, auth_context_getter_.get())); 54 refresh_token_fetcher_->StartCookieForOAuthLoginTokenExchange(std::string()); 55} 56 57void PolicyOAuth2TokenFetcher::StartFetchingAccessToken() { 58 std::vector<std::string> scopes; 59 scopes.push_back(GaiaConstants::kDeviceManagementServiceOAuth); 60 access_token_fetcher_.reset( 61 new OAuth2AccessTokenFetcher(this, system_context_getter_.get())); 62 access_token_fetcher_->Start( 63 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), 64 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), 65 oauth2_refresh_token_, 66 scopes); 67} 68 69void PolicyOAuth2TokenFetcher::OnClientOAuthSuccess( 70 const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) { 71 VLOG(1) << "OAuth2 tokens for policy fetching succeeded."; 72 oauth2_tokens_ = oauth2_tokens; 73 oauth2_refresh_token_ = oauth2_tokens.refresh_token; 74 retry_count_ = 0; 75 StartFetchingAccessToken(); 76} 77 78void PolicyOAuth2TokenFetcher::OnClientOAuthFailure( 79 const GoogleServiceAuthError& error) { 80 VLOG(1) << "OAuth2 tokens fetch for policy fetch failed!"; 81 RetryOnError(error, 82 base::Bind(&PolicyOAuth2TokenFetcher::StartFetchingRefreshToken, 83 AsWeakPtr())); 84} 85 86void PolicyOAuth2TokenFetcher::OnGetTokenSuccess( 87 const std::string& access_token, 88 const base::Time& expiration_time) { 89 VLOG(1) << "OAuth2 access token (device management) fetching succeeded."; 90 oauth2_access_token_ = access_token; 91 ForwardPolicyToken(access_token, 92 GoogleServiceAuthError(GoogleServiceAuthError::NONE)); 93} 94 95void PolicyOAuth2TokenFetcher::OnGetTokenFailure( 96 const GoogleServiceAuthError& error) { 97 LOG(ERROR) << "OAuth2 access token (device management) fetching failed!"; 98 RetryOnError(error, 99 base::Bind(&PolicyOAuth2TokenFetcher::StartFetchingAccessToken, 100 AsWeakPtr())); 101} 102 103void PolicyOAuth2TokenFetcher::RetryOnError(const GoogleServiceAuthError& error, 104 const base::Closure& task) { 105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 106 if ((error.state() == GoogleServiceAuthError::CONNECTION_FAILED || 107 error.state() == GoogleServiceAuthError::SERVICE_UNAVAILABLE || 108 error.state() == GoogleServiceAuthError::REQUEST_CANCELED) && 109 retry_count_ < kMaxRequestAttemptCount) { 110 retry_count_++; 111 BrowserThread::PostDelayedTask( 112 BrowserThread::UI, FROM_HERE, task, 113 base::TimeDelta::FromMilliseconds(kRequestRestartDelay)); 114 return; 115 } 116 LOG(ERROR) << "Unrecoverable error or retry count max reached."; 117 failed_ = true; 118 // Invoking the |callback_| signals to the owner of this object that it has 119 // completed, and the owner may delete this object on the callback method. 120 // So don't rely on |this| still being valid after ForwardPolicyToken() 121 // returns i.e. don't write to |failed_| or other fields. 122 ForwardPolicyToken(std::string(), error); 123} 124 125void PolicyOAuth2TokenFetcher::ForwardPolicyToken( 126 const std::string& token, 127 const GoogleServiceAuthError& error) { 128 if (!callback_.is_null()) 129 callback_.Run(token, error); 130} 131 132} // namespace policy 133