Don't preload rarely seen large images
[chromium-blink-merge.git] / google_apis / gaia / gaia_auth_fetcher.h
blob4a9838f54e58add413115d9a05b2849420872591
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 revoke |auth_token|.
102 // OnOAuth2RevokeTokenCompleted will be called on the consumer on the original
103 // thread.
104 void StartRevokeOAuth2Token(const std::string& auth_token);
106 // Start a request to exchange the cookies of a signed-in user session
107 // for an OAuthLogin-scoped oauth2 token. In the case of a session with
108 // multiple accounts signed in, |session_index| indicate the which of accounts
109 // within the session.
111 // Either OnClientOAuthSuccess or OnClientOAuthFailure will be
112 // called on the consumer on the original thread.
113 void StartCookieForOAuthLoginTokenExchange(const std::string& session_index);
115 // Start a request to exchange the cookies of a signed-in user session
116 // for an OAuthLogin-scoped oauth2 token. In the case of a session with
117 // multiple accounts signed in, |session_index| indicate the which of accounts
118 // within the session.
119 // Resulting refresh token is annotated on the server with |device_id|. Format
120 // of device_id on the server is at most 64 unicode characters.
122 // Either OnClientOAuthSuccess or OnClientOAuthFailure will be
123 // called on the consumer on the original thread.
124 void StartCookieForOAuthLoginTokenExchangeWithDeviceId(
125 const std::string& session_index,
126 const std::string& device_id);
128 // Start a request to exchange the authorization code for an OAuthLogin-scoped
129 // oauth2 token.
131 // Either OnClientOAuthSuccess or OnClientOAuthFailure will be
132 // called on the consumer on the original thread.
133 void StartAuthCodeForOAuth2TokenExchange(const std::string& auth_code);
135 // Start a request to exchange the authorization code for an OAuthLogin-scoped
136 // oauth2 token.
137 // Resulting refresh token is annotated on the server with |device_id|. Format
138 // of device_id on the server is at most 64 unicode characters.
140 // Either OnClientOAuthSuccess or OnClientOAuthFailure will be
141 // called on the consumer on the original thread.
142 void StartAuthCodeForOAuth2TokenExchangeWithDeviceId(
143 const std::string& auth_code,
144 const std::string& device_id);
146 // Start a request to get user info for the account identified by |lsid|.
148 // Either OnGetUserInfoSuccess or OnGetUserInfoFailure will be
149 // called on the consumer on the original thread.
150 void StartGetUserInfo(const std::string& lsid);
152 // Start a MergeSession request to pre-login the user with the given
153 // credentials.
155 // Start a MergeSession request to fill the browsing cookie jar with
156 // credentials represented by the account whose uber-auth token is
157 // |uber_token|. This method will modify the cookies of the current profile.
159 // The |external_cc_result| string can specify the result of connetion checks
160 // for various google properties, and MergeSession will set cookies on those
161 // properties too if appropriate. See StartGetCheckConnectionInfo() for
162 // details. The string is a comma separated list of token/result pairs, where
163 // token and result are separated by a colon. This string may be empty, in
164 // which case no specific handling is performed.
166 // Either OnMergeSessionSuccess or OnMergeSessionFailure will be
167 // called on the consumer on the original thread.
168 void StartMergeSession(const std::string& uber_token,
169 const std::string& external_cc_result);
171 // Start a request to exchange an OAuthLogin-scoped oauth2 access token for an
172 // uber-auth token. The returned token can be used with the method
173 // StartMergeSession().
175 // Either OnUberAuthTokenSuccess or OnUberAuthTokenFailure will be
176 // called on the consumer on the original thread.
177 void StartTokenFetchForUberAuthExchange(const std::string& access_token);
179 // Start a request to exchange an OAuthLogin-scoped oauth2 access token for a
180 // ClientLogin-style service tokens. The response to this request is the
181 // same as the response to a ClientLogin request, except that captcha
182 // challenges are never issued.
184 // Either OnClientLoginSuccess or OnClientLoginFailure will be
185 // called on the consumer on the original thread. If |service| is empty,
186 // the call will attempt to fetch uber auth token.
187 void StartOAuthLogin(const std::string& access_token,
188 const std::string& service);
190 // Starts a request to list the accounts in the GAIA cookie.
191 void StartListAccounts();
193 // Starts a request to log out the accounts in the GAIA cookie.
194 void StartLogOut();
196 // Starts a request to get the list of URLs to check for connection info.
197 // Returns token/URL pairs to check, and the resulting status can be given to
198 // /MergeSession requests.
199 void StartGetCheckConnectionInfo();
201 // Starts listing any sessions that exist for the IDP. If all requested scopes
202 // have been approved by the session user, then a login hint is included in
203 // the response.
204 void StartListIDPSessions(const std::string& scopes,
205 const std::string& domain);
207 // Generates an access token for the session, specifying the scopes and
208 // |login_hint|.
209 void StartGetTokenResponse(const std::string& scopes,
210 const std::string& domain,
211 const std::string& login_hint);
213 // Implementation of net::URLFetcherDelegate
214 void OnURLFetchComplete(const net::URLFetcher* source) override;
216 // StartClientLogin been called && results not back yet?
217 bool HasPendingFetch();
219 // Stop any URL fetches in progress.
220 virtual void CancelRequest();
222 // From a URLFetcher result, generate an appropriate error.
223 // From the API documentation, both IssueAuthToken and ClientLogin have
224 // the same error returns.
225 static GoogleServiceAuthError GenerateOAuthLoginError(
226 const std::string& data,
227 const net::URLRequestStatus& status);
229 protected:
230 // Create and start |fetcher_|, used to make all Gaia request. |body| is
231 // used as the body of the POST request sent to GAIA. Any strings listed in
232 // |headers| are added as extra HTTP headers in the request.
234 // |load_flags| are passed to directly to net::URLFetcher::Create() when
235 // creating the URL fetcher.
237 // HasPendingFetch() should return false before calling this method, and will
238 // return true afterwards.
239 virtual void CreateAndStartGaiaFetcher(const std::string& body,
240 const std::string& headers,
241 const GURL& gaia_gurl,
242 int load_flags);
244 // Dispatch the results of a request.
245 void DispatchFetchedRequest(const GURL& url,
246 const std::string& data,
247 const net::ResponseCookies& cookies,
248 const net::URLRequestStatus& status,
249 int response_code);
251 void SetPendingFetch(bool pending_fetch);
253 private:
254 // ClientLogin body constants that don't change
255 static const char kCookiePersistence[];
256 static const char kAccountTypeHostedOrGoogle[];
257 static const char kAccountTypeGoogle[];
259 // The format of the POST body for ClientLogin.
260 static const char kClientLoginFormat[];
261 // The format of said POST body when CAPTCHA token & answer are specified.
262 static const char kClientLoginCaptchaFormat[];
263 // The format of the POST body for IssueAuthToken.
264 static const char kIssueAuthTokenFormat[];
265 // The format of the query string to get OAuth2 auth code from auth token.
266 static const char kClientLoginToOAuth2URLFormat[];
267 // The format of the POST body to get OAuth2 token pair from auth code.
268 static const char kOAuth2CodeToTokenPairBodyFormat[];
269 // Additional param for the POST body to get OAuth2 token pair from auth code.
270 static const char kOAuth2CodeToTokenPairDeviceIdParam[];
271 // The format of the POST body to revoke an OAuth2 token.
272 static const char kOAuth2RevokeTokenBodyFormat[];
273 // The format of the POST body for GetUserInfo.
274 static const char kGetUserInfoFormat[];
275 // The format of the POST body for MergeSession.
276 static const char kMergeSessionFormat[];
277 // The format of the URL for UberAuthToken.
278 static const char kUberAuthTokenURLFormat[];
279 // The format of the body for OAuthLogin.
280 static const char kOAuthLoginFormat[];
282 // Constants for parsing ClientLogin errors.
283 static const char kAccountDeletedError[];
284 static const char kAccountDeletedErrorCode[];
285 static const char kAccountDisabledError[];
286 static const char kAccountDisabledErrorCode[];
287 static const char kBadAuthenticationError[];
288 static const char kBadAuthenticationErrorCode[];
289 static const char kCaptchaError[];
290 static const char kCaptchaErrorCode[];
291 static const char kServiceUnavailableError[];
292 static const char kServiceUnavailableErrorCode[];
293 static const char kErrorParam[];
294 static const char kErrorUrlParam[];
295 static const char kCaptchaUrlParam[];
296 static const char kCaptchaTokenParam[];
298 // Constants for parsing ClientOAuth errors.
299 static const char kNeedsAdditional[];
300 static const char kCaptcha[];
301 static const char kTwoFactor[];
303 // Constants for request/response for OAuth2 requests.
304 static const char kAuthHeaderFormat[];
305 static const char kOAuthHeaderFormat[];
306 static const char kOAuth2BearerHeaderFormat[];
307 static const char kDeviceIdHeaderFormat[];
308 static const char kClientLoginToOAuth2CookiePartSecure[];
309 static const char kClientLoginToOAuth2CookiePartHttpOnly[];
310 static const char kClientLoginToOAuth2CookiePartCodePrefix[];
311 static const int kClientLoginToOAuth2CookiePartCodePrefixLength;
313 // Process the results of a ClientLogin fetch.
314 void OnClientLoginFetched(const std::string& data,
315 const net::URLRequestStatus& status,
316 int response_code);
318 void OnIssueAuthTokenFetched(const std::string& data,
319 const net::URLRequestStatus& status,
320 int response_code);
322 void OnClientLoginToOAuth2Fetched(const std::string& data,
323 const net::ResponseCookies& cookies,
324 const net::URLRequestStatus& status,
325 int response_code);
327 void OnOAuth2TokenPairFetched(const std::string& data,
328 const net::URLRequestStatus& status,
329 int response_code);
331 void OnOAuth2RevokeTokenFetched(const std::string& data,
332 const net::URLRequestStatus& status,
333 int response_code);
335 void OnListAccountsFetched(const std::string& data,
336 const net::URLRequestStatus& status,
337 int response_code);
339 void OnLogOutFetched(const std::string& data,
340 const net::URLRequestStatus& status,
341 int response_code);
343 void OnGetUserInfoFetched(const std::string& data,
344 const net::URLRequestStatus& status,
345 int response_code);
347 void OnMergeSessionFetched(const std::string& data,
348 const net::URLRequestStatus& status,
349 int response_code);
351 void OnUberAuthTokenFetch(const std::string& data,
352 const net::URLRequestStatus& status,
353 int response_code);
355 void OnOAuthLoginFetched(const std::string& data,
356 const net::URLRequestStatus& status,
357 int response_code);
359 void OnGetCheckConnectionInfoFetched(const std::string& data,
360 const net::URLRequestStatus& status,
361 int response_code);
363 void OnListIdpSessionsFetched(const std::string& data,
364 const net::URLRequestStatus& status,
365 int response_code);
367 void OnGetTokenResponseFetched(const std::string& data,
368 const net::URLRequestStatus& status,
369 int response_code);
371 // Tokenize the results of a ClientLogin fetch.
372 static void ParseClientLoginResponse(const std::string& data,
373 std::string* sid,
374 std::string* lsid,
375 std::string* token);
377 static void ParseClientLoginFailure(const std::string& data,
378 std::string* error,
379 std::string* error_url,
380 std::string* captcha_url,
381 std::string* captcha_token);
383 // Parse ClientLogin to OAuth2 response.
384 static bool ParseClientLoginToOAuth2Response(
385 const net::ResponseCookies& cookies,
386 std::string* auth_code);
388 static bool ParseClientLoginToOAuth2Cookie(const std::string& cookie,
389 std::string* auth_code);
391 static bool ParseListIdpSessionsResponse(const std::string& data,
392 std::string* login_hint);
394 // Is this a special case Gaia error for TwoFactor auth?
395 static bool IsSecondFactorSuccess(const std::string& alleged_error);
397 // Is this a special case Gaia error for Less Secure Apps?
398 static bool IsWebLoginRequiredSuccess(const std::string& alleged_error);
400 // Given parameters, create a ClientLogin request body.
401 static std::string MakeClientLoginBody(
402 const std::string& username,
403 const std::string& password,
404 const std::string& source,
405 const char* const service,
406 const std::string& login_token,
407 const std::string& login_captcha,
408 HostedAccountsSetting allow_hosted_accounts);
409 // Supply the sid / lsid returned from ClientLogin in order to
410 // request a long lived auth token for a service.
411 static std::string MakeIssueAuthTokenBody(const std::string& sid,
412 const std::string& lsid,
413 const char* const service);
414 // Given auth code and device ID (optional), create body to get OAuth2 token
415 // pair.
416 static std::string MakeGetTokenPairBody(const std::string& auth_code,
417 const std::string& device_id);
418 // Given an OAuth2 token, create body to revoke the token.
419 std::string MakeRevokeTokenBody(const std::string& auth_token);
420 // Supply the lsid returned from ClientLogin in order to fetch
421 // user information.
422 static std::string MakeGetUserInfoBody(const std::string& lsid);
424 // Supply the authentication token returned from StartIssueAuthToken.
425 static std::string MakeMergeSessionBody(const std::string& auth_token,
426 const std::string& external_cc_result,
427 const std::string& continue_url,
428 const std::string& source);
430 static std::string MakeGetAuthCodeHeader(const std::string& auth_token);
432 static std::string MakeOAuthLoginBody(const std::string& service,
433 const std::string& source);
435 static std::string MakeListIDPSessionsBody(const std::string& scopes,
436 const std::string& domain);
438 static std::string MakeGetTokenResponseBody(const std::string& scopes,
439 const std::string& domain,
440 const std::string& login_hint);
442 // From a URLFetcher result, generate an appropriate error.
443 // From the API documentation, both IssueAuthToken and ClientLogin have
444 // the same error returns.
445 static GoogleServiceAuthError GenerateAuthError(
446 const std::string& data,
447 const net::URLRequestStatus& status);
449 // These fields are common to GaiaAuthFetcher, same every request.
450 GaiaAuthConsumer* const consumer_;
451 net::URLRequestContextGetter* const getter_;
452 std::string source_;
453 const GURL client_login_gurl_;
454 const GURL issue_auth_token_gurl_;
455 const GURL oauth2_token_gurl_;
456 const GURL oauth2_revoke_gurl_;
457 const GURL get_user_info_gurl_;
458 const GURL merge_session_gurl_;
459 const GURL uberauth_token_gurl_;
460 const GURL oauth_login_gurl_;
461 const GURL list_accounts_gurl_;
462 const GURL logout_gurl_;
463 const GURL get_check_connection_info_url_;
464 const GURL oauth2_iframe_url_;
466 // While a fetch is going on:
467 scoped_ptr<net::URLFetcher> fetcher_;
468 GURL client_login_to_oauth2_gurl_;
469 std::string request_body_;
470 std::string requested_service_;
471 bool fetch_pending_;
473 friend class GaiaAuthFetcherTest;
474 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CaptchaParse);
475 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, AccountDeletedError);
476 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, AccountDisabledError);
477 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, BadAuthenticationError);
478 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, IncomprehensibleError);
479 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ServiceUnavailableError);
480 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CheckNormalErrorCode);
481 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CheckTwoFactorResponse);
482 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, LoginNetFailure);
483 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest,
484 ParseClientLoginToOAuth2Response);
485 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ParseOAuth2TokenPairResponse);
486 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ClientOAuthSuccess);
487 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ClientOAuthWithQuote);
488 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ClientOAuthChallengeSuccess);
489 FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ClientOAuthChallengeQuote);
491 DISALLOW_COPY_AND_ASSIGN(GaiaAuthFetcher);
494 #endif // GOOGLE_APIS_GAIA_GAIA_AUTH_FETCHER_H_