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