Make castv2 performance test work.
[chromium-blink-merge.git] / google_apis / gaia / gaia_auth_fetcher.h
blob0243d60da96f5a9d8fa0381aca913a293db9ae80
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 enum HostedAccountsSetting {
39 HostedAccountsAllowed,
40 HostedAccountsNotAllowed
43 // Magic string indicating that, while a second factor is still
44 // needed to complete authentication, the user provided the right password.
45 static const char kSecondFactor[];
47 // Magic string indicating that though the user does not have Less Secure
48 // Apps enabled, the user provided the right password.
49 static const char kWebLoginRequired[];
51 // This will later be hidden behind an auth service which caches
52 // tokens.
53 GaiaAuthFetcher(GaiaAuthConsumer* consumer,
54 const std::string& source,
55 net::URLRequestContextGetter* getter);
56 ~GaiaAuthFetcher() override;
58 // Start a request to obtain the SID and LSID cookies for the the account
59 // identified by |username| and |password|. If |service| is not null or
60 // empty, then also obtains a service token for specified service.
62 // If this is a second call because of captcha challenge, then the
63 // |login_token| and |login_captcha| arugment should correspond to the
64 // solution of the challenge.
66 // Either OnClientLoginSuccess or OnClientLoginFailure will be
67 // called on the consumer on the original thread.
68 void StartClientLogin(const std::string& username,
69 const std::string& password,
70 const char* const service,
71 const std::string& login_token,
72 const std::string& login_captcha,
73 HostedAccountsSetting allow_hosted_accounts);
75 // Start a request to obtain service token for the the account identified by
76 // |sid| and |lsid| and the |service|.
78 // Either OnIssueAuthTokenSuccess or OnIssueAuthTokenFailure will be
79 // called on the consumer on the original thread.
80 void StartIssueAuthToken(const std::string& sid,
81 const std::string& lsid,
82 const char* const service);
84 // Start a request to obtain |service| token for the the account identified by
85 // |uber_token|.
87 // Either OnIssueAuthTokenSuccess or OnIssueAuthTokenFailure will be
88 // called on the consumer on the original thread.
89 void StartTokenAuth(const std::string& uber_token,
90 const char* const service);
92 // Start a request to obtain service token for the the account identified by
93 // |oauth2_access_token| and the |service|.
95 // Either OnIssueAuthTokenSuccess or OnIssueAuthTokenFailure will be
96 // called on the consumer on the original thread.
97 void StartIssueAuthTokenForOAuth2(const std::string& oauth2_access_token,
98 const char* const service);
100 // Start a request to exchange an "lso" service token given by |auth_token|
101 // for an OAuthLogin-scoped oauth2 token.
103 // Either OnClientOAuthSuccess or OnClientOAuthFailure will be
104 // called on the consumer on the original thread.
105 void StartLsoForOAuthLoginTokenExchange(const std::string& auth_token);
107 // Start a request to revoke |auth_token|.
109 // OnOAuth2RevokeTokenCompleted will be called on the consumer on the original
110 // thread.
111 void StartRevokeOAuth2Token(const std::string& auth_token);
113 // Start a request to exchange the cookies of a signed-in user session
114 // for an OAuthLogin-scoped oauth2 token. In the case of a session with
115 // multiple accounts signed in, |session_index| indicate the which of accounts
116 // within the session.
118 // Either OnClientOAuthSuccess or OnClientOAuthFailure will be
119 // called on the consumer on the original thread.
120 void StartCookieForOAuthLoginTokenExchange(const std::string& session_index);
122 // Start a request to exchange the cookies of a signed-in user session
123 // for an OAuthLogin-scoped oauth2 token. In the case of a session with
124 // multiple accounts signed in, |session_index| indicate the which of accounts
125 // within the session.
126 // Resulting refresh token is annotated on the server with |device_id|. Format
127 // of device_id on the server is at most 64 unicode characters.
129 // Either OnClientOAuthSuccess or OnClientOAuthFailure will be
130 // called on the consumer on the original thread.
131 void StartCookieForOAuthLoginTokenExchangeWithDeviceId(
132 const std::string& session_index,
133 const std::string& device_id);
135 // Start a request to exchange the authorization code for an OAuthLogin-scoped
136 // oauth2 token.
138 // Either OnClientOAuthSuccess or OnClientOAuthFailure will be
139 // called on the consumer on the original thread.
140 void StartAuthCodeForOAuth2TokenExchange(const std::string& auth_code);
142 // Start a request to get user info for the account identified by |lsid|.
144 // Either OnGetUserInfoSuccess or OnGetUserInfoFailure will be
145 // called on the consumer on the original thread.
146 void StartGetUserInfo(const std::string& lsid);
148 // Start a MergeSession request to pre-login the user with the given
149 // credentials.
151 // Start a MergeSession request to fill the browsing cookie jar with
152 // credentials represented by the account whose uber-auth token is
153 // |uber_token|. This method will modify the cookies of the current profile.
155 // The |external_cc_result| string can specify the result of connetion checks
156 // for various google properties, and MergeSession will set cookies on those
157 // properties too if appropriate. See StartGetCheckConnectionInfo() for
158 // details. The string is a comma separated list of token/result pairs, where
159 // token and result are separated by a colon. This string may be empty, in
160 // which case no specific handling is performed.
162 // Either OnMergeSessionSuccess or OnMergeSessionFailure will be
163 // called on the consumer on the original thread.
164 void StartMergeSession(const std::string& uber_token,
165 const std::string& external_cc_result);
167 // Start a request to exchange an OAuthLogin-scoped oauth2 access token for an
168 // uber-auth token. The returned token can be used with the method
169 // StartMergeSession().
171 // Either OnUberAuthTokenSuccess or OnUberAuthTokenFailure will be
172 // called on the consumer on the original thread.
173 void StartTokenFetchForUberAuthExchange(const std::string& access_token);
175 // Start a request to exchange an OAuthLogin-scoped oauth2 access token for a
176 // ClientLogin-style service tokens. The response to this request is the
177 // same as the response to a ClientLogin request, except that captcha
178 // challenges are never issued.
180 // Either OnClientLoginSuccess or OnClientLoginFailure will be
181 // called on the consumer on the original thread. If |service| is empty,
182 // the call will attempt to fetch uber auth token.
183 void StartOAuthLogin(const std::string& access_token,
184 const std::string& service);
186 // Starts a request to list the accounts in the GAIA cookie.
187 void StartListAccounts();
189 // Starts a request to get the list of URLs to check for connection info.
190 // Returns token/URL pairs to check, and the resulting status can be given to
191 // /MergeSession requests.
192 void StartGetCheckConnectionInfo();
194 // Starts listing any sessions that exist for the IDP. If all requested scopes
195 // have been approved by the session user, then a login hint is included in
196 // the response.
197 void StartListIDPSessions(const std::string& scopes,
198 const std::string& domain);
200 // Generates an access token for the session, specifying the scopes and
201 // |login_hint|.
202 void StartGetTokenResponse(const std::string& scopes,
203 const std::string& domain,
204 const std::string& login_hint);
206 // Implementation of net::URLFetcherDelegate
207 void OnURLFetchComplete(const net::URLFetcher* source) override;
209 // StartClientLogin been called && results not back yet?
210 bool HasPendingFetch();
212 // Stop any URL fetches in progress.
213 void CancelRequest();
215 // From a URLFetcher result, generate an appropriate error.
216 // From the API documentation, both IssueAuthToken and ClientLogin have
217 // the same error returns.
218 static GoogleServiceAuthError GenerateOAuthLoginError(
219 const std::string& data,
220 const net::URLRequestStatus& status);
222 private:
223 // ClientLogin body constants that don't change
224 static const char kCookiePersistence[];
225 static const char kAccountTypeHostedOrGoogle[];
226 static const char kAccountTypeGoogle[];
228 // The format of the POST body for ClientLogin.
229 static const char kClientLoginFormat[];
230 // The format of said POST body when CAPTCHA token & answer are specified.
231 static const char kClientLoginCaptchaFormat[];
232 // The format of the POST body for IssueAuthToken.
233 static const char kIssueAuthTokenFormat[];
234 // The format of the POST body to get OAuth2 auth code from auth token.
235 static const char kClientLoginToOAuth2BodyFormat[];
236 // The format of the POST body to get OAuth2 auth code from auth token. This
237 // format is used for request annotated with device_id.
238 static const char kClientLoginToOAuth2WithDeviceTypeBodyFormat[];
239 // The format of the POST body to get OAuth2 token pair from auth code.
240 static const char kOAuth2CodeToTokenPairBodyFormat[];
241 // The format of the POST body to revoke an OAuth2 token.
242 static const char kOAuth2RevokeTokenBodyFormat[];
243 // The format of the POST body for GetUserInfo.
244 static const char kGetUserInfoFormat[];
245 // The format of the POST body for MergeSession.
246 static const char kMergeSessionFormat[];
247 // The format of the URL for UberAuthToken.
248 static const char kUberAuthTokenURLFormat[];
249 // The format of the body for OAuthLogin.
250 static const char kOAuthLoginFormat[];
252 // Constants for parsing ClientLogin errors.
253 static const char kAccountDeletedError[];
254 static const char kAccountDeletedErrorCode[];
255 static const char kAccountDisabledError[];
256 static const char kAccountDisabledErrorCode[];
257 static const char kBadAuthenticationError[];
258 static const char kBadAuthenticationErrorCode[];
259 static const char kCaptchaError[];
260 static const char kCaptchaErrorCode[];
261 static const char kServiceUnavailableError[];
262 static const char kServiceUnavailableErrorCode[];
263 static const char kErrorParam[];
264 static const char kErrorUrlParam[];
265 static const char kCaptchaUrlParam[];
266 static const char kCaptchaTokenParam[];
268 // Constants for parsing ClientOAuth errors.
269 static const char kNeedsAdditional[];
270 static const char kCaptcha[];
271 static const char kTwoFactor[];
273 // Constants for request/response for OAuth2 requests.
274 static const char kAuthHeaderFormat[];
275 static const char kOAuthHeaderFormat[];
276 static const char kOAuth2BearerHeaderFormat[];
277 static const char kDeviceIdHeaderFormat[];
278 static const char kClientLoginToOAuth2CookiePartSecure[];
279 static const char kClientLoginToOAuth2CookiePartHttpOnly[];
280 static const char kClientLoginToOAuth2CookiePartCodePrefix[];
281 static const int kClientLoginToOAuth2CookiePartCodePrefixLength;
283 // Process the results of a ClientLogin fetch.
284 void OnClientLoginFetched(const std::string& data,
285 const net::URLRequestStatus& status,
286 int response_code);
288 void OnIssueAuthTokenFetched(const std::string& data,
289 const net::URLRequestStatus& status,
290 int response_code);
292 void OnClientLoginToOAuth2Fetched(const std::string& data,
293 const net::ResponseCookies& cookies,
294 const net::URLRequestStatus& status,
295 int response_code);
297 void OnOAuth2TokenPairFetched(const std::string& data,
298 const net::URLRequestStatus& status,
299 int response_code);
301 void OnOAuth2RevokeTokenFetched(const std::string& data,
302 const net::URLRequestStatus& status,
303 int response_code);
305 void OnListAccountsFetched(const std::string& data,
306 const net::URLRequestStatus& status,
307 int response_code);
309 void OnGetUserInfoFetched(const std::string& data,
310 const net::URLRequestStatus& status,
311 int response_code);
313 void OnMergeSessionFetched(const std::string& data,
314 const net::URLRequestStatus& status,
315 int response_code);
317 void OnUberAuthTokenFetch(const std::string& data,
318 const net::URLRequestStatus& status,
319 int response_code);
321 void OnOAuthLoginFetched(const std::string& data,
322 const net::URLRequestStatus& status,
323 int response_code);
325 void OnGetCheckConnectionInfoFetched(const std::string& data,
326 const net::URLRequestStatus& status,
327 int response_code);
329 void OnListIdpSessionsFetched(const std::string& data,
330 const net::URLRequestStatus& status,
331 int response_code);
333 void OnGetTokenResponseFetched(const std::string& data,
334 const net::URLRequestStatus& status,
335 int response_code);
337 // Tokenize the results of a ClientLogin fetch.
338 static void ParseClientLoginResponse(const std::string& data,
339 std::string* sid,
340 std::string* lsid,
341 std::string* token);
343 static void ParseClientLoginFailure(const std::string& data,
344 std::string* error,
345 std::string* error_url,
346 std::string* captcha_url,
347 std::string* captcha_token);
349 // Parse ClientLogin to OAuth2 response.
350 static bool ParseClientLoginToOAuth2Response(
351 const net::ResponseCookies& cookies,
352 std::string* auth_code);
354 static bool ParseClientLoginToOAuth2Cookie(const std::string& cookie,
355 std::string* auth_code);
357 static bool ParseListIdpSessionsResponse(const std::string& data,
358 std::string* login_hint);
360 // Is this a special case Gaia error for TwoFactor auth?
361 static bool IsSecondFactorSuccess(const std::string& alleged_error);
363 // Is this a special case Gaia error for Less Secure Apps?
364 static bool IsWebLoginRequiredSuccess(const std::string& alleged_error);
366 // Given parameters, create a ClientLogin request body.
367 static std::string MakeClientLoginBody(
368 const std::string& username,
369 const std::string& password,
370 const std::string& source,
371 const char* const service,
372 const std::string& login_token,
373 const std::string& login_captcha,
374 HostedAccountsSetting allow_hosted_accounts);
375 // Supply the sid / lsid returned from ClientLogin in order to
376 // request a long lived auth token for a service.
377 static std::string MakeIssueAuthTokenBody(const std::string& sid,
378 const std::string& lsid,
379 const char* const service);
380 // Create body to get OAuth2 auth code.
381 static std::string MakeGetAuthCodeBody(bool include_device_type);
382 // Given auth code, create body to get OAuth2 token pair.
383 static std::string MakeGetTokenPairBody(const std::string& auth_code);
384 // Given an OAuth2 token, create body to revoke the token.
385 std::string MakeRevokeTokenBody(const std::string& auth_token);
386 // Supply the lsid returned from ClientLogin in order to fetch
387 // user information.
388 static std::string MakeGetUserInfoBody(const std::string& lsid);
390 // Supply the authentication token returned from StartIssueAuthToken.
391 static std::string MakeMergeSessionBody(const std::string& auth_token,
392 const std::string& external_cc_result,
393 const std::string& continue_url,
394 const std::string& source);
396 static std::string MakeGetAuthCodeHeader(const std::string& auth_token);
398 static std::string MakeOAuthLoginBody(const std::string& service,
399 const std::string& source);
401 static std::string MakeListIDPSessionsBody(const std::string& scopes,
402 const std::string& domain);
404 static std::string MakeGetTokenResponseBody(const std::string& scopes,
405 const std::string& domain,
406 const std::string& login_hint);
408 // Create a fetcher usable for making any Gaia request. |body| is used
409 // as the body of the POST request sent to GAIA. Any strings listed in
410 // |headers| are added as extra HTTP headers in the request.
412 // |load_flags| are passed to directly to net::URLFetcher::Create() when
413 // creating the URL fetcher.
414 static net::URLFetcher* CreateGaiaFetcher(
415 net::URLRequestContextGetter* getter,
416 const std::string& body,
417 const std::string& headers,
418 const GURL& gaia_gurl,
419 int load_flags,
420 net::URLFetcherDelegate* delegate);
422 // From a URLFetcher result, generate an appropriate error.
423 // From the API documentation, both IssueAuthToken and ClientLogin have
424 // the same error returns.
425 static GoogleServiceAuthError GenerateAuthError(
426 const std::string& data,
427 const net::URLRequestStatus& status);
429 // These fields are common to GaiaAuthFetcher, same every request.
430 GaiaAuthConsumer* const consumer_;
431 net::URLRequestContextGetter* const getter_;
432 std::string source_;
433 const GURL client_login_gurl_;
434 const GURL issue_auth_token_gurl_;
435 const GURL oauth2_token_gurl_;
436 const GURL oauth2_revoke_gurl_;
437 const GURL get_user_info_gurl_;
438 const GURL merge_session_gurl_;
439 const GURL uberauth_token_gurl_;
440 const GURL oauth_login_gurl_;
441 const GURL list_accounts_gurl_;
442 const GURL get_check_connection_info_url_;
443 const GURL oauth2_iframe_url_;
445 // While a fetch is going on:
446 scoped_ptr<net::URLFetcher> fetcher_;
447 GURL client_login_to_oauth2_gurl_;
448 std::string request_body_;
449 std::string requested_service_;
450 bool fetch_pending_;
452 friend class GaiaAuthFetcherTest;
453 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CaptchaParse);
454 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, AccountDeletedError);
455 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, AccountDisabledError);
456 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, BadAuthenticationError);
457 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, IncomprehensibleError);
458 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ServiceUnavailableError);
459 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CheckNormalErrorCode);
460 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CheckTwoFactorResponse);
461 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, LoginNetFailure);
462 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest,
463 ParseClientLoginToOAuth2Response);
464 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ParseOAuth2TokenPairResponse);
465 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ClientOAuthSuccess);
466 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ClientOAuthWithQuote);
467 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ClientOAuthChallengeSuccess);
468 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ClientOAuthChallengeQuote);
470 DISALLOW_COPY_AND_ASSIGN(GaiaAuthFetcher);
473 #endif // GOOGLE_APIS_GAIA_GAIA_AUTH_FETCHER_H_