1// Copyright (c) 2012 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#ifndef GOOGLE_APIS_GAIA_OAUTH2_ACCESS_TOKEN_FETCHER_H_ 6#define GOOGLE_APIS_GAIA_OAUTH2_ACCESS_TOKEN_FETCHER_H_ 7 8#include <string> 9#include <vector> 10 11#include "base/gtest_prod_util.h" 12#include "base/memory/scoped_ptr.h" 13#include "google_apis/gaia/oauth2_access_token_consumer.h" 14#include "net/url_request/url_fetcher_delegate.h" 15#include "url/gurl.h" 16 17class OAuth2AccessTokenFetcherTest; 18 19namespace base { 20class Time; 21} 22 23namespace net { 24class URLFetcher; 25class URLRequestContextGetter; 26class URLRequestStatus; 27} 28 29// Abstracts the details to get OAuth2 access token token from 30// OAuth2 refresh token. 31// See "Using the Refresh Token" section in: 32// http://code.google.com/apis/accounts/docs/OAuth2WebServer.html 33// 34// This class should be used on a single thread, but it can be whichever thread 35// that you like. 36// Also, do not reuse the same instance. Once Start() is called, the instance 37// should not be reused. 38// 39// Usage: 40// * Create an instance with a consumer. 41// * Call Start() 42// * The consumer passed in the constructor will be called on the same 43// thread Start was called with the results. 44// 45// This class can handle one request at a time. To parallelize requests, 46// create multiple instances. 47class OAuth2AccessTokenFetcher : public net::URLFetcherDelegate { 48 public: 49 OAuth2AccessTokenFetcher(OAuth2AccessTokenConsumer* consumer, 50 net::URLRequestContextGetter* getter); 51 virtual ~OAuth2AccessTokenFetcher(); 52 53 // Starts the flow with the given parameters. 54 // |scopes| can be empty. If it is empty then the access token will have the 55 // same scope as the refresh token. If not empty, then access token will have 56 // the scopes specified. In this case, the access token will successfully be 57 // generated only if refresh token has login scope of a list of scopes that is 58 // a super-set of the specified scopes. 59 virtual void Start(const std::string& client_id, 60 const std::string& client_secret, 61 const std::string& refresh_token, 62 const std::vector<std::string>& scopes); 63 64 void CancelRequest(); 65 66 // Implementation of net::URLFetcherDelegate 67 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 68 69 private: 70 enum State { 71 INITIAL, 72 GET_ACCESS_TOKEN_STARTED, 73 GET_ACCESS_TOKEN_DONE, 74 ERROR_STATE, 75 }; 76 77 // Helper methods for the flow. 78 void StartGetAccessToken(); 79 void EndGetAccessToken(const net::URLFetcher* source); 80 81 // Helper mehtods for reporting back results. 82 void OnGetTokenSuccess(const std::string& access_token, 83 const base::Time& expiration_time); 84 void OnGetTokenFailure(const GoogleServiceAuthError& error); 85 86 // Other helpers. 87 static GURL MakeGetAccessTokenUrl(); 88 static std::string MakeGetAccessTokenBody( 89 const std::string& client_id, 90 const std::string& client_secret, 91 const std::string& refresh_token, 92 const std::vector<std::string>& scopes); 93 94 static bool ParseGetAccessTokenSuccessResponse( 95 const net::URLFetcher* source, 96 std::string* access_token, 97 int* expires_in); 98 99 static bool ParseGetAccessTokenFailureResponse( 100 const net::URLFetcher* source, 101 std::string* error); 102 103 // State that is set during construction. 104 OAuth2AccessTokenConsumer* const consumer_; 105 net::URLRequestContextGetter* const getter_; 106 State state_; 107 108 // While a fetch is in progress. 109 scoped_ptr<net::URLFetcher> fetcher_; 110 std::string client_id_; 111 std::string client_secret_; 112 std::string refresh_token_; 113 std::vector<std::string> scopes_; 114 115 friend class OAuth2AccessTokenFetcherTest; 116 FRIEND_TEST_ALL_PREFIXES(OAuth2AccessTokenFetcherTest, 117 ParseGetAccessTokenResponse); 118 FRIEND_TEST_ALL_PREFIXES(OAuth2AccessTokenFetcherTest, 119 MakeGetAccessTokenBody); 120 121 DISALLOW_COPY_AND_ASSIGN(OAuth2AccessTokenFetcher); 122}; 123 124#endif // GOOGLE_APIS_GAIA_OAUTH2_ACCESS_TOKEN_FETCHER_H_ 125