policy_oauth2_token_fetcher.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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_impl.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 scopes.push_back(GaiaConstants::kOAuthWrapBridgeUserInfoScope); 61 scopes.push_back(GaiaConstants::kGoogleUserInfoEmail); 62 scopes.push_back(GaiaConstants::kGoogleUserInfoProfile); 63 access_token_fetcher_.reset( 64 new OAuth2AccessTokenFetcherImpl(this, 65 system_context_getter_.get(), 66 oauth2_refresh_token_)); 67 access_token_fetcher_->Start( 68 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), 69 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), 70 scopes); 71} 72 73void PolicyOAuth2TokenFetcher::OnClientOAuthSuccess( 74 const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) { 75 VLOG(1) << "OAuth2 tokens for policy fetching succeeded."; 76 oauth2_refresh_token_ = oauth2_tokens.refresh_token; 77 retry_count_ = 0; 78 StartFetchingAccessToken(); 79} 80 81void PolicyOAuth2TokenFetcher::OnClientOAuthFailure( 82 const GoogleServiceAuthError& error) { 83 VLOG(1) << "OAuth2 tokens fetch for policy fetch failed!"; 84 RetryOnError(error, 85 base::Bind(&PolicyOAuth2TokenFetcher::StartFetchingRefreshToken, 86 AsWeakPtr())); 87} 88 89void PolicyOAuth2TokenFetcher::OnGetTokenSuccess( 90 const std::string& access_token, 91 const base::Time& expiration_time) { 92 VLOG(1) << "OAuth2 access token (device management) fetching succeeded."; 93 oauth2_access_token_ = access_token; 94 ForwardPolicyToken(access_token, 95 GoogleServiceAuthError(GoogleServiceAuthError::NONE)); 96} 97 98void PolicyOAuth2TokenFetcher::OnGetTokenFailure( 99 const GoogleServiceAuthError& error) { 100 LOG(ERROR) << "OAuth2 access token (device management) fetching failed!"; 101 RetryOnError(error, 102 base::Bind(&PolicyOAuth2TokenFetcher::StartFetchingAccessToken, 103 AsWeakPtr())); 104} 105 106void PolicyOAuth2TokenFetcher::RetryOnError(const GoogleServiceAuthError& error, 107 const base::Closure& task) { 108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 109 if ((error.state() == GoogleServiceAuthError::CONNECTION_FAILED || 110 error.state() == GoogleServiceAuthError::SERVICE_UNAVAILABLE || 111 error.state() == GoogleServiceAuthError::REQUEST_CANCELED) && 112 retry_count_ < kMaxRequestAttemptCount) { 113 retry_count_++; 114 BrowserThread::PostDelayedTask( 115 BrowserThread::UI, FROM_HERE, task, 116 base::TimeDelta::FromMilliseconds(kRequestRestartDelay)); 117 return; 118 } 119 LOG(ERROR) << "Unrecoverable error or retry count max reached."; 120 failed_ = true; 121 // Invoking the |callback_| signals to the owner of this object that it has 122 // completed, and the owner may delete this object on the callback method. 123 // So don't rely on |this| still being valid after ForwardPolicyToken() 124 // returns i.e. don't write to |failed_| or other fields. 125 ForwardPolicyToken(std::string(), error); 126} 127 128void PolicyOAuth2TokenFetcher::ForwardPolicyToken( 129 const std::string& token, 130 const GoogleServiceAuthError& error) { 131 if (!callback_.is_null()) 132 callback_.Run(token, error); 133} 134 135} // namespace policy 136