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