policy_oauth2_token_fetcher.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/chromeos/policy/policy_oauth2_token_fetcher.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <vector> 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "base/bind.h" 1090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/logging.h" 11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/string_util.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/gaia_auth_fetcher.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/gaia_constants.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/gaia_urls.h" 1690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "google_apis/gaia/google_service_auth_error.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/oauth2_access_token_fetcher.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace policy { 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace { 2590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Max retry count for token fetching requests. 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kMaxRequestAttemptCount = 5; 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// OAuth token request retry delay in milliseconds. 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const int kRequestRestartDelay = 3000; 3190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} // namespace 3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)PolicyOAuth2TokenFetcher::PolicyOAuth2TokenFetcher( 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::URLRequestContextGetter* auth_context_getter, 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::URLRequestContextGetter* system_context_getter, 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const TokenCallback& callback) 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : auth_context_getter_(auth_context_getter), 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) system_context_getter_(system_context_getter), 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) retry_count_(0), 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) failed_(false), 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback_(callback) {} 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)PolicyOAuth2TokenFetcher::PolicyOAuth2TokenFetcher( 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::URLRequestContextGetter* system_context_getter, 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& oauth2_refresh_token, 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const TokenCallback& callback) 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : system_context_getter_(system_context_getter), 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) oauth2_refresh_token_(oauth2_refresh_token), 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) retry_count_(0), 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) failed_(false), 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) callback_(callback) {} 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)PolicyOAuth2TokenFetcher::~PolicyOAuth2TokenFetcher() {} 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PolicyOAuth2TokenFetcher::Start() { 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) retry_count_ = 0; 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (oauth2_refresh_token_.empty()) { 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StartFetchingRefreshToken(); 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StartFetchingAccessToken(); 6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PolicyOAuth2TokenFetcher::StartFetchingRefreshToken() { 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!refresh_token_fetcher_.get()); 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) refresh_token_fetcher_.reset( 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new GaiaAuthFetcher(this, 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GaiaConstants::kChromeSource, 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) auth_context_getter_)); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) refresh_token_fetcher_->StartCookieForOAuthLoginTokenExchange(EmptyString()); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PolicyOAuth2TokenFetcher::StartFetchingAccessToken() { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> scopes; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scopes.push_back(GaiaConstants::kDeviceManagementServiceOAuth); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) access_token_fetcher_.reset( 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) new OAuth2AccessTokenFetcher(this, system_context_getter_)); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) access_token_fetcher_->Start( 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GaiaUrls::GetInstance()->oauth2_chrome_client_id(), 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) oauth2_refresh_token_, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scopes); 84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PolicyOAuth2TokenFetcher::OnClientOAuthSuccess( 87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const GaiaAuthConsumer::ClientOAuthResult& oauth2_tokens) { 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LOG(INFO) << "OAuth2 tokens for policy fetching succeeded."; 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) oauth2_tokens_ = oauth2_tokens; 90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) oauth2_refresh_token_ = oauth2_tokens.refresh_token; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) retry_count_ = 0; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartFetchingAccessToken(); 93b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PolicyOAuth2TokenFetcher::OnClientOAuthFailure( 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GoogleServiceAuthError& error) { 97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(ERROR) << "OAuth2 tokens fetch for policy fetch failed!"; 9890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RetryOnError(error, 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&PolicyOAuth2TokenFetcher::StartFetchingRefreshToken, 100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AsWeakPtr())); 101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PolicyOAuth2TokenFetcher::OnGetTokenSuccess( 10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& access_token, 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::Time& expiration_time) { 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LOG(INFO) << "OAuth2 access token (device management) fetching succeeded."; 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ForwardPolicyToken(access_token); 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PolicyOAuth2TokenFetcher::OnGetTokenFailure( 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const GoogleServiceAuthError& error) { 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) LOG(ERROR) << "OAuth2 access token (device management) fetching failed!"; 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) RetryOnError(error, 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::Bind(&PolicyOAuth2TokenFetcher::StartFetchingAccessToken, 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AsWeakPtr())); 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void PolicyOAuth2TokenFetcher::RetryOnError(const GoogleServiceAuthError& error, 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Closure& task) { 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if ((error.state() == GoogleServiceAuthError::CONNECTION_FAILED || 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error.state() == GoogleServiceAuthError::SERVICE_UNAVAILABLE || 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error.state() == GoogleServiceAuthError::REQUEST_CANCELED) && 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) retry_count_ < kMaxRequestAttemptCount) { 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) retry_count_++; 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserThread::PostDelayedTask( 12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) BrowserThread::UI, FROM_HERE, task, 12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::TimeDelta::FromMilliseconds(kRequestRestartDelay)); 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return; 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Unrecoverable error or retry count max reached."; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) failed_ = true; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invoking the |callback_| signals to the owner of this object that it has 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // completed, and the owner may delete this object on the callback method. 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // So don't rely on |this| still being valid after ForwardPolicyToken() 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returns i.e. don't write to |failed_| or other fields. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ForwardPolicyToken(EmptyString()); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PolicyOAuth2TokenFetcher::ForwardPolicyToken(const std::string& token) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback_.Run(token); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace policy 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)