oauth2_api_call_flow.h revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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_API_CALL_FLOW_H_ 6#define GOOGLE_APIS_GAIA_OAUTH2_API_CALL_FLOW_H_ 7 8#include <string> 9 10#include "base/memory/scoped_ptr.h" 11#include "google_apis/gaia/oauth2_access_token_consumer.h" 12#include "google_apis/gaia/oauth2_access_token_fetcher.h" 13#include "net/url_request/url_fetcher_delegate.h" 14 15class GoogleServiceAuthError; 16class OAuth2MintTokenFlowTest; 17 18namespace net { 19class URLFetcher; 20class URLRequestContextGetter; 21} 22 23// Base class for all classes that implement a flow to call OAuth2 24// enabled APIs. 25// 26// Given a refresh token, an access token, and a list of scopes an OAuth2 27// enabled API is called in the following way: 28// 1. Try the given access token to call the API. 29// 2. If that does not work, use the refresh token and scopes to generate 30// a new access token. 31// 3. Try the new access token to call the API. 32// 33// This class abstracts the basic steps and exposes template methods 34// for sub-classes to implement for API specific details. 35class OAuth2ApiCallFlow 36 : public net::URLFetcherDelegate, 37 public OAuth2AccessTokenConsumer { 38 public: 39 // Creates an instance that works with the given data. 40 // Note that |access_token| can be empty. In that case, the flow will skip 41 // the first step (of trying an existing access token). 42 OAuth2ApiCallFlow( 43 net::URLRequestContextGetter* context, 44 const std::string& refresh_token, 45 const std::string& access_token, 46 const std::vector<std::string>& scopes); 47 48 virtual ~OAuth2ApiCallFlow(); 49 50 // Start the flow. 51 virtual void Start(); 52 53#if defined(OS_CHROMEOS) 54 void SetChromeOAuthClientInfo(const std::string& chrome_client_id, 55 const std::string& chrome_client_secret); 56#endif 57 58 // OAuth2AccessTokenFetcher implementation. 59 virtual void OnGetTokenSuccess(const std::string& access_token, 60 const base::Time& expiration_time) OVERRIDE; 61 virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) OVERRIDE; 62 63 // net::URLFetcherDelegate implementation. 64 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 65 66 protected: 67 // Template methods for sub-classes. 68 69 // Methods to help create HTTP request. 70 virtual GURL CreateApiCallUrl() = 0; 71 virtual std::string CreateApiCallBody() = 0; 72 73 // Sub-classes can expose an appropriate observer interface by implementing 74 // these template methods. 75 // Called when the API call finished successfully. 76 virtual void ProcessApiCallSuccess(const net::URLFetcher* source) = 0; 77 // Called when the API call failed. 78 virtual void ProcessApiCallFailure(const net::URLFetcher* source) = 0; 79 // Called when a new access token is generated. 80 virtual void ProcessNewAccessToken(const std::string& access_token) = 0; 81 virtual void ProcessMintAccessTokenFailure( 82 const GoogleServiceAuthError& error) = 0; 83 84 private: 85 enum State { 86 INITIAL, 87 API_CALL_STARTED, 88 API_CALL_DONE, 89 MINT_ACCESS_TOKEN_STARTED, 90 MINT_ACCESS_TOKEN_DONE, 91 ERROR_STATE 92 }; 93 94 friend class OAuth2ApiCallFlowTest; 95 FRIEND_TEST_ALL_PREFIXES(OAuth2ApiCallFlowTest, CreateURLFetcher); 96 97 // Helper to create an instance of access token fetcher. 98 // Caller owns the returned instance. 99 // Note that this is virtual since it is mocked during unit testing. 100 virtual OAuth2AccessTokenFetcher* CreateAccessTokenFetcher(); 101 102 // Creates an instance of URLFetcher that does not send or save cookies. 103 // Template method CreateApiCallUrl is used to get the URL. 104 // Template method CreateApiCallBody is used to get the body. 105 // The URLFether's method will be GET if body is empty, POST otherwise. 106 // Caller owns the returned instance. 107 // Note that this is virtual since it is mocked during unit testing. 108 virtual net::URLFetcher* CreateURLFetcher(); 109 110 // Helper methods to implement the state machine for the flow. 111 void BeginApiCall(); 112 void EndApiCall(const net::URLFetcher* source); 113 void BeginMintAccessToken(); 114 void EndMintAccessToken(const GoogleServiceAuthError* error); 115 116 net::URLRequestContextGetter* context_; 117 std::string refresh_token_; 118 std::string access_token_; 119 std::vector<std::string> scopes_; 120 121 // Override values for the main chrome client id and secret. 122 std::string chrome_client_id_; 123 std::string chrome_client_secret_; 124 125 State state_; 126 // Whether we have already tried minting an access token once. 127 bool tried_mint_access_token_; 128 129 scoped_ptr<net::URLFetcher> url_fetcher_; 130 scoped_ptr<OAuth2AccessTokenFetcher> oauth2_access_token_fetcher_; 131 132 DISALLOW_COPY_AND_ASSIGN(OAuth2ApiCallFlow); 133}; 134 135#endif // GOOGLE_APIS_GAIA_OAUTH2_API_CALL_FLOW_H_ 136