13f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Use of this source code is governed by a BSD-style license that can be
306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// found in the LICENSE file.
406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
54a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#ifndef CHROME_COMMON_NET_GAIA_GAIA_AUTH_FETCHER_H_
64a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#define CHROME_COMMON_NET_GAIA_GAIA_AUTH_FETCHER_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once
806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include <string>
1006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
1106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "base/gtest_prod_util.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h"
1306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "chrome/common/net/gaia/gaia_auth_consumer.h"
1406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "chrome/common/net/url_fetcher.h"
1506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "googleurl/src/gurl.h"
1606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
1706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// Authenticate a user against the Google Accounts ClientLogin API
1806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// with various capabilities and return results to a GaiaAuthConsumer.
1906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch//
2006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// In the future, we will also issue auth tokens from this class.
2106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// This class should be used on a single thread, but it can be whichever thread
2206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// that you like.
2306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch//
2406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch// This class can handle one request at a time. To parallelize requests,
254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// create multiple GaiaAuthFetcher's.
2606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochclass GaiaAuthFetcherTest;
2806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochclass GaiaAuthFetcher : public URLFetcher::Delegate {
3006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch public:
31731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  enum HostedAccountsSetting {
32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    HostedAccountsAllowed,
33731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    HostedAccountsNotAllowed
34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  };
35731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // The URLs for different calls in the Google Accounts programmatic login API.
3706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  static const char kClientLoginUrl[];
3806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  static const char kIssueAuthTokenUrl[];
393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static const char kGetUserInfoUrl[];
4006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
4106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Magic string indicating that, while a second factor is still
4206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // needed to complete authentication, the user provided the right password.
4306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  static const char kSecondFactor[];
4406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
4506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // This will later be hidden behind an auth service which caches
4606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // tokens.
474a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  GaiaAuthFetcher(GaiaAuthConsumer* consumer,
484a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch                  const std::string& source,
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                  net::URLRequestContextGetter* getter);
504a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  virtual ~GaiaAuthFetcher();
5106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
5206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // GaiaAuthConsumer will be called on the original thread
5306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // after results come back. This class is thread agnostic.
5406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // You can't make more than request at a time.
5506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void StartClientLogin(const std::string& username,
5606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                        const std::string& password,
5706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                        const char* const service,
5806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                        const std::string& login_token,
59731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                        const std::string& login_captcha,
60731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                        HostedAccountsSetting allow_hosted_accounts);
6106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
6206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // GaiaAuthConsumer will be called on the original thread
6306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // after results come back. This class is thread agnostic.
6406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // You can't make more than one request at a time.
6506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void StartIssueAuthToken(const std::string& sid,
6606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                           const std::string& lsid,
6706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                           const char* const service);
6806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Start a request to get a particular key from user info.
703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // GaiaAuthConsumer will be called back on the same thread when
713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // results come back.
723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // You can't make more than one request at a time.
733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void StartGetUserInfo(const std::string& lsid,
743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                        const std::string& info_key);
753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
7606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Implementation of URLFetcher::Delegate
7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual void OnURLFetchComplete(const URLFetcher* source,
7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                  const GURL& url,
793f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                                  const net::URLRequestStatus& status,
8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                  int response_code,
8121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                  const ResponseCookies& cookies,
8221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                  const std::string& data);
8306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
8406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // StartClientLogin been called && results not back yet?
8506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  bool HasPendingFetch();
8606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
8706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Stop any URL fetches in progress.
8806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void CancelRequest();
8906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
9006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch private:
9106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // ClientLogin body constants that don't change
9206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  static const char kCookiePersistence[];
93731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  static const char kAccountTypeHostedOrGoogle[];
94731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  static const char kAccountTypeGoogle[];
9506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
9606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // The format of the POST body for ClientLogin.
9706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  static const char kClientLoginFormat[];
9806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // The format of said POST body when CAPTCHA token & answer are specified.
9906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  static const char kClientLoginCaptchaFormat[];
10006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // The format of the POST body for IssueAuthToken.
10106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  static const char kIssueAuthTokenFormat[];
1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The format of the POSt body for GetUserInfo.
1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static const char kGetUserInfoFormat[];
1043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Constants for parsing ClientLogin errors.
1063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static const char kAccountDeletedError[];
1073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static const char kAccountDisabledError[];
108201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  static const char kBadAuthenticationError[];
1093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static const char kCaptchaError[];
1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static const char kServiceUnavailableError[];
1113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static const char kErrorParam[];
1123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static const char kErrorUrlParam[];
1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static const char kCaptchaUrlParam[];
1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static const char kCaptchaTokenParam[];
1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static const char kCaptchaUrlPrefix[];
11606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
11706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Process the results of a ClientLogin fetch.
11806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void OnClientLoginFetched(const std::string& data,
1193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                            const net::URLRequestStatus& status,
12006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                            int response_code);
12106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
12206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  void OnIssueAuthTokenFetched(const std::string& data,
1233f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                               const net::URLRequestStatus& status,
12406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                               int response_code);
12506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  void OnGetUserInfoFetched(const std::string& data,
1273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen                            const net::URLRequestStatus& status,
1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                            int response_code);
1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
13006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Tokenize the results of a ClientLogin fetch.
13106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  static void ParseClientLoginResponse(const std::string& data,
13206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                                       std::string* sid,
13306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                                       std::string* lsid,
13406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                                       std::string* token);
13506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static void ParseClientLoginFailure(const std::string& data,
1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                      std::string* error,
1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                      std::string* error_url,
1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                      std::string* captcha_url,
1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                      std::string* captcha_token);
1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // From a URLFetcher result, generate an appropriate error.
14306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // From the API documentation, both IssueAuthToken and ClientLogin have
14406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // the same error returns.
1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static GoogleServiceAuthError GenerateAuthError(
14606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch      const std::string& data,
1473f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      const net::URLRequestStatus& status);
14806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
14906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Is this a special case Gaia error for TwoFactor auth?
15006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  static bool IsSecondFactorSuccess(const std::string& alleged_error);
15106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
15206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Given parameters, create a ClientLogin request body.
153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  static std::string MakeClientLoginBody(
154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      const std::string& username,
155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      const std::string& password,
156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      const std::string& source,
157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      const char* const service,
158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      const std::string& login_token,
159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      const std::string& login_captcha,
160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      HostedAccountsSetting allow_hosted_accounts);
16106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Supply the sid / lsid returned from ClientLogin in order to
16206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // request a long lived auth token for a service.
16306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  static std::string MakeIssueAuthTokenBody(const std::string& sid,
16406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                                            const std::string& lsid,
16506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                                            const char* const service);
1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Supply the lsid returned from ClientLogin in order to fetch
1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // user information.
1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static std::string MakeGetUserInfoBody(const std::string& lsid);
16906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
17006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // Create a fetcher useable for making any Gaia request.
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  static URLFetcher* CreateGaiaFetcher(net::URLRequestContextGetter* getter,
17206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                                       const std::string& body,
17306741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                                       const GURL& gaia_gurl_,
17406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch                                       URLFetcher::Delegate* delegate);
17506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
17606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
1774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  // These fields are common to GaiaAuthFetcher, same every request
17806741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  GaiaAuthConsumer* const consumer_;
179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  net::URLRequestContextGetter* const getter_;
18006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  std::string source_;
18106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  const GURL client_login_gurl_;
18206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  const GURL issue_auth_token_gurl_;
1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const GURL get_user_info_gurl_;
18406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
18506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  // While a fetch is going on:
18606741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  scoped_ptr<URLFetcher> fetcher_;
18706741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  std::string request_body_;
1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string requested_service_;   // Currently tracked for IssueAuthToken only
1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string requested_info_key_;  // Currently tracked for GetUserInfo only
19006741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch  bool fetch_pending_;
19106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
1924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  friend class GaiaAuthFetcherTest;
1934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CaptchaParse);
1944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, AccountDeletedError);
1954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, AccountDisabledError);
196201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, BadAuthenticationError);
197201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, IncomprehensibleError);
1984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ServiceUnavailableError);
1994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CheckNormalErrorCode);
2004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CheckTwoFactorResponse);
2014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, LoginNetFailure);
20206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
2034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(GaiaAuthFetcher);
20406741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch};
20506741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch
2064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#endif  // CHROME_COMMON_NET_GAIA_GAIA_AUTH_FETCHER_H_
207