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 15 class GoogleServiceAuthError; 16 class OAuth2MintTokenFlowTest; 17 18 namespace net { 19 class URLFetcher; 20 class 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. 35 class 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 // OAuth2AccessTokenFetcher implementation. 54 virtual void OnGetTokenSuccess(const std::string& access_token, 55 const base::Time& expiration_time) OVERRIDE; 56 virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) OVERRIDE; 57 58 // net::URLFetcherDelegate implementation. 59 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; 60 61 protected: 62 // Template methods for sub-classes. 63 64 // Methods to help create HTTP request. 65 virtual GURL CreateApiCallUrl() = 0; 66 virtual std::string CreateApiCallBody() = 0; 67 68 // Sub-classes can expose an appropriate observer interface by implementing 69 // these template methods. 70 // Called when the API call finished successfully. 71 virtual void ProcessApiCallSuccess(const net::URLFetcher* source) = 0; 72 // Called when the API call failed. 73 virtual void ProcessApiCallFailure(const net::URLFetcher* source) = 0; 74 // Called when a new access token is generated. 75 virtual void ProcessNewAccessToken(const std::string& access_token) = 0; 76 virtual void ProcessMintAccessTokenFailure( 77 const GoogleServiceAuthError& error) = 0; 78 79 private: 80 enum State { 81 INITIAL, 82 API_CALL_STARTED, 83 API_CALL_DONE, 84 MINT_ACCESS_TOKEN_STARTED, 85 MINT_ACCESS_TOKEN_DONE, 86 ERROR_STATE 87 }; 88 89 friend class OAuth2ApiCallFlowTest; 90 FRIEND_TEST_ALL_PREFIXES(OAuth2ApiCallFlowTest, CreateURLFetcher); 91 92 // Helper to create an instance of access token fetcher. 93 // Caller owns the returned instance. 94 // Note that this is virtual since it is mocked during unit testing. 95 virtual OAuth2AccessTokenFetcher* CreateAccessTokenFetcher(); 96 97 // Creates an instance of URLFetcher that does not send or save cookies. 98 // Template method CreateApiCallUrl is used to get the URL. 99 // Template method CreateApiCallBody is used to get the body. 100 // The URLFether's method will be GET if body is empty, POST otherwise. 101 // Caller owns the returned instance. 102 // Note that this is virtual since it is mocked during unit testing. 103 virtual net::URLFetcher* CreateURLFetcher(); 104 105 // Helper methods to implement the state machine for the flow. 106 void BeginApiCall(); 107 void EndApiCall(const net::URLFetcher* source); 108 void BeginMintAccessToken(); 109 void EndMintAccessToken(const GoogleServiceAuthError* error); 110 111 net::URLRequestContextGetter* context_; 112 std::string refresh_token_; 113 std::string access_token_; 114 std::vector<std::string> scopes_; 115 116 State state_; 117 // Whether we have already tried minting an access token once. 118 bool tried_mint_access_token_; 119 120 scoped_ptr<net::URLFetcher> url_fetcher_; 121 scoped_ptr<OAuth2AccessTokenFetcher> oauth2_access_token_fetcher_; 122 123 DISALLOW_COPY_AND_ASSIGN(OAuth2ApiCallFlow); 124 }; 125 126 #endif // GOOGLE_APIS_GAIA_OAUTH2_API_CALL_FLOW_H_ 127