Home | History | Annotate | Download | only in gaia
      1 // Copyright (c) 2011 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.
      4 
      5 #ifndef CHROME_COMMON_NET_GAIA_GAIA_AUTH_FETCHER_H_
      6 #define CHROME_COMMON_NET_GAIA_GAIA_AUTH_FETCHER_H_
      7 #pragma once
      8 
      9 #include <string>
     10 
     11 #include "base/gtest_prod_util.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "chrome/common/net/gaia/gaia_auth_consumer.h"
     14 #include "chrome/common/net/url_fetcher.h"
     15 #include "googleurl/src/gurl.h"
     16 
     17 // Authenticate a user against the Google Accounts ClientLogin API
     18 // with various capabilities and return results to a GaiaAuthConsumer.
     19 //
     20 // In the future, we will also issue auth tokens from this class.
     21 // This class should be used on a single thread, but it can be whichever thread
     22 // that you like.
     23 //
     24 // This class can handle one request at a time. To parallelize requests,
     25 // create multiple GaiaAuthFetcher's.
     26 
     27 class GaiaAuthFetcherTest;
     28 
     29 class GaiaAuthFetcher : public URLFetcher::Delegate {
     30  public:
     31   enum HostedAccountsSetting {
     32     HostedAccountsAllowed,
     33     HostedAccountsNotAllowed
     34   };
     35 
     36   // The URLs for different calls in the Google Accounts programmatic login API.
     37   static const char kClientLoginUrl[];
     38   static const char kIssueAuthTokenUrl[];
     39   static const char kGetUserInfoUrl[];
     40 
     41   // Magic string indicating that, while a second factor is still
     42   // needed to complete authentication, the user provided the right password.
     43   static const char kSecondFactor[];
     44 
     45   // This will later be hidden behind an auth service which caches
     46   // tokens.
     47   GaiaAuthFetcher(GaiaAuthConsumer* consumer,
     48                   const std::string& source,
     49                   net::URLRequestContextGetter* getter);
     50   virtual ~GaiaAuthFetcher();
     51 
     52   // GaiaAuthConsumer will be called on the original thread
     53   // after results come back. This class is thread agnostic.
     54   // You can't make more than request at a time.
     55   void StartClientLogin(const std::string& username,
     56                         const std::string& password,
     57                         const char* const service,
     58                         const std::string& login_token,
     59                         const std::string& login_captcha,
     60                         HostedAccountsSetting allow_hosted_accounts);
     61 
     62   // GaiaAuthConsumer will be called on the original thread
     63   // after results come back. This class is thread agnostic.
     64   // You can't make more than one request at a time.
     65   void StartIssueAuthToken(const std::string& sid,
     66                            const std::string& lsid,
     67                            const char* const service);
     68 
     69   // Start a request to get a particular key from user info.
     70   // GaiaAuthConsumer will be called back on the same thread when
     71   // results come back.
     72   // You can't make more than one request at a time.
     73   void StartGetUserInfo(const std::string& lsid,
     74                         const std::string& info_key);
     75 
     76   // Implementation of URLFetcher::Delegate
     77   virtual void OnURLFetchComplete(const URLFetcher* source,
     78                                   const GURL& url,
     79                                   const net::URLRequestStatus& status,
     80                                   int response_code,
     81                                   const ResponseCookies& cookies,
     82                                   const std::string& data);
     83 
     84   // StartClientLogin been called && results not back yet?
     85   bool HasPendingFetch();
     86 
     87   // Stop any URL fetches in progress.
     88   void CancelRequest();
     89 
     90  private:
     91   // ClientLogin body constants that don't change
     92   static const char kCookiePersistence[];
     93   static const char kAccountTypeHostedOrGoogle[];
     94   static const char kAccountTypeGoogle[];
     95 
     96   // The format of the POST body for ClientLogin.
     97   static const char kClientLoginFormat[];
     98   // The format of said POST body when CAPTCHA token & answer are specified.
     99   static const char kClientLoginCaptchaFormat[];
    100   // The format of the POST body for IssueAuthToken.
    101   static const char kIssueAuthTokenFormat[];
    102   // The format of the POSt body for GetUserInfo.
    103   static const char kGetUserInfoFormat[];
    104 
    105   // Constants for parsing ClientLogin errors.
    106   static const char kAccountDeletedError[];
    107   static const char kAccountDisabledError[];
    108   static const char kBadAuthenticationError[];
    109   static const char kCaptchaError[];
    110   static const char kServiceUnavailableError[];
    111   static const char kErrorParam[];
    112   static const char kErrorUrlParam[];
    113   static const char kCaptchaUrlParam[];
    114   static const char kCaptchaTokenParam[];
    115   static const char kCaptchaUrlPrefix[];
    116 
    117   // Process the results of a ClientLogin fetch.
    118   void OnClientLoginFetched(const std::string& data,
    119                             const net::URLRequestStatus& status,
    120                             int response_code);
    121 
    122   void OnIssueAuthTokenFetched(const std::string& data,
    123                                const net::URLRequestStatus& status,
    124                                int response_code);
    125 
    126   void OnGetUserInfoFetched(const std::string& data,
    127                             const net::URLRequestStatus& status,
    128                             int response_code);
    129 
    130   // Tokenize the results of a ClientLogin fetch.
    131   static void ParseClientLoginResponse(const std::string& data,
    132                                        std::string* sid,
    133                                        std::string* lsid,
    134                                        std::string* token);
    135 
    136   static void ParseClientLoginFailure(const std::string& data,
    137                                       std::string* error,
    138                                       std::string* error_url,
    139                                       std::string* captcha_url,
    140                                       std::string* captcha_token);
    141 
    142   // From a URLFetcher result, generate an appropriate error.
    143   // From the API documentation, both IssueAuthToken and ClientLogin have
    144   // the same error returns.
    145   static GoogleServiceAuthError GenerateAuthError(
    146       const std::string& data,
    147       const net::URLRequestStatus& status);
    148 
    149   // Is this a special case Gaia error for TwoFactor auth?
    150   static bool IsSecondFactorSuccess(const std::string& alleged_error);
    151 
    152   // Given parameters, create a ClientLogin request body.
    153   static std::string MakeClientLoginBody(
    154       const std::string& username,
    155       const std::string& password,
    156       const std::string& source,
    157       const char* const service,
    158       const std::string& login_token,
    159       const std::string& login_captcha,
    160       HostedAccountsSetting allow_hosted_accounts);
    161   // Supply the sid / lsid returned from ClientLogin in order to
    162   // request a long lived auth token for a service.
    163   static std::string MakeIssueAuthTokenBody(const std::string& sid,
    164                                             const std::string& lsid,
    165                                             const char* const service);
    166   // Supply the lsid returned from ClientLogin in order to fetch
    167   // user information.
    168   static std::string MakeGetUserInfoBody(const std::string& lsid);
    169 
    170   // Create a fetcher useable for making any Gaia request.
    171   static URLFetcher* CreateGaiaFetcher(net::URLRequestContextGetter* getter,
    172                                        const std::string& body,
    173                                        const GURL& gaia_gurl_,
    174                                        URLFetcher::Delegate* delegate);
    175 
    176 
    177   // These fields are common to GaiaAuthFetcher, same every request
    178   GaiaAuthConsumer* const consumer_;
    179   net::URLRequestContextGetter* const getter_;
    180   std::string source_;
    181   const GURL client_login_gurl_;
    182   const GURL issue_auth_token_gurl_;
    183   const GURL get_user_info_gurl_;
    184 
    185   // While a fetch is going on:
    186   scoped_ptr<URLFetcher> fetcher_;
    187   std::string request_body_;
    188   std::string requested_service_;   // Currently tracked for IssueAuthToken only
    189   std::string requested_info_key_;  // Currently tracked for GetUserInfo only
    190   bool fetch_pending_;
    191 
    192   friend class GaiaAuthFetcherTest;
    193   FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CaptchaParse);
    194   FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, AccountDeletedError);
    195   FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, AccountDisabledError);
    196   FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, BadAuthenticationError);
    197   FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, IncomprehensibleError);
    198   FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, ServiceUnavailableError);
    199   FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CheckNormalErrorCode);
    200   FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, CheckTwoFactorResponse);
    201   FRIEND_TEST_ALL_PREFIXES(GaiaAuthFetcherTest, LoginNetFailure);
    202 
    203   DISALLOW_COPY_AND_ASSIGN(GaiaAuthFetcher);
    204 };
    205 
    206 #endif  // CHROME_COMMON_NET_GAIA_GAIA_AUTH_FETCHER_H_
    207