OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "chrome/browser/password_manager/password_store_mac.h" | 5 #include "chrome/browser/password_manager/password_store_mac.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/files/scoped_temp_dir.h" | 10 #include "base/files/scoped_temp_dir.h" |
11 #include "base/scoped_observer.h" | 11 #include "base/scoped_observer.h" |
12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
13 #include "base/strings/string_util.h" | 13 #include "base/strings/string_util.h" |
14 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
15 #include "base/synchronization/waitable_event.h" | 15 #include "base/synchronization/waitable_event.h" |
16 #include "base/test/histogram_tester.h" | 16 #include "base/test/histogram_tester.h" |
17 #include "base/thread_task_runner_handle.h" | 17 #include "base/thread_task_runner_handle.h" |
18 #include "chrome/browser/password_manager/password_store_mac_internal.h" | 18 #include "chrome/browser/password_manager/password_store_mac_internal.h" |
19 #include "chrome/common/chrome_paths.h" | 19 #include "chrome/common/chrome_paths.h" |
20 #include "components/os_crypt/os_crypt.h" | 20 #include "components/os_crypt/os_crypt.h" |
21 #include "components/password_manager/core/browser/login_database.h" | 21 #include "components/password_manager/core/browser/login_database.h" |
22 #include "components/password_manager/core/browser/password_manager_test_utils.h " | 22 #include "components/password_manager/core/browser/password_manager_test_utils.h " |
23 #include "components/password_manager/core/browser/password_store_consumer.h" | 23 #include "components/password_manager/core/browser/password_store_consumer.h" |
24 #include "content/public/test/test_browser_thread.h" | 24 #include "components/password_manager/core/browser/password_store_origin_unittes t.h" |
25 #include "content/public/test/test_browser_thread_bundle.h" | |
25 #include "content/public/test/test_utils.h" | 26 #include "content/public/test/test_utils.h" |
26 #include "crypto/mock_apple_keychain.h" | 27 #include "crypto/mock_apple_keychain.h" |
27 #include "testing/gmock/include/gmock/gmock.h" | 28 #include "testing/gmock/include/gmock/gmock.h" |
28 #include "testing/gtest/include/gtest/gtest.h" | 29 #include "testing/gtest/include/gtest/gtest.h" |
29 | 30 |
30 using autofill::PasswordForm; | 31 using autofill::PasswordForm; |
31 using base::ASCIIToUTF16; | 32 using base::ASCIIToUTF16; |
32 using base::WideToUTF16; | 33 using base::WideToUTF16; |
33 using content::BrowserThread; | 34 using content::BrowserThread; |
34 using crypto::MockAppleKeychain; | 35 using crypto::MockAppleKeychain; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
69 public: | 70 public: |
70 MOCK_METHOD1(OnGetPasswordStoreResultsConstRef, | 71 MOCK_METHOD1(OnGetPasswordStoreResultsConstRef, |
71 void(const std::vector<PasswordForm*>&)); | 72 void(const std::vector<PasswordForm*>&)); |
72 | 73 |
73 // GMock cannot mock methods with move-only args. | 74 // GMock cannot mock methods with move-only args. |
74 void OnGetPasswordStoreResults(ScopedVector<PasswordForm> results) override { | 75 void OnGetPasswordStoreResults(ScopedVector<PasswordForm> results) override { |
75 OnGetPasswordStoreResultsConstRef(results.get()); | 76 OnGetPasswordStoreResultsConstRef(results.get()); |
76 } | 77 } |
77 }; | 78 }; |
78 | 79 |
79 class MockPasswordStoreObserver : public PasswordStore::Observer { | |
80 public: | |
81 MOCK_METHOD1(OnLoginsChanged, | |
82 void(const password_manager::PasswordStoreChangeList& changes)); | |
83 }; | |
84 | |
85 // A LoginDatabase that simulates an Init() method that takes a long time. | 80 // A LoginDatabase that simulates an Init() method that takes a long time. |
86 class SlowToInitLoginDatabase : public password_manager::LoginDatabase { | 81 class SlowToInitLoginDatabase : public password_manager::LoginDatabase { |
87 public: | 82 public: |
88 // Creates an instance whose Init() method will block until |event| is | 83 // Creates an instance whose Init() method will block until |event| is |
89 // signaled. |event| must outlive |this|. | 84 // signaled. |event| must outlive |this|. |
90 SlowToInitLoginDatabase(const base::FilePath& db_path, | 85 SlowToInitLoginDatabase(const base::FilePath& db_path, |
91 base::WaitableEvent* event) | 86 base::WaitableEvent* event) |
92 : password_manager::LoginDatabase(db_path), event_(event) {} | 87 : password_manager::LoginDatabase(db_path), event_(event) {} |
93 ~SlowToInitLoginDatabase() override {} | 88 ~SlowToInitLoginDatabase() override {} |
94 | 89 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
167 form->date_synced); | 162 form->date_synced); |
168 EXPECT_EQ(GURL(password_manager::kTestingIconUrlSpec), form->icon_url); | 163 EXPECT_EQ(GURL(password_manager::kTestingIconUrlSpec), form->icon_url); |
169 } | 164 } |
170 } | 165 } |
171 | 166 |
172 PasswordStoreChangeList AddChangeForForm(const PasswordForm& form) { | 167 PasswordStoreChangeList AddChangeForForm(const PasswordForm& form) { |
173 return PasswordStoreChangeList( | 168 return PasswordStoreChangeList( |
174 1, PasswordStoreChange(PasswordStoreChange::ADD, form)); | 169 1, PasswordStoreChange(PasswordStoreChange::ADD, form)); |
175 } | 170 } |
176 | 171 |
172 class PasswordStoreMacTestDelegate { | |
173 public: | |
174 PasswordStoreMacTestDelegate(); | |
175 ~PasswordStoreMacTestDelegate(); | |
176 | |
177 static void FinishAsyncProcessing() { | |
178 scoped_refptr<content::MessageLoopRunner> runner = | |
179 new content::MessageLoopRunner; | |
180 ASSERT_TRUE(base::ThreadTaskRunnerHandle::Get()->PostTaskAndReply( | |
181 FROM_HERE, base::Bind(&Noop), runner->QuitClosure())); | |
182 runner->Run(); | |
183 } | |
184 | |
185 PasswordStoreMac* store() const { return store_.get(); } | |
186 | |
187 PasswordStoreMac* store() { return store_.get(); } | |
188 | |
189 private: | |
190 static void InitLoginDatabase(LoginDatabase* login_db); | |
191 void Initialize(); | |
192 base::FilePath test_login_db_file_path() const; | |
193 | |
194 void ClosePasswordStore(); | |
195 | |
196 content::TestBrowserThreadBundle thread_bundle_; | |
197 | |
198 base::ScopedTempDir db_dir_; | |
199 scoped_ptr<LoginDatabase> login_db_; | |
200 scoped_refptr<PasswordStoreMac> store_; | |
201 | |
202 DISALLOW_COPY_AND_ASSIGN(PasswordStoreMacTestDelegate); | |
203 }; | |
204 | |
205 PasswordStoreMacTestDelegate::PasswordStoreMacTestDelegate() | |
206 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) { | |
vasilii
2015/11/24 18:14:55
By passing IO_MAINLOOP you still create a single-t
Timo Reimann
2015/11/24 23:06:02
Gotcha. Replaced by REAL_FILE_THREAD.
| |
207 Initialize(); | |
208 } | |
209 | |
210 PasswordStoreMacTestDelegate::~PasswordStoreMacTestDelegate() { | |
211 ClosePasswordStore(); | |
212 login_db_.reset(); | |
213 } | |
214 | |
215 void PasswordStoreMacTestDelegate::Initialize() { | |
216 ASSERT_TRUE(db_dir_.CreateUniqueTempDir()); | |
217 | |
218 // Ensure that LoginDatabase will use the mock keychain if it needs to | |
219 // encrypt/decrypt a password. | |
220 OSCrypt::UseMockKeychain(true); | |
221 login_db_.reset(new LoginDatabase(test_login_db_file_path())); | |
222 ASSERT_TRUE(BrowserThread::PostTask( | |
223 BrowserThread::IO, FROM_HERE, | |
224 base::Bind(&PasswordStoreMacTestDelegate::InitLoginDatabase, | |
225 base::Unretained(login_db_.get())))); | |
226 | |
227 // Creat and initialize the password store. | |
228 store_ = new PasswordStoreMac(base::ThreadTaskRunnerHandle::Get(), nullptr, | |
229 make_scoped_ptr(new MockAppleKeychain)); | |
230 ASSERT_TRUE(BrowserThread::PostTask( | |
231 BrowserThread::IO, FROM_HERE, | |
232 base::Bind(&PasswordStoreMac::InitWithTaskRunner, store_, | |
233 base::ThreadTaskRunnerHandle::Get()))); | |
234 | |
235 ASSERT_TRUE(BrowserThread::PostTask( | |
236 BrowserThread::IO, FROM_HERE, | |
237 base::Bind(&PasswordStoreMac::set_login_metadata_db, store_, | |
238 base::Unretained(login_db_.get())))); | |
239 | |
240 // Make sure deferred initialization is performed before some tests start | |
241 // accessing the |login_db| directly. | |
242 FinishAsyncProcessing(); | |
243 } | |
244 | |
245 void PasswordStoreMacTestDelegate::InitLoginDatabase(LoginDatabase* login_db) { | |
246 ASSERT_TRUE(login_db->Init()); | |
247 } | |
248 | |
249 base::FilePath PasswordStoreMacTestDelegate::test_login_db_file_path() const { | |
250 return db_dir_.path().Append(FILE_PATH_LITERAL("login.db")); | |
251 } | |
252 | |
253 void PasswordStoreMacTestDelegate::ClosePasswordStore() { | |
254 store_->ShutdownOnUIThread(); | |
255 FinishAsyncProcessing(); | |
256 } | |
257 | |
177 } // namespace | 258 } // namespace |
178 | 259 |
260 namespace password_manager { | |
261 | |
262 INSTANTIATE_TYPED_TEST_CASE_P(Mac, | |
263 PasswordStoreOriginTest, | |
264 PasswordStoreMacTestDelegate); | |
265 | |
266 } // namespace password_manager | |
267 | |
179 #pragma mark - | 268 #pragma mark - |
180 | 269 |
181 class PasswordStoreMacInternalsTest : public testing::Test { | 270 class PasswordStoreMacInternalsTest : public testing::Test { |
182 public: | 271 public: |
183 void SetUp() override { | 272 void SetUp() override { |
184 MockAppleKeychain::KeychainTestData test_data[] = { | 273 MockAppleKeychain::KeychainTestData test_data[] = { |
185 // Basic HTML form. | 274 // Basic HTML form. |
186 {kSecAuthenticationTypeHTMLForm, | 275 {kSecAuthenticationTypeHTMLForm, |
187 "some.domain.com", | 276 "some.domain.com", |
188 kSecProtocolTypeHTTP, | 277 kSecProtocolTypeHTTP, |
(...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1168 | 1257 |
1169 ScopedVector<autofill::PasswordForm> owned_passwords = | 1258 ScopedVector<autofill::PasswordForm> owned_passwords = |
1170 owned_keychain_adapter.GetAllPasswordFormPasswords(); | 1259 owned_keychain_adapter.GetAllPasswordFormPasswords(); |
1171 EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size()); | 1260 EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size()); |
1172 } | 1261 } |
1173 | 1262 |
1174 #pragma mark - | 1263 #pragma mark - |
1175 | 1264 |
1176 class PasswordStoreMacTest : public testing::Test { | 1265 class PasswordStoreMacTest : public testing::Test { |
1177 public: | 1266 public: |
1178 PasswordStoreMacTest() : ui_thread_(BrowserThread::UI, &message_loop_) {} | 1267 PasswordStoreMacTest() : histogram_tester_(new base::HistogramTester) {} |
1179 | 1268 |
1180 void SetUp() override { | 1269 ~PasswordStoreMacTest() override { |
1181 ASSERT_TRUE(db_dir_.CreateUniqueTempDir()); | |
1182 histogram_tester_.reset(new base::HistogramTester); | |
1183 | |
1184 // Ensure that LoginDatabase will use the mock keychain if it needs to | |
1185 // encrypt/decrypt a password. | |
1186 OSCrypt::UseMockKeychain(true); | |
1187 login_db_.reset( | |
1188 new password_manager::LoginDatabase(test_login_db_file_path())); | |
1189 thread_.reset(new base::Thread("Chrome_PasswordStore_Thread")); | |
1190 ASSERT_TRUE(thread_->Start()); | |
1191 ASSERT_TRUE(thread_->task_runner()->PostTask( | |
1192 FROM_HERE, base::Bind(&PasswordStoreMacTest::InitLoginDatabase, | |
1193 base::Unretained(login_db_.get())))); | |
1194 CreateAndInitPasswordStore(login_db_.get()); | |
1195 // Make sure deferred initialization is performed before some tests start | |
1196 // accessing the |login_db| directly. | |
1197 FinishAsyncProcessing(); | |
1198 } | |
1199 | |
1200 void TearDown() override { | |
1201 ClosePasswordStore(); | |
1202 thread_.reset(); | |
1203 login_db_.reset(); | |
1204 // Whatever a test did, PasswordStoreMac stores only empty password values | 1270 // Whatever a test did, PasswordStoreMac stores only empty password values |
1205 // in LoginDatabase. The empty valus do not require encryption and therefore | 1271 // in LoginDatabase. The empty valus do not require encryption and therefore |
1206 // OSCrypt shouldn't call the Keychain. The histogram doesn't cover the | 1272 // OSCrypt shouldn't call the Keychain. The histogram doesn't cover the |
1207 // internet passwords. | 1273 // internet passwords. |
1208 if (histogram_tester_) { | 1274 if (histogram_tester_) { |
1209 histogram_tester_->ExpectTotalCount("OSX.Keychain.Access", 0); | 1275 histogram_tester_->ExpectTotalCount("OSX.Keychain.Access", 0); |
1210 } | 1276 } |
1211 } | 1277 } |
1212 | 1278 |
1213 static void InitLoginDatabase(password_manager::LoginDatabase* login_db) { | |
1214 ASSERT_TRUE(login_db->Init()); | |
1215 } | |
1216 | |
1217 void CreateAndInitPasswordStore(password_manager::LoginDatabase* login_db) { | |
1218 store_ = new PasswordStoreMac( | |
1219 base::ThreadTaskRunnerHandle::Get(), nullptr, | |
1220 make_scoped_ptr<AppleKeychain>(new MockAppleKeychain)); | |
1221 ASSERT_TRUE(thread_->task_runner()->PostTask( | |
1222 FROM_HERE, base::Bind(&PasswordStoreMac::InitWithTaskRunner, store_, | |
1223 thread_->task_runner()))); | |
1224 | |
1225 ASSERT_TRUE(thread_->task_runner()->PostTask( | |
1226 FROM_HERE, base::Bind(&PasswordStoreMac::set_login_metadata_db, store_, | |
1227 base::Unretained(login_db)))); | |
1228 } | |
1229 | |
1230 void ClosePasswordStore() { | |
1231 if (!store_) | |
1232 return; | |
1233 | |
1234 store_->ShutdownOnUIThread(); | |
1235 store_ = nullptr; | |
1236 } | |
1237 | |
1238 // Verifies that the given |form| can be properly stored so that it can be | 1279 // Verifies that the given |form| can be properly stored so that it can be |
1239 // retrieved by FillMatchingLogins() and GetAutofillableLogins(), and then it | 1280 // retrieved by FillMatchingLogins() and GetAutofillableLogins(), and then it |
1240 // can be properly removed. | 1281 // can be properly removed. |
1241 void VerifyCredentialLifecycle(const PasswordForm& form) { | 1282 void VerifyCredentialLifecycle(const PasswordForm& form) { |
1242 // Run everything twice to make sure no garbage is left behind that would | 1283 // Run everything twice to make sure no garbage is left behind that would |
1243 // prevent storing the form a second time. | 1284 // prevent storing the form a second time. |
1244 for (size_t iteration = 0; iteration < 2; ++iteration) { | 1285 for (size_t iteration = 0; iteration < 2; ++iteration) { |
1245 SCOPED_TRACE(testing::Message("Iteration: ") << iteration); | 1286 SCOPED_TRACE(testing::Message("Iteration: ") << iteration); |
1246 | 1287 |
1247 MockPasswordStoreConsumer mock_consumer; | 1288 MockPasswordStoreConsumer mock_consumer; |
1248 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())) | 1289 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())) |
1249 .WillOnce(QuitUIMessageLoop()); | 1290 .WillOnce(QuitUIMessageLoop()); |
1250 store()->GetAutofillableLogins(&mock_consumer); | 1291 delegate_.store()->GetAutofillableLogins(&mock_consumer); |
1251 base::MessageLoop::current()->Run(); | 1292 base::MessageLoop::current()->Run(); |
1252 ::testing::Mock::VerifyAndClearExpectations(&mock_consumer); | 1293 ::testing::Mock::VerifyAndClearExpectations(&mock_consumer); |
1253 | 1294 |
1254 store()->AddLogin(form); | 1295 delegate_.store()->AddLogin(form); |
1255 FinishAsyncProcessing(); | 1296 delegate_.FinishAsyncProcessing(); |
1256 | 1297 |
1257 PasswordForm returned_form; | 1298 PasswordForm returned_form; |
1258 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u))) | 1299 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u))) |
1259 .WillOnce( | 1300 .WillOnce( |
1260 DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop())); | 1301 DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop())); |
1261 | 1302 |
1262 // The query operations will also do some housekeeping: they will remove | 1303 // The query operations will also do some housekeeping: they will remove |
1263 // dangling credentials in the LoginDatabase without a matching Keychain | 1304 // dangling credentials in the LoginDatabase without a matching Keychain |
1264 // item when one is expected. If the logic that stores the Keychain item | 1305 // item when one is expected. If the logic that stores the Keychain item |
1265 // is incorrect, this will wipe the newly added form before the second | 1306 // is incorrect, this will wipe the newly added form before the second |
1266 // query. | 1307 // query. |
1267 store()->GetAutofillableLogins(&mock_consumer); | 1308 delegate_.store()->GetAutofillableLogins(&mock_consumer); |
1268 base::MessageLoop::current()->Run(); | 1309 base::MessageLoop::current()->Run(); |
1269 ::testing::Mock::VerifyAndClearExpectations(&mock_consumer); | 1310 ::testing::Mock::VerifyAndClearExpectations(&mock_consumer); |
1270 EXPECT_EQ(form, returned_form); | 1311 EXPECT_EQ(form, returned_form); |
1271 | 1312 |
1272 PasswordForm query_form = form; | 1313 PasswordForm query_form = form; |
1273 query_form.password_value.clear(); | 1314 query_form.password_value.clear(); |
1274 query_form.username_value.clear(); | 1315 query_form.username_value.clear(); |
1275 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u))) | 1316 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u))) |
1276 .WillOnce( | 1317 .WillOnce( |
1277 DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop())); | 1318 DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop())); |
1278 store()->GetLogins(query_form, PasswordStore::ALLOW_PROMPT, | 1319 delegate_.store()->GetLogins(query_form, PasswordStore::ALLOW_PROMPT, |
1279 &mock_consumer); | 1320 &mock_consumer); |
1280 base::MessageLoop::current()->Run(); | 1321 base::MessageLoop::current()->Run(); |
1281 ::testing::Mock::VerifyAndClearExpectations(&mock_consumer); | 1322 ::testing::Mock::VerifyAndClearExpectations(&mock_consumer); |
1282 EXPECT_EQ(form, returned_form); | 1323 EXPECT_EQ(form, returned_form); |
1283 | 1324 |
1284 store()->RemoveLogin(form); | 1325 delegate_.store()->RemoveLogin(form); |
1285 } | 1326 } |
1286 } | 1327 } |
1287 | 1328 |
1288 base::FilePath test_login_db_file_path() const { | |
1289 return db_dir_.path().Append(FILE_PATH_LITERAL("login.db")); | |
1290 } | |
1291 | |
1292 password_manager::LoginDatabase* login_db() const { | 1329 password_manager::LoginDatabase* login_db() const { |
1293 return store_->login_metadata_db(); | 1330 return delegate_.store()->login_metadata_db(); |
1294 } | 1331 } |
1295 | 1332 |
1296 MockAppleKeychain* keychain() { | 1333 MockAppleKeychain* keychain() { |
1297 return static_cast<MockAppleKeychain*>(store_->keychain()); | 1334 return static_cast<MockAppleKeychain*>(delegate_.store()->keychain()); |
1298 } | 1335 } |
1299 | 1336 |
1300 void FinishAsyncProcessing() { | 1337 PasswordStoreMacTestDelegate& delegate() { return delegate_; } |
1301 scoped_refptr<content::MessageLoopRunner> runner = | |
1302 new content::MessageLoopRunner; | |
1303 ASSERT_TRUE(thread_->task_runner()->PostTaskAndReply( | |
1304 FROM_HERE, base::Bind(&Noop), runner->QuitClosure())); | |
1305 runner->Run(); | |
1306 } | |
1307 | |
1308 PasswordStoreMac* store() { return store_.get(); } | |
1309 | 1338 |
1310 protected: | 1339 protected: |
1311 base::MessageLoopForUI message_loop_; | |
1312 content::TestBrowserThread ui_thread_; | |
1313 // Thread that the synchronous methods are run on. | |
1314 scoped_ptr<base::Thread> thread_; | |
1315 | |
1316 base::ScopedTempDir db_dir_; | |
1317 scoped_ptr<password_manager::LoginDatabase> login_db_; | |
1318 scoped_refptr<PasswordStoreMac> store_; | |
1319 scoped_ptr<base::HistogramTester> histogram_tester_; | 1340 scoped_ptr<base::HistogramTester> histogram_tester_; |
1341 PasswordStoreMacTestDelegate delegate_; | |
1320 }; | 1342 }; |
1321 | 1343 |
1322 TEST_F(PasswordStoreMacTest, TestStoreUpdate) { | 1344 TEST_F(PasswordStoreMacTest, TestStoreUpdate) { |
1323 // Insert a password into both the database and the keychain. | 1345 // Insert a password into both the database and the keychain. |
1324 // This is done manually, rather than through store_->AddLogin, because the | 1346 // This is done manually, rather than through delegate_.store()->AddLogin, |
1347 // because the | |
1325 // Mock Keychain isn't smart enough to be able to support update generically, | 1348 // Mock Keychain isn't smart enough to be able to support update generically, |
1326 // so some.domain.com triggers special handling to test it that make inserting | 1349 // so some.domain.com triggers special handling to test it that make inserting |
1327 // fail. | 1350 // fail. |
1328 PasswordFormData joint_data = { | 1351 PasswordFormData joint_data = { |
1329 PasswordForm::SCHEME_HTML, "http://some.domain.com/", | 1352 PasswordForm::SCHEME_HTML, "http://some.domain.com/", |
1330 "http://some.domain.com/insecure.html", "login.cgi", | 1353 "http://some.domain.com/insecure.html", "login.cgi", |
1331 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 | 1354 L"username", L"password", L"submit", L"joe_user", L"sekrit", true, false, 1 |
1332 }; | 1355 }; |
1333 scoped_ptr<PasswordForm> joint_form = | 1356 scoped_ptr<PasswordForm> joint_form = |
1334 CreatePasswordFormFromDataForTesting(joint_data); | 1357 CreatePasswordFormFromDataForTesting(joint_data); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1375 { { PasswordForm::SCHEME_HTML, "http://different.com/", | 1398 { { PasswordForm::SCHEME_HTML, "http://different.com/", |
1376 "http://different.com/index.html", "login.cgi", | 1399 "http://different.com/index.html", "login.cgi", |
1377 L"username", L"password", L"submit", L"abc", L"123", | 1400 L"username", L"password", L"submit", L"abc", L"123", |
1378 true, false, 2 }, | 1401 true, false, 2 }, |
1379 NULL, | 1402 NULL, |
1380 }, | 1403 }, |
1381 }; | 1404 }; |
1382 for (unsigned int i = 0; i < arraysize(updates); ++i) { | 1405 for (unsigned int i = 0; i < arraysize(updates); ++i) { |
1383 scoped_ptr<PasswordForm> form = | 1406 scoped_ptr<PasswordForm> form = |
1384 CreatePasswordFormFromDataForTesting(updates[i].form_data); | 1407 CreatePasswordFormFromDataForTesting(updates[i].form_data); |
1385 store_->UpdateLogin(*form); | 1408 delegate_.store()->UpdateLogin(*form); |
1386 } | 1409 } |
1387 | 1410 |
1388 FinishAsyncProcessing(); | 1411 delegate_.FinishAsyncProcessing(); |
1389 | 1412 |
1390 MacKeychainPasswordFormAdapter keychain_adapter(keychain()); | 1413 MacKeychainPasswordFormAdapter keychain_adapter(keychain()); |
1391 for (unsigned int i = 0; i < arraysize(updates); ++i) { | 1414 for (unsigned int i = 0; i < arraysize(updates); ++i) { |
1392 scoped_ptr<PasswordForm> query_form = | 1415 scoped_ptr<PasswordForm> query_form = |
1393 CreatePasswordFormFromDataForTesting(updates[i].form_data); | 1416 CreatePasswordFormFromDataForTesting(updates[i].form_data); |
1394 | 1417 |
1395 ScopedVector<autofill::PasswordForm> matching_items = | 1418 ScopedVector<autofill::PasswordForm> matching_items = |
1396 keychain_adapter.PasswordsFillingForm(query_form->signon_realm, | 1419 keychain_adapter.PasswordsFillingForm(query_form->signon_realm, |
1397 query_form->scheme); | 1420 query_form->scheme); |
1398 if (updates[i].password) { | 1421 if (updates[i].password) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1438 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain()); | 1461 MacKeychainPasswordFormAdapter owned_keychain_adapter(keychain()); |
1439 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); | 1462 owned_keychain_adapter.SetFindsOnlyOwnedItems(true); |
1440 owned_keychain_adapter.AddPassword(*www_form); | 1463 owned_keychain_adapter.AddPassword(*www_form); |
1441 | 1464 |
1442 // 2. Get a password for m.facebook.com. | 1465 // 2. Get a password for m.facebook.com. |
1443 PasswordForm m_form(*www_form); | 1466 PasswordForm m_form(*www_form); |
1444 m_form.signon_realm = "http://m.facebook.com"; | 1467 m_form.signon_realm = "http://m.facebook.com"; |
1445 m_form.origin = GURL("http://m.facebook.com/index.html"); | 1468 m_form.origin = GURL("http://m.facebook.com/index.html"); |
1446 | 1469 |
1447 MockPasswordStoreConsumer consumer; | 1470 MockPasswordStoreConsumer consumer; |
1448 store_->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer); | 1471 delegate_.store()->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer); |
1449 PasswordForm returned_form; | 1472 PasswordForm returned_form; |
1450 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u))) | 1473 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u))) |
1451 .WillOnce( | 1474 .WillOnce( |
1452 DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop())); | 1475 DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop())); |
1453 base::MessageLoop::current()->Run(); | 1476 base::MessageLoop::current()->Run(); |
1454 | 1477 |
1455 // 3. Add the returned password for m.facebook.com. | 1478 // 3. Add the returned password for m.facebook.com. |
1456 returned_form.signon_realm = "http://m.facebook.com"; | 1479 returned_form.signon_realm = "http://m.facebook.com"; |
1457 returned_form.origin = GURL("http://m.facebook.com/index.html"); | 1480 returned_form.origin = GURL("http://m.facebook.com/index.html"); |
1458 EXPECT_EQ(AddChangeForForm(returned_form), | 1481 EXPECT_EQ(AddChangeForForm(returned_form), |
1459 login_db()->AddLogin(returned_form)); | 1482 login_db()->AddLogin(returned_form)); |
1460 owned_keychain_adapter.AddPassword(m_form); | 1483 owned_keychain_adapter.AddPassword(m_form); |
1461 | 1484 |
1462 // 4. Remove both passwords. | 1485 // 4. Remove both passwords. |
1463 store_->RemoveLogin(*www_form); | 1486 delegate_.store()->RemoveLogin(*www_form); |
1464 store_->RemoveLogin(m_form); | 1487 delegate_.store()->RemoveLogin(m_form); |
1465 FinishAsyncProcessing(); | 1488 delegate_.FinishAsyncProcessing(); |
1466 | 1489 |
1467 // No trace of www.facebook.com. | 1490 // No trace of www.facebook.com. |
1468 ScopedVector<autofill::PasswordForm> matching_items = | 1491 ScopedVector<autofill::PasswordForm> matching_items = |
1469 owned_keychain_adapter.PasswordsFillingForm(www_form->signon_realm, | 1492 owned_keychain_adapter.PasswordsFillingForm(www_form->signon_realm, |
1470 www_form->scheme); | 1493 www_form->scheme); |
1471 EXPECT_EQ(0u, matching_items.size()); | 1494 EXPECT_EQ(0u, matching_items.size()); |
1472 EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items)); | 1495 EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items)); |
1473 EXPECT_EQ(0u, matching_items.size()); | 1496 EXPECT_EQ(0u, matching_items.size()); |
1474 // No trace of m.facebook.com. | 1497 // No trace of m.facebook.com. |
1475 matching_items = owned_keychain_adapter.PasswordsFillingForm( | 1498 matching_items = owned_keychain_adapter.PasswordsFillingForm( |
1476 m_form.signon_realm, m_form.scheme); | 1499 m_form.signon_realm, m_form.scheme); |
1477 EXPECT_EQ(0u, matching_items.size()); | 1500 EXPECT_EQ(0u, matching_items.size()); |
1478 EXPECT_TRUE(login_db()->GetLogins(m_form, &matching_items)); | 1501 EXPECT_TRUE(login_db()->GetLogins(m_form, &matching_items)); |
1479 EXPECT_EQ(0u, matching_items.size()); | 1502 EXPECT_EQ(0u, matching_items.size()); |
1480 } | 1503 } |
1481 | 1504 |
1482 namespace { | 1505 namespace { |
1483 | 1506 |
1484 class PasswordsChangeObserver | 1507 class PasswordsChangeObserver |
1485 : public password_manager::PasswordStore::Observer { | 1508 : public password_manager::PasswordStore::Observer { |
1486 public: | 1509 public: |
1487 explicit PasswordsChangeObserver(PasswordStoreMac* store) : observer_(this) { | 1510 explicit PasswordsChangeObserver(PasswordStoreMac* store) : observer_(this) { |
1488 observer_.Add(store); | 1511 observer_.Add(store); |
1489 } | 1512 } |
1490 | 1513 |
1491 void WaitAndVerify(PasswordStoreMacTest* test) { | 1514 void WaitAndVerify(PasswordStoreMacTest* test) { |
1492 test->FinishAsyncProcessing(); | 1515 test->delegate().FinishAsyncProcessing(); |
1493 ::testing::Mock::VerifyAndClearExpectations(this); | 1516 ::testing::Mock::VerifyAndClearExpectations(this); |
1494 } | 1517 } |
1495 | 1518 |
1496 // password_manager::PasswordStore::Observer: | 1519 // password_manager::PasswordStore::Observer: |
1497 MOCK_METHOD1(OnLoginsChanged, | 1520 MOCK_METHOD1(OnLoginsChanged, |
1498 void(const password_manager::PasswordStoreChangeList& changes)); | 1521 void(const password_manager::PasswordStoreChangeList& changes)); |
1499 | 1522 |
1500 private: | 1523 private: |
1501 ScopedObserver<password_manager::PasswordStore, PasswordsChangeObserver> | 1524 ScopedObserver<password_manager::PasswordStore, PasswordsChangeObserver> |
1502 observer_; | 1525 observer_; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1536 if (check_created) { | 1559 if (check_created) { |
1537 form_facebook_old->date_created = now; | 1560 form_facebook_old->date_created = now; |
1538 form_facebook->date_created = next_day; | 1561 form_facebook->date_created = next_day; |
1539 form_other->date_created = next_day; | 1562 form_other->date_created = next_day; |
1540 } else { | 1563 } else { |
1541 form_facebook_old->date_synced = now; | 1564 form_facebook_old->date_synced = now; |
1542 form_facebook->date_synced = next_day; | 1565 form_facebook->date_synced = next_day; |
1543 form_other->date_synced = next_day; | 1566 form_other->date_synced = next_day; |
1544 } | 1567 } |
1545 | 1568 |
1546 PasswordsChangeObserver observer(test->store()); | 1569 PasswordsChangeObserver observer(test->delegate().store()); |
1547 test->store()->AddLogin(*form_facebook_old); | 1570 test->delegate().store()->AddLogin(*form_facebook_old); |
1548 test->store()->AddLogin(*form_facebook); | 1571 test->delegate().store()->AddLogin(*form_facebook); |
1549 test->store()->AddLogin(*form_other); | 1572 test->delegate().store()->AddLogin(*form_other); |
1550 EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_facebook_old))); | 1573 EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_facebook_old))); |
1551 EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_facebook))); | 1574 EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_facebook))); |
1552 EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_other))); | 1575 EXPECT_CALL(observer, OnLoginsChanged(GetAddChangeList(*form_other))); |
1553 observer.WaitAndVerify(test); | 1576 observer.WaitAndVerify(test); |
1554 | 1577 |
1555 // Check the keychain content. | 1578 // Check the keychain content. |
1556 MacKeychainPasswordFormAdapter owned_keychain_adapter(test->keychain()); | 1579 MacKeychainPasswordFormAdapter owned_keychain_adapter(test->keychain()); |
1557 owned_keychain_adapter.SetFindsOnlyOwnedItems(false); | 1580 owned_keychain_adapter.SetFindsOnlyOwnedItems(false); |
1558 ScopedVector<PasswordForm> matching_items( | 1581 ScopedVector<PasswordForm> matching_items( |
1559 owned_keychain_adapter.PasswordsFillingForm(form_facebook->signon_realm, | 1582 owned_keychain_adapter.PasswordsFillingForm(form_facebook->signon_realm, |
1560 form_facebook->scheme)); | 1583 form_facebook->scheme)); |
1561 EXPECT_EQ(1u, matching_items.size()); | 1584 EXPECT_EQ(1u, matching_items.size()); |
1562 matching_items = owned_keychain_adapter.PasswordsFillingForm( | 1585 matching_items = owned_keychain_adapter.PasswordsFillingForm( |
1563 form_other->signon_realm, form_other->scheme); | 1586 form_other->signon_realm, form_other->scheme); |
1564 EXPECT_EQ(1u, matching_items.size()); | 1587 EXPECT_EQ(1u, matching_items.size()); |
1565 | 1588 |
1566 // Remove facebook. | 1589 // Remove facebook. |
1567 if (check_created) { | 1590 if (check_created) { |
1568 test->store()->RemoveLoginsCreatedBetween(base::Time(), next_day, | 1591 test->delegate().store()->RemoveLoginsCreatedBetween(base::Time(), next_day, |
1569 base::Closure()); | 1592 base::Closure()); |
1570 } else { | 1593 } else { |
1571 test->store()->RemoveLoginsSyncedBetween(base::Time(), next_day); | 1594 test->delegate().store()->RemoveLoginsSyncedBetween(base::Time(), next_day); |
1572 } | 1595 } |
1573 password_manager::PasswordStoreChangeList list; | 1596 password_manager::PasswordStoreChangeList list; |
1574 form_facebook_old->password_value.clear(); | 1597 form_facebook_old->password_value.clear(); |
1575 form_facebook->password_value.clear(); | 1598 form_facebook->password_value.clear(); |
1576 list.push_back(password_manager::PasswordStoreChange( | 1599 list.push_back(password_manager::PasswordStoreChange( |
1577 password_manager::PasswordStoreChange::REMOVE, *form_facebook_old)); | 1600 password_manager::PasswordStoreChange::REMOVE, *form_facebook_old)); |
1578 list.push_back(password_manager::PasswordStoreChange( | 1601 list.push_back(password_manager::PasswordStoreChange( |
1579 password_manager::PasswordStoreChange::REMOVE, *form_facebook)); | 1602 password_manager::PasswordStoreChange::REMOVE, *form_facebook)); |
1580 EXPECT_CALL(observer, OnLoginsChanged(list)); | 1603 EXPECT_CALL(observer, OnLoginsChanged(list)); |
1581 list.clear(); | 1604 list.clear(); |
1582 observer.WaitAndVerify(test); | 1605 observer.WaitAndVerify(test); |
1583 | 1606 |
1584 matching_items = owned_keychain_adapter.PasswordsFillingForm( | 1607 matching_items = owned_keychain_adapter.PasswordsFillingForm( |
1585 form_facebook->signon_realm, form_facebook->scheme); | 1608 form_facebook->signon_realm, form_facebook->scheme); |
1586 EXPECT_EQ(0u, matching_items.size()); | 1609 EXPECT_EQ(0u, matching_items.size()); |
1587 matching_items = owned_keychain_adapter.PasswordsFillingForm( | 1610 matching_items = owned_keychain_adapter.PasswordsFillingForm( |
1588 form_other->signon_realm, form_other->scheme); | 1611 form_other->signon_realm, form_other->scheme); |
1589 EXPECT_EQ(1u, matching_items.size()); | 1612 EXPECT_EQ(1u, matching_items.size()); |
1590 | 1613 |
1591 // Remove form_other. | 1614 // Remove form_other. |
1592 if (check_created) { | 1615 if (check_created) { |
1593 test->store()->RemoveLoginsCreatedBetween(next_day, base::Time(), | 1616 test->delegate().store()->RemoveLoginsCreatedBetween(next_day, base::Time(), |
1594 base::Closure()); | 1617 base::Closure()); |
1595 } else { | 1618 } else { |
1596 test->store()->RemoveLoginsSyncedBetween(next_day, base::Time()); | 1619 test->delegate().store()->RemoveLoginsSyncedBetween(next_day, base::Time()); |
1597 } | 1620 } |
1598 form_other->password_value.clear(); | 1621 form_other->password_value.clear(); |
1599 list.push_back(password_manager::PasswordStoreChange( | 1622 list.push_back(password_manager::PasswordStoreChange( |
1600 password_manager::PasswordStoreChange::REMOVE, *form_other)); | 1623 password_manager::PasswordStoreChange::REMOVE, *form_other)); |
1601 EXPECT_CALL(observer, OnLoginsChanged(list)); | 1624 EXPECT_CALL(observer, OnLoginsChanged(list)); |
1602 observer.WaitAndVerify(test); | 1625 observer.WaitAndVerify(test); |
1603 matching_items = owned_keychain_adapter.PasswordsFillingForm( | 1626 matching_items = owned_keychain_adapter.PasswordsFillingForm( |
1604 form_other->signon_realm, form_other->scheme); | 1627 form_other->signon_realm, form_other->scheme); |
1605 EXPECT_EQ(0u, matching_items.size()); | 1628 EXPECT_EQ(0u, matching_items.size()); |
1606 } | 1629 } |
(...skipping 30 matching lines...) Expand all Loading... | |
1637 scoped_ptr<PasswordForm> www_form = | 1660 scoped_ptr<PasswordForm> www_form = |
1638 CreatePasswordFormFromDataForTesting(www_form_data1); | 1661 CreatePasswordFormFromDataForTesting(www_form_data1); |
1639 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*www_form)); | 1662 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*www_form)); |
1640 | 1663 |
1641 // Add a password from the current profile. | 1664 // Add a password from the current profile. |
1642 PasswordFormData www_form_data2 = { | 1665 PasswordFormData www_form_data2 = { |
1643 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1666 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
1644 "http://www.facebook.com/index.html", "login", L"username", L"password", | 1667 "http://www.facebook.com/index.html", "login", L"username", L"password", |
1645 L"submit", L"not_joe_user", L"12345", true, false, 1 }; | 1668 L"submit", L"not_joe_user", L"12345", true, false, 1 }; |
1646 www_form = CreatePasswordFormFromDataForTesting(www_form_data2); | 1669 www_form = CreatePasswordFormFromDataForTesting(www_form_data2); |
1647 store_->AddLogin(*www_form); | 1670 delegate_.store()->AddLogin(*www_form); |
1648 FinishAsyncProcessing(); | 1671 delegate_.FinishAsyncProcessing(); |
1649 | 1672 |
1650 ScopedVector<PasswordForm> matching_items; | 1673 ScopedVector<PasswordForm> matching_items; |
1651 EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items)); | 1674 EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items)); |
1652 EXPECT_EQ(1u, matching_items.size()); | 1675 EXPECT_EQ(1u, matching_items.size()); |
1653 | 1676 |
1654 store_->RemoveLoginsCreatedBetween(base::Time(), base::Time(), | 1677 delegate_.store()->RemoveLoginsCreatedBetween(base::Time(), base::Time(), |
1655 base::Closure()); | 1678 base::Closure()); |
1656 FinishAsyncProcessing(); | 1679 delegate_.FinishAsyncProcessing(); |
1657 | 1680 |
1658 // Check the second facebook form is gone. | 1681 // Check the second facebook form is gone. |
1659 EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items)); | 1682 EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items)); |
1660 EXPECT_EQ(0u, matching_items.size()); | 1683 EXPECT_EQ(0u, matching_items.size()); |
1661 | 1684 |
1662 // Check the first facebook form is still there. | 1685 // Check the first facebook form is still there. |
1663 matching_items = owned_keychain_adapter.PasswordsFillingForm( | 1686 matching_items = owned_keychain_adapter.PasswordsFillingForm( |
1664 www_form->signon_realm, www_form->scheme); | 1687 www_form->signon_realm, www_form->scheme); |
1665 ASSERT_EQ(1u, matching_items.size()); | 1688 ASSERT_EQ(1u, matching_items.size()); |
1666 EXPECT_EQ(ASCIIToUTF16("joe_user"), matching_items[0]->username_value); | 1689 EXPECT_EQ(ASCIIToUTF16("joe_user"), matching_items[0]->username_value); |
1667 | 1690 |
1668 // Check the third-party password is still there. | 1691 // Check the third-party password is still there. |
1669 owned_keychain_adapter.SetFindsOnlyOwnedItems(false); | 1692 owned_keychain_adapter.SetFindsOnlyOwnedItems(false); |
1670 matching_items = owned_keychain_adapter.PasswordsFillingForm( | 1693 matching_items = owned_keychain_adapter.PasswordsFillingForm( |
1671 "http://some.domain.com/insecure.html", PasswordForm::SCHEME_HTML); | 1694 "http://some.domain.com/insecure.html", PasswordForm::SCHEME_HTML); |
1672 ASSERT_EQ(1u, matching_items.size()); | 1695 ASSERT_EQ(1u, matching_items.size()); |
1673 } | 1696 } |
1674 | 1697 |
1675 // Add a facebook form to the store but not to the keychain. The form is to be | 1698 // Add a facebook form to the store but not to the keychain. The form is to be |
1676 // implicitly deleted. However, the observers shouldn't get notified about | 1699 // implicitly deleted. However, the observers shouldn't get notified about |
1677 // deletion of non-existent forms like m.facebook.com. | 1700 // deletion of non-existent forms like m.facebook.com. |
1678 TEST_F(PasswordStoreMacTest, SilentlyRemoveOrphanedForm) { | 1701 TEST_F(PasswordStoreMacTest, SilentlyRemoveOrphanedForm) { |
1679 testing::StrictMock<MockPasswordStoreObserver> mock_observer; | 1702 testing::StrictMock<password_manager::MockPasswordStoreObserver> |
1680 store()->AddObserver(&mock_observer); | 1703 mock_observer; |
1704 delegate_.store()->AddObserver(&mock_observer); | |
1681 | 1705 |
1682 // 1. Add a password for www.facebook.com to the LoginDatabase. | 1706 // 1. Add a password for www.facebook.com to the LoginDatabase. |
1683 PasswordFormData www_form_data = { | 1707 PasswordFormData www_form_data = { |
1684 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", | 1708 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", |
1685 "http://www.facebook.com/index.html", "login", | 1709 "http://www.facebook.com/index.html", "login", |
1686 L"username", L"password", L"submit", L"joe_user", L"", true, false, 1 | 1710 L"username", L"password", L"submit", L"joe_user", L"", true, false, 1 |
1687 }; | 1711 }; |
1688 scoped_ptr<PasswordForm> www_form( | 1712 scoped_ptr<PasswordForm> www_form( |
1689 CreatePasswordFormFromDataForTesting(www_form_data)); | 1713 CreatePasswordFormFromDataForTesting(www_form_data)); |
1690 EXPECT_EQ(AddChangeForForm(*www_form), login_db()->AddLogin(*www_form)); | 1714 EXPECT_EQ(AddChangeForForm(*www_form), login_db()->AddLogin(*www_form)); |
1691 | 1715 |
1692 // 2. Get a PSL-matched password for m.facebook.com. The observer isn't | 1716 // 2. Get a PSL-matched password for m.facebook.com. The observer isn't |
1693 // notified because the form isn't in the database. | 1717 // notified because the form isn't in the database. |
1694 PasswordForm m_form(*www_form); | 1718 PasswordForm m_form(*www_form); |
1695 m_form.signon_realm = "http://m.facebook.com"; | 1719 m_form.signon_realm = "http://m.facebook.com"; |
1696 m_form.origin = GURL("http://m.facebook.com/index.html"); | 1720 m_form.origin = GURL("http://m.facebook.com/index.html"); |
1697 | 1721 |
1698 MockPasswordStoreConsumer consumer; | 1722 MockPasswordStoreConsumer consumer; |
1699 ON_CALL(consumer, OnGetPasswordStoreResultsConstRef(_)) | 1723 ON_CALL(consumer, OnGetPasswordStoreResultsConstRef(_)) |
1700 .WillByDefault(QuitUIMessageLoop()); | 1724 .WillByDefault(QuitUIMessageLoop()); |
1701 EXPECT_CALL(mock_observer, OnLoginsChanged(_)).Times(0); | 1725 EXPECT_CALL(mock_observer, OnLoginsChanged(_)).Times(0); |
1702 // The PSL-matched form isn't returned because there is no actual password in | 1726 // The PSL-matched form isn't returned because there is no actual password in |
1703 // the keychain. | 1727 // the keychain. |
1704 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())); | 1728 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())); |
1705 store_->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer); | 1729 delegate_.store()->GetLogins(m_form, PasswordStore::ALLOW_PROMPT, &consumer); |
1706 base::MessageLoop::current()->Run(); | 1730 base::MessageLoop::current()->Run(); |
1707 ScopedVector<autofill::PasswordForm> all_forms; | 1731 ScopedVector<autofill::PasswordForm> all_forms; |
1708 EXPECT_TRUE(login_db()->GetAutofillableLogins(&all_forms)); | 1732 EXPECT_TRUE(login_db()->GetAutofillableLogins(&all_forms)); |
1709 EXPECT_EQ(1u, all_forms.size()); | 1733 EXPECT_EQ(1u, all_forms.size()); |
1710 ::testing::Mock::VerifyAndClearExpectations(&mock_observer); | 1734 ::testing::Mock::VerifyAndClearExpectations(&mock_observer); |
1711 | 1735 |
1712 // 3. Get a password for www.facebook.com. The form is implicitly removed and | 1736 // 3. Get a password for www.facebook.com. The form is implicitly removed and |
1713 // the observer is notified. | 1737 // the observer is notified. |
1714 password_manager::PasswordStoreChangeList list; | 1738 password_manager::PasswordStoreChangeList list; |
1715 list.push_back(password_manager::PasswordStoreChange( | 1739 list.push_back(password_manager::PasswordStoreChange( |
1716 password_manager::PasswordStoreChange::REMOVE, *www_form)); | 1740 password_manager::PasswordStoreChange::REMOVE, *www_form)); |
1717 EXPECT_CALL(mock_observer, OnLoginsChanged(list)); | 1741 EXPECT_CALL(mock_observer, OnLoginsChanged(list)); |
1718 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())); | 1742 EXPECT_CALL(consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())); |
1719 store_->GetLogins(*www_form, PasswordStore::ALLOW_PROMPT, &consumer); | 1743 delegate_.store()->GetLogins(*www_form, PasswordStore::ALLOW_PROMPT, |
1744 &consumer); | |
1720 base::MessageLoop::current()->Run(); | 1745 base::MessageLoop::current()->Run(); |
1721 EXPECT_TRUE(login_db()->GetAutofillableLogins(&all_forms)); | 1746 EXPECT_TRUE(login_db()->GetAutofillableLogins(&all_forms)); |
1722 EXPECT_EQ(0u, all_forms.size()); | 1747 EXPECT_EQ(0u, all_forms.size()); |
1723 } | 1748 } |
1724 | 1749 |
1725 // Verify that Android app passwords can be stored, retrieved, and deleted. | 1750 // Verify that Android app passwords can be stored, retrieved, and deleted. |
1726 // Regression test for http://crbug.com/455551 | 1751 // Regression test for http://crbug.com/455551 |
1727 TEST_F(PasswordStoreMacTest, StoringAndRetrievingAndroidCredentials) { | 1752 TEST_F(PasswordStoreMacTest, StoringAndRetrievingAndroidCredentials) { |
1728 PasswordForm form; | 1753 PasswordForm form; |
1729 form.signon_realm = "android://7x7IDboo8u9YKraUsbmVkuf1@net.rateflix.app/"; | 1754 form.signon_realm = "android://7x7IDboo8u9YKraUsbmVkuf1@net.rateflix.app/"; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1762 form2.origin = GURL("http://facebook.com/Login"); | 1787 form2.origin = GURL("http://facebook.com/Login"); |
1763 form2.signon_realm = "http://facebook.com/"; | 1788 form2.signon_realm = "http://facebook.com/"; |
1764 form2.username_value = ASCIIToUTF16("my_username"); | 1789 form2.username_value = ASCIIToUTF16("my_username"); |
1765 form2.password_value = ASCIIToUTF16("my_password"); | 1790 form2.password_value = ASCIIToUTF16("my_password"); |
1766 | 1791 |
1767 PasswordForm blacklisted_form; | 1792 PasswordForm blacklisted_form; |
1768 blacklisted_form.origin = GURL("http://badsite.com/Login"); | 1793 blacklisted_form.origin = GURL("http://badsite.com/Login"); |
1769 blacklisted_form.signon_realm = "http://badsite.com/"; | 1794 blacklisted_form.signon_realm = "http://badsite.com/"; |
1770 blacklisted_form.blacklisted_by_user = true; | 1795 blacklisted_form.blacklisted_by_user = true; |
1771 | 1796 |
1772 store()->AddLogin(form1); | 1797 delegate_.store()->AddLogin(form1); |
1773 store()->AddLogin(form2); | 1798 delegate_.store()->AddLogin(form2); |
1774 store()->AddLogin(blacklisted_form); | 1799 delegate_.store()->AddLogin(blacklisted_form); |
1775 FinishAsyncProcessing(); | 1800 delegate_.FinishAsyncProcessing(); |
1776 | 1801 |
1777 ASSERT_TRUE(base::PostTaskAndReplyWithResult( | 1802 ASSERT_TRUE(base::PostTaskAndReplyWithResult( |
1778 thread_->task_runner().get(), FROM_HERE, | 1803 base::ThreadTaskRunnerHandle::Get().get(), FROM_HERE, |
1779 base::Bind(&PasswordStoreMac::ImportFromKeychain, store()), | 1804 base::Bind(&PasswordStoreMac::ImportFromKeychain, delegate_.store()), |
1780 base::Bind(&CheckMigrationResult, PasswordStoreMac::MIGRATION_OK))); | 1805 base::Bind(&CheckMigrationResult, PasswordStoreMac::MIGRATION_OK))); |
1781 FinishAsyncProcessing(); | 1806 delegate_.FinishAsyncProcessing(); |
1782 | 1807 |
1783 // The password should be stored in the database by now. | 1808 // The password should be stored in the database by now. |
1784 ScopedVector<PasswordForm> matching_items; | 1809 ScopedVector<PasswordForm> matching_items; |
1785 EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items)); | 1810 EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items)); |
1786 ASSERT_EQ(1u, matching_items.size()); | 1811 ASSERT_EQ(1u, matching_items.size()); |
1787 EXPECT_EQ(form1, *matching_items[0]); | 1812 EXPECT_EQ(form1, *matching_items[0]); |
1788 | 1813 |
1789 EXPECT_TRUE(login_db()->GetLogins(form2, &matching_items)); | 1814 EXPECT_TRUE(login_db()->GetLogins(form2, &matching_items)); |
1790 ASSERT_EQ(1u, matching_items.size()); | 1815 ASSERT_EQ(1u, matching_items.size()); |
1791 EXPECT_EQ(form2, *matching_items[0]); | 1816 EXPECT_EQ(form2, *matching_items[0]); |
(...skipping 10 matching lines...) Expand all Loading... | |
1802 | 1827 |
1803 // Import a federated credential while the Keychain is locked. | 1828 // Import a federated credential while the Keychain is locked. |
1804 TEST_F(PasswordStoreMacTest, ImportFederatedFromLockedKeychain) { | 1829 TEST_F(PasswordStoreMacTest, ImportFederatedFromLockedKeychain) { |
1805 keychain()->set_locked(true); | 1830 keychain()->set_locked(true); |
1806 PasswordForm form1; | 1831 PasswordForm form1; |
1807 form1.origin = GURL("http://example.com/Login"); | 1832 form1.origin = GURL("http://example.com/Login"); |
1808 form1.signon_realm = "http://example.com/"; | 1833 form1.signon_realm = "http://example.com/"; |
1809 form1.username_value = ASCIIToUTF16("my_username"); | 1834 form1.username_value = ASCIIToUTF16("my_username"); |
1810 form1.federation_url = GURL("https://accounts.google.com/"); | 1835 form1.federation_url = GURL("https://accounts.google.com/"); |
1811 | 1836 |
1812 store()->AddLogin(form1); | 1837 delegate_.store()->AddLogin(form1); |
1813 FinishAsyncProcessing(); | 1838 delegate_.FinishAsyncProcessing(); |
1814 ASSERT_TRUE(base::PostTaskAndReplyWithResult( | 1839 ASSERT_TRUE(base::PostTaskAndReplyWithResult( |
1815 thread_->task_runner().get(), FROM_HERE, | 1840 base::ThreadTaskRunnerHandle::Get().get(), FROM_HERE, |
1816 base::Bind(&PasswordStoreMac::ImportFromKeychain, store()), | 1841 base::Bind(&PasswordStoreMac::ImportFromKeychain, delegate_.store()), |
1817 base::Bind(&CheckMigrationResult, PasswordStoreMac::MIGRATION_OK))); | 1842 base::Bind(&CheckMigrationResult, PasswordStoreMac::MIGRATION_OK))); |
1818 FinishAsyncProcessing(); | 1843 delegate_.FinishAsyncProcessing(); |
1819 | 1844 |
1820 ScopedVector<PasswordForm> matching_items; | 1845 ScopedVector<PasswordForm> matching_items; |
1821 EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items)); | 1846 EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items)); |
1822 ASSERT_EQ(1u, matching_items.size()); | 1847 ASSERT_EQ(1u, matching_items.size()); |
1823 EXPECT_EQ(form1, *matching_items[0]); | 1848 EXPECT_EQ(form1, *matching_items[0]); |
1824 } | 1849 } |
1825 | 1850 |
1826 // Try to import while the Keychain is locked but the encryption key had been | 1851 // Try to import while the Keychain is locked but the encryption key had been |
1827 // read earlier. | 1852 // read earlier. |
1828 TEST_F(PasswordStoreMacTest, ImportFromLockedKeychainError) { | 1853 TEST_F(PasswordStoreMacTest, ImportFromLockedKeychainError) { |
1829 PasswordForm form1; | 1854 PasswordForm form1; |
1830 form1.origin = GURL("http://accounts.google.com/LoginAuth"); | 1855 form1.origin = GURL("http://accounts.google.com/LoginAuth"); |
1831 form1.signon_realm = "http://accounts.google.com/"; | 1856 form1.signon_realm = "http://accounts.google.com/"; |
1832 form1.username_value = ASCIIToUTF16("my_username"); | 1857 form1.username_value = ASCIIToUTF16("my_username"); |
1833 form1.password_value = ASCIIToUTF16("my_password"); | 1858 form1.password_value = ASCIIToUTF16("my_password"); |
1834 store()->AddLogin(form1); | 1859 delegate_.store()->AddLogin(form1); |
1835 FinishAsyncProcessing(); | 1860 delegate_.FinishAsyncProcessing(); |
1836 | 1861 |
1837 // Add a second keychain item matching the Database entry. | 1862 // Add a second keychain item matching the Database entry. |
1838 PasswordForm form2 = form1; | 1863 PasswordForm form2 = form1; |
1839 form2.origin = GURL("http://accounts.google.com/Login"); | 1864 form2.origin = GURL("http://accounts.google.com/Login"); |
1840 form2.password_value = ASCIIToUTF16("1234"); | 1865 form2.password_value = ASCIIToUTF16("1234"); |
1841 MacKeychainPasswordFormAdapter adapter(keychain()); | 1866 MacKeychainPasswordFormAdapter adapter(keychain()); |
1842 EXPECT_TRUE(adapter.AddPassword(form2)); | 1867 EXPECT_TRUE(adapter.AddPassword(form2)); |
1843 | 1868 |
1844 keychain()->set_locked(true); | 1869 keychain()->set_locked(true); |
1845 ASSERT_TRUE(base::PostTaskAndReplyWithResult( | 1870 ASSERT_TRUE(base::PostTaskAndReplyWithResult( |
1846 thread_->task_runner().get(), FROM_HERE, | 1871 base::ThreadTaskRunnerHandle::Get().get(), FROM_HERE, |
1847 base::Bind(&PasswordStoreMac::ImportFromKeychain, store()), | 1872 base::Bind(&PasswordStoreMac::ImportFromKeychain, delegate_.store()), |
1848 base::Bind(&CheckMigrationResult, PasswordStoreMac::KEYCHAIN_BLOCKED))); | 1873 base::Bind(&CheckMigrationResult, PasswordStoreMac::KEYCHAIN_BLOCKED))); |
1849 FinishAsyncProcessing(); | 1874 delegate_.FinishAsyncProcessing(); |
1850 | 1875 |
1851 ScopedVector<PasswordForm> matching_items; | 1876 ScopedVector<PasswordForm> matching_items; |
1852 EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items)); | 1877 EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items)); |
1853 ASSERT_EQ(1u, matching_items.size()); | 1878 ASSERT_EQ(1u, matching_items.size()); |
1854 EXPECT_EQ(base::string16(), matching_items[0]->password_value); | 1879 EXPECT_EQ(base::string16(), matching_items[0]->password_value); |
1855 | 1880 |
1856 histogram_tester_->ExpectUniqueSample( | 1881 histogram_tester_->ExpectUniqueSample( |
1857 "PasswordManager.KeychainMigration.NumPasswordsOnFailure", 1, 1); | 1882 "PasswordManager.KeychainMigration.NumPasswordsOnFailure", 1, 1); |
1858 histogram_tester_->ExpectUniqueSample( | 1883 histogram_tester_->ExpectUniqueSample( |
1859 "PasswordManager.KeychainMigration.NumFailedPasswords", 1, 1); | 1884 "PasswordManager.KeychainMigration.NumFailedPasswords", 1, 1); |
1860 histogram_tester_->ExpectUniqueSample( | 1885 histogram_tester_->ExpectUniqueSample( |
1861 "PasswordManager.KeychainMigration.NumChromeOwnedInaccessiblePasswords", | 1886 "PasswordManager.KeychainMigration.NumChromeOwnedInaccessiblePasswords", |
1862 2, 1); | 1887 2, 1); |
1863 // Don't test the encryption key access. | 1888 // Don't test the encryption key access. |
1864 histogram_tester_.reset(); | 1889 histogram_tester_.reset(); |
1865 } | 1890 } |
OLD | NEW |