diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/password_manager/password_form_data.h | 54 | ||||
-rw-r--r-- | chrome/browser/password_manager/password_store.h | 22 | ||||
-rw-r--r-- | chrome/browser/password_manager/password_store_default.cc | 158 | ||||
-rw-r--r-- | chrome/browser/password_manager/password_store_default.h | 63 | ||||
-rw-r--r-- | chrome/browser/password_manager/password_store_default_unittest.cc (renamed from chrome/browser/password_manager/password_store_linux_unittest.cc) | 92 | ||||
-rw-r--r-- | chrome/browser/password_manager/password_store_linux.cc | 100 | ||||
-rw-r--r-- | chrome/browser/password_manager/password_store_linux.h | 61 | ||||
-rw-r--r-- | chrome/browser/password_manager/password_store_win.cc | 119 | ||||
-rw-r--r-- | chrome/browser/password_manager/password_store_win.h | 28 | ||||
-rw-r--r-- | chrome/browser/password_manager/password_store_win_unittest.cc | 327 | ||||
-rw-r--r-- | chrome/browser/profile.cc | 31 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 4 |
13 files changed, 576 insertions, 485 deletions
diff --git a/chrome/browser/password_manager/password_form_data.h b/chrome/browser/password_manager/password_form_data.h index 0bfa487..04b78df 100644 --- a/chrome/browser/password_manager/password_form_data.h +++ b/chrome/browser/password_manager/password_form_data.h @@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_FORM_DATA_H_ #define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_FORM_DATA_H_ +#include "testing/gmock/include/gmock/gmock.h" #include "webkit/glue/password_form.h" // Struct used for creation of PasswordForms from static arrays of data. @@ -29,4 +30,57 @@ struct PasswordFormData { webkit_glue::PasswordForm* CreatePasswordFormFromData( const PasswordFormData& form_data); +typedef std::set<webkit_glue::PasswordForm*> SetOfForms; + +// This gmock matcher is used to check that the |arg| contains exactly the same +// PasswordForms as |forms|, regardless of order. +MATCHER_P(ContainsAllPasswordForms, forms, "") { + if (forms.size() != arg.size()) + return false; + SetOfForms expectations(forms.begin(), forms.end()); + for (unsigned int i = 0; i < arg.size(); ++i) { + webkit_glue::PasswordForm* actual = arg[i]; + bool found_match = false; + for (SetOfForms::iterator it = expectations.begin(); + it != expectations.end(); ++it) { + webkit_glue::PasswordForm* expected = *it; + if (expected->scheme == actual->scheme && + expected->signon_realm == actual->signon_realm && + expected->origin == actual->origin && + expected->action == actual->action && + expected->submit_element == actual->submit_element && + expected->username_element == actual->username_element && + expected->password_element == actual->password_element && + expected->username_value == actual->username_value && + expected->password_value == actual->password_value && + expected->blacklisted_by_user == actual->blacklisted_by_user && + expected->preferred == actual->preferred && + expected->ssl_valid == actual->ssl_valid && + expected->date_created == actual->date_created) { + found_match = true; + expectations.erase(it); + break; + } + } + if (!found_match) { + LOG(ERROR) << "No match for:" << std::endl + << "scheme: " << actual->scheme << std::endl + << "signon_realm: " << actual->signon_realm << std::endl + << "origin: " << actual->origin << std::endl + << "action: " << actual->action << std::endl + << "submit_element: " << actual->submit_element << std::endl + << "username_elem: " << actual->username_element << std::endl + << "password_elem: " << actual->password_element << std::endl + << "username_value: " << actual->username_value << std::endl + << "password_value: " << actual->password_value << std::endl + << "blacklisted: " << actual->blacklisted_by_user << std::endl + << "preferred: " << actual->preferred << std::endl + << "ssl_valid: " << actual->ssl_valid << std::endl + << "date_created: " << actual->date_created.ToDoubleT(); + return false; + } + } + return true; +} + #endif // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_FORM_DATA_H_ diff --git a/chrome/browser/password_manager/password_store.h b/chrome/browser/password_manager/password_store.h index f963611..d105240 100644 --- a/chrome/browser/password_manager/password_store.h +++ b/chrome/browser/password_manager/password_store.h @@ -35,21 +35,18 @@ class PasswordStore : public base::RefCountedThreadSafe<PasswordStore> { // Reimplement this to add custom initialization. Always call this too. virtual bool Init(); - // TODO(stuartmorgan): These are only virtual to support the shim version of - // password_store_default; once that is fixed, they can become non-virtual. - // Adds the given PasswordForm to the secure password store asynchronously. virtual void AddLogin(const webkit_glue::PasswordForm& form); // Updates the matching PasswordForm in the secure password store (async). - virtual void UpdateLogin(const webkit_glue::PasswordForm& form); + void UpdateLogin(const webkit_glue::PasswordForm& form); // Removes the matching PasswordForm from the secure password store (async). - virtual void RemoveLogin(const webkit_glue::PasswordForm& form); + void RemoveLogin(const webkit_glue::PasswordForm& form); // Removes all logins created in the given date range. - virtual void RemoveLoginsCreatedBetween(const base::Time& delete_begin, - const base::Time& delete_end); + void RemoveLoginsCreatedBetween(const base::Time& delete_begin, + const base::Time& delete_end); // Searches for a matching PasswordForm and returns a handle so the async // request can be tracked. Implement the PasswordStoreConsumer interface to @@ -61,15 +58,15 @@ class PasswordStore : public base::RefCountedThreadSafe<PasswordStore> { // are thus auto-fillable--and returns a handle so the async request can be // tracked. Implement the PasswordStoreConsumer interface to be notified // on completion. - virtual int GetAutofillableLogins(PasswordStoreConsumer* consumer); + int GetAutofillableLogins(PasswordStoreConsumer* consumer); // Gets the complete list of PasswordForms that are blacklist entries, and // returns a handle so the async request can be tracked. Implement the // PasswordStoreConsumer interface to be notified on completion. - virtual int GetBlacklistLogins(PasswordStoreConsumer* consumer); + int GetBlacklistLogins(PasswordStoreConsumer* consumer); // Cancels a previous Get*Logins query (async) - virtual void CancelLoginsQuery(int handle); + void CancelLoginsQuery(int handle); protected: friend class base::RefCountedThreadSafe<PasswordStore>; @@ -117,8 +114,9 @@ class PasswordStore : public base::RefCountedThreadSafe<PasswordStore> { virtual void GetBlacklistLoginsImpl(GetLoginsRequest* request) = 0; // Notifies the consumer that a Get*Logins() request is complete. - void NotifyConsumer(GetLoginsRequest* request, - const std::vector<webkit_glue::PasswordForm*> forms); + virtual void NotifyConsumer( + GetLoginsRequest* request, + const std::vector<webkit_glue::PasswordForm*> forms); private: // Called by NotifyConsumer, but runs in the consumer's thread. Will not diff --git a/chrome/browser/password_manager/password_store_default.cc b/chrome/browser/password_manager/password_store_default.cc index c27d932..0628294 100644 --- a/chrome/browser/password_manager/password_store_default.cc +++ b/chrome/browser/password_manager/password_store_default.cc @@ -1,152 +1,100 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/password_manager/password_store_default.h" +#include "chrome/browser/pref_service.h" #include "chrome/browser/webdata/web_data_service.h" #include "chrome/common/chrome_constants.h" +#include "chrome/common/pref_names.h" #include "base/logging.h" #include "base/task.h" using webkit_glue::PasswordForm; -PasswordStoreDefault::PasswordStoreDefault(WebDataService* web_data_service) - : web_data_service_(web_data_service), handle_(0) { +PasswordStoreDefault::PasswordStoreDefault(LoginDatabase* login_db, + Profile* profile, + WebDataService* web_data_service) + : web_data_service_(web_data_service), + login_db_(login_db), profile_(profile) { + DCHECK(login_db); + DCHECK(profile); + DCHECK(web_data_service); + MigrateIfNecessary(); } PasswordStoreDefault::~PasswordStoreDefault() { - for (PendingRequestMap::const_iterator it = pending_requests_.begin(); - it != pending_requests_.end(); ++it) { - web_data_service_->CancelRequest(it->first); - } -} - -// Override all the public methods to avoid passthroughs to the Impl -// versions. Since we are calling through to WebDataService, which is -// asynchronous, we'll still behave as the caller expects. -void PasswordStoreDefault::AddLogin(const PasswordForm& form) { - web_data_service_->AddLogin(form); -} - -void PasswordStoreDefault::UpdateLogin(const PasswordForm& form) { - web_data_service_->UpdateLogin(form); -} - -void PasswordStoreDefault::RemoveLogin(const PasswordForm& form) { - web_data_service_->RemoveLogin(form); -} - -void PasswordStoreDefault::RemoveLoginsCreatedBetween( - const base::Time& delete_begin, const base::Time& delete_end) { - web_data_service_->RemoveLoginsCreatedBetween(delete_begin, delete_end); } -int PasswordStoreDefault::GetLogins(const PasswordForm& form, - PasswordStoreConsumer* consumer) { - WebDataService::Handle web_data_handle = web_data_service_->GetLogins(form, - this); - return CreateNewRequestForQuery(web_data_handle, consumer); -} - -int PasswordStoreDefault::GetAutofillableLogins( - PasswordStoreConsumer* consumer) { - WebDataService::Handle web_data_handle = - web_data_service_->GetAutofillableLogins(this); - return CreateNewRequestForQuery(web_data_handle, consumer); -} - -int PasswordStoreDefault::GetBlacklistLogins( - PasswordStoreConsumer* consumer) { - WebDataService::Handle web_data_handle = - web_data_service_->GetBlacklistLogins(this); - return CreateNewRequestForQuery(web_data_handle, consumer); -} - -void PasswordStoreDefault::CancelLoginsQuery(int handle) { - for (PendingRequestMap::iterator it = pending_requests_.begin(); - it != pending_requests_.end(); ++it) { - GetLoginsRequest* request = it->second; - if (request->handle == handle) { - web_data_service_->CancelRequest(it->first); - delete request; - pending_requests_.erase(it); - return; - } - } +void PasswordStoreDefault::AddLoginImpl(const PasswordForm& form) { + login_db_->AddLogin(form); } -void PasswordStoreDefault::AddLoginImpl(const PasswordForm& form) { - NOTREACHED(); +void PasswordStoreDefault::UpdateLoginImpl(const PasswordForm& form) { + login_db_->UpdateLogin(form, NULL); } void PasswordStoreDefault::RemoveLoginImpl(const PasswordForm& form) { - NOTREACHED(); + login_db_->RemoveLogin(form); } void PasswordStoreDefault::RemoveLoginsCreatedBetweenImpl( const base::Time& delete_begin, const base::Time& delete_end) { - NOTREACHED(); -} - -void PasswordStoreDefault::UpdateLoginImpl(const PasswordForm& form) { - NOTREACHED(); + login_db_->RemoveLoginsCreatedBetween(delete_begin, delete_end); } void PasswordStoreDefault::GetLoginsImpl( GetLoginsRequest* request, const webkit_glue::PasswordForm& form) { - NOTREACHED(); + std::vector<PasswordForm*> forms; + login_db_->GetLogins(form, &forms); + NotifyConsumer(request, forms); } void PasswordStoreDefault::GetAutofillableLoginsImpl( GetLoginsRequest* request) { - NOTREACHED(); + std::vector<PasswordForm*> forms; + login_db_->GetAutofillableLogins(&forms); + NotifyConsumer(request, forms); } void PasswordStoreDefault::GetBlacklistLoginsImpl( GetLoginsRequest* request) { - NOTREACHED(); + std::vector<PasswordForm*> forms; + login_db_->GetBlacklistLogins(&forms); + NotifyConsumer(request, forms); } -void PasswordStoreDefault::OnWebDataServiceRequestDone( - WebDataService::Handle h, - const WDTypedResult *result) { - scoped_ptr<GetLoginsRequest> request(TakeRequestWithHandle(h)); - // If the request was cancelled, we are done. - if (!request.get()) - return; - - DCHECK(result); - if (!result) +void PasswordStoreDefault::MigrateIfNecessary() { + PrefService* prefs = profile_->GetPrefs(); + if (prefs->FindPreference(prefs::kLoginDatabaseMigrated)) return; - - const WDResult<std::vector<PasswordForm*> >* r = - static_cast<const WDResult<std::vector<PasswordForm*> >*>(result); - - request->consumer->OnPasswordStoreRequestDone(request->handle, - r->GetValue()); + handles_.insert(web_data_service_->GetAutofillableLogins(this)); + handles_.insert(web_data_service_->GetBlacklistLogins(this)); } -PasswordStoreDefault::GetLoginsRequest* - PasswordStoreDefault::TakeRequestWithHandle(WebDataService::Handle handle) { - PendingRequestMap::iterator it(pending_requests_.find(handle)); - if (it == pending_requests_.end()) - return NULL; +typedef std::vector<const PasswordForm*> PasswordForms; - GetLoginsRequest* request = it->second; - pending_requests_.erase(it); - return request; -} +void PasswordStoreDefault::OnWebDataServiceRequestDone( + WebDataService::Handle handle, + const WDTypedResult *result) { + DCHECK(handles_.end() != handles_.find(handle)); + DCHECK(result); -int PasswordStoreDefault::CreateNewRequestForQuery( - WebDataService::Handle web_data_handle, PasswordStoreConsumer* consumer) { - int api_handle = handle_++; - GetLoginsRequest* request = new GetLoginsRequest(consumer, api_handle); - TrackRequest(web_data_handle, request); - return api_handle; -} + handles_.erase(handle); + if (!result) + return; -void PasswordStoreDefault::TrackRequest(WebDataService::Handle handle, - GetLoginsRequest* request) { - pending_requests_.insert(PendingRequestMap::value_type(handle, request)); + const PasswordForms& forms = + static_cast<const WDResult<PasswordForms>*>(result)->GetValue(); + for (PasswordForms::const_iterator it = forms.begin(); + it != forms.end(); ++it) { + AddLoginImpl(**it); + web_data_service_->RemoveLogin(**it); + delete *it; + } + if (handles_.empty()) { + profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated, + true); + } } diff --git a/chrome/browser/password_manager/password_store_default.h b/chrome/browser/password_manager/password_store_default.h index 2c26a7b..5ca06ca 100644 --- a/chrome/browser/password_manager/password_store_default.h +++ b/chrome/browser/password_manager/password_store_default.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -10,34 +10,22 @@ #include "base/file_path.h" #include "base/ref_counted.h" #include "base/scoped_ptr.h" +#include "chrome/browser/password_manager/login_database.h" #include "chrome/browser/password_manager/password_store.h" +#include "chrome/browser/profile.h" #include "chrome/browser/webdata/web_data_service.h" class Task; // Simple password store implementation that delegates everything to -// the WebDatabase. -// TODO(stuartmorgan): This is a temprorary shim for Windows from the new -// PasswordStore interface to the old model of storing passwords in the -// WebDatabase. This should be replaced by a self-contained Windows -// implementation once PasswordStore is completed. +// the LoginDatabase. class PasswordStoreDefault : public PasswordStore, public WebDataServiceConsumer { public: - explicit PasswordStoreDefault(WebDataService* web_data_service); - - // Overridden to bypass the threading logic in PasswordStore, since - // WebDataService's API is not threadsafe. - virtual void AddLogin(const webkit_glue::PasswordForm& form); - virtual void UpdateLogin(const webkit_glue::PasswordForm& form); - virtual void RemoveLogin(const webkit_glue::PasswordForm& form); - virtual void RemoveLoginsCreatedBetween(const base::Time& delete_begin, - const base::Time& delete_end); - virtual int GetLogins(const webkit_glue::PasswordForm& form, - PasswordStoreConsumer* consumer); - virtual int GetAutofillableLogins(PasswordStoreConsumer* consumer); - virtual int GetBlacklistLogins(PasswordStoreConsumer* consumer); - virtual void CancelLoginsQuery(int handle); + // Takes ownership of |login_db|. + PasswordStoreDefault(LoginDatabase* login_db, + Profile* profile, + WebDataService* web_data_service); protected: virtual ~PasswordStoreDefault(); @@ -53,37 +41,20 @@ class PasswordStoreDefault : public PasswordStore, void GetAutofillableLoginsImpl(GetLoginsRequest* request); void GetBlacklistLoginsImpl(GetLoginsRequest* request); - // Called when a WebDataService method finishes. - virtual void OnWebDataServiceRequestDone(WebDataService::Handle h, - const WDTypedResult* result); - - // Finds the GetLoginsRequest associated with the in-flight WebDataService - // request identified by |handle|, removes it from the tracking list, and - // returns it. Ownership of the GetLoginsRequest passes to the caller. - // Returns NULL if the request has been cancelled. - GetLoginsRequest* TakeRequestWithHandle(WebDataService::Handle handle); - - // Takes ownership of |request| and tracks it under |handle|. - void TrackRequest(WebDataService::Handle handle, GetLoginsRequest* request); - scoped_refptr<WebDataService> web_data_service_; private: - // Creates a new request, stored in pending_requests_, for the given - // WebDataService query, and returns the request handle that should be used - // for it in the client API. - int CreateNewRequestForQuery(WebDataService::Handle web_data_handle, - PasswordStoreConsumer* consumer); + // Migrates logins from the WDS to the LoginDatabase. + void MigrateIfNecessary(); + + // Implements the WebDataService consumer interface. + void OnWebDataServiceRequestDone(WebDataService::Handle handle, + const WDTypedResult *result); - // Next handle to return from our Get*Logins() overrides to allow callers to - // track their request. - int handle_; + scoped_ptr<LoginDatabase> login_db_; + Profile* profile_; - // Methods in this class call async WebDataService methods. This mapping - // remembers which WebDataService request corresponds to which PasswordStore - // request. - typedef std::map<WebDataService::Handle, GetLoginsRequest*> PendingRequestMap; - PendingRequestMap pending_requests_; + std::set<WebDataService::Handle> handles_; DISALLOW_COPY_AND_ASSIGN(PasswordStoreDefault); }; diff --git a/chrome/browser/password_manager/password_store_linux_unittest.cc b/chrome/browser/password_manager/password_store_default_unittest.cc index c93c9f24..b94a361 100644 --- a/chrome/browser/password_manager/password_store_linux_unittest.cc +++ b/chrome/browser/password_manager/password_store_default_unittest.cc @@ -9,12 +9,9 @@ #include "base/time.h" #include "base/waitable_event.h" #include "chrome/browser/password_manager/password_store_change.h" -#include "chrome/browser/password_manager/password_store_linux.h" +#include "chrome/browser/password_manager/password_store_default.h" #include "chrome/browser/password_manager/password_form_data.h" #include "chrome/browser/webdata/web_data_service.h" -#include "chrome/common/notification_details.h" -#include "chrome/common/notification_service.h" -#include "chrome/common/notification_type.h" #include "chrome/common/pref_names.h" #include "chrome/test/testing_profile.h" #include "testing/gmock/include/gmock/gmock.h" @@ -28,9 +25,6 @@ using webkit_glue::PasswordForm; namespace { -typedef std::vector<PasswordForm*> VectorOfForms; -typedef std::set<PasswordForm*> SetOfForms; - class MockPasswordStoreConsumer : public PasswordStoreConsumer { public: MOCK_METHOD2(OnPasswordStoreRequestDone, @@ -43,9 +37,24 @@ class MockWebDataServiceConsumer : public WebDataServiceConsumer { const WDTypedResult*)); }; -class PasswordStoreLinuxTest : public testing::Test { +class SignalingTask : public Task { + public: + explicit SignalingTask(WaitableEvent* event) : event_(event) { + } + virtual void Run() { + event_->Signal(); + } + private: + WaitableEvent* event_; +}; + +} // anonymous namespace + +typedef std::vector<PasswordForm*> VectorOfForms; + +class PasswordStoreDefaultTest : public testing::Test { protected: - PasswordStoreLinuxTest() + PasswordStoreDefaultTest() : ui_thread_(ChromeThread::UI, &message_loop_), db_thread_(ChromeThread::DB) { } @@ -81,19 +90,6 @@ class PasswordStoreLinuxTest : public testing::Test { ScopedTempDir temp_dir_; }; -class SignalingTask : public Task { - public: - explicit SignalingTask(WaitableEvent* event) : event_(event) { - } - virtual void Run() { - event_->Signal(); - } - private: - WaitableEvent* event_; -}; - -} // anonymous namespace - ACTION(STLDeleteElements0) { STLDeleteContainerPointers(arg0.begin(), arg0.end()); } @@ -103,51 +99,12 @@ ACTION(QuitUIMessageLoop) { MessageLoop::current()->Quit(); } -// This matcher is used to check that the |arg| contains exactly the same -// PasswordForms as |forms|, regardless of order. -// TODO(albertb): Convince GMock to pretty-print PasswordForms instead of just -// printing pointers when expectations fail. -MATCHER_P(ContainsAllPasswordForms, forms, "") { - if (forms.size() != arg.size()) - return false; - SetOfForms expectations(forms.begin(), forms.end()); - for (unsigned int i = 0; i < arg.size(); ++i) { - PasswordForm* actual = arg[i]; - bool found_match = false; - for (SetOfForms::iterator it = expectations.begin(); - it != expectations.end(); ++it) { - PasswordForm* expected = *it; - if (expected->scheme == actual->scheme && - expected->signon_realm == actual->signon_realm && - expected->origin == actual->origin && - expected->action == actual->action && - expected->submit_element == actual->submit_element && - expected->username_element == actual->username_element && - expected->password_element == actual->password_element && - expected->username_value == actual->username_value && - expected->password_value == actual->password_value && - expected->blacklisted_by_user == actual->blacklisted_by_user && - expected->preferred == actual->preferred && - expected->ssl_valid == actual->ssl_valid && - expected->date_created == actual->date_created) { - found_match = true; - expectations.erase(it); - break; - } - } - if (!found_match) { - return false; - } - } - return true; // Both forms and arg are empty. -} - MATCHER(EmptyWDResult,"") { return static_cast<const WDResult<std::vector<PasswordForm*> >*>( arg)->GetValue().empty(); } -TEST_F(PasswordStoreLinuxTest, Migration) { +TEST_F(PasswordStoreDefaultTest, Migration) { PasswordFormData autofillable_data[] = { { PasswordForm::SCHEME_HTML, "http://foo.example.com", @@ -232,8 +189,8 @@ TEST_F(PasswordStoreLinuxTest, Migration) { done.Wait(); // Initializing the PasswordStore should trigger a migration. - scoped_refptr<PasswordStoreLinux> store( - new PasswordStoreLinux(login_db_.release(), profile_.get(), wds_.get())); + scoped_refptr<PasswordStoreDefault> store( + new PasswordStoreDefault(login_db_.release(), profile_.get(), wds_.get())); store->Init(); // Check that the migration preference has not been initialized; @@ -309,7 +266,7 @@ TEST_F(PasswordStoreLinuxTest, Migration) { STLDeleteElements(&expected_blacklisted); } -TEST_F(PasswordStoreLinuxTest, MigrationAlreadyDone) { +TEST_F(PasswordStoreDefaultTest, MigrationAlreadyDone) { PasswordFormData wds_data[] = { { PasswordForm::SCHEME_HTML, "http://bar.example.com", @@ -346,8 +303,9 @@ TEST_F(PasswordStoreLinuxTest, MigrationAlreadyDone) { true); // Initializing the PasswordStore shouldn't trigger a migration. - scoped_refptr<PasswordStoreLinux> store( - new PasswordStoreLinux(login_db_.release(), profile_.get(), wds_.get())); + scoped_refptr<PasswordStoreDefault> store( + new PasswordStoreDefault(login_db_.release(), profile_.get(), + wds_.get())); store->Init(); MockPasswordStoreConsumer consumer; diff --git a/chrome/browser/password_manager/password_store_linux.cc b/chrome/browser/password_manager/password_store_linux.cc deleted file mode 100644 index 481d861..0000000 --- a/chrome/browser/password_manager/password_store_linux.cc +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/password_manager/password_store_linux.h" -#include "chrome/browser/pref_service.h" -#include "chrome/browser/webdata/web_data_service.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/pref_names.h" - -#include "base/logging.h" -#include "base/task.h" - -using webkit_glue::PasswordForm; - -PasswordStoreLinux::PasswordStoreLinux(LoginDatabase* login_db, - Profile* profile, - WebDataService* web_data_service) - : login_db_(login_db), profile_(profile), - web_data_service_(web_data_service) { - DCHECK(login_db); - DCHECK(profile); - DCHECK(web_data_service); - MigrateIfNecessary(); -} - -PasswordStoreLinux::~PasswordStoreLinux() { -} - -void PasswordStoreLinux::AddLoginImpl(const PasswordForm& form) { - login_db_->AddLogin(form); -} - -void PasswordStoreLinux::UpdateLoginImpl(const PasswordForm& form) { - login_db_->UpdateLogin(form, NULL); -} - -void PasswordStoreLinux::RemoveLoginImpl(const PasswordForm& form) { - login_db_->RemoveLogin(form); -} - -void PasswordStoreLinux::RemoveLoginsCreatedBetweenImpl( - const base::Time& delete_begin, const base::Time& delete_end) { - login_db_->RemoveLoginsCreatedBetween(delete_begin, delete_end); -} - -void PasswordStoreLinux::GetLoginsImpl( - GetLoginsRequest* request, const webkit_glue::PasswordForm& form) { - std::vector<PasswordForm*> forms; - login_db_->GetLogins(form, &forms); - NotifyConsumer(request, forms); -} - -void PasswordStoreLinux::GetAutofillableLoginsImpl( - GetLoginsRequest* request) { - std::vector<PasswordForm*> forms; - login_db_->GetAutofillableLogins(&forms); - NotifyConsumer(request, forms); -} - -void PasswordStoreLinux::GetBlacklistLoginsImpl( - GetLoginsRequest* request) { - std::vector<PasswordForm*> forms; - login_db_->GetBlacklistLogins(&forms); - NotifyConsumer(request, forms); -} - -void PasswordStoreLinux::MigrateIfNecessary() { - PrefService* prefs = profile_->GetPrefs(); - if (prefs->FindPreference(prefs::kLoginDatabaseMigrated)) - return; - handles_.insert(web_data_service_->GetAutofillableLogins(this)); - handles_.insert(web_data_service_->GetBlacklistLogins(this)); -} - -typedef std::vector<const PasswordForm*> PasswordForms; - -void PasswordStoreLinux::OnWebDataServiceRequestDone( - WebDataService::Handle handle, - const WDTypedResult *result) { - DCHECK(handles_.end() != handles_.find(handle)); - DCHECK(result); - - handles_.erase(handle); - if (!result) - return; - - const PasswordForms& forms = - static_cast<const WDResult<PasswordForms>*>(result)->GetValue(); - for (PasswordForms::const_iterator it = forms.begin(); - it != forms.end(); ++it) { - AddLoginImpl(**it); - web_data_service_->RemoveLogin(**it); - delete *it; - } - if (handles_.empty()) { - profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated, - true); - } -} diff --git a/chrome/browser/password_manager/password_store_linux.h b/chrome/browser/password_manager/password_store_linux.h deleted file mode 100644 index d3c6f59..0000000 --- a/chrome/browser/password_manager/password_store_linux.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_LINUX_H_ -#define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_LINUX_H_ - -#include <map> - -#include "base/file_path.h" -#include "base/ref_counted.h" -#include "base/scoped_ptr.h" -#include "chrome/browser/password_manager/login_database.h" -#include "chrome/browser/password_manager/password_store.h" -#include "chrome/browser/profile.h" -#include "chrome/browser/webdata/web_data_service.h" - -class Task; - -// Simple password store implementation that delegates everything to -// the LoginDatabase. -class PasswordStoreLinux : public PasswordStore, - public WebDataServiceConsumer { - public: - // Takes ownership of |login_db|. - PasswordStoreLinux(LoginDatabase* login_db, - Profile* profile, - WebDataService* web_data_service); - - protected: - virtual ~PasswordStoreLinux(); - - // Implements PasswordStore interface. - void AddLoginImpl(const webkit_glue::PasswordForm& form); - void UpdateLoginImpl(const webkit_glue::PasswordForm& form); - void RemoveLoginImpl(const webkit_glue::PasswordForm& form); - void RemoveLoginsCreatedBetweenImpl(const base::Time& delete_begin, - const base::Time& delete_end); - void GetLoginsImpl(GetLoginsRequest* request, - const webkit_glue::PasswordForm& form); - void GetAutofillableLoginsImpl(GetLoginsRequest* request); - void GetBlacklistLoginsImpl(GetLoginsRequest* request); - - private: - // Migrates logins from the WDS to the LoginDatabase. - void MigrateIfNecessary(); - - // Implements the WebDataService consumer interface. - void OnWebDataServiceRequestDone(WebDataService::Handle handle, - const WDTypedResult *result); - - scoped_ptr<LoginDatabase> login_db_; - Profile* profile_; - scoped_refptr<WebDataService> web_data_service_; - - std::set<WebDataService::Handle> handles_; - - DISALLOW_COPY_AND_ASSIGN(PasswordStoreLinux); -}; - -#endif // CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_STORE_LINUX_H_ diff --git a/chrome/browser/password_manager/password_store_win.cc b/chrome/browser/password_manager/password_store_win.cc index 1e5a6c6..3280f40 100644 --- a/chrome/browser/password_manager/password_store_win.cc +++ b/chrome/browser/password_manager/password_store_win.cc @@ -14,13 +14,17 @@ using std::map; using std::vector; using webkit_glue::PasswordForm; -PasswordStoreWin::PasswordStoreWin(WebDataService* web_data_service) - : PasswordStoreDefault(web_data_service) { +PasswordStoreWin::PasswordStoreWin(LoginDatabase* login_database, + Profile* profile, + WebDataService* web_data_service) + : PasswordStoreDefault(login_database, profile, web_data_service) { } -void PasswordStoreWin::CancelLoginsQuery(int handle) { - PasswordStoreDefault::CancelLoginsQuery(handle); - DeleteFormForRequest(handle); +PasswordStoreWin::~PasswordStoreWin() { + for (PendingRequestMap::const_iterator it = pending_requests_.begin(); + it != pending_requests_.end(); ++it) { + web_data_service_->CancelRequest(it->first); + } } int PasswordStoreWin::GetLogins(const webkit_glue::PasswordForm& form, @@ -31,82 +35,73 @@ int PasswordStoreWin::GetLogins(const webkit_glue::PasswordForm& form, return request_handle; } +void PasswordStoreWin::NotifyConsumer(GetLoginsRequest* request, + const std::vector<PasswordForm*> forms) { + if (!forms.empty()) { + pending_request_forms_.erase(request->handle); + PasswordStore::NotifyConsumer(request, forms); + } else { + PendingRequestFormMap::iterator it(pending_request_forms_.find( + request->handle)); + if (it != pending_request_forms_.end()) { + IE7PasswordInfo info; + std::wstring url = ASCIIToWide(it->second.origin.spec()); + info.url_hash = ie7_password::GetUrlHash(url); + WebDataService::Handle handle = web_data_service_->GetIE7Login(info, + this); + TrackRequest(handle, request); + } + } +} + void PasswordStoreWin::OnWebDataServiceRequestDone( - WebDataService::Handle h, const WDTypedResult *result) { - scoped_ptr<GetLoginsRequest> request(TakeRequestWithHandle(h)); + WebDataService::Handle handle, const WDTypedResult *result) { + scoped_ptr<GetLoginsRequest> request(TakeRequestWithHandle(handle)); // If the request was cancelled, we are done. if (!request.get()) return; - DCHECK(result); if (!result) - return; + return; // The WDS returns NULL if it is shutting down. - switch (result->GetType()) { - case PASSWORD_RESULT: { - // This is a response from a WebDataService::Get*Logins method. - const WDResult<std::vector<PasswordForm*> >* r = - static_cast<const WDResult<std::vector<PasswordForm*> >*>(result); - std::vector<PasswordForm*> result_value = r->GetValue(); - - if (result_value.size()) { - // If we found some results then return them now. - CompleteRequest(request.get(), result_value); - return; - } else { - // Otherwise try finding IE7 logins if we were looking for a specific - // page. - PendingRequestFormMap::iterator it(pending_request_forms_.find( - request->handle)); - if (it != pending_request_forms_.end()) { - IE7PasswordInfo info; - std::wstring url = ASCIIToWide(it->second.origin.spec()); - info.url_hash = ie7_password::GetUrlHash(url); - - if (web_data_service_->IsRunning()) { - WebDataService::Handle web_data_handle = - web_data_service_->GetIE7Login(info, this); - TrackRequest(web_data_handle, request.release()); - } - } - } - break; - } + if (PASSWORD_IE7_RESULT == result->GetType()) { + // This is a response from WebDataService::GetIE7Login. + PendingRequestFormMap::iterator it(pending_request_forms_.find( + request->handle)); + DCHECK(pending_request_forms_.end() != it); + PasswordForm* ie7_form = GetIE7Result(result, it->second); - case PASSWORD_IE7_RESULT: { - // This is a response from WebDataService::GetIE7Login. - PendingRequestFormMap::iterator it(pending_request_forms_.find( - request->handle)); - PasswordForm* ie7_form = GetIE7Result(result, it->second); + std::vector<PasswordForm*> forms; + if (ie7_form) + forms.push_back(ie7_form); - std::vector<PasswordForm*> forms; - if (ie7_form) - forms.push_back(ie7_form); - - CompleteRequest(request.get(), forms); - break; - } + pending_request_forms_.erase(it); + PasswordStore::NotifyConsumer(request.release(), forms); + } else { + NOTREACHED(); } } -void PasswordStoreWin::DeleteFormForRequest(int handle) { - PendingRequestFormMap::iterator it(pending_request_forms_.find(handle)); - if (it != pending_request_forms_.end()) { - pending_request_forms_.erase(it); - } +void PasswordStoreWin::TrackRequest(WebDataService::Handle handle, + GetLoginsRequest* request) { + pending_requests_.insert(PendingRequestMap::value_type(handle, request)); } -void PasswordStoreWin::CompleteRequest( - GetLoginsRequest* request, - const std::vector<webkit_glue::PasswordForm*>& forms) { - DeleteFormForRequest(request->handle); - request->consumer->OnPasswordStoreRequestDone(request->handle, forms); +PasswordStoreDefault::GetLoginsRequest* + PasswordStoreWin::TakeRequestWithHandle(WebDataService::Handle handle) { + PendingRequestMap::iterator it(pending_requests_.find(handle)); + if (it == pending_requests_.end()) + return NULL; + + GetLoginsRequest* request = it->second; + pending_requests_.erase(it); + return request; } PasswordForm* PasswordStoreWin::GetIE7Result(const WDTypedResult *result, const PasswordForm& form) { const WDResult<IE7PasswordInfo>* r = - static_cast<const WDResult<IE7PasswordInfo>*>(result); + static_cast<const WDResult<IE7PasswordInfo>*>(result); IE7PasswordInfo info = r->GetValue(); if (!info.encrypted_data.empty()) { diff --git a/chrome/browser/password_manager/password_store_win.h b/chrome/browser/password_manager/password_store_win.h index 924fc07..6eea056 100644 --- a/chrome/browser/password_manager/password_store_win.h +++ b/chrome/browser/password_manager/password_store_win.h @@ -20,27 +20,33 @@ class PasswordStoreWin : public PasswordStoreDefault { public: // FilePath specifies path to WebDatabase. - explicit PasswordStoreWin(WebDataService* web_data_service); + PasswordStoreWin(LoginDatabase* login_database, + Profile* profile, + WebDataService* web_data_service); // Overridden so that we can save the form for later use. virtual int GetLogins(const webkit_glue::PasswordForm& form, PasswordStoreConsumer* consumer); - virtual void CancelLoginsQuery(int handle); private: - virtual ~PasswordStoreWin() {} + virtual ~PasswordStoreWin(); // See PasswordStoreDefault. void OnWebDataServiceRequestDone(WebDataService::Handle h, const WDTypedResult* result); - // Removes the form for |handle| from pending_request_forms_ (if any). - void DeleteFormForRequest(int handle); + virtual void NotifyConsumer( + GetLoginsRequest* request, + const std::vector<webkit_glue::PasswordForm*> forms); - // Cleans up internal state related to |request|, and sends its results to - // the request's consumer. - void CompleteRequest(GetLoginsRequest* request, - const std::vector<webkit_glue::PasswordForm*>& forms); + // Takes ownership of |request| and tracks it under |handle|. + void TrackRequest(WebDataService::Handle handle, GetLoginsRequest* request); + + // Finds the GetLoginsRequest associated with the in-flight WebDataService + // request identified by |handle|, removes it from the tracking list, and + // returns it. Ownership of the GetLoginsRequest passes to the caller. + // Returns NULL if the request has been cancelled. + GetLoginsRequest* TakeRequestWithHandle(WebDataService::Handle handle); // Gets logins from IE7 if no others are found. Also copies them into // Chrome's WebDatabase so we don't need to look next time. @@ -48,6 +54,10 @@ class PasswordStoreWin : public PasswordStoreDefault { const WDTypedResult* result, const webkit_glue::PasswordForm& form); + // Holds requests associated with in-flight GetLogin queries. + typedef std::map<int, GetLoginsRequest*> PendingRequestMap; + PendingRequestMap pending_requests_; + // Holds forms associated with in-flight GetLogin queries. typedef std::map<int, webkit_glue::PasswordForm> PendingRequestFormMap; PendingRequestFormMap pending_request_forms_; diff --git a/chrome/browser/password_manager/password_store_win_unittest.cc b/chrome/browser/password_manager/password_store_win_unittest.cc new file mode 100644 index 0000000..ed78289 --- /dev/null +++ b/chrome/browser/password_manager/password_store_win_unittest.cc @@ -0,0 +1,327 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <windows.h> +#include <wincrypt.h> +#include <string> +#include <vector> + +#include "base/message_loop.h" +#include "base/scoped_ptr.h" +#include "base/scoped_temp_dir.h" +#include "base/time.h" +#include "base/waitable_event.h" +#include "chrome/browser/chrome_thread.h" +#include "chrome/browser/password_manager/password_form_data.h" +#include "chrome/browser/password_manager/password_store_win.h" +#include "chrome/browser/password_manager/ie7_password.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/testing_profile.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using base::WaitableEvent; +using testing::_; +using webkit_glue::PasswordForm; + +namespace { + +class MockPasswordStoreConsumer : public PasswordStoreConsumer { + public: + MOCK_METHOD2(OnPasswordStoreRequestDone, + void(int, const std::vector<webkit_glue::PasswordForm*>&)); +}; + +class MockWebDataServiceConsumer : public WebDataServiceConsumer { +public: + MOCK_METHOD2(OnWebDataServiceRequestDone, + void(WebDataService::Handle, const WDTypedResult*)); +}; + +class SignalingTask : public Task { + public: + explicit SignalingTask(WaitableEvent* event) : event_(event) { + } + virtual void Run() { + event_->Signal(); + } + private: + WaitableEvent* event_; +}; + +} // anonymous namespace + +class PasswordStoreWinTest : public testing::Test { + protected: + PasswordStoreWinTest() + : ui_thread_(ChromeThread::UI, &message_loop_), + db_thread_(ChromeThread::DB) { + } + + bool CreateIE7PasswordInfo(const std::wstring& url, const base::Time& created, + IE7PasswordInfo* info) { + // Copied from chrome/browser/importer/importer_unittest.cc + // The username is "abcdefgh" and the password "abcdefghijkl". + unsigned char data[] = "\x0c\x00\x00\x00\x38\x00\x00\x00\x2c\x00\x00\x00" + "\x57\x49\x43\x4b\x18\x00\x00\x00\x02\x00\x00\x00" + "\x67\x00\x72\x00\x01\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x4e\xfa\x67\x76\x22\x94\xc8\x01" + "\x08\x00\x00\x00\x12\x00\x00\x00\x4e\xfa\x67\x76" + "\x22\x94\xc8\x01\x0c\x00\x00\x00\x61\x00\x62\x00" + "\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00" + "\x00\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00" + "\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00" + "\x6c\x00\x00\x00"; + DATA_BLOB input = {0}; + DATA_BLOB url_key = {0}; + DATA_BLOB output = {0}; + + input.pbData = data; + input.cbData = sizeof(data); + + url_key.pbData = reinterpret_cast<unsigned char*>( + const_cast<wchar_t*>(url.data())); + url_key.cbData = static_cast<DWORD>((url.size() + 1) * + sizeof(std::wstring::value_type)); + + if (!CryptProtectData(&input, NULL, &url_key, NULL, NULL, + CRYPTPROTECT_UI_FORBIDDEN, &output)) + return false; + + std::vector<unsigned char> encrypted_data; + encrypted_data.resize(output.cbData); + memcpy(&encrypted_data.front(), output.pbData, output.cbData); + + LocalFree(output.pbData); + + info->url_hash = ie7_password::GetUrlHash(url); + info->encrypted_data = encrypted_data; + info->date_created = created; + + return true; + } + + virtual void SetUp() { + ASSERT_TRUE(db_thread_.Start()); + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + + profile_.reset(new TestingProfile()); + + login_db_.reset(new LoginDatabase()); + ASSERT_TRUE(login_db_->Init(temp_dir_.path().Append( + FILE_PATH_LITERAL("login_test")))); + + wds_ = new WebDataService(); + ASSERT_TRUE(wds_->Init(temp_dir_.path())); + } + + virtual void TearDown() { + if (wds_.get()) + wds_->Shutdown(); + MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask); + MessageLoop::current()->Run(); + db_thread_.Stop(); + } + + MessageLoopForUI message_loop_; + ChromeThread ui_thread_; + ChromeThread db_thread_; // PasswordStore, WDS schedule work on this thread. + + scoped_ptr<LoginDatabase> login_db_; + scoped_ptr<TestingProfile> profile_; + scoped_refptr<WebDataService> wds_; + ScopedTempDir temp_dir_; +}; + +ACTION(QuitUIMessageLoop) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + MessageLoop::current()->Quit(); +} + +TEST_F(PasswordStoreWinTest, ConvertIE7Login) { + IE7PasswordInfo password_info; + ASSERT_TRUE(CreateIE7PasswordInfo(L"http://example.com/origin", + base::Time::FromDoubleT(1), + &password_info)); + + // This IE7 password will be retrieved by the GetLogins call. + wds_->AddIE7Login(password_info); + + // The WDS schedules tasks to run on the DB thread so we schedule yet another + // task to notify us that it's safe to carry on with the test. + WaitableEvent done(false, false); + ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done)); + done.Wait(); + + // Prentend that the migration has already taken place. + profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated, + true); + + // Initializing the PasswordStore shouldn't trigger a migration. + scoped_refptr<PasswordStoreWin> store( + new PasswordStoreWin(login_db_.release(), profile_.get(), wds_.get())); + EXPECT_TRUE(store->Init()); + + MockPasswordStoreConsumer consumer; + + // Make sure we quit the MessageLoop even if the test fails. + ON_CALL(consumer, OnPasswordStoreRequestDone(_, _)) + .WillByDefault(QuitUIMessageLoop()); + + PasswordFormData form_data = { + PasswordForm::SCHEME_HTML, + "http://example.com/", + "http://example.com/origin", + "http://example.com/action", + L"submit_element", + L"username_element", + L"password_element", + L"", + L"", + true, false, 1, + }; + scoped_ptr<PasswordForm> form(CreatePasswordFormFromData(form_data)); + + PasswordFormData expected_form_data = { + PasswordForm::SCHEME_HTML, + "http://example.com/", + "http://example.com/origin", + "http://example.com/action", + L"submit_element", + L"username_element", + L"password_element", + L"abcdefgh", + L"abcdefghijkl", + true, false, 1, + }; + std::vector<PasswordForm*> forms; + forms.push_back(CreatePasswordFormFromData(expected_form_data)); + + // The IE7 password should be returned. + EXPECT_CALL(consumer, + OnPasswordStoreRequestDone(_, + ContainsAllPasswordForms(forms))) + .WillOnce(QuitUIMessageLoop()); + + store->GetLogins(*form, &consumer); + MessageLoop::current()->Run(); + + STLDeleteElements(&forms); +} + +TEST_F(PasswordStoreWinTest, OutstandingWDSQueries) { + // Prentend that the migration has already taken place. + profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated, + true); + + // Initializing the PasswordStore shouldn't trigger a migration. + scoped_refptr<PasswordStoreWin> store( + new PasswordStoreWin(login_db_.release(), profile_.get(), wds_.get())); + EXPECT_TRUE(store->Init()); + + PasswordFormData form_data = { + PasswordForm::SCHEME_HTML, + "http://example.com/", + "http://example.com/origin", + "http://example.com/action", + L"submit_element", + L"username_element", + L"password_element", + L"", + L"", + true, false, 1, + }; + scoped_ptr<PasswordForm> form(CreatePasswordFormFromData(form_data)); + + MockPasswordStoreConsumer consumer; + store->GetLogins(*form, &consumer); + + // Release the PSW and the WDS before the query can return. + store = NULL; + wds_->Shutdown(); + wds_ = NULL; + + MessageLoop::current()->RunAllPending(); +} + +TEST_F(PasswordStoreWinTest, MultipleWDSQueriesOnDifferentThreads) { + IE7PasswordInfo password_info; + ASSERT_TRUE(CreateIE7PasswordInfo(L"http://example.com/origin", + base::Time::FromDoubleT(1), + &password_info)); + wds_->AddIE7Login(password_info); + + // The WDS schedules tasks to run on the DB thread so we schedule yet another + // task to notify us that it's safe to carry on with the test. + WaitableEvent done(false, false); + ChromeThread::PostTask(ChromeThread::DB, FROM_HERE, new SignalingTask(&done)); + done.Wait(); + + // Prentend that the migration has already taken place. + profile_->GetPrefs()->RegisterBooleanPref(prefs::kLoginDatabaseMigrated, + true); + + // Initializing the PasswordStore shouldn't trigger a migration. + scoped_refptr<PasswordStoreWin> store( + new PasswordStoreWin(login_db_.release(), profile_.get(), wds_.get())); + EXPECT_TRUE(store->Init()); + + MockPasswordStoreConsumer password_consumer; + // Make sure we quit the MessageLoop even if the test fails. + ON_CALL(password_consumer, OnPasswordStoreRequestDone(_, _)) + .WillByDefault(QuitUIMessageLoop()); + + PasswordFormData form_data = { + PasswordForm::SCHEME_HTML, + "http://example.com/", + "http://example.com/origin", + "http://example.com/action", + L"submit_element", + L"username_element", + L"password_element", + L"", + L"", + true, false, 1, + }; + scoped_ptr<PasswordForm> form(CreatePasswordFormFromData(form_data)); + + PasswordFormData expected_form_data = { + PasswordForm::SCHEME_HTML, + "http://example.com/", + "http://example.com/origin", + "http://example.com/action", + L"submit_element", + L"username_element", + L"password_element", + L"abcdefgh", + L"abcdefghijkl", + true, false, 1, + }; + std::vector<PasswordForm*> forms; + forms.push_back(CreatePasswordFormFromData(expected_form_data)); + + // The IE7 password should be returned. + EXPECT_CALL(password_consumer, + OnPasswordStoreRequestDone(_, + ContainsAllPasswordForms(forms))) + .WillOnce(QuitUIMessageLoop()); + + store->GetLogins(*form, &password_consumer); + + MockWebDataServiceConsumer wds_consumer; + + EXPECT_CALL(wds_consumer, + OnWebDataServiceRequestDone(_, _)) + .WillOnce(QuitUIMessageLoop()); + + wds_->GetIE7Login(password_info, &wds_consumer); + + // Run the MessageLoop twice: once for the GetIE7Login that PasswordStoreWin + // schedules on the DB thread and once for the one we just scheduled on the UI + // thread. + MessageLoop::current()->Run(); + MessageLoop::current()->Run(); + + STLDeleteElements(&forms); +}
\ No newline at end of file diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc index 4332a35..98bae1d 100644 --- a/chrome/browser/profile.cc +++ b/chrome/browser/profile.cc @@ -44,7 +44,6 @@ #include "chrome/browser/net/ssl_config_service_manager.h" #include "chrome/browser/notifications/desktop_notification_service.h" #include "chrome/browser/password_manager/password_store_default.h" -#include "chrome/browser/password_manager/password_store_linux.h" #include "chrome/browser/privacy_blacklist/blacklist.h" #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h" #include "chrome/browser/profile_manager.h" @@ -1196,9 +1195,6 @@ void ProfileImpl::CreatePasswordStore() { DCHECK(!created_password_store_ && password_store_.get() == NULL); created_password_store_ = true; scoped_refptr<PasswordStore> ps; -#if defined(OS_WIN) - ps = new PasswordStoreWin(GetWebDataService(Profile::IMPLICIT_ACCESS)); -#elif defined(OS_MACOSX) FilePath login_db_file_path = GetPath(); login_db_file_path = login_db_file_path.Append(chrome::kLoginDataFileName); LoginDatabase* login_db = new LoginDatabase(); @@ -1207,31 +1203,26 @@ void ProfileImpl::CreatePasswordStore() { delete login_db; return; } +#if defined(OS_WIN) + ps = new PasswordStoreWin(login_db, this, + GetWebDataService(Profile::IMPLICIT_ACCESS)); +#elif defined(OS_MACOSX) ps = new PasswordStoreMac(new MacKeychain(), login_db); #elif defined(OS_POSIX) // TODO(evanm): implement "native" password management. // This bug describes the issues. // http://code.google.com/p/chromium/issues/detail?id=12351 - FilePath login_db_file_path = GetPath(); - login_db_file_path = login_db_file_path.Append(chrome::kLoginDataFileName); - LoginDatabase* login_db = new LoginDatabase(); - if (!login_db->Init(login_db_file_path)) { - LOG(ERROR) << "Could not initialize login database."; - delete login_db; - return; - } - ps = new PasswordStoreLinux(login_db, this, - GetWebDataService(Profile::IMPLICIT_ACCESS)); + ps = new PasswordStoreDefault(login_db, this, + GetWebDataService(Profile::IMPLICIT_ACCESS)); #else NOTIMPLEMENTED(); #endif + if (!ps) + delete login_db; + if (!ps || !ps->Init()) { - // Try falling back to the default password manager - NOTREACHED() << "Could not initialise native password manager - " - "falling back to default"; - ps = new PasswordStoreDefault(GetWebDataService(Profile::IMPLICIT_ACCESS)); - if (!ps->Init()) - return; + NOTREACHED() << "Could not initialise password manager"; + return; } password_store_.swap(ps); } diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index dc046fe..900725d 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1701,8 +1701,6 @@ 'browser/password_manager/password_store.h', 'browser/password_manager/password_store_default.cc', 'browser/password_manager/password_store_default.h', - 'browser/password_manager/password_store_linux.cc', - 'browser/password_manager/password_store_linux.h', # Temporarily disabled while we figure some stuff out. # http://code.google.com/p/chromium/issues/detail?id=12351 # 'browser/password_manager/password_store_gnome.h', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 68bbca1..85497a3 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -859,8 +859,9 @@ 'browser/password_manager/password_form_manager_unittest.cc', 'browser/password_manager/password_manager_unittest.cc', 'browser/password_manager/password_form_data.cc', - 'browser/password_manager/password_store_linux_unittest.cc', + 'browser/password_manager/password_store_default_unittest.cc', 'browser/password_manager/password_store_mac_unittest.cc', + 'browser/password_manager/password_store_win_unittest.cc', 'browser/pref_member_unittest.cc', 'browser/pref_service_unittest.cc', 'browser/printing/print_job_unittest.cc', @@ -1101,6 +1102,7 @@ # Blocked on bookmark manager. 'browser/bookmarks/bookmark_context_menu_controller_unittest.cc', 'browser/views/accessibility_event_router_views_unittest.cc', + 'browser/password_manager/password_store_default_unittest.cc', 'browser/views/bookmark_context_menu_test.cc', 'browser/gtk/go_button_gtk_unittest.cc', 'browser/gtk/tabs/tab_renderer_gtk_unittest.cc', |