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 |