Roll WebRTC 9745:9761, Libjingle 9742:9761
[chromium-blink-merge.git] / google_apis / gaia / gaia_auth_fetcher.h
blobf6e4aa861540397a5becc1f4f1163badde702de7
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.
5 #ifndef GOOGLE_APIS_GAIA_GAIA_AUTH_FETCHER_H_
6 #define GOOGLE_APIS_GAIA_GAIA_AUTH_FETCHER_H_
8 #include <string>
9 #include <vector>
11 #include "base/gtest_prod_util.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "google_apis/gaia/gaia_auth_consumer.h"
14 #include "google_apis/gaia/google_service_auth_error.h"
15 #include "net/url_request/url_fetcher_delegate.h"
16 #include "url/gurl.h"
18 // Authenticate a user against the Google Accounts ClientLogin API
19 // with various capabilities and return results to a GaiaAuthConsumer.
21 // In the future, we will also issue auth tokens from this class.
22 // This class should be used on a single thread, but it can be whichever thread
23 // that you like.
25 // This class can handle one request at a time on any thread. To parallelize
26 // requests, create multiple GaiaAuthFetcher's.
28 class GaiaAuthFetcherTest;
30 namespace net {
31 class URLFetcher;
32 class URLRequestContextGetter;
33 class URLRequestStatus;
36 class GaiaAuthFetcher : public net::URLFetcherDelegate {
37 public:
38 // Magic string indicating that, while a second factor is still
39 // needed to complete authentication, the user provided the right password.
40 static const char kSecondFactor[];
42 // Magic string indicating that though the user does not have Less Secure
43 // Apps enabled, the user provided the right password.
44 static const char kWebLoginRequired[];
46 // This will later be hidden behind an auth service which caches
47 // tokens.
48 GaiaAuthFetcher(GaiaAuthConsumer* consumer,
49 const std::string& source,
50 net::URLRequestContextGetter* getter);
51 ~GaiaAuthFetcher() override;
53 // Start a request to obtain service token for the the account identified by
54 // |sid| and |lsid| and the |service|.
56 // Either OnIssueAuthTokenSuccess or OnIssueAuthTokenFailure will be
57 // called on the consumer on the original thread.
58 void StartIssueAuthToken(const std::string& sid,
59 const std::string& lsid,
60 const char* const service);
62 // Start a request to obtain |service| token for the the account identified by
63 // |uber_token|.
65 // Either OnIssueAuthTokenSuccess or OnIssueAuthTokenFailure will be
66 // called on the consumer on the original thread.
67 void StartTokenAuth(const std::string& uber_token,
68 const char* const service);
70 // Start a request to obtain service token for the the account identified by
71 // |oauth2_access_token| and the |service|.
73 // Either OnIssueAuthTokenSuccess or OnIssueAuthTokenFailure will be
74 // called on the consumer on the original thread.
75 void StartIssueAuthTokenForOAuth2(const std::string& oauth2_access_token,
76 const char* const service);
78 // Start a request to revoke |auth_token|.
80 // OnOAuth2RevokeTokenCompleted will be called on the consumer on the original
81 // thread.
82 void StartRevokeOAuth2Token(const std::string& auth_token);
84 // Start a request to exchange the cookies of a signed-in user session
85 // for an OAuthLogin-scoped oauth2 token. In the case of a session with
86 // multiple accounts signed in, |session_index| indicate the which of accounts
87 // within the session.
89 // Either OnClientOAuthSuccess or OnClientOAuthFailure will be
90 // called on the consumer on the original thread.
91 void StartCookieForOAuthLoginTokenExchange(const std::string& session_index);
93 // Start a request to exchange the cookies of a signed-in user session
94 // for an OAuthLogin-scoped oauth2 token. In the case of a session with
95 // multiple accounts signed in, |session_index| indicate the which of accounts
96 // within the session.
97 // Resulting refresh token is annotated on the server with |device_id|. Format
98 // of device_id on the server is at most 64 unicode characters.
100 // Either OnClientOAuthSuccess or OnClientOAuthFailure will be
101 // called on the consumer on the original thread.
102 void StartCookieForOAuthLoginTokenExchangeWithDeviceId(
103 const std::string& session_index,
104 const std::string& device_id);
106 // Start a request to exchange the authorization code for an OAuthLogin-scoped
107 // oauth2 token.
109 // Either OnClientOAuthSuccess or OnClientOAuthFailure will be
110 // called on the consumer on the original thread.
111 void StartAuthCodeForOAuth2TokenExchange(const std::string& auth_code);
113 // Start a request to exchange the authorization code for an OAuthLogin-scoped
114 // oauth2 token.
115 // Resulting refresh token is annotated on the server with |device_id|. Format
116 // of device_id on the server is at most 64 unicode characters.
118 // Either OnClientOAuthSuccess or OnClientOAuthFailure will be
119 // called on the consumer on the original thread.
120 void StartAuthCodeForOAuth2TokenExchangeWithDeviceId(
121 const std::string& auth_code,
122 const std::string& device_id);
124 // Start a request to get user info for the account identified by |lsid|.
126 // Either OnGetUserInfoSuccess or OnGetUserInfoFailure will be
127 // called on the consumer on the original thread.
128 void StartGetUserInfo(const std::string& lsid);
130 // Start a MergeSession request to pre-login the user with the given
131 // credentials.
133 // Start a MergeSession request to fill the browsing cookie jar with
134 // credentials represented by the account whose uber-auth token is
135 // |uber_token|. This method will modify the cookies of the current profile.
137 // The |external_cc_result| string can specify the result of connetion checks
138 // for various google properties, and MergeSession will set cookies on those
139 // properties too if appropriate. See StartGetCheckConnectionInfo() for
140 // details. The string is a comma separated list of token/result pairs, where
141 // token and result are separated by a colon. This string may be empty, in
142 // which case no specific handling is performed.
144 // Either OnMergeSessionSuccess or OnMergeSessionFailure will be
145 // called on the consumer on the original thread.
146 void StartMergeSession(const std::string& uber_token,
147 const std::string& external_cc_result);
149 // Start a request to exchange an OAuthLogin-scoped oauth2 access token for an
150 // uber-auth token. The returned token can be used with the method
151 // StartMergeSession().
153 // Either OnUberAuthTokenSuccess or OnUberAuthTokenFailure will be
154 // called on the consumer on the original thread.
155 void StartTokenFetchForUberAuthExchange(const std::string& access_token);
157 // Start a request to exchange an OAuthLogin-scoped oauth2 access token for a
158 // ClientLogin-style service tokens. The response to this request is the
159 // same as the response to a ClientLogin request, except that captcha
160 // challenges are never issued.
162 // Either OnClientLoginSuccess or OnClientLoginFailure will be
163 // called on the consumer on the original thread. If |service| is empty,
164 // the call will attempt to fetch uber auth token.
165 void StartOAuthLogin(const std::string& access_token,
166 const std::string& service);
168 // Starts a request to list the accounts in the GAIA cookie.
169 void StartListAccounts();
171 // Starts a request to log out the accounts in the GAIA cookie.
172 void StartLogOut();
174 // Starts a request to get the list of URLs to check for connection info.
175 // Returns token/URL pairs to check, and the resulting status can be given to
176 // /MergeSession requests.
177 void StartGetCheckConnectionInfo();
179 // Starts listing any sessions that exist for the IDP. If all requested scopes
180 // have been approved by the session user, then a login hint is included in
181 // the response.
182 void StartListIDPSessions(const std::string& scopes,
183 const std::string& domain);
185 // Generates an access token for the session, specifying the scopes and
186 // |login_hint|.
187 void StartGetTokenResponse(const std::string& scopes,
188 const std::string& domain,
189 const std::string& login_hint);
191 // Implementation of net::URLFetcherDelegate
192 void OnURLFetchComplete(const net::URLFetcher* source) override;
194 // StartClientLogin been called && results not back yet?
195 bool HasPendingFetch();
197 // Stop any URL fetches in progress.
198 virtual void CancelRequest();
200 // From a URLFetcher result, generate an appropriate error.
201 // From the API documentation, both IssueAuthToken and ClientLogin have
202 // the same error returns.
203 static GoogleServiceAuthError GenerateOAuthLoginError(
204 const std::string& data,
205 const net::URLRequestStatus& status);
207 protected:
208 // Create and start |fetcher_|, used to make all Gaia request. |body| is
209 // used as the body of the POST request sent to GAIA. Any strings listed in
210 // |headers| are added as extra HTTP headers in the request.
212 // |load_flags| are passed to directly to net::URLFetcher::Create() when
213 // creating the URL fetcher.
215 // HasPendingFetch() should return false before calling this method, and will
216 // return true afterwards.
217 virtual void CreateAndStartGaiaFetcher(const std::string& body,
218 const std::string& headers,
219 const GURL& gaia_gurl,
220 int load_flags);
222 // Dispatch the results of a request.
223 void DispatchFetchedRequest(const GURL& url,
224 const std::string& data,
225 const net::ResponseCookies& cookies,
226 const net::URLRequestStatus& status,
227 int response_code);
229 void SetPendingFetch(bool pending_fetch);
231 private:
232 // The format of the POST body for IssueAuthToken.
233 static const char kIssueAuthTokenFormat[];
234 // The format of the query string to get OAuth2 auth code from auth token.
235 static const char kClientLoginToOAuth2URLFormat[];
236 // The format of the POST body to get OAuth2 token pair from auth code.
237 static const char kOAuth2CodeToTokenPairBodyFormat[];
238 // Additional param for the POST body to get OAuth2 token pair from auth code.
239 static const char kOAuth2CodeToTokenPairDeviceIdParam[];
240 // The format of the POST body to revoke an OAuth2 token.
241 static const char kOAuth2RevokeTokenBodyFormat[];
242 // The format of the POST body for GetUserInfo.
243 static const char kGetUserInfoFormat[];
244 // The format of the POST body for MergeSession.
245 static const char kMergeSessionFormat[];
246 // The format of the URL for UberAuthToken.
247 static const char kUberAuthTokenURLFormat[];
248 // The format of the body for OAuthLogin.
249 static const char kOAuthLoginFormat[];
251 // Constants for parsing ClientLogin errors.
252 static const char kAccountDeletedError[];
253 static const char kAccountDeletedErrorCode[];
254 static const char kAccountDisabledError[];
255 static const char kAccountDisabledErrorCode[];
256 static const char kBadAuthenticationError[];
257 static const char kBadAuthenticationErrorCode[];
258 static const char kCaptchaError[];
259 static const char kCaptchaErrorCode[];
260 static const char kServiceUnavailableError[];
261 static const char kServiceUnavailableErrorCode[];
262 static const char kErrorParam[];
263 static const char kErrorUrlParam[];
264 static const char kCaptchaUrlParam[];
265 static const char kCaptchaTokenParam[];
267 // Constants for parsing ClientOAuth errors.
268 static const char kNeedsAdditional[];
269 static const char kCaptcha[];
270 static const char kTwoFactor[];
272 // Constants for request/response for OAuth2 requests.
273 static const char kAuthHeaderFormat[];
274 static const char kOAuthHeaderFormat[];
275 static const char kOAuth2BearerHeaderFormat[];
276 static const char kDeviceIdHeaderFormat[];
277 static const char kClientLoginToOAuth2CookiePartSecure[];
278 static const char kClientLoginToOAuth2CookiePartHttpOnly[];
279 static const char kClientLoginToOAuth2CookiePartCodePrefix[];
280 static const int kClientLoginToOAuth2CookiePartCodePrefixLength;
282 // Process the results of a ClientLogin fetch.
283 void OnClientLoginFetched(const std::string& data,
284 const net::URLRequestStatus& status,
285 int response_code);
287 void OnIssueAuthTokenFetched(const std::string& data,
288 const net::URLRequestStatus& status,
289 int response_code);
291 void OnClientLoginToOAuth2Fetched(const std::string& data,
292 const net::ResponseCookies& cookies,
293 const net::URLRequestStatus& status,
294 int response_code);
296 void OnOAuth2TokenPairFetched(const std::string& data,
297 const net::URLRequestStatus& status,
298 int response_code);
300 void OnOAuth2RevokeTokenFetched(const std::string& data,
301 const net::URLRequestStatus& status,
302 int response_code);
304 void OnListAccountsFetched(const std::string& data,
305 const net::URLRequestStatus& status,
306 int response_code);
308 void OnLogOutFetched(const std::string& data,
309 const net::URLRequestStatus& status,
310 int response_code);
312 void OnGetUserInfoFetched(const std::string& data,
313 const net::URLRequestStatus& status,
314 int response_code);
316 void OnMergeSessionFetched(const std::string& data,
317 const net::URLRequestStatus& status,
318 int response_code);
320 void OnUberAuthTokenFetch(const std::string& data,
321 const net::URLRequestStatus& status,
322 int response_code);
324 void OnOAuthLoginFetched(const std::string& data,
325 const net::URLRequestStatus& status,
326 int response_code);
328 void OnGetCheckConnectionInfoFetched(const std::string& data,
329 const net::URLRequestStatus& status,
330 int response_code);
332 void OnListIdpSessionsFetched(const std::string& data,
333 const net::URLRequestStatus& status,
334 int response_code);
336 void OnGetTokenResponseFetched(const std::string& data,
337 const net::URLRequestStatus& status,
338 int response_code);
340 // Tokenize the results of a ClientLogin fetch.
341 static void ParseClientLoginResponse(const std::string& data,
342 std::string* sid,
343 std::string* lsid,
344 std::string* token);
346 static void ParseClientLoginFailure(const std::string& data,
347 std::string* error,
348 std::string* error_url,
349 std::string* captcha_url,
350 std::string* captcha_token);
352 // Parse ClientLogin to OAuth2 response.
353 static bool ParseClientLoginToOAuth2Response(
354 const net::ResponseCookies& cookies,
355 std::string* auth_code);
357 static bool ParseClientLoginToOAuth2Cookie(const std::string& cookie,
358 std::string* auth_code);
360 static bool ParseListIdpSessionsResponse(const std::string& data,
361 std::string* login_hint);
363 // Is this a special case Gaia error for TwoFactor auth?
364 static bool IsSecondFactorSuccess(const std::string& alleged_error);
366 // Is this a special case Gaia error for Less Secure Apps?
367 static bool IsWebLoginRequiredSuccess(const std::string& alleged_error);
369 // Supply the sid / lsid returned from ClientLogin in order to
370 // request a long lived auth token for a service.
371 static std::string MakeIssueAuthTokenBody(const std::string& sid,
372 const std::string& lsid,
373 const char* const service);
374 // Given auth code and device ID (optional), create body to get OAuth2 token
375 // pair.
376 static std::string MakeGetTokenPairBody(const std::string& auth_code,
377 const std::string& device_id);
378 // Given an OAuth2 token, create body to revoke the token.
379 std::string MakeRevokeTokenBody(const std::string& auth_token);
380 // Supply the lsid returned from ClientLogin in order to fetch
381 // user information.
382 static std::string MakeGetUserInfoBody(const std::string& lsid);
384 // Supply the authentication token returned from StartIssueAuthToken.
385 static std::string MakeMergeSessionBody(const std::string& auth_token,
386 const std::string& external_cc_result,
387 const std::string& continue_url,
388 const std::string& source);
390 static std::string MakeGetAuthCodeHeader(const std::string& auth_token);
392 static std::string MakeOAuthLoginBody(const std::string& service,
393 const std::string& source);
395 static std::string MakeListIDPSessionsBody(const std::string& scopes,
396 const std::string& domain);
398 static std::string MakeGetTokenResponseBody(const std::string& scopes,
399 const std::string& domain,
400 const std::string& login_hint);
402 // From a URLFetcher result, generate an appropriate error.
403 // From the API documentation, both IssueAuthToken and ClientLogin have
404 // the same error returns.
405 static GoogleServiceAuthError GenerateAuthError(
406 const std::string& data,
407 const net::URLRequestStatus& status);
409 // These fields are common to GaiaAuthFetcher, same every request.
410 GaiaAuthConsumer* const consumer_;
411 net::URLRequestContextGetter* const getter_;
412 std::string source_;
413 const GURL issue_auth_token_gurl_;
414 const GURL oauth2_token_gurl_;
415 const GURL oauth2_revoke_gurl_;
416 const GURL get_user_info_gurl_;
417 const GURL merge_session_gurl_;
418 const GURL uberauth_token_gurl_;
419 const GURL oauth_login_gurl_;
420 const GURL list_accounts_gurl_;
421 const GURL logout_gurl_;
422 const GURL get_check_connection_info_url_;
423 const GURL oauth2_iframe_url_;
425 // While a fetch is going on:
426 scoped_ptr<net::URLFetcher> fetcher_;
427 GURL client_login_to_oauth2_gurl_;
428 std::string request_body_;
429 std::string requested_service_;
430 bool fetch_pending_;
432 friend class GaiaAuthFetcherTest;
433 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CaptchaParse);
434 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, AccountDeletedError);
435 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, AccountDisabledError);
436 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, BadAuthenticationError);
437 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, IncomprehensibleError);
438 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ServiceUnavailableError);
439 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CheckNormalErrorCode);
440 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CheckTwoFactorResponse);
441 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, LoginNetFailure);
442 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest,
443 ParseClientLoginToOAuth2Response);
444 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ParseOAuth2TokenPairResponse);
445 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ClientOAuthSuccess);
446 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ClientOAuthWithQuote);
447 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ClientOAuthChallengeSuccess);
448 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ClientOAuthChallengeQuote);
450 DISALLOW_COPY_AND_ASSIGN(GaiaAuthFetcher);
453 #endif // GOOGLE_APIS_GAIA_GAIA_AUTH_FETCHER_H_