diff options
author | albertb@google.com <albertb@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-01 00:39:53 +0000 |
---|---|---|
committer | albertb@google.com <albertb@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-01 00:39:53 +0000 |
commit | 35e4c0db8edf9390aa3e1b0debbec3993e4120f8 (patch) | |
tree | fda423d8c5d5d02e3a6dfa3129e637aa1e792420 | |
parent | bc10d9d99a26a7da6df8e359604bae90fa772e44 (diff) | |
download | chromium_src-35e4c0db8edf9390aa3e1b0debbec3993e4120f8.zip chromium_src-35e4c0db8edf9390aa3e1b0debbec3993e4120f8.tar.gz chromium_src-35e4c0db8edf9390aa3e1b0debbec3993e4120f8.tar.bz2 |
Plumping for taking LSID cookie from ProfileSyncService to GaiaAuthenticator.
Review URL: http://codereview.chromium.org/366035
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@33391 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/sync/engine/auth_watcher.cc | 21 | ||||
-rw-r--r-- | chrome/browser/sync/engine/auth_watcher.h | 5 | ||||
-rw-r--r-- | chrome/browser/sync/engine/net/gaia_authenticator.cc | 13 | ||||
-rw-r--r-- | chrome/browser/sync/engine/net/gaia_authenticator.h | 5 | ||||
-rwxr-xr-x | chrome/browser/sync/engine/syncapi.cc | 51 | ||||
-rw-r--r-- | chrome/browser/sync/engine/syncapi.h | 5 | ||||
-rw-r--r-- | chrome/browser/sync/glue/sync_backend_host.cc | 12 | ||||
-rw-r--r-- | chrome/browser/sync/glue/sync_backend_host.h | 10 | ||||
-rw-r--r-- | chrome/browser/sync/profile_sync_service.cc | 39 | ||||
-rw-r--r-- | chrome/browser/sync/profile_sync_service.h | 4 |
10 files changed, 136 insertions, 29 deletions
diff --git a/chrome/browser/sync/engine/auth_watcher.cc b/chrome/browser/sync/engine/auth_watcher.cc index b62c948..8d6c189 100644 --- a/chrome/browser/sync/engine/auth_watcher.cc +++ b/chrome/browser/sync/engine/auth_watcher.cc @@ -92,6 +92,25 @@ void AuthWatcher::PersistCredentials() { } } +void AuthWatcher::AuthenticateWithLsid(const std::string& lsid) { + message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, + &AuthWatcher::DoAuthenticateWithLsid, lsid)); +} + +void AuthWatcher::DoAuthenticateWithLsid(const std::string& lsid) { + DCHECK_EQ(MessageLoop::current(), message_loop()); + + AuthWatcherEvent event = { AuthWatcherEvent::AUTHENTICATION_ATTEMPT_START }; + NotifyListeners(&event); + + if (gaia_->AuthenticateWithLsid(lsid, true)) { + PersistCredentials(); + DoAuthenticateWithToken(gaia_->email(), gaia_->auth_token()); + } else { + ProcessGaiaAuthFailure(); + } +} + const char kAuthWatcher[] = "AuthWatcher"; void AuthWatcher::AuthenticateWithToken(const std::string& gaia_email, @@ -242,7 +261,7 @@ void AuthWatcher::DoAuthenticate(const AuthRequest& request) { ProcessGaiaAuthFailure(); } } else if (!request.auth_token.empty()) { - DoAuthenticateWithToken(request.email, request.auth_token); + DoAuthenticateWithToken(request.email, request.auth_token); } else { LOG(ERROR) << "Attempt to authenticate with no credentials."; } diff --git a/chrome/browser/sync/engine/auth_watcher.h b/chrome/browser/sync/engine/auth_watcher.h index e5422ad..0a17d95 100644 --- a/chrome/browser/sync/engine/auth_watcher.h +++ b/chrome/browser/sync/engine/auth_watcher.h @@ -120,6 +120,10 @@ class AuthWatcher : public base::RefCountedThreadSafe<AuthWatcher> { } // Use this version when you don't need the gaia authentication step because + // you already have a valid LSID cookie for |gaia_email|. + void AuthenticateWithLsid(const std::string& lsid); + + // Use this version when you don't need the gaia authentication step because // you already have a valid token for |gaia_email|. void AuthenticateWithToken(const std::string& gaia_email, const std::string& auth_token); @@ -187,6 +191,7 @@ class AuthWatcher : public base::RefCountedThreadSafe<AuthWatcher> { // The public interface Authenticate methods are proxies to these, which // can only be called from |auth_backend_thread_|. void DoAuthenticate(const AuthRequest& request); + void DoAuthenticateWithLsid(const std::string& lsid); void DoAuthenticateWithToken(const std::string& email, const std::string& auth_token); diff --git a/chrome/browser/sync/engine/net/gaia_authenticator.cc b/chrome/browser/sync/engine/net/gaia_authenticator.cc index b3f7ad5..3dfaae4 100644 --- a/chrome/browser/sync/engine/net/gaia_authenticator.cc +++ b/chrome/browser/sync/engine/net/gaia_authenticator.cc @@ -139,6 +139,19 @@ bool GaiaAuthenticator::Authenticate(const string& user_name, return AuthenticateImpl(params); } +bool GaiaAuthenticator::AuthenticateWithLsid(const string& lsid, + bool long_lived) { + auth_results_.lsid = lsid; + // We need to lookup the email associated with this LSID cookie in order to + // update |auth_results_| with the correct values. + if (LookupEmail(&auth_results_)) { + auth_results_.email = auth_results_.primary_email; + return IssueAuthToken(&auth_results_, service_id_, long_lived); + } + return false; +} + + bool GaiaAuthenticator::AuthenticateImpl(const AuthParams& params) { DCHECK_EQ(MessageLoop::current(), message_loop_); AuthResults results; diff --git a/chrome/browser/sync/engine/net/gaia_authenticator.h b/chrome/browser/sync/engine/net/gaia_authenticator.h index 0f818c1..55e2745 100644 --- a/chrome/browser/sync/engine/net/gaia_authenticator.h +++ b/chrome/browser/sync/engine/net/gaia_authenticator.h @@ -123,6 +123,11 @@ class GaiaAuthenticator { SaveCredentials should_save_credentials, SignIn try_first); + // Pass the LSID to authenticate with. If the authentication succeeds, you can + // retrieve the authetication token via the respective accessors. Returns a + // boolean indicating whether authentication succeeded or not. + bool AuthenticateWithLsid(const std::string& lsid, bool long_lived_token); + // Resets all stored cookies to their default values. void ResetCredentials(); diff --git a/chrome/browser/sync/engine/syncapi.cc b/chrome/browser/sync/engine/syncapi.cc index 6e62942..7e47c59 100755 --- a/chrome/browser/sync/engine/syncapi.cc +++ b/chrome/browser/sync/engine/syncapi.cc @@ -665,7 +665,8 @@ class SyncManager::SyncInternal { HttpPostProviderFactory* auth_post_factory, ModelSafeWorkerInterface* model_safe_worker, bool attempt_last_user_authentication, - const char* user_agent); + const char* user_agent, + const std::string& lsid); // Tell sync engine to submit credentials to GAIA for verification and start // the syncing process on success. Successful GAIA authentication will kick @@ -750,6 +751,9 @@ class SyncManager::SyncInternal { return initialized_; } private: + // Try to authenticate using a LSID cookie. + void AuthenticateWithLsid(const std::string& lsid); + // Try to authenticate using persisted credentials from a previous successful // authentication. If no such credentials exist, calls OnAuthError on the // client to collect credentials. Otherwise, there exist local credentials @@ -759,7 +763,8 @@ class SyncManager::SyncInternal { // authenticate directly with the sync service using a cached token, // authentication failure will generally occur due to expired credentials, or // possibly because of a password change. - void AuthenticateForLastKnownUser(); + bool AuthenticateForUser(const std::string& username, + const std::string& auth_token); // Helper to call OnAuthError when no authentication credentials are // available. @@ -890,7 +895,8 @@ bool SyncManager::Init(const FilePath& database_location, HttpPostProviderFactory* auth_post_factory, ModelSafeWorkerInterface* model_safe_worker, bool attempt_last_user_authentication, - const char* user_agent) { + const char* user_agent, + const char* lsid) { DCHECK(post_factory); string server_string(sync_server_and_path); @@ -904,7 +910,8 @@ bool SyncManager::Init(const FilePath& database_location, auth_post_factory, model_safe_worker, attempt_last_user_authentication, - user_agent); + user_agent, + lsid); } void SyncManager::Authenticate(const char* username, const char* password, @@ -928,7 +935,8 @@ bool SyncManager::SyncInternal::Init( HttpPostProviderFactory* auth_post_factory, ModelSafeWorkerInterface* model_safe_worker, bool attempt_last_user_authentication, - const char* user_agent) { + const char* user_agent, + const std::string& lsid) { // Set up UserSettings, creating the db if necessary. We need this to // instantiate a URLFactory to give to the Syncer. @@ -1008,8 +1016,18 @@ bool SyncManager::SyncInternal::Init( // DirectoryManager broadcasts the OPENED event, // and a valid server connection is detected. - if (attempt_last_user_authentication) - AuthenticateForLastKnownUser(); + bool attempting_auth = false; + std::string username, auth_token; + if (attempt_last_user_authentication && + auth_watcher()->settings()->GetLastUserAndServiceToken( + SYNC_SERVICE_NAME, &username, &auth_token)) { + attempting_auth = AuthenticateForUser(username, auth_token); + } else if (!lsid.empty()) { + attempting_auth = true; + AuthenticateWithLsid(lsid); + } + if (!attempting_auth) + RaiseAuthNeededEvent(); return true; } @@ -1049,22 +1067,20 @@ void SyncManager::SyncInternal::Authenticate(const std::string& username, captcha, true); } -void SyncManager::SyncInternal::AuthenticateForLastKnownUser() { - std::string username; - std::string auth_token; - if (!(auth_watcher()->settings()->GetLastUserAndServiceToken( - SYNC_SERVICE_NAME, &username, &auth_token))) { - RaiseAuthNeededEvent(); - return; - } +void SyncManager::SyncInternal::AuthenticateWithLsid(const string& lsid) { + DCHECK(!lsid.empty()); + auth_watcher()->AuthenticateWithLsid(lsid); +} +bool SyncManager::SyncInternal::AuthenticateForUser( + const std::string& username, const std::string& auth_token) { share_.authenticated_name = username; // We optimize by opening the directory before the "fresh" authentication // attempt completes so that we can immediately begin processing changes. if (!dir_manager()->Open(username_for_share())) { DCHECK(false) << "Had last known user but could not open directory"; - return; + return false; } // Set the sync data type so that the server only sends us bookmarks @@ -1073,7 +1089,7 @@ void SyncManager::SyncInternal::AuthenticateForLastKnownUser() { syncable::ScopedDirLookup lookup(dir_manager(), username_for_share()); if (!lookup.good()) { DCHECK(false) << "ScopedDirLookup failed on successfully opened dir"; - return; + return false; } if (lookup->initial_sync_ended()) MarkAndNotifyInitializationComplete(); @@ -1084,6 +1100,7 @@ void SyncManager::SyncInternal::AuthenticateForLastKnownUser() { // will update the connection manager if necessary. connection_manager()->set_auth_token(auth_token); auth_watcher()->AuthenticateWithToken(username, auth_token); + return true; } void SyncManager::SyncInternal::RaiseAuthNeededEvent() { diff --git a/chrome/browser/sync/engine/syncapi.h b/chrome/browser/sync/engine/syncapi.h index d2a519a..040620b 100644 --- a/chrome/browser/sync/engine/syncapi.h +++ b/chrome/browser/sync/engine/syncapi.h @@ -499,6 +499,8 @@ class SYNC_EXPORT SyncManager { // |model_safe_worker| ownership is given to the SyncManager. // |user_agent| is a 7-bit ASCII string suitable for use as the User-Agent // HTTP header. Used internally when collecting stats to classify clients. + // As a fallback when no cached auth information is available, try to + // bootstrap authentication using |lsid|, if it isn't empty. bool Init(const FilePath& database_location, const char* sync_server_and_path, int sync_server_port, @@ -509,7 +511,8 @@ class SYNC_EXPORT SyncManager { HttpPostProviderFactory* auth_post_factory, ModelSafeWorkerInterface* model_safe_worker, bool attempt_last_user_authentication, - const char* user_agent); + const char* user_agent, + const char* lsid); // Returns the username last used for a successful authentication. // Returns empty if there is no such username. diff --git a/chrome/browser/sync/glue/sync_backend_host.cc b/chrome/browser/sync/glue/sync_backend_host.cc index 1c74419..1a13480 100644 --- a/chrome/browser/sync/glue/sync_backend_host.cc +++ b/chrome/browser/sync/glue/sync_backend_host.cc @@ -43,7 +43,8 @@ SyncBackendHost::~SyncBackendHost() { void SyncBackendHost::Initialize( const GURL& sync_service_url, - URLRequestContextGetter* baseline_context_getter) { + URLRequestContextGetter* baseline_context_getter, + const std::string& lsid) { if (!core_thread_.Start()) return; bookmark_model_worker_ = new BookmarkModelWorker(frontend_loop_); @@ -52,7 +53,8 @@ void SyncBackendHost::Initialize( NewRunnableMethod(core_.get(), &SyncBackendHost::Core::DoInitialize, sync_service_url, bookmark_model_worker_, true, new HttpBridgeFactory(baseline_context_getter), - new HttpBridgeFactory(baseline_context_getter))); + new HttpBridgeFactory(baseline_context_getter), + lsid)); } void SyncBackendHost::Authenticate(const std::string& username, @@ -169,7 +171,8 @@ void SyncBackendHost::Core::DoInitialize( BookmarkModelWorker* bookmark_model_worker, bool attempt_last_user_authentication, sync_api::HttpPostProviderFactory* http_provider_factory, - sync_api::HttpPostProviderFactory* auth_http_provider_factory) { + sync_api::HttpPostProviderFactory* auth_http_provider_factory, + const std::string& lsid) { DCHECK(MessageLoop::current() == host_->core_thread_.message_loop()); // Make sure that the directory exists before initializing the backend. @@ -189,7 +192,8 @@ void SyncBackendHost::Core::DoInitialize( auth_http_provider_factory, bookmark_model_worker, attempt_last_user_authentication, - MakeUserAgentForSyncapi().c_str()); + MakeUserAgentForSyncapi().c_str(), + lsid.c_str()); DCHECK(success) << "Syncapi initialization failed!"; } diff --git a/chrome/browser/sync/glue/sync_backend_host.h b/chrome/browser/sync/glue/sync_backend_host.h index 8192b34..80696eb 100644 --- a/chrome/browser/sync/glue/sync_backend_host.h +++ b/chrome/browser/sync/glue/sync_backend_host.h @@ -83,8 +83,11 @@ class SyncBackendHost { ~SyncBackendHost(); // Called on |frontend_loop_| to kick off asynchronous initialization. + // As a fallback when no cached auth information is available, try to + // bootstrap authentication using |lsid|, if it isn't empty. void Initialize(const GURL& service_url, - URLRequestContextGetter* baseline_context_getter); + URLRequestContextGetter* baseline_context_getter, + const std::string& lsid); // Called on |frontend_loop_| to kick off asynchronous authentication. void Authenticate(const std::string& username, const std::string& password, @@ -164,7 +167,8 @@ class SyncBackendHost { BookmarkModelWorker* bookmark_model_worker, bool attempt_last_user_authentication, sync_api::HttpPostProviderFactory* http_bridge_factory, - sync_api::HttpPostProviderFactory* auth_http_bridge_factory); + sync_api::HttpPostProviderFactory* auth_http_bridge_factory, + const std::string& lsid); // Called on our SyncBackendHost's core_thread_ to perform authentication // on behalf of SyncBackendHost::Authenticate. @@ -198,7 +202,7 @@ class SyncBackendHost { sync_api::HttpPostProviderFactory* factory, sync_api::HttpPostProviderFactory* auth_factory) { DoInitialize(GURL(), bookmark_model_worker, false, factory, - auth_factory); + auth_factory, std::string()); syncapi_->SetupForTestMode(test_user); } #endif diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc index ca95b97..4cd9c6b 100644 --- a/chrome/browser/sync/profile_sync_service.cc +++ b/chrome/browser/sync/profile_sync_service.cc @@ -28,6 +28,7 @@ #include "chrome/common/pref_service.h" #include "chrome/common/time_format.h" #include "grit/generated_resources.h" +#include "net/base/cookie_monster.h" #include "views/window/window.h" using browser_sync::ChangeProcessor; @@ -64,10 +65,15 @@ void ProfileSyncService::set_model_associator( void ProfileSyncService::Initialize() { InitSettings(); RegisterPreferences(); - if (!profile()->GetPrefs()->GetBoolean(prefs::kSyncHasSetupCompleted)) + + if (!profile()->GetPrefs()->GetBoolean(prefs::kSyncHasSetupCompleted)) { DisableForUser(); // Clean up in case of previous crash / setup abort. - else +#if defined(CHROMEOS) + StartUp(); // We always start sync for Chrome OS. +#endif + } else { StartUp(); + } } void ProfileSyncService::InitSettings() { @@ -106,8 +112,35 @@ void ProfileSyncService::ClearPreferences() { pref_service->ScheduleSavePersistentPrefs(); } +#if defined(CHROMEOS) +// The domain and name of the LSID cookie which we use to bootstrap the sync +// authentication in chromeos. +const char kLsidCookieDomain[] = "www.google.com"; +const char kLsidCookieName[] = "LSID"; +#endif + +std::string ProfileSyncService::GetLsidForAuthBootstraping() { +#if defined(CHROMEOS) + // If we're running inside Chrome OS, bootstrap the sync authentication by + // using the LSID cookie provided by the Chrome OS login manager. + net::CookieMonster::CookieList cookies = profile()->GetRequestContext()-> + GetCookieStore()->GetCookieMonster()->GetAllCookies(); + for (net::CookieMonster::CookieList::const_iterator it = cookies.begin(); + it != cookies.end(); ++it) { + if (kLsidCookieDomain == it->first) { + const net::CookieMonster::CanonicalCookie& cookie = it->second; + if (kLsidCookieName == cookie.Name()) { + return cookie.Value(); + } + } + } +#endif + return std::string(); +} + void ProfileSyncService::InitializeBackend() { - backend_->Initialize(sync_service_url_, profile_->GetRequestContext()); + backend_->Initialize(sync_service_url_, profile_->GetRequestContext(), + GetLsidForAuthBootstraping()); } void ProfileSyncService::StartUp() { diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h index 10cb7d5..59bc2e5 100644 --- a/chrome/browser/sync/profile_sync_service.h +++ b/chrome/browser/sync/profile_sync_service.h @@ -257,6 +257,10 @@ class ProfileSyncService : public NotificationObserver, // Sets the last synced time to the current time. void UpdateLastSyncedTime(); + // When running inside Chrome OS, extract the LSID cookie from the cookie + // store to bootstrap the authentication process. + std::string GetLsidForAuthBootstraping(); + // Time at which we begin an attempt a GAIA authorization. base::TimeTicks auth_start_time_; |