gaia_oauth_client.cc revision 868fa2fe829687343ffae624259930155e16dbd8
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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 "google_apis/gaia/gaia_oauth_client.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_reader.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/gaia_urls.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "googleurl/src/gurl.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_status_code.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kAccessTokenValue[] = "access_token"; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kRefreshTokenValue[] = "refresh_token"; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kExpiresInValue[] = "expires_in"; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gaia { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GaiaOAuthClient::Core 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public base::RefCountedThreadSafe<GaiaOAuthClient::Core>, 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public net::URLFetcherDelegate { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Core(const std::string& gaia_url, 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequestContextGetter* request_context_getter) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : gaia_url_(gaia_url), 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_retries_(0), 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_context_getter_(request_context_getter), 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_(NULL), 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_type_(NO_PENDING_REQUEST) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void GetTokensFromAuthCode(const OAuthClientInfo& oauth_client_info, 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& auth_code, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_retries, 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GaiaOAuthClient::Delegate* delegate); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RefreshToken(const OAuthClientInfo& oauth_client_info, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& refresh_token, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_retries, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GaiaOAuthClient::Delegate* delegate); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void GetUserInfo(const std::string& oauth_access_token, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_retries, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Delegate* delegate); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // net::URLFetcherDelegate implementation. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCountedThreadSafe<Core>; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum RequestType { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NO_PENDING_REQUEST, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TOKENS_FROM_AUTH_CODE, 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REFRESH_TOKEN, 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USER_INFO, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Core() {} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void MakeGaiaRequest(const std::string& post_body, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_retries, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GaiaOAuthClient::Delegate* delegate); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void HandleResponse(const net::URLFetcher* source, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* should_retry_request); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL gaia_url_; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_retries_; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> request_context_getter_; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GaiaOAuthClient::Delegate* delegate_; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<net::URLFetcher> request_; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RequestType request_type_; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GaiaOAuthClient::Core::GetTokensFromAuthCode( 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OAuthClientInfo& oauth_client_info, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& auth_code, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_retries, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GaiaOAuthClient::Delegate* delegate) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(request_type_, NO_PENDING_REQUEST); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_type_ = TOKENS_FROM_AUTH_CODE; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string post_body = 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "code=" + net::EscapeUrlEncodedData(auth_code, true) + 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "&client_id=" + net::EscapeUrlEncodedData(oauth_client_info.client_id, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true) + 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "&client_secret=" + 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::EscapeUrlEncodedData(oauth_client_info.client_secret, true) + 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "&redirect_uri=" + 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::EscapeUrlEncodedData(oauth_client_info.redirect_uri, true) + 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "&grant_type=authorization_code"; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeGaiaRequest(post_body, max_retries, delegate); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GaiaOAuthClient::Core::RefreshToken( 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OAuthClientInfo& oauth_client_info, 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& refresh_token, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_retries, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GaiaOAuthClient::Delegate* delegate) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(request_type_, NO_PENDING_REQUEST); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_type_ = REFRESH_TOKEN; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string post_body = 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "refresh_token=" + net::EscapeUrlEncodedData(refresh_token, true) + 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "&client_id=" + net::EscapeUrlEncodedData(oauth_client_info.client_id, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true) + 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "&client_secret=" + 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::EscapeUrlEncodedData(oauth_client_info.client_secret, true) + 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "&grant_type=refresh_token"; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MakeGaiaRequest(post_body, max_retries, delegate); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GaiaOAuthClient::Core::GetUserInfo(const std::string& oauth_access_token, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_retries, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Delegate* delegate) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(request_type_, NO_PENDING_REQUEST); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!request_.get()); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_type_ = USER_INFO; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_ = delegate; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_retries_ = 0; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_.reset(net::URLFetcher::Create( 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, GURL(GaiaUrls::GetInstance()->oauth_user_info_url()), 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLFetcher::GET, this)); 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_->SetRequestContext(request_context_getter_.get()); 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_->AddExtraRequestHeader("Authorization: OAuth " + oauth_access_token); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->SetMaxRetriesOn5xx(max_retries); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Fetchers are sometimes cancelled because a network change was detected, 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // especially at startup and after sign-in on ChromeOS. Retrying once should 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // be enough in those cases; let the fetcher retry up to 3 times just in case. 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // http://crbug.com/163710 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->SetAutomaticallyRetryOnNetworkChanges(3); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->Start(); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GaiaOAuthClient::Core::MakeGaiaRequest( 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& post_body, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_retries, 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GaiaOAuthClient::Delegate* delegate) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!request_.get()) << "Tried to fetch two things at once!"; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_ = delegate; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_retries_ = 0; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_.reset(net::URLFetcher::Create( 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, gaia_url_, net::URLFetcher::POST, this)); 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_->SetRequestContext(request_context_getter_.get()); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->SetUploadData("application/x-www-form-urlencoded", post_body); 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->SetMaxRetriesOn5xx(max_retries); 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // See comment on SetAutomaticallyRetryOnNetworkChanges() above. 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_->SetAutomaticallyRetryOnNetworkChanges(3); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->Start(); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// URLFetcher::Delegate implementation. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GaiaOAuthClient::Core::OnURLFetchComplete( 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::URLFetcher* source) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool should_retry = false; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HandleResponse(source, &should_retry); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (should_retry) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Explicitly call ReceivedContentWasMalformed() to ensure the current 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // request gets counted as a failure for calculation of the back-off 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // period. If it was already a failure by status code, this call will 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be ignored. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->ReceivedContentWasMalformed(); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_retries_++; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We must set our request_context_getter_ again because 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URLFetcher::Core::RetryOrCompleteUrlFetch resets it to NULL... 170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request_->SetRequestContext(request_context_getter_.get()); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->Start(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GaiaOAuthClient::Core::HandleResponse( 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::URLFetcher* source, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* should_retry_request) { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Keep the URLFetcher object in case we need to reuse it. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<net::URLFetcher> old_request = request_.Pass(); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(source, old_request.get()); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RC_BAD_REQUEST means the arguments are invalid. No point retrying. We are 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // done here. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (source->GetResponseCode() == net::HTTP_BAD_REQUEST) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnOAuthError(); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<DictionaryValue> response_dict; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (source->GetResponseCode() == net::HTTP_OK) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string data; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source->GetResponseAsString(&data); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<Value> message_value(base::JSONReader::Read(data)); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message_value.get() && 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_value->IsType(Value::TYPE_DICTIONARY)) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_dict.reset( 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<DictionaryValue*>(message_value.release())); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!response_dict.get()) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we don't have an access token yet and the the error was not 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // RC_BAD_REQUEST, we may need to retry. 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((source->GetMaxRetriesOn5xx() != -1) && 205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) (num_retries_ >= source->GetMaxRetriesOn5xx())) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Retry limit reached. Give up. 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnNetworkError(source->GetResponseCode()); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_ = old_request.Pass(); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *should_retry_request = true; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RequestType type = request_type_; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_type_ = NO_PENDING_REQUEST; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case USER_INFO: { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string email; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_dict->GetString("email", &email); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnGetUserInfoResponse(email); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TOKENS_FROM_AUTH_CODE: 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case REFRESH_TOKEN: { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string access_token; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string refresh_token; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int expires_in_seconds = 0; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_dict->GetString(kAccessTokenValue, &access_token); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_dict->GetString(kRefreshTokenValue, &refresh_token); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) response_dict->GetInteger(kExpiresInValue, &expires_in_seconds); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (access_token.empty()) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnOAuthError(); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (type == REFRESH_TOKEN) { 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnRefreshTokenResponse(access_token, expires_in_seconds); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate_->OnGetTokensResponse(refresh_token, 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) access_token, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expires_in_seconds); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GaiaOAuthClient::GaiaOAuthClient(const std::string& gaia_url, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequestContextGetter* context_getter) { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_ = new Core(gaia_url, context_getter); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GaiaOAuthClient::~GaiaOAuthClient() { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GaiaOAuthClient::GetTokensFromAuthCode( 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const OAuthClientInfo& oauth_client_info, 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& auth_code, 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_retries, 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Delegate* delegate) { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return core_->GetTokensFromAuthCode(oauth_client_info, 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_code, 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_retries, 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GaiaOAuthClient::RefreshToken(const OAuthClientInfo& oauth_client_info, 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& refresh_token, 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_retries, 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Delegate* delegate) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return core_->RefreshToken(oauth_client_info, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) refresh_token, 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_retries, 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GaiaOAuthClient::GetUserInfo(const std::string& access_token, 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_retries, 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Delegate* delegate) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return core_->GetUserInfo(access_token, max_retries, delegate); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gaia 291