Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(506)

Side by Side Diff: chrome/browser/sync/engine/net/gaia_authenticator.h

Issue 194065: Initial commit of sync engine code to browser/sync.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Fixes to gtest include path, reverted syncapi. Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2009 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 // Use this class to authenticate users with Gaia and access cookies sent
6 // by the Gaia servers.
7 //
8 // Sample usage:
9 // GaiaAuthenticator gaia_auth("User-Agent", SYNC_SERVICE_NAME,
10 // browser_sync::kExternalGaiaUrl);
11 // if (gaia_auth.Authenticate("email", "passwd", SAVE_IN_MEMORY_ONLY,
12 // true)) { // Synchronous
13 // // Do something with: gaia_auth.auth_token(), or gaia_auth.sid(),
14 // // or gaia_auth.lsid()
15 // }
16 //
17 // Sample asynchonous usage:
18 // GaiaAuthenticator gaia_auth("User-Agent", SYNC_SERVICE_NAME,
19 // browser_sync::kExternalGaiaUrl);
20 // EventListenerHookup* hookup = NewListenerHookup(gaia_auth.channel(),
21 // this, &OnAuthenticate);
22 // gaia_auth.Authenticate("email", "passwd", true, false);
23 // // OnAuthenticate() will get called with result;
24 //
25 // Credentials can also be preserved for subsequent requests, though these are
26 // saved in plain-text in memory, and not very secure on client systems. The
27 // email address associated with the Gaia account can be read; the password is
28 // write-only.
29
30 #ifndef CHROME_BROWSER_SYNC_ENGINE_NET_GAIA_AUTHENTICATOR_H_
31 #define CHROME_BROWSER_SYNC_ENGINE_NET_GAIA_AUTHENTICATOR_H_
32
33 #include <string>
34
35 #include "base/basictypes.h"
36 #include "chrome/browser/sync/engine/net/http_return.h"
37 #include "chrome/browser/sync/util/event_sys.h"
38 #include "chrome/browser/sync/util/pthread_helpers.h"
39 #include "chrome/browser/sync/util/signin.h"
40 #include "googleurl/src/gurl.h"
41 #include "testing/gtest/include/gtest/gtest_prod.h" // For FRIEND_TEST
42
43 namespace browser_sync {
44
45 static const char kGaiaUrl[] =
46 "https://www.google.com:443/accounts/ClientLogin";
47
48 // Use of the following enum is odd. GaiaAuthenticator only looks at
49 // and DONT_SAVE_CREDENTIALS and SAVE_IN_MEMORY_ONLY (PERSIST_TO_DISK is == to
50 // SAVE_IN_MEMORY_ONLY for GaiaAuthenticator). The sync engine never uses
51 // DONT_SAVE_CREDENTIALS. AuthWatcher does look in GaiaAuthenticator's results
52 // object to decide if it should save credentials to disk. This currently
53 // works so I'm leaving the odd dance alone.
54
55 enum SaveCredentials {
56 DONT_SAVE_CREDENTIALS,
57 SAVE_IN_MEMORY_ONLY,
58 PERSIST_TO_DISK // Saved in both memory and disk
59 };
60
61 // Error codes from Gaia. These will be set correctly for both Gaia V1
62 // (/ClientAuth) and V2 (/ClientLogin)
63 enum AuthenticationError {
64 None = 0,
65 BadAuthentication = 1,
66 NotVerified = 2,
67 TermsNotAgreed = 3,
68 Unknown = 4,
69 AccountDeleted = 5,
70 AccountDisabled = 6,
71 CaptchaRequired = 7,
72 ServiceUnavailable = 8,
73 // Errors generated by this class not Gaia.
74 CredentialsNotSet = 9,
75 ConnectionUnavailable = 10
76 };
77
78 class GaiaAuthenticator;
79
80 struct GaiaAuthEvent {
81 enum {
82 GAIA_AUTH_FAILED,
83 GAIA_AUTH_SUCCEEDED,
84 GAIA_AUTHENTICATOR_DESTROYED
85 }
86 what_happened;
87 AuthenticationError error;
88 const GaiaAuthenticator* authenticator;
89
90 // Lets us use GaiaAuthEvent as its own traits type in hookups.
91 typedef GaiaAuthEvent EventType;
92 static inline bool IsChannelShutdownEvent(const GaiaAuthEvent& event) {
93 return event.what_happened == GAIA_AUTHENTICATOR_DESTROYED;
94 }
95 };
96
97 // GaiaAuthenticator can be used to pass user credentials to Gaia and obtain
98 // cookies set by the Gaia servers.
99 class GaiaAuthenticator {
100 FRIEND_TEST(GaiaAuthenticatorTest, TestNewlineAtEndOfAuthTokenRemoved);
101 public:
102
103 // Since GaiaAuthenticator can be used for any service, or by any client, you
104 // must include a user-agent and a service-id when creating one. The
105 // user_agent is a short string used for simple log analysis. gaia_url is used
106 // to choose the server to authenticate with (e.g.
107 // http://www.google.com/accounts/ClientLogin).
108 GaiaAuthenticator(const std::string& user_agent,
109 const std::string& service_id,
110 const std::string& gaia_url);
111
112 virtual ~GaiaAuthenticator();
113
114 // Pass credentials to authenticate with, or use saved credentials via an
115 // overload. If authentication succeeds, you can retrieve the authentication
116 // token via the respective accessors. Returns a boolean indicating whether
117 // authentication succeeded or not.
118 bool Authenticate(const std::string& user_name, const std::string& password,
119 SaveCredentials should_save_credentials, bool synchronous,
120 const std::string& captcha_token,
121 const std::string& captcha_value,
122 SignIn try_first);
123
124 bool Authenticate(const std::string& user_name, const std::string& password,
125 SaveCredentials should_save_credentials, bool synchronous,
126 SignIn try_first);
127
128 bool AuthenticateService(const std::string& service_id,
129 const std::string& sid,
130 const std::string& lsid,
131 std::string* other_service_cookie);
132
133 // Resets all stored cookies to their default values.
134 void ResetCredentials();
135
136 void SetUsernamePassword(const std::string& username,
137 const std::string& password);
138
139 void SetUsername(const std::string& username);
140
141 void SetAuthToken(const std::string& auth_token, SaveCredentials);
142
143 struct AuthResults {
144 SaveCredentials credentials_saved;
145 std::string email;
146 std::string password;
147
148 // Fields that store various cookies.
149 std::string sid;
150 std::string lsid;
151 std::string auth_token;
152
153 std::string primary_email;
154
155 // Fields for items returned when authentication fails.
156 std::string error_msg;
157 enum AuthenticationError auth_error;
158 std::string auth_error_url;
159 std::string captcha_token;
160 std::string captcha_url;
161 SignIn signin;
162
163 AuthResults () : credentials_saved(DONT_SAVE_CREDENTIALS),
164 auth_error(None) { }
165 };
166
167 protected:
168
169 struct AuthParams {
170 GaiaAuthenticator* authenticator;
171 uint32 request_id;
172 SaveCredentials should_save_credentials;
173 std::string email;
174 std::string password;
175 std::string captcha_token;
176 std::string captcha_value;
177 SignIn try_first;
178 };
179
180 // mutex_ must be entered before calling this function.
181 AuthParams MakeParams(const std::string& user_name,
182 const std::string& password,
183 SaveCredentials should_save_credentials,
184 const std::string& captcha_token,
185 const std::string& captcha_value,
186 SignIn try_first);
187
188 // The real Authenticate implementations.
189 bool AuthenticateImpl(const AuthParams& params);
190 bool AuthenticateImpl(const AuthParams& params, AuthResults* results);
191 bool PerformGaiaRequest(const AuthParams& params, AuthResults* results);
192 bool LaunchAuthenticate(const AuthParams& params, bool synchronous);
193 static void *ThreadMain(void *arg);
194
195 // virtual for testing purposes
196 virtual bool Post(const GURL& url, const std::string& post_body,
197 unsigned long* response_code, std::string* response_body) {
198 return false;
199 }
200
201 // Caller should fill in results->LSID before calling. Result in
202 // results->primary_email.
203 bool LookupEmail(AuthResults* results);
204
205 public:
206 // Retrieve email
207 inline std::string email() const {
208 PThreadScopedLock<PThreadMutex> enter(&mutex_);
209 return auth_results_.email;
210 }
211
212 // Retrieve password
213 inline std::string password() const {
214 PThreadScopedLock<PThreadMutex> enter(&mutex_);
215 return auth_results_.password;
216 }
217
218 // Retrieve AuthToken, if previously authenticated; otherwise returns "".
219 inline std::string auth_token() const {
220 PThreadScopedLock<PThreadMutex> enter(&mutex_);
221 return auth_results_.auth_token;
222 }
223
224 // Retrieve SID cookie. For details, see the Google Accounts documentation.
225 inline std::string sid() const {
226 PThreadScopedLock<PThreadMutex> enter(&mutex_);
227 return auth_results_.sid;
228 }
229
230 // Retrieve LSID cookie. For details, see the Google Accounts documentation.
231 inline std::string lsid() const {
232 PThreadScopedLock<PThreadMutex> enter(&mutex_);
233 return auth_results_.lsid;
234 }
235
236 // Get last authentication error.
237 inline enum AuthenticationError auth_error() const {
238 PThreadScopedLock<PThreadMutex> enter(&mutex_);
239 return auth_results_.auth_error;
240 }
241
242 inline std::string auth_error_url() const {
243 PThreadScopedLock<PThreadMutex> enter(&mutex_);
244 return auth_results_.auth_error_url;
245 }
246
247 inline std::string captcha_token() const {
248 PThreadScopedLock<PThreadMutex> enter(&mutex_);
249 return auth_results_.captcha_token;
250 }
251
252 inline std::string captcha_url() const {
253 PThreadScopedLock<PThreadMutex> enter(&mutex_);
254 return auth_results_.captcha_url;
255 }
256
257 inline AuthResults results() const {
258 PThreadScopedLock<PThreadMutex> enter(&mutex_);
259 return auth_results_;
260 }
261
262 typedef EventChannel<GaiaAuthEvent, PThreadMutex> Channel;
263
264 inline Channel* channel() const {
265 return channel_;
266 }
267
268 private:
269 bool IssueAuthToken(AuthResults* results, const std::string& service_id,
270 bool long_lived_token);
271
272 // Helper method to parse response when authentication succeeds.
273 void ExtractTokensFrom(const std::string& response, AuthResults* results);
274 // Helper method to parse response when authentication fails.
275 void ExtractAuthErrorFrom(const std::string& response, AuthResults* results);
276
277 // Fields for the obvious data items.
278 const std::string user_agent_;
279 const std::string service_id_;
280 const std::string gaia_url_;
281
282 AuthResults auth_results_;
283
284 // When multiple async requests are running, only the one that started most
285 // recently updates the values.
286 //
287 // Note that even though this code was written to handle multiple requests
288 // simultaneously, the sync code issues auth requests one at a time.
289 uint32 request_count_;
290
291 Channel* channel_;
292
293 // Used to compute backoff time for next allowed authentication.
294 int delay_; // In seconds.
295 time_t next_allowed_auth_attempt_time_;
296 int early_auth_attempt_count_;
297
298 // Protects auth_results_, and request_count_.
299 mutable PThreadMutex mutex_;
300 };
301
302 } // namespace browser_sync
303
304 #endif // CHROME_BROWSER_SYNC_ENGINE_NET_GAIA_AUTHENTICATOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698