15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef GOOGLE_APIS_GAIA_GAIA_AUTH_FETCHER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GOOGLE_APIS_GAIA_GAIA_AUTH_FETCHER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/gaia_auth_consumer.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/google_service_auth_error.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h"
167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Authenticate a user against the Google Accounts ClientLogin API
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// with various capabilities and return results to a GaiaAuthConsumer.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In the future, we will also issue auth tokens from this class.
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class should be used on a single thread, but it can be whichever thread
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that you like.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class can handle one request at a time on any thread. To parallelize
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// requests, create multiple GaiaAuthFetcher's.
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GaiaAuthFetcherTest;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLFetcher;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLRequestContextGetter;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLRequestStatus;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GaiaAuthFetcher : public net::URLFetcherDelegate {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum HostedAccountsSetting {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostedAccountsAllowed,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HostedAccountsNotAllowed
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Magic string indicating that, while a second factor is still
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // needed to complete authentication, the user provided the right password.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kSecondFactor[];
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This will later be hidden behind an auth service which caches
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // tokens.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GaiaAuthFetcher(GaiaAuthConsumer* consumer,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const std::string& source,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  net::URLRequestContextGetter* getter);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~GaiaAuthFetcher();
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a request to obtain the SID and LSID cookies for the the account
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // identified by |username| and |password|.  If |service| is not null or
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // empty, then also obtains a service token for specified service.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If this is a second call because of captcha challenge, then the
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |login_token| and |login_captcha| arugment should correspond to the
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // solution of the challenge.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Either OnClientLoginSuccess or OnClientLoginFailure will be
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called on the consumer on the original thread.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartClientLogin(const std::string& username,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const std::string& password,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const char* const service,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const std::string& login_token,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        const std::string& login_captcha,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        HostedAccountsSetting allow_hosted_accounts);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a request to obtain service token for the the account identified by
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |sid| and |lsid| and the |service|.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Either OnIssueAuthTokenSuccess or OnIssueAuthTokenFailure will be
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called on the consumer on the original thread.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartIssueAuthToken(const std::string& sid,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const std::string& lsid,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const char* const service);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Start a request to obtain |service| token for the the account identified by
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |uber_token|.
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Either OnIssueAuthTokenSuccess or OnIssueAuthTokenFailure will be
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // called on the consumer on the original thread.
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StartTokenAuth(const std::string& uber_token,
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      const char* const service);
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Start a request to obtain service token for the the account identified by
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |oauth2_access_token| and the |service|.
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Either OnIssueAuthTokenSuccess or OnIssueAuthTokenFailure will be
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // called on the consumer on the original thread.
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StartIssueAuthTokenForOAuth2(const std::string& oauth2_access_token,
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const char* const service);
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a request to exchange an "lso" service token given by |auth_token|
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for an OAuthLogin-scoped oauth2 token.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Either OnClientOAuthSuccess or OnClientOAuthFailure will be
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called on the consumer on the original thread.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartLsoForOAuthLoginTokenExchange(const std::string& auth_token);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Start a request to revoke |auth_token|.
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
105558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // OnOAuth2RevokeTokenCompleted will be called on the consumer on the original
106558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // thread.
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void StartRevokeOAuth2Token(const std::string& auth_token);
108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a request to exchange the cookies of a signed-in user session
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for an OAuthLogin-scoped oauth2 token.  In the case of a session with
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // multiple accounts signed in, |session_index| indicate the which of accounts
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // within the session.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Either OnClientOAuthSuccess or OnClientOAuthFailure will be
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called on the consumer on the original thread.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartCookieForOAuthLoginTokenExchange(const std::string& session_index);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Start a request to exchange the authorization code for an OAuthLogin-scoped
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // oauth2 token.
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Either OnClientOAuthSuccess or OnClientOAuthFailure will be
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // called on the consumer on the original thread.
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StartAuthCodeForOAuth2TokenExchange(const std::string& auth_code);
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a request to get user info for the account identified by |lsid|.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Either OnGetUserInfoSuccess or OnGetUserInfoFailure will be
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called on the consumer on the original thread.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartGetUserInfo(const std::string& lsid);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a MergeSession request to pre-login the user with the given
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // credentials.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a MergeSession request to fill the browsing cookie jar with
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // credentials represented by the account whose uber-auth token is
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |uber_token|.  This method will modify the cookies of the current profile.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Either OnMergeSessionSuccess or OnMergeSessionFailure will be
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called on the consumer on the original thread.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartMergeSession(const std::string& uber_token);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a request to exchange an OAuthLogin-scoped oauth2 access token for an
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // uber-auth token.  The returned token can be used with the method
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // StartMergeSession().
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Either OnUberAuthTokenSuccess or OnUberAuthTokenFailure will be
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called on the consumer on the original thread.
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartTokenFetchForUberAuthExchange(const std::string& access_token);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Start a request to exchange an OAuthLogin-scoped oauth2 access token for a
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ClientLogin-style service tokens.  The response to this request is the
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // same as the response to a ClientLogin request, except that captcha
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // challenges are never issued.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Either OnClientLoginSuccess or OnClientLoginFailure will be
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // called on the consumer on the original thread. If |service| is empty,
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the call will attempt to fetch uber auth token.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartOAuthLogin(const std::string& access_token,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const std::string& service);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Starts a request to list the accounts in the GAIA cookie.
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void StartListAccounts();
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Implementation of net::URLFetcherDelegate
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // StartClientLogin been called && results not back yet?
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool HasPendingFetch();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stop any URL fetches in progress.
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CancelRequest();
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // From a URLFetcher result, generate an appropriate error.
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // From the API documentation, both IssueAuthToken and ClientLogin have
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the same error returns.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static GoogleServiceAuthError GenerateOAuthLoginError(
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& data,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::URLRequestStatus& status);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ClientLogin body constants that don't change
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kCookiePersistence[];
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kAccountTypeHostedOrGoogle[];
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kAccountTypeGoogle[];
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The format of the POST body for ClientLogin.
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kClientLoginFormat[];
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The format of said POST body when CAPTCHA token & answer are specified.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kClientLoginCaptchaFormat[];
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The format of the POST body for IssueAuthToken.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kIssueAuthTokenFormat[];
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The format of the POST body to get OAuth2 auth code from auth token.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kClientLoginToOAuth2BodyFormat[];
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The format of the POST body to get OAuth2 token pair from auth code.
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kOAuth2CodeToTokenPairBodyFormat[];
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The format of the POST body to revoke an OAuth2 token.
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static const char kOAuth2RevokeTokenBodyFormat[];
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The format of the POST body for GetUserInfo.
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kGetUserInfoFormat[];
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The format of the POST body for MergeSession.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kMergeSessionFormat[];
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The format of the URL for UberAuthToken.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kUberAuthTokenURLFormat[];
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The format of the body for OAuthLogin.
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kOAuthLoginFormat[];
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Constants for parsing ClientLogin errors.
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kAccountDeletedError[];
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kAccountDeletedErrorCode[];
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kAccountDisabledError[];
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kAccountDisabledErrorCode[];
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kBadAuthenticationError[];
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kBadAuthenticationErrorCode[];
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kCaptchaError[];
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kCaptchaErrorCode[];
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kServiceUnavailableError[];
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kServiceUnavailableErrorCode[];
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kErrorParam[];
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kErrorUrlParam[];
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kCaptchaUrlParam[];
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kCaptchaTokenParam[];
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Constants for parsing ClientOAuth errors.
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kNeedsAdditional[];
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kCaptcha[];
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kTwoFactor[];
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Constants for request/response for OAuth2 requests.
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kAuthHeaderFormat[];
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kOAuthHeaderFormat[];
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const char kOAuth2BearerHeaderFormat[];
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kClientLoginToOAuth2CookiePartSecure[];
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kClientLoginToOAuth2CookiePartHttpOnly[];
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kClientLoginToOAuth2CookiePartCodePrefix[];
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kClientLoginToOAuth2CookiePartCodePrefixLength;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Process the results of a ClientLogin fetch.
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnClientLoginFetched(const std::string& data,
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const net::URLRequestStatus& status,
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            int response_code);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnIssueAuthTokenFetched(const std::string& data,
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const net::URLRequestStatus& status,
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               int response_code);
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnClientLoginToOAuth2Fetched(const std::string& data,
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const net::ResponseCookies& cookies,
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const net::URLRequestStatus& status,
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int response_code);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnOAuth2TokenPairFetched(const std::string& data,
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const net::URLRequestStatus& status,
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                int response_code);
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void OnOAuth2RevokeTokenFetched(const std::string& data,
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  const net::URLRequestStatus& status,
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  int response_code);
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void OnListAccountsFetched(const std::string& data,
260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             const net::URLRequestStatus& status,
261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             int response_code);
262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnGetUserInfoFetched(const std::string& data,
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const net::URLRequestStatus& status,
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            int response_code);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnMergeSessionFetched(const std::string& data,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const net::URLRequestStatus& status,
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int response_code);
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnUberAuthTokenFetch(const std::string& data,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const net::URLRequestStatus& status,
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            int response_code);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnOAuthLoginFetched(const std::string& data,
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const net::URLRequestStatus& status,
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           int response_code);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tokenize the results of a ClientLogin fetch.
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void ParseClientLoginResponse(const std::string& data,
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       std::string* sid,
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       std::string* lsid,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       std::string* token);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void ParseClientLoginFailure(const std::string& data,
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      std::string* error,
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      std::string* error_url,
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      std::string* captcha_url,
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      std::string* captcha_token);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parse ClientLogin to OAuth2 response.
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool ParseClientLoginToOAuth2Response(
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::ResponseCookies& cookies,
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string* auth_code);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool ParseClientLoginToOAuth2Cookie(const std::string& cookie,
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             std::string* auth_code);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Is this a special case Gaia error for TwoFactor auth?
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool IsSecondFactorSuccess(const std::string& alleged_error);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Given parameters, create a ClientLogin request body.
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::string MakeClientLoginBody(
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& username,
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& password,
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& source,
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const char* const service,
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& login_token,
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& login_captcha,
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      HostedAccountsSetting allow_hosted_accounts);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Supply the sid / lsid returned from ClientLogin in order to
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // request a long lived auth token for a service.
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::string MakeIssueAuthTokenBody(const std::string& sid,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const std::string& lsid,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const char* const service);
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create body to get OAuth2 auth code.
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::string MakeGetAuthCodeBody();
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Given auth code, create body to get OAuth2 token pair.
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::string MakeGetTokenPairBody(const std::string& auth_code);
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Given an OAuth2 token, create body to revoke the token.
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string MakeRevokeTokenBody(const std::string& auth_token);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Supply the lsid returned from ClientLogin in order to fetch
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // user information.
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::string MakeGetUserInfoBody(const std::string& lsid);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Supply the authentication token returned from StartIssueAuthToken.
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::string MakeMergeSessionBody(const std::string& auth_token,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const std::string& continue_url,
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const std::string& source);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::string MakeGetAuthCodeHeader(const std::string& auth_token);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static std::string MakeOAuthLoginBody(const std::string& service,
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const std::string& source);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a fetcher usable for making any Gaia request.  |body| is used
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as the body of the POST request sent to GAIA.  Any strings listed in
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |headers| are added as extra HTTP headers in the request.
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |load_flags| are passed to directly to net::URLFetcher::Create() when
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // creating the URL fetcher.
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static net::URLFetcher* CreateGaiaFetcher(
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::URLRequestContextGetter* getter,
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& body,
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& headers,
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& gaia_gurl,
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int load_flags,
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::URLFetcherDelegate* delegate);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // From a URLFetcher result, generate an appropriate error.
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // From the API documentation, both IssueAuthToken and ClientLogin have
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the same error returns.
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static GoogleServiceAuthError GenerateAuthError(
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& data,
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::URLRequestStatus& status);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These fields are common to GaiaAuthFetcher, same every request
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GaiaAuthConsumer* const consumer_;
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestContextGetter* const getter_;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string source_;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL client_login_gurl_;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL issue_auth_token_gurl_;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL oauth2_token_gurl_;
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const GURL oauth2_revoke_gurl_;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL get_user_info_gurl_;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL merge_session_gurl_;
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL uberauth_token_gurl_;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const GURL oauth_login_gurl_;
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  const GURL list_accounts_gurl_;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // While a fetch is going on:
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::URLFetcher> fetcher_;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL client_login_to_oauth2_gurl_;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string request_body_;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string requested_service_; // Currently tracked for IssueAuthToken only.
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool fetch_pending_;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class GaiaAuthFetcherTest;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CaptchaParse);
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, AccountDeletedError);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, AccountDisabledError);
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, BadAuthenticationError);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, IncomprehensibleError);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ServiceUnavailableError);
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CheckNormalErrorCode);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CheckTwoFactorResponse);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, LoginNetFailure);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest,
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ParseClientLoginToOAuth2Response);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ParseOAuth2TokenPairResponse);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ClientOAuthSuccess);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ClientOAuthWithQuote);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ClientOAuthChallengeSuccess);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ClientOAuthChallengeQuote);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GaiaAuthFetcher);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // GOOGLE_APIS_GAIA_GAIA_AUTH_FETCHER_H_
400