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

Side by Side Diff: chrome/browser/sync/engine/auth_watcher.h

Issue 246098: Sync: Remove pthreads from auth_watcher. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 2 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
« no previous file with comments | « no previous file | chrome/browser/sync/engine/auth_watcher.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // AuthWatcher watches authentication events and user open and close 5 // AuthWatcher watches authentication events and user open and close
6 // events and accordingly opens and closes shares. 6 // events and accordingly opens and closes shares.
7 7
8 #ifndef CHROME_BROWSER_SYNC_ENGINE_AUTH_WATCHER_H_ 8 #ifndef CHROME_BROWSER_SYNC_ENGINE_AUTH_WATCHER_H_
9 #define CHROME_BROWSER_SYNC_ENGINE_AUTH_WATCHER_H_ 9 #define CHROME_BROWSER_SYNC_ENGINE_AUTH_WATCHER_H_
10 10
11 #include <map> 11 #include <map>
12 #include <string> 12 #include <string>
13 13
14 #include "base/atomicops.h" 14 #include "base/atomicops.h"
15 #include "base/ref_counted.h"
15 #include "base/scoped_ptr.h" 16 #include "base/scoped_ptr.h"
17 #include "base/thread.h"
16 #include "chrome/browser/sync/engine/net/gaia_authenticator.h" 18 #include "chrome/browser/sync/engine/net/gaia_authenticator.h"
19 #include "chrome/browser/sync/protocol/service_constants.h"
17 #include "chrome/browser/sync/util/event_sys.h" 20 #include "chrome/browser/sync/util/event_sys.h"
18 #include "chrome/browser/sync/util/pthread_helpers.h"
19 #include "chrome/browser/sync/util/sync_types.h" 21 #include "chrome/browser/sync/util/sync_types.h"
22 #include "testing/gtest/include/gtest/gtest_prod.h" // For FRIEND_TEST
20 23
21 namespace syncable { 24 namespace syncable {
22 struct DirectoryManagerEvent; 25 struct DirectoryManagerEvent;
23 class DirectoryManager; 26 class DirectoryManager;
24 } 27 }
25 28
26 namespace browser_sync { 29 namespace browser_sync {
27 30
28 class AllStatus; 31 class AllStatus;
29 class AuthWatcher; 32 class AuthWatcher;
(...skipping 28 matching lines...) Expand all
58 61
59 // How was this auth attempt initiated? 62 // How was this auth attempt initiated?
60 enum AuthenticationTrigger { 63 enum AuthenticationTrigger {
61 USER_INITIATED = 0, // default value. 64 USER_INITIATED = 0, // default value.
62 EXPIRED_CREDENTIALS, 65 EXPIRED_CREDENTIALS,
63 }; 66 };
64 67
65 AuthenticationTrigger trigger; 68 AuthenticationTrigger trigger;
66 }; 69 };
67 70
68 class AuthWatcher { 71 // The mother-class of Authentication for the sync backend. Handles both gaia
72 // and sync service authentication via asynchronous Authenticate* methods,
73 // raising AuthWatcherEvents on success/failure. The implementation currently
74 // runs its own backend thread for the actual auth processing, which means
75 // the AuthWatcherEvents can be raised on a different thread than the one that
76 // invoked authentication.
77 class AuthWatcher : public base::RefCountedThreadSafe<AuthWatcher> {
78 friend class AuthWatcherTest;
79 FRIEND_TEST(AuthWatcherTest, Construction);
69 public: 80 public:
70 // Normal progression is local -> gaia -> token. 81 // Normal progression is local -> gaia -> token.
71 enum Status { LOCALLY_AUTHENTICATED, GAIA_AUTHENTICATED, NOT_AUTHENTICATED }; 82 enum Status { LOCALLY_AUTHENTICATED, GAIA_AUTHENTICATED, NOT_AUTHENTICATED };
72 typedef syncable::DirectoryManagerEvent DirectoryManagerEvent; 83 typedef syncable::DirectoryManagerEvent DirectoryManagerEvent;
73 typedef syncable::DirectoryManager DirectoryManager; 84 typedef syncable::DirectoryManager DirectoryManager;
74 85
75 AuthWatcher(DirectoryManager* dirman, 86 AuthWatcher(DirectoryManager* dirman,
76 ServerConnectionManager* scm, 87 ServerConnectionManager* scm,
77 AllStatus* allstatus, 88 AllStatus* allstatus,
78 const std::string& user_agent, 89 const std::string& user_agent,
79 const std::string& service_id, 90 const std::string& service_id,
80 const std::string& gaia_url, 91 const std::string& gaia_url,
81 UserSettings* user_settings, 92 UserSettings* user_settings,
82 GaiaAuthenticator* gaia_auth, 93 GaiaAuthenticator* gaia_auth,
83 TalkMediator* talk_mediator); 94 TalkMediator* talk_mediator);
84 ~AuthWatcher(); 95 ~AuthWatcher();
85 96
86 // Returns true if the open share has gotten zero updates from the sync 97 // Returns true if the open share has gotten zero updates from the sync
87 // server (initial sync complete). 98 // server (initial sync complete).
88 bool LoadDirectoryListAndOpen(const PathString& login); 99 bool LoadDirectoryListAndOpen(const PathString& login);
89 100
90 typedef EventChannel<AuthWatcherEvent, Lock> Channel; 101 typedef EventChannel<AuthWatcherEvent, Lock> Channel;
91 102
92 inline Channel* channel() const { 103 inline Channel* channel() const {
93 return channel_.get(); 104 return channel_.get();
94 } 105 }
95 106
107 // The following 3 flavors of authentication routines are asynchronous and can
108 // be called from any thread.
96 void Authenticate(const std::string& email, const std::string& password, 109 void Authenticate(const std::string& email, const std::string& password,
97 const std::string& captcha_token, const std::string& captcha_value, 110 const std::string& captcha_token, const std::string& captcha_value,
98 bool persist_creds_to_disk); 111 bool persist_creds_to_disk);
99 112
100 void Authenticate(const std::string& email, const std::string& password, 113 void Authenticate(const std::string& email, const std::string& password,
101 bool persist_creds_to_disk) { 114 bool persist_creds_to_disk) {
102 Authenticate(email, password, "", "", persist_creds_to_disk); 115 Authenticate(email, password, "", "", persist_creds_to_disk);
103 } 116 }
104 117
105 // Retrieves an auth token for a named service for which a long-lived token 118 // Use this version when you don't need the gaia authentication step because
106 // was obtained at login time. Returns true if a long-lived token can be 119 // you already have a valid token for |gaia_email|.
107 // found, false otherwise. 120 void AuthenticateWithToken(const std::string& gaia_email,
108 bool GetAuthTokenForService(const std::string& service_name, 121 const std::string& auth_token);
109 std::string* service_token); 122
123 // Joins on the backend thread. The AuthWatcher is useless after this and
124 // should be destroyed.
125 void Shutdown() { auth_backend_thread_.Stop(); }
110 126
111 std::string email() const; 127 std::string email() const;
112 syncable::DirectoryManager* dirman() const { return dirman_; } 128 syncable::DirectoryManager* dirman() const { return dirman_; }
113 ServerConnectionManager* scm() const { return scm_; } 129 ServerConnectionManager* scm() const { return scm_; }
114 AllStatus* allstatus() const { return allstatus_; } 130 AllStatus* allstatus() const { return allstatus_; }
115 UserSettings* settings() const { return user_settings_; } 131 UserSettings* settings() const { return user_settings_; }
116 Status status() const { return (Status)status_; } 132 Status status() const { return (Status)status_; }
117 133
118 void Logout();
119
120 // For synchronizing other destructors.
121 void WaitForAuthThreadFinish();
122
123 bool AuthenticateWithToken(const std::string& email,
124 const std::string& auth_token);
125
126 protected: 134 protected:
127 void Reset();
128 void ClearAuthenticationData(); 135 void ClearAuthenticationData();
129 136
130 void NotifyAuthSucceeded(const std::string& email); 137 void NotifyAuthSucceeded(const std::string& email);
131 bool StartNewAuthAttempt(const std::string& email,
132 const std::string& password,
133 const std::string& auth_token, const std::string& captcha_token,
134 const std::string& captcha_value, bool persist_creds_to_disk,
135 AuthWatcherEvent::AuthenticationTrigger trigger);
136 void HandleServerConnectionEvent(const ServerConnectionEvent& event); 138 void HandleServerConnectionEvent(const ServerConnectionEvent& event);
137 139
138 void SaveUserSettings(const std::string& username, 140 void SaveUserSettings(const std::string& username,
139 const std::string& auth_token, 141 const std::string& auth_token,
140 const bool save_credentials); 142 const bool save_credentials);
141 143
144 MessageLoop* message_loop() { return auth_backend_thread_.message_loop(); }
145
146 private:
142 // These two helpers should only be called from the auth function. 147 // These two helpers should only be called from the auth function.
143 // Returns false iff we had problems and should try GAIA_AUTH again. 148 // Called when authentication with gaia succeeds, to save credential info.
144 bool ProcessGaiaAuthSuccess(); 149 void PersistCredentials();
150 // Called when authentication with gaia fails.
145 void ProcessGaiaAuthFailure(); 151 void ProcessGaiaAuthFailure();
146 152
147 // Just checks that the user has at least one local share cache. 153 // Just checks that the user has at least one local share cache.
148 bool AuthenticateLocally(std::string email); 154 bool AuthenticateLocally(std::string email);
149 // Also checks the user's password against stored password hash. 155 // Also checks the user's password against stored password hash.
150 bool AuthenticateLocally(std::string email, const std::string& password); 156 bool AuthenticateLocally(std::string email, const std::string& password);
151 157
152 // Sets the trigger member of the event and sends the event on channel_. 158 // Sets the trigger member of the event and sends the event on channel_.
153 void NotifyListeners(AuthWatcherEvent* event); 159 void NotifyListeners(AuthWatcherEvent* event);
154 160
155 const std::string& sync_service_token() const { return sync_service_token_; } 161 inline std::string FormatAsEmailAddress(const std::string& email) const {
162 std::string mail(email);
163 if (email.find('@') == std::string::npos) {
164 mail.push_back('@');
165 // TODO(chron): Should this be done only at the UI level?
166 mail.append(DEFAULT_SIGNIN_DOMAIN);
167 }
168 return mail;
169 }
156 170
157 typedef PThreadScopedLock<PThreadMutex> MutexLock; 171 // A struct to marshal various data across to the auth_backend_thread_ on
158 172 // Authenticate() and AuthenticateWithToken calls.
159 // Passed to newly created threads. 173 struct AuthRequest {
160 struct ThreadParams { 174 std::string email;
161 AuthWatcher* self; 175 std::string password;
162 std::string email; 176 std::string auth_token;
163 std::string password; 177 std::string captcha_token;
164 std::string auth_token; 178 std::string captcha_value;
165 std::string captcha_token; 179 bool persist_creds_to_disk;
166 std::string captcha_value; 180 AuthWatcherEvent::AuthenticationTrigger trigger;
167 bool persist_creds_to_disk;
168 AuthWatcherEvent::AuthenticationTrigger trigger;
169 }; 181 };
170 182
171 // Initial function passed to pthread_create. 183 // The public interface Authenticate methods are proxies to these, which
172 static void* AuthenticationThreadStartRoutine(void* arg); 184 // can only be called from |auth_backend_thread_|.
173 // Member function called by AuthenticationThreadStartRoutine. 185 void DoAuthenticate(const AuthRequest& request);
174 void* AuthenticationThreadMain(struct ThreadParams* arg); 186 void DoAuthenticateWithToken(const std::string& email,
187 const std::string& auth_token);
188
189 // The public HandleServerConnectionEvent method proxies to this method, which
190 // can only be called on |auth_backend_thread_|.
191 void DoHandleServerConnectionEvent(
192 const ServerConnectionEvent& event,
193 const std::string& auth_token_snapshot);
175 194
176 scoped_ptr<GaiaAuthenticator> const gaia_; 195 scoped_ptr<GaiaAuthenticator> const gaia_;
177 syncable::DirectoryManager* const dirman_; 196 syncable::DirectoryManager* const dirman_;
178 ServerConnectionManager* const scm_; 197 ServerConnectionManager* const scm_;
179 scoped_ptr<EventListenerHookup> connmgr_hookup_; 198 scoped_ptr<EventListenerHookup> connmgr_hookup_;
180 AllStatus* const allstatus_; 199 AllStatus* const allstatus_;
181 // TODO(chron): It is incorrect to make assignments to AtomicWord. 200 Status status_;
182 volatile base::subtle::AtomicWord status_;
183 UserSettings* const user_settings_; 201 UserSettings* const user_settings_;
184 TalkMediator* talk_mediator_; // Interface to the notifications engine. 202 TalkMediator* talk_mediator_; // Interface to the notifications engine.
185 scoped_ptr<Channel> channel_; 203 scoped_ptr<Channel> channel_;
186 204
187 // We store our service token in memory as a workaround to the fact that we 205 base::Thread auth_backend_thread_;
188 // don't persist it when the user unchecks "remember me".
189 // We also include it on outgoing requests.
190 std::string sync_service_token_;
191 206
192 PThreadMutex mutex_;
193 // All members below are protected by the above mutex
194 pthread_t thread_;
195 bool thread_handle_valid_;
196 bool authenticating_now_;
197 AuthWatcherEvent::AuthenticationTrigger current_attempt_trigger_; 207 AuthWatcherEvent::AuthenticationTrigger current_attempt_trigger_;
198 DISALLOW_COPY_AND_ASSIGN(AuthWatcher); 208 DISALLOW_COPY_AND_ASSIGN(AuthWatcher);
199 }; 209 };
200 210
201 } // namespace browser_sync 211 } // namespace browser_sync
202 212
203 #endif // CHROME_BROWSER_SYNC_ENGINE_AUTH_WATCHER_H_ 213 #endif // CHROME_BROWSER_SYNC_ENGINE_AUTH_WATCHER_H_
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/sync/engine/auth_watcher.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698