oauth2_mint_token_flow.h 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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. #ifndef GOOGLE_APIS_GAIA_OAUTH2_MINT_TOKEN_FLOW_H_
  5. #define GOOGLE_APIS_GAIA_OAUTH2_MINT_TOKEN_FLOW_H_
  6. #include <set>
  7. #include <string>
  8. #include <vector>
  9. #include "base/gtest_prod_util.h"
  10. #include "base/memory/raw_ptr.h"
  11. #include "base/memory/weak_ptr.h"
  12. #include "google_apis/gaia/oauth2_api_call_flow.h"
  13. #include "net/cookies/canonical_cookie.h"
  14. #include "services/network/public/mojom/url_response_head.mojom-forward.h"
  15. #include "url/gurl.h"
  16. class GoogleServiceAuthError;
  17. class OAuth2MintTokenFlowTest;
  18. namespace base {
  19. class Value;
  20. }
  21. extern const char kOAuth2MintTokenApiCallResultHistogram[];
  22. // Values carrying the result of processing a successful API call.
  23. // These values are persisted to logs. Entries should not be renumbered and
  24. // numeric values should never be reused.
  25. enum class OAuth2MintTokenApiCallResult {
  26. kMintTokenSuccess = 0,
  27. // DEPRECATED:
  28. // kIssueAdviceSuccess = 1,
  29. kRemoteConsentSuccess = 2,
  30. kApiCallFailure = 3,
  31. kParseJsonFailure = 4,
  32. kIssueAdviceKeyNotFoundFailure = 5,
  33. kParseMintTokenFailure = 6,
  34. // DEPRECATED:
  35. // kParseIssueAdviceFailure = 7,
  36. // DEPRECATED:
  37. // kRemoteConsentFallback = 8
  38. kParseRemoteConsentFailure = 9,
  39. // DEPRECATED:
  40. // kMintTokenSuccessWithFallbackScopes = 10,
  41. kMaxValue = kParseRemoteConsentFailure
  42. };
  43. // Data for the remote consent resolution:
  44. // - URL of the consent page to be displayed to the user.
  45. // - Cookies that should be set before navigating to that URL.
  46. struct RemoteConsentResolutionData {
  47. RemoteConsentResolutionData();
  48. ~RemoteConsentResolutionData();
  49. RemoteConsentResolutionData(const RemoteConsentResolutionData& other);
  50. RemoteConsentResolutionData& operator=(
  51. const RemoteConsentResolutionData& other);
  52. GURL url;
  53. net::CookieList cookies;
  54. bool operator==(const RemoteConsentResolutionData& rhs) const;
  55. };
  56. // This class implements the OAuth2 flow to Google to mint an OAuth2 access
  57. // token for the given client and the given set of scopes from the OAuthLogin
  58. // scoped "master" OAuth2 token for the user logged in to Chrome.
  59. class OAuth2MintTokenFlow : public OAuth2ApiCallFlow {
  60. public:
  61. // There are four different modes when minting a token to grant
  62. // access to third-party app for a user.
  63. enum Mode {
  64. // Get the messages to display to the user without minting a token.
  65. MODE_ISSUE_ADVICE,
  66. // Record a grant but do not get a token back.
  67. MODE_RECORD_GRANT,
  68. // Mint a token for an existing grant.
  69. MODE_MINT_TOKEN_NO_FORCE,
  70. // Mint a token forcefully even if there is no existing grant.
  71. MODE_MINT_TOKEN_FORCE,
  72. };
  73. // Parameters needed to mint a token.
  74. struct Parameters {
  75. public:
  76. Parameters();
  77. Parameters(const std::string& eid,
  78. const std::string& cid,
  79. const std::vector<std::string>& scopes_arg,
  80. bool enable_granular_permissions,
  81. const std::string& device_id,
  82. const std::string& selected_user_id,
  83. const std::string& consent_result,
  84. const std::string& version,
  85. const std::string& channel,
  86. Mode mode_arg);
  87. Parameters(const Parameters& other);
  88. ~Parameters();
  89. std::string extension_id;
  90. std::string client_id;
  91. std::vector<std::string> scopes;
  92. bool enable_granular_permissions;
  93. std::string device_id;
  94. std::string selected_user_id;
  95. std::string consent_result;
  96. std::string version;
  97. std::string channel;
  98. Mode mode;
  99. };
  100. class Delegate {
  101. public:
  102. virtual void OnMintTokenSuccess(const std::string& access_token,
  103. const std::set<std::string>& granted_scopes,
  104. int time_to_live) {}
  105. virtual void OnMintTokenFailure(const GoogleServiceAuthError& error) {}
  106. virtual void OnRemoteConsentSuccess(
  107. const RemoteConsentResolutionData& resolution_data) {}
  108. protected:
  109. virtual ~Delegate() {}
  110. };
  111. OAuth2MintTokenFlow(Delegate* delegate, const Parameters& parameters);
  112. OAuth2MintTokenFlow(const OAuth2MintTokenFlow&) = delete;
  113. OAuth2MintTokenFlow& operator=(const OAuth2MintTokenFlow&) = delete;
  114. ~OAuth2MintTokenFlow() override;
  115. protected:
  116. // Implementation of template methods in OAuth2ApiCallFlow.
  117. GURL CreateApiCallUrl() override;
  118. std::string CreateApiCallBody() override;
  119. void ProcessApiCallSuccess(const network::mojom::URLResponseHead* head,
  120. std::unique_ptr<std::string> body) override;
  121. void ProcessApiCallFailure(int net_error,
  122. const network::mojom::URLResponseHead* head,
  123. std::unique_ptr<std::string> body) override;
  124. net::PartialNetworkTrafficAnnotationTag GetNetworkTrafficAnnotationTag()
  125. override;
  126. private:
  127. friend class OAuth2MintTokenFlowTest;
  128. FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, CreateApiCallBody);
  129. FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, ParseIssueAdviceResponse);
  130. FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, ParseRemoteConsentResponse);
  131. FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest,
  132. ParseRemoteConsentResponse_EmptyCookies);
  133. FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest,
  134. ParseRemoteConsentResponse_NoResolutionData);
  135. FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest,
  136. ParseRemoteConsentResponse_NoUrl);
  137. FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest,
  138. ParseRemoteConsentResponse_BadUrl);
  139. FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest,
  140. ParseRemoteConsentResponse_NoApproach);
  141. FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest,
  142. ParseRemoteConsentResponse_BadApproach);
  143. FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest,
  144. ParseRemoteConsentResponse_NoCookies);
  145. FRIEND_TEST_ALL_PREFIXES(
  146. OAuth2MintTokenFlowTest,
  147. ParseRemoteConsentResponse_BadCookie_MissingRequiredField);
  148. FRIEND_TEST_ALL_PREFIXES(
  149. OAuth2MintTokenFlowTest,
  150. ParseRemoteConsentResponse_MissingCookieOptionalField);
  151. FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest,
  152. ParseRemoteConsentResponse_BadCookie_BadMaxAge);
  153. FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest,
  154. ParseRemoteConsentResponse_BadCookieList);
  155. FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, ParseMintTokenResponse);
  156. void ReportSuccess(const std::string& access_token,
  157. const std::set<std::string>& granted_scopes,
  158. int time_to_live);
  159. void ReportRemoteConsentSuccess(
  160. const RemoteConsentResolutionData& resolution_data);
  161. void ReportFailure(const GoogleServiceAuthError& error);
  162. static bool ParseRemoteConsentResponse(
  163. const base::Value* dict,
  164. RemoteConsentResolutionData* resolution_data);
  165. // Currently, grantedScopes is a new parameter for an unlaunched feature, so
  166. // it may not always be populated in server responses. In those cases,
  167. // ParseMintTokenResponse can still succeed and will just leave the
  168. // granted_scopes set unmodified. When the grantedScopes parameter is present
  169. // and the function returns true, granted_scopes will include the scopes
  170. // returned by the server. Once the feature is fully launched, this function
  171. // will be updated to fail if the grantedScopes parameter is missing.
  172. static bool ParseMintTokenResponse(const base::Value* dict,
  173. std::string* access_token,
  174. std::set<std::string>* granted_scopes,
  175. int* time_to_live);
  176. raw_ptr<Delegate> delegate_;
  177. Parameters parameters_;
  178. base::WeakPtrFactory<OAuth2MintTokenFlow> weak_factory_{this};
  179. };
  180. #endif // GOOGLE_APIS_GAIA_OAUTH2_MINT_TOKEN_FLOW_H_