• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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