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.
5 // Use this class to authenticate users with Gaia and access cookies sent
6 // by the Gaia servers. This class cannot be used on its own becaue it relies
7 // on a subclass to provide the virtual Post and GetBackoffDelaySeconds methods.
10 // class ActualGaiaAuthenticator : public gaia::GaiaAuthenticator {
11 // Provides actual implementation of Post and GetBackoffDelaySeconds.
13 // ActualGaiaAuthenticator gaia_auth("User-Agent", SERVICE_NAME, kGaiaUrl);
14 // if (gaia_auth.Authenticate("email", "passwd", SAVE_IN_MEMORY_ONLY,
15 // true)) { // Synchronous
16 // // Do something with: gaia_auth.auth_token(), or gaia_auth.sid(),
17 // // or gaia_auth.lsid()
20 // Credentials can also be preserved for subsequent requests, though these are
21 // saved in plain-text in memory, and not very secure on client systems. The
22 // email address associated with the Gaia account can be read; the password is
25 // TODO(sanjeevr): This class has been moved here from the bookmarks sync code.
26 // While it is a generic class that handles GAIA authentication, there are some
27 // artifacts of the sync code which needs to be cleaned up.
28 #ifndef GOOGLE_APIS_GAIA_GAIA_AUTHENTICATOR_H_
29 #define GOOGLE_APIS_GAIA_GAIA_AUTHENTICATOR_H_
33 #include "base/basictypes.h"
34 #include "base/gtest_prod_util.h"
35 #include "base/message_loop.h"
36 #include "googleurl/src/gurl.h"
40 // Error codes from Gaia. These will be set correctly for both Gaia V1
41 // (/ClientAuth) and V2 (/ClientLogin)
42 enum AuthenticationError
{
44 BadAuthentication
= 1,
51 ServiceUnavailable
= 8,
52 // Errors generated by this class not Gaia.
53 CredentialsNotSet
= 9,
54 ConnectionUnavailable
= 10
57 class GaiaAuthenticator
;
59 // GaiaAuthenticator can be used to pass user credentials to Gaia and obtain
60 // cookies set by the Gaia servers.
61 class GaiaAuthenticator
{
62 FRIEND_TEST_ALL_PREFIXES(GaiaAuthenticatorTest
,
63 TestNewlineAtEndOfAuthTokenRemoved
);
66 // Since GaiaAuthenticator can be used for any service, or by any client, you
67 // must include a user-agent and a service-id when creating one. The
68 // user_agent is a short string used for simple log analysis. gaia_url is used
69 // to choose the server to authenticate with (e.g.
70 // http://accounts.google.com/ClientLogin).
71 GaiaAuthenticator(const std::string
& user_agent
,
72 const std::string
& service_id
,
73 const std::string
& gaia_url
);
75 virtual ~GaiaAuthenticator();
77 // This object should only be invoked from the AuthWatcherThread message
78 // loop, which is injected here.
79 void set_message_loop(const MessageLoop
* loop
) {
83 // Pass credentials to authenticate with, or use saved credentials via an
84 // overload. If authentication succeeds, you can retrieve the authentication
85 // token via the respective accessors. Returns a boolean indicating whether
86 // authentication succeeded or not.
87 bool Authenticate(const std::string
& user_name
, const std::string
& password
,
88 const std::string
& captcha_token
,
89 const std::string
& captcha_value
);
91 bool Authenticate(const std::string
& user_name
, const std::string
& password
);
93 // Pass the LSID to authenticate with. If the authentication succeeds, you can
94 // retrieve the authetication token via the respective accessors. Returns a
95 // boolean indicating whether authentication succeeded or not.
96 // Always returns a long lived token.
97 bool AuthenticateWithLsid(const std::string
& lsid
);
99 // Resets all stored cookies to their default values.
100 void ResetCredentials();
102 void SetUsernamePassword(const std::string
& username
,
103 const std::string
& password
);
105 void SetUsername(const std::string
& username
);
107 // Virtual for testing
108 virtual void RenewAuthToken(const std::string
& auth_token
);
109 void SetAuthToken(const std::string
& auth_token
);
113 AuthResults(const AuthResults
& other
);
117 std::string password
;
119 // Fields that store various cookies.
122 std::string auth_token
;
124 std::string primary_email
;
126 // Fields for items returned when authentication fails.
127 std::string error_msg
;
128 enum AuthenticationError auth_error
;
129 std::string auth_error_url
;
130 std::string captcha_token
;
131 std::string captcha_url
;
140 GaiaAuthenticator
* authenticator
;
143 std::string password
;
144 std::string captcha_token
;
145 std::string captcha_value
;
148 // mutex_ must be entered before calling this function.
149 AuthParams
MakeParams(const std::string
& user_name
,
150 const std::string
& password
,
151 const std::string
& captcha_token
,
152 const std::string
& captcha_value
);
154 // The real Authenticate implementations.
155 bool AuthenticateImpl(const AuthParams
& params
);
156 bool AuthenticateImpl(const AuthParams
& params
, AuthResults
* results
);
158 // virtual for testing purposes.
159 virtual bool PerformGaiaRequest(const AuthParams
& params
,
160 AuthResults
* results
);
161 virtual bool Post(const GURL
& url
, const std::string
& post_body
,
162 unsigned long* response_code
, std::string
* response_body
);
164 // Caller should fill in results->LSID before calling. Result in
165 // results->primary_email.
166 virtual bool LookupEmail(AuthResults
* results
);
168 // Subclasses must override to provide a backoff delay. It is virtual instead
169 // of pure virtual for testing purposes.
170 // TODO(sanjeevr): This should be made pure virtual. But this class is
171 // currently directly being used in sync/engine/authenticator.cc, which is
173 virtual int GetBackoffDelaySeconds(int current_backoff_delay
);
177 inline std::string
email() const {
178 DCHECK_EQ(MessageLoop::current(), message_loop_
);
179 return auth_results_
.email
;
182 // Retrieve password.
183 inline std::string
password() const {
184 DCHECK_EQ(MessageLoop::current(), message_loop_
);
185 return auth_results_
.password
;
188 // Retrieve AuthToken, if previously authenticated; otherwise returns "".
189 inline std::string
auth_token() const {
190 DCHECK_EQ(MessageLoop::current(), message_loop_
);
191 return auth_results_
.auth_token
;
194 // Retrieve SID cookie. For details, see the Google Accounts documentation.
195 inline std::string
sid() const {
196 DCHECK_EQ(MessageLoop::current(), message_loop_
);
197 return auth_results_
.sid
;
200 // Retrieve LSID cookie. For details, see the Google Accounts documentation.
201 inline std::string
lsid() const {
202 DCHECK_EQ(MessageLoop::current(), message_loop_
);
203 return auth_results_
.lsid
;
206 // Get last authentication error.
207 inline enum AuthenticationError
auth_error() const {
208 DCHECK_EQ(MessageLoop::current(), message_loop_
);
209 return auth_results_
.auth_error
;
212 inline std::string
auth_error_url() const {
213 DCHECK_EQ(MessageLoop::current(), message_loop_
);
214 return auth_results_
.auth_error_url
;
217 inline std::string
captcha_token() const {
218 DCHECK_EQ(MessageLoop::current(), message_loop_
);
219 return auth_results_
.captcha_token
;
222 inline std::string
captcha_url() const {
223 DCHECK_EQ(MessageLoop::current(), message_loop_
);
224 return auth_results_
.captcha_url
;
227 inline AuthResults
results() const {
228 DCHECK_EQ(MessageLoop::current(), message_loop_
);
229 return auth_results_
;
233 bool IssueAuthToken(AuthResults
* results
, const std::string
& service_id
);
235 // Helper method to parse response when authentication succeeds.
236 void ExtractTokensFrom(const std::string
& response
, AuthResults
* results
);
237 // Helper method to parse response when authentication fails.
238 void ExtractAuthErrorFrom(const std::string
& response
, AuthResults
* results
);
240 // Fields for the obvious data items.
241 const std::string user_agent_
;
242 const std::string service_id_
;
243 const std::string gaia_url_
;
245 AuthResults auth_results_
;
247 // When multiple async requests are running, only the one that started most
248 // recently updates the values.
250 // Note that even though this code was written to handle multiple requests
251 // simultaneously, the sync code issues auth requests one at a time.
252 uint32 request_count_
;
254 // Used to compute backoff time for next allowed authentication.
255 int delay_
; // In seconds.
256 // On Windows, time_t is 64-bit by default. Even though we have defined the
257 // _USE_32BIT_TIME_T preprocessor flag, other libraries including this header
258 // may not have that preprocessor flag defined resulting in mismatched class
259 // sizes. So we explicitly define it as 32-bit on Windows.
260 // TODO(sanjeevr): Change this to to use base::Time
262 __time32_t next_allowed_auth_attempt_time_
;
263 #else // defined(OS_WIN)
264 time_t next_allowed_auth_attempt_time_
;
265 #endif // defined(OS_WIN)
266 int early_auth_attempt_count_
;
268 // The message loop all our methods are invoked on.
269 const MessageLoop
* message_loop_
;
273 #endif // GOOGLE_APIS_GAIA_GAIA_AUTHENTICATOR_H_