Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef CHROME_COMMON_NET_GAIA_OAUTH2_MINT_TOKEN_FLOW_H_ | 5 #ifndef CHROME_COMMON_NET_GAIA_OAUTH2_MINT_TOKEN_FLOW_H_ |
| 6 #define CHROME_COMMON_NET_GAIA_OAUTH2_MINT_TOKEN_FLOW_H_ | 6 #define CHROME_COMMON_NET_GAIA_OAUTH2_MINT_TOKEN_FLOW_H_ |
| 7 | 7 |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | |
| 9 | 10 |
| 10 #include "base/memory/scoped_ptr.h" | 11 #include "chrome/common/net/gaia/oauth2_api_call_flow.h" |
| 11 #include "base/memory/weak_ptr.h" | |
| 12 #include "chrome/common/net/gaia/oauth2_access_token_consumer.h" | |
| 13 #include "chrome/common/net/gaia/oauth2_access_token_fetcher.h" | |
| 14 #include "chrome/common/net/gaia/oauth2_mint_token_consumer.h" | |
| 15 #include "chrome/common/net/gaia/oauth2_mint_token_fetcher.h" | |
| 16 | 12 |
| 17 class GoogleServiceAuthError; | 13 class GoogleServiceAuthError; |
| 18 class OAuth2MintTokenFlowTest; | 14 class OAuth2MintTokenFlowTest; |
| 19 | 15 |
| 16 namespace base { | |
| 17 class DictionaryValue; | |
| 18 } | |
| 19 | |
| 20 namespace content { | |
| 21 class URLFetcher; | |
| 22 } | |
| 23 | |
| 20 namespace net { | 24 namespace net { |
| 21 class URLRequestContextGetter; | 25 class URLRequestContextGetter; |
| 22 } | 26 } |
| 23 | 27 |
| 28 // IssueAdvice: messages to show to the user to get a user's approval. | |
| 29 // The structure is as follows: | |
| 30 // * Descritpion 1 | |
| 31 // - Detail 1.1 | |
| 32 // - Details 1.2 | |
|
jstritar
2012/04/11 19:14:29
nit: details-> detail?
| |
| 33 // * Description 2 | |
| 34 // - Detail 2.1 | |
| 35 // - Detail 2.2 | |
| 36 // - Detail 2.3 | |
| 37 // * Description 3 | |
| 38 // - Detail 3.1 | |
| 39 struct IssueAdviceInfoEntry { | |
| 40 std::string description; | |
| 41 std::vector<std::string> details; | |
| 42 | |
| 43 bool operator==(const IssueAdviceInfoEntry& rhs) const { | |
| 44 return description == rhs.description && details == rhs.details; | |
| 45 } | |
| 46 }; | |
| 47 | |
| 48 typedef std::vector<IssueAdviceInfoEntry> IssueAdviceInfo; | |
| 49 | |
| 24 // This class implements the OAuth2 flow to Google to mint an OAuth2 | 50 // This class implements the OAuth2 flow to Google to mint an OAuth2 |
| 25 // token for the given client and the given set of scopes from the | 51 // token for the given client and the given set of scopes from the |
| 26 // OAuthLogin scoped "master" OAuth2 token for the user logged in to | 52 // OAuthLogin scoped "master" OAuth2 token for the user logged in to |
| 27 // Chrome. | 53 // Chrome. |
| 28 class OAuth2MintTokenFlow | 54 class OAuth2MintTokenFlow |
| 29 : public OAuth2AccessTokenConsumer, | 55 : public OAuth2ApiCallFlow { |
|
jstritar
2012/04/11 19:14:29
nit: this can go on the same line now
Munjal (Google)
2012/04/11 19:37:55
Done.
| |
| 30 public OAuth2MintTokenConsumer { | |
| 31 public: | 56 public: |
| 57 // There are four differnt modes when minting a token to grant | |
| 58 // access to third-party app for a user. | |
| 59 enum Mode { | |
| 60 // Get the messages to display to the user without minting a token. | |
| 61 MODE_ISSUE_ADVICE, | |
| 62 // Record a grant but do not get a token back. | |
| 63 MODE_RECORD_GRANT, | |
| 64 // Mint a token for an existing grant. | |
| 65 MODE_MINT_TOKEN_NO_FORCE, | |
| 66 // Mint a token forcefully even if there is no existing grant. | |
| 67 MODE_MINT_TOKEN_FORCE, | |
| 68 }; | |
| 69 | |
| 70 // Parameters needed to mint a token. | |
| 71 struct Parameters { | |
| 72 Parameters() : mode(MODE_ISSUE_ADVICE) { } | |
| 73 Parameters(const std::string& rt, | |
| 74 const std::string& eid, | |
| 75 const std::string& cid, | |
| 76 const std::vector<std::string>& scopes_arg, | |
|
jstritar
2012/04/11 19:14:29
nit: don't think you need to actually have differe
Munjal (Google)
2012/04/11 19:37:55
I see. I think this is still better for readabilit
| |
| 77 Mode mode_arg) | |
| 78 : login_refresh_token(rt), | |
| 79 extension_id(eid), | |
| 80 client_id(cid), | |
| 81 scopes(scopes_arg), | |
| 82 mode(mode_arg) { | |
| 83 } | |
| 84 | |
| 85 std::string login_refresh_token; | |
| 86 std::string extension_id; | |
| 87 std::string client_id; | |
| 88 std::vector<std::string> scopes; | |
| 89 Mode mode; | |
| 90 }; | |
| 91 | |
| 32 class Delegate { | 92 class Delegate { |
| 33 public: | 93 public: |
| 34 virtual void OnMintTokenSuccess(const std::string& access_token) { } | 94 Delegate() {} |
| 35 virtual void OnMintTokenFailure(const GoogleServiceAuthError& error) { } | 95 virtual ~Delegate() {} |
| 96 virtual void OnMintTokenSuccess(const std::string& access_token) {} | |
| 97 virtual void OnIssueAdviceSuccess(const IssueAdviceInfo& issue_advice) {} | |
| 98 virtual void OnMintTokenFailure(const GoogleServiceAuthError& error) {} | |
| 36 }; | 99 }; |
| 37 | 100 |
| 38 // An interceptor for tests. | 101 // An interceptor for tests. |
| 39 class InterceptorForTests { | 102 class InterceptorForTests { |
| 40 public: | 103 public: |
| 41 // Returns true if the success callback should be called and false for | 104 // Returns true if the success callback should be called and false for |
| 42 // failures. | 105 // failures. |
| 43 virtual bool DoIntercept(const OAuth2MintTokenFlow* flow, | 106 virtual bool DoIntercept(const OAuth2MintTokenFlow* flow, |
| 44 std::string* access_token, | 107 std::string* access_token, |
| 45 GoogleServiceAuthError* error) = 0; | 108 GoogleServiceAuthError* error) = 0; |
| 46 }; | 109 }; |
| 47 static void SetInterceptorForTests(InterceptorForTests* interceptor); | 110 static void SetInterceptorForTests(InterceptorForTests* interceptor); |
| 48 | 111 |
| 49 OAuth2MintTokenFlow(net::URLRequestContextGetter* context, | 112 OAuth2MintTokenFlow(net::URLRequestContextGetter* context, |
| 50 Delegate* delegate); | 113 Delegate* delegate, |
| 114 const Parameters& parameters); | |
| 51 virtual ~OAuth2MintTokenFlow(); | 115 virtual ~OAuth2MintTokenFlow(); |
| 52 | 116 |
| 53 // Start the process to mint a token. | 117 virtual void Start() OVERRIDE; |
| 54 void Start(const std::string& login_refresh_token, | |
| 55 const std::string& extension_id, | |
| 56 const std::string& client_id, | |
| 57 const std::vector<std::string>& scopes); | |
| 58 | |
| 59 // OAuth2AccessTokenConsumer implementation. | |
| 60 virtual void OnGetTokenSuccess(const std::string& access_token) OVERRIDE; | |
| 61 virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) OVERRIDE; | |
| 62 // OAuth2MintTokenConsumer implementation. | |
| 63 virtual void OnMintTokenSuccess(const std::string& access_token) OVERRIDE; | |
| 64 virtual void OnMintTokenFailure(const GoogleServiceAuthError& error) OVERRIDE; | |
| 65 | |
| 66 // Getters for various members. | |
| 67 const std::string& extension_id() const { return extension_id_; } | |
| 68 const std::string& client_id() const { return client_id_; } | |
| 69 | 118 |
| 70 protected: | 119 protected: |
| 71 // Helper to create an instance of access token fetcher. | 120 // Implementation of template methods in OAuth2ApiCallFlow. |
| 72 // Caller owns the returned instance. | 121 virtual GURL CreateApiCallUrl() OVERRIDE; |
| 73 virtual OAuth2AccessTokenFetcher* CreateAccessTokenFetcher(); | 122 virtual std::string CreateApiCallBody() OVERRIDE; |
| 74 | 123 |
| 75 // Helper to create an instance of mint token fetcher. | 124 virtual void ProcessApiCallSuccess( |
| 76 // Caller owns the returned instance. | 125 const content::URLFetcher* source) OVERRIDE; |
| 77 virtual OAuth2MintTokenFetcher* CreateMintTokenFetcher(); | 126 virtual void ProcessApiCallFailure( |
| 127 const content::URLFetcher* source) OVERRIDE; | |
| 128 virtual void ProcessNewAccessToken(const std::string& access_token) OVERRIDE; | |
| 129 virtual void ProcessMintAccessTokenFailure( | |
| 130 const GoogleServiceAuthError& error) OVERRIDE; | |
|
jstritar
2012/04/11 19:14:29
Just verifying behavior: this error method would b
Munjal (Google)
2012/04/11 19:37:55
Actually it will be called for all errors that can
| |
| 78 | 131 |
| 79 private: | 132 private: |
| 80 // The steps this class performs are: | 133 friend class OAuth2MintTokenFlowTest; |
| 81 // 1. Create a login scoped access token from login scoped refresh token. | 134 FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, CreateApiCallBody); |
| 82 // 2. Use login scoped access token to call the API to mint an access token | 135 FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, ParseIssueAdviceResponse); |
| 83 // for the app. | 136 FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, ParseMintTokenResponse); |
| 84 enum State { | 137 FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, ProcessApiCallSuccess); |
| 85 INITIAL, | 138 FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, ProcessApiCallFailure); |
| 86 FETCH_LOGIN_ACCESS_TOKEN_STARTED, | 139 FRIEND_TEST_ALL_PREFIXES(OAuth2MintTokenFlowTest, |
| 87 FETCH_LOGIN_ACCESS_TOKEN_DONE, | 140 ProcessMintAccessTokenFailure); |
| 88 MINT_ACCESS_TOKEN_STARTED, | |
| 89 MINT_ACCESS_TOKEN_DONE, | |
| 90 ERROR_STATE | |
| 91 }; | |
| 92 | 141 |
| 93 enum SetupError { | 142 void ReportSuccess(const std::string& access_token); |
| 94 NONE, | 143 void ReportSuccess(const IssueAdviceInfo& issue_advice); |
| 95 AUTH_ERROR, | |
| 96 INTERNAL_ERROR, | |
| 97 USER_CANCELLED, | |
| 98 | |
| 99 // This is used for histograms, and should always be the last value. | |
| 100 SETUP_ERROR_BOUNDARY | |
| 101 }; | |
| 102 | |
| 103 friend class OAuth2MintTokenFlowTest; | |
| 104 | |
| 105 // Creates an instance of URLFetcher that does not send or save cookies. | |
| 106 // The URLFether's method will be GET if body is empty, POST otherwise. | |
| 107 // Caller owns the returned instance. | |
| 108 content::URLFetcher* CreateURLFetcher( | |
| 109 const GURL& url, const std::string& body, const std::string& auth_token); | |
| 110 void BeginGetLoginAccessToken(); | |
| 111 void EndGetLoginAccessToken(const GoogleServiceAuthError* error); | |
| 112 void BeginMintAccessToken(); | |
| 113 void EndMintAccessToken(const GoogleServiceAuthError* error); | |
| 114 | |
| 115 void ReportSuccess(); | |
| 116 void ReportFailure(const GoogleServiceAuthError& error); | 144 void ReportFailure(const GoogleServiceAuthError& error); |
| 117 | 145 |
| 118 static std::string GetErrorString(SetupError error); | 146 // Parses the response from the given URLFetcher to a JSON dictionary. |
| 147 // Returns NULL if parsing to JSON fails. | |
| 148 // Callers owns the returned instance. | |
| 149 static base::DictionaryValue* ParseResponse( | |
| 150 const content::URLFetcher* url_fetcher); | |
| 151 | |
| 152 static bool ParseIssueAdviceResponse( | |
| 153 const base::DictionaryValue* dict, IssueAdviceInfo* issue_advice); | |
| 154 static bool ParseMintTokenResponse( | |
| 155 const base::DictionaryValue* dict, std::string* access_token); | |
| 119 | 156 |
| 120 net::URLRequestContextGetter* context_; | 157 net::URLRequestContextGetter* context_; |
| 121 Delegate* delegate_; | 158 Delegate* delegate_; |
| 122 State state_; | 159 Parameters parameters_; |
| 123 | |
| 124 std::string login_refresh_token_; | |
| 125 std::string extension_id_; | |
| 126 std::string client_id_; | |
| 127 std::vector<std::string> scopes_; | |
| 128 | |
| 129 scoped_ptr<OAuth2AccessTokenFetcher> oauth2_access_token_fetcher_; | |
| 130 scoped_ptr<OAuth2MintTokenFetcher> oauth2_mint_token_fetcher_; | |
| 131 std::string login_access_token_; | |
| 132 std::string app_access_token_; | |
| 133 | 160 |
| 134 DISALLOW_COPY_AND_ASSIGN(OAuth2MintTokenFlow); | 161 DISALLOW_COPY_AND_ASSIGN(OAuth2MintTokenFlow); |
| 135 }; | 162 }; |
| 136 | 163 |
| 137 #endif // CHROME_COMMON_NET_GAIA_OAUTH2_MINT_TOKEN_FLOW_H_ | 164 #endif // CHROME_COMMON_NET_GAIA_OAUTH2_MINT_TOKEN_FLOW_H_ |
| OLD | NEW |