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_MINT_TOKEN_FLOW_H_
6#define GOOGLE_APIS_GAIA_OAUTH2_MINT_TOKEN_FLOW_H_
7
8#include <string>
9#include <vector>
10
11#include "base/gtest_prod_util.h"
12#include "base/memory/weak_ptr.h"
13#include "base/strings/string16.h"
14#include "google_apis/gaia/oauth2_api_call_flow.h"
15#include "url/gurl.h"
16
17class GoogleServiceAuthError;
18class OAuth2MintTokenFlowTest;
19
20namespace base {
21class DictionaryValue;
22}
23
24namespace content {
25class URLFetcher;
26}
27
28namespace net {
29class URLRequestContextGetter;
30}
31
32// IssueAdvice: messages to show to the user to get a user's approval.
33// The structure is as follows:
34// * Description 1
35//   - Detail 1.1
36//   - Details 1.2
37// * Description 2
38//   - Detail 2.1
39//   - Detail 2.2
40//   - Detail 2.3
41// * Description 3
42//   - Detail 3.1
43struct IssueAdviceInfoEntry {
44 public:
45  IssueAdviceInfoEntry();
46  ~IssueAdviceInfoEntry();
47
48  base::string16 description;
49  std::vector<base::string16> details;
50
51  bool operator==(const IssueAdviceInfoEntry& rhs) const;
52};
53
54typedef std::vector<IssueAdviceInfoEntry> IssueAdviceInfo;
55
56// This class implements the OAuth2 flow to Google to mint an OAuth2
57// token for the given client and the given set of scopes from the
58// OAuthLogin scoped "master" OAuth2 token for the user logged in to
59// Chrome.
60class OAuth2MintTokenFlow : public OAuth2ApiCallFlow {
61 public:
62  // There are four differnt modes when minting a token to grant
63  // access to third-party app for a user.
64  enum Mode {
65    // Get the messages to display to the user without minting a token.
66    MODE_ISSUE_ADVICE,
67    // Record a grant but do not get a token back.
68    MODE_RECORD_GRANT,
69    // Mint a token for an existing grant.
70    MODE_MINT_TOKEN_NO_FORCE,
71    // Mint a token forcefully even if there is no existing grant.
72    MODE_MINT_TOKEN_FORCE,
73  };
74
75  // Parameters needed to mint a token.
76  struct Parameters {
77   public:
78    Parameters();
79    Parameters(const std::string& at,
80               const std::string& eid,
81               const std::string& cid,
82               const std::vector<std::string>& scopes_arg,
83               Mode mode_arg);
84    ~Parameters();
85
86    std::string access_token;
87    std::string extension_id;
88    std::string client_id;
89    std::vector<std::string> scopes;
90    Mode mode;
91  };
92
93  class Delegate {
94   public:
95    virtual void OnMintTokenSuccess(const std::string& access_token,
96                                    int time_to_live) {}
97    virtual void OnIssueAdviceSuccess(const IssueAdviceInfo& issue_advice)  {}
98    virtual void OnMintTokenFailure(const GoogleServiceAuthError& error) {}
99
100   protected:
101    virtual ~Delegate() {}
102  };
103
104  OAuth2MintTokenFlow(net::URLRequestContextGetter* context,
105                      Delegate* delegate,
106                      const Parameters& parameters);
107  virtual ~OAuth2MintTokenFlow();
108
109 protected:
110  // Implementation of template methods in OAuth2ApiCallFlow.
111  virtual GURL CreateApiCallUrl() OVERRIDE;
112  virtual std::string CreateApiCallBody() OVERRIDE;
113
114  virtual void ProcessApiCallSuccess(
115      const net::URLFetcher* source) OVERRIDE;
116  virtual void ProcessApiCallFailure(
117      const net::URLFetcher* source) OVERRIDE;
118  virtual void ProcessNewAccessToken(const std::string& access_token) OVERRIDE;
119  virtual void ProcessMintAccessTokenFailure(
120      const GoogleServiceAuthError& error) OVERRIDE;
121
122 private:
123  friend class OAuth2MintTokenFlowTest;
124  FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, CreateApiCallBody);
125  FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, ParseIssueAdviceResponse);
126  FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, ParseMintTokenResponse);
127  FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, ProcessApiCallSuccess);
128  FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, ProcessApiCallFailure);
129  FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest,
130      ProcessMintAccessTokenFailure);
131
132  void ReportSuccess(const std::string& access_token, int time_to_live);
133  void ReportIssueAdviceSuccess(const IssueAdviceInfo& issue_advice);
134  void ReportFailure(const GoogleServiceAuthError& error);
135
136  static bool ParseIssueAdviceResponse(
137      const base::DictionaryValue* dict, IssueAdviceInfo* issue_advice);
138  static bool ParseMintTokenResponse(
139      const base::DictionaryValue* dict, std::string* access_token,
140      int* time_to_live);
141
142  Delegate* delegate_;
143  Parameters parameters_;
144  base::WeakPtrFactory<OAuth2MintTokenFlow> weak_factory_;
145
146  DISALLOW_COPY_AND_ASSIGN(OAuth2MintTokenFlow);
147};
148
149#endif  // GOOGLE_APIS_GAIA_OAUTH2_MINT_TOKEN_FLOW_H_
150