summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralbertb@google.com <albertb@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-01 00:39:53 +0000
committeralbertb@google.com <albertb@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-01 00:39:53 +0000
commit35e4c0db8edf9390aa3e1b0debbec3993e4120f8 (patch)
treefda423d8c5d5d02e3a6dfa3129e637aa1e792420
parentbc10d9d99a26a7da6df8e359604bae90fa772e44 (diff)
downloadchromium_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.cc21
-rw-r--r--chrome/browser/sync/engine/auth_watcher.h5
-rw-r--r--chrome/browser/sync/engine/net/gaia_authenticator.cc13
-rw-r--r--chrome/browser/sync/engine/net/gaia_authenticator.h5
-rwxr-xr-xchrome/browser/sync/engine/syncapi.cc51
-rw-r--r--chrome/browser/sync/engine/syncapi.h5
-rw-r--r--chrome/browser/sync/glue/sync_backend_host.cc12
-rw-r--r--chrome/browser/sync/glue/sync_backend_host.h10
-rw-r--r--chrome/browser/sync/profile_sync_service.cc39
-rw-r--r--chrome/browser/sync/profile_sync_service.h4
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_;