gaia_auth_fetcher.h revision 3f50c38dc070f4bb515c1b64450dae14f316474e
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" 1206741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch#include "base/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, 494a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 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. 17106741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch static URLFetcher* CreateGaiaFetcher(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_; 17906741cbc25cd4227a9fba40dfd0273bfcc1a587aBen Murdoch 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