• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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