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

Side by Side Diff: chrome/browser/password_manager/password_store_mac_unittest.cc

Issue 1414463004: Implement origin-based deletion for passwords in PasswordDefaultMac. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@lkgr
Patch Set: Address first round of comments. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/files/scoped_temp_dir.h" 8 #include "base/files/scoped_temp_dir.h"
9 #include "base/scoped_observer.h" 9 #include "base/scoped_observer.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
11 #include "base/strings/string_util.h" 11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "base/synchronization/waitable_event.h" 13 #include "base/synchronization/waitable_event.h"
14 #include "base/test/histogram_tester.h" 14 #include "base/test/histogram_tester.h"
15 #include "base/thread_task_runner_handle.h" 15 #include "base/thread_task_runner_handle.h"
16 #include "chrome/browser/password_manager/password_store_mac_internal.h" 16 #include "chrome/browser/password_manager/password_store_mac_internal.h"
17 #include "chrome/common/chrome_paths.h" 17 #include "chrome/common/chrome_paths.h"
18 #include "components/os_crypt/os_crypt.h" 18 #include "components/os_crypt/os_crypt.h"
19 #include "components/password_manager/core/browser/login_database.h" 19 #include "components/password_manager/core/browser/login_database.h"
20 #include "components/password_manager/core/browser/password_manager_test_utils.h " 20 #include "components/password_manager/core/browser/password_manager_test_utils.h "
21 #include "components/password_manager/core/browser/password_store_consumer.h" 21 #include "components/password_manager/core/browser/password_store_consumer.h"
22 #include "components/password_manager/core/browser/password_store_origin_unittes t.h"
22 #include "content/public/test/test_browser_thread.h" 23 #include "content/public/test/test_browser_thread.h"
23 #include "content/public/test/test_utils.h" 24 #include "content/public/test/test_utils.h"
24 #include "crypto/mock_apple_keychain.h" 25 #include "crypto/mock_apple_keychain.h"
25 #include "testing/gmock/include/gmock/gmock.h" 26 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h" 27 #include "testing/gtest/include/gtest/gtest.h"
27 28
28 using autofill::PasswordForm; 29 using autofill::PasswordForm;
29 using base::ASCIIToUTF16; 30 using base::ASCIIToUTF16;
30 using base::WideToUTF16; 31 using base::WideToUTF16;
31 using content::BrowserThread; 32 using content::BrowserThread;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 public: 68 public:
68 MOCK_METHOD1(OnGetPasswordStoreResultsConstRef, 69 MOCK_METHOD1(OnGetPasswordStoreResultsConstRef,
69 void(const std::vector<PasswordForm*>&)); 70 void(const std::vector<PasswordForm*>&));
70 71
71 // GMock cannot mock methods with move-only args. 72 // GMock cannot mock methods with move-only args.
72 void OnGetPasswordStoreResults(ScopedVector<PasswordForm> results) override { 73 void OnGetPasswordStoreResults(ScopedVector<PasswordForm> results) override {
73 OnGetPasswordStoreResultsConstRef(results.get()); 74 OnGetPasswordStoreResultsConstRef(results.get());
74 } 75 }
75 }; 76 };
76 77
77 class MockPasswordStoreObserver : public PasswordStore::Observer {
78 public:
79 MOCK_METHOD1(OnLoginsChanged,
80 void(const password_manager::PasswordStoreChangeList& changes));
81 };
82
83 // A LoginDatabase that simulates an Init() method that takes a long time. 78 // A LoginDatabase that simulates an Init() method that takes a long time.
84 class SlowToInitLoginDatabase : public password_manager::LoginDatabase { 79 class SlowToInitLoginDatabase : public password_manager::LoginDatabase {
85 public: 80 public:
86 // Creates an instance whose Init() method will block until |event| is 81 // Creates an instance whose Init() method will block until |event| is
87 // signaled. |event| must outlive |this|. 82 // signaled. |event| must outlive |this|.
88 SlowToInitLoginDatabase(const base::FilePath& db_path, 83 SlowToInitLoginDatabase(const base::FilePath& db_path,
89 base::WaitableEvent* event) 84 base::WaitableEvent* event)
90 : password_manager::LoginDatabase(db_path), event_(event) {} 85 : password_manager::LoginDatabase(db_path), event_(event) {}
91 ~SlowToInitLoginDatabase() override {} 86 ~SlowToInitLoginDatabase() override {}
92 87
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 form->date_synced); 160 form->date_synced);
166 EXPECT_EQ(GURL(password_manager::kTestingIconUrlSpec), form->icon_url); 161 EXPECT_EQ(GURL(password_manager::kTestingIconUrlSpec), form->icon_url);
167 } 162 }
168 } 163 }
169 164
170 PasswordStoreChangeList AddChangeForForm(const PasswordForm& form) { 165 PasswordStoreChangeList AddChangeForForm(const PasswordForm& form) {
171 return PasswordStoreChangeList( 166 return PasswordStoreChangeList(
172 1, PasswordStoreChange(PasswordStoreChange::ADD, form)); 167 1, PasswordStoreChange(PasswordStoreChange::ADD, form));
173 } 168 }
174 169
170 class PasswordStoreMacTestDelegate {
171 public:
172 PasswordStoreMacTestDelegate();
173 ~PasswordStoreMacTestDelegate();
174
175 PasswordStoreMac* store() { return store_.get(); }
176
177 base::Thread* thread() { return thread_.get(); }
178
179 void FinishAsyncProcessing();
180
181 private:
182 static void InitLoginDatabase(LoginDatabase* login_db);
183 void Initialize();
184 base::FilePath test_login_db_file_path() const;
185
186 void ClosePasswordStore();
187
188 base::MessageLoopForUI message_loop_;
189 content::TestBrowserThread ui_thread_;
vasilii 2015/11/18 16:27:42 It's deprecated. Use TestBrowserThreadBundle. It c
Timo Reimann 2015/11/18 23:42:15 Okay, done. Apart from adding TestBrowserThreadBun
vasilii 2015/11/23 15:04:56 In the implementation you made the test single-thr
Timo Reimann 2015/11/24 02:36:09 This part was and still is somewhat unclear to me:
vasilii 2015/11/24 18:14:54 You don't have to refactor PasswordStoreMacTest. Y
Timo Reimann 2015/11/24 23:06:02 Without any refactoring permitted, wouldn't that p
vasilii 2015/11/25 18:18:39 I don't understand your concern. You have Password
Timo Reimann 2015/11/25 18:47:32 I believe I'm starting to understand where you're
Timo Reimann 2015/11/26 01:12:51 I followed your advice and build a simplified Pass
190 // Thread that the synchronous methods are run on.
191 scoped_ptr<base::Thread> thread_;
192
193 base::ScopedTempDir db_dir_;
194 scoped_ptr<LoginDatabase> login_db_;
195 scoped_refptr<PasswordStoreMac> store_;
196
197 DISALLOW_COPY_AND_ASSIGN(PasswordStoreMacTestDelegate);
198 };
199
200 PasswordStoreMacTestDelegate::PasswordStoreMacTestDelegate()
201 : ui_thread_(BrowserThread::UI, &message_loop_) {
202 Initialize();
203 }
204
205 PasswordStoreMacTestDelegate::~PasswordStoreMacTestDelegate() {
206 ClosePasswordStore();
207 thread_.reset();
208 login_db_.reset();
209 }
210
211 void PasswordStoreMacTestDelegate::Initialize() {
212 ASSERT_TRUE(db_dir_.CreateUniqueTempDir());
213
214 // Ensure that LoginDatabase will use the mock keychain if it needs to
215 // encrypt/decrypt a password.
216 OSCrypt::UseMockKeychain(true);
217 login_db_.reset(new LoginDatabase(test_login_db_file_path()));
218 thread_.reset(new base::Thread("Chrome_PasswordStore_Thread"));
219 ASSERT_TRUE(thread_->Start());
220 ASSERT_TRUE(thread_->task_runner()->PostTask(
221 FROM_HERE, base::Bind(&PasswordStoreMacTestDelegate::InitLoginDatabase,
222 base::Unretained(login_db_.get()))));
223
224 // Creat and initialize the password store.
225 store_ = new PasswordStoreMac(
226 base::ThreadTaskRunnerHandle::Get(), nullptr,
227 make_scoped_ptr<AppleKeychain>(new MockAppleKeychain));
vasilii 2015/11/18 16:27:42 I think it should work without the type specifier.
Timo Reimann 2015/11/18 23:42:15 It does. Removed.
228 ASSERT_TRUE(thread_->task_runner()->PostTask(
229 FROM_HERE, base::Bind(&PasswordStoreMac::InitWithTaskRunner, store_,
230 thread_->task_runner())));
231
232 ASSERT_TRUE(thread_->task_runner()->PostTask(
233 FROM_HERE, base::Bind(&PasswordStoreMac::set_login_metadata_db, store_,
234 base::Unretained(login_db_.get()))));
235
236 // Make sure deferred initialization is performed before some tests start
237 // accessing the |login_db| directly.
238 FinishAsyncProcessing();
239 }
240
241 void PasswordStoreMacTestDelegate::FinishAsyncProcessing() {
242 scoped_refptr<content::MessageLoopRunner> runner =
243 new content::MessageLoopRunner;
244 ASSERT_TRUE(thread_->task_runner()->PostTaskAndReply(
245 FROM_HERE, base::Bind(&Noop), runner->QuitClosure()));
246 runner->Run();
247 }
248
vasilii 2015/11/18 16:27:42 // static
Timo Reimann 2015/11/18 23:42:15 Done.
249 void PasswordStoreMacTestDelegate::InitLoginDatabase(LoginDatabase* login_db) {
250 ASSERT_TRUE(login_db->Init());
251 }
252
253 base::FilePath PasswordStoreMacTestDelegate::test_login_db_file_path() const {
254 return db_dir_.path().Append(FILE_PATH_LITERAL("login.db"));
255 }
256
257 void PasswordStoreMacTestDelegate::ClosePasswordStore() {
258 if (!store_)
259 return;
260
261 store_->Shutdown();
262 FinishAsyncProcessing();
263 store_ = nullptr;
264 }
265
175 } // namespace 266 } // namespace
176 267
268 namespace password_manager {
269
270 INSTANTIATE_TYPED_TEST_CASE_P(Mac,
271 PasswordStoreOriginTest,
272 PasswordStoreMacTestDelegate);
273
274 } // namespace password_manager
275
177 #pragma mark - 276 #pragma mark -
178 277
179 class PasswordStoreMacInternalsTest : public testing::Test { 278 class PasswordStoreMacInternalsTest : public testing::Test {
180 public: 279 public:
181 void SetUp() override { 280 void SetUp() override {
182 MockAppleKeychain::KeychainTestData test_data[] = { 281 MockAppleKeychain::KeychainTestData test_data[] = {
183 // Basic HTML form. 282 // Basic HTML form.
184 {kSecAuthenticationTypeHTMLForm, 283 {kSecAuthenticationTypeHTMLForm,
185 "some.domain.com", 284 "some.domain.com",
186 kSecProtocolTypeHTTP, 285 kSecProtocolTypeHTTP,
(...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after
1166 1265
1167 ScopedVector<autofill::PasswordForm> owned_passwords = 1266 ScopedVector<autofill::PasswordForm> owned_passwords =
1168 owned_keychain_adapter.GetAllPasswordFormPasswords(); 1267 owned_keychain_adapter.GetAllPasswordFormPasswords();
1169 EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size()); 1268 EXPECT_EQ(arraysize(owned_password_data), owned_passwords.size());
1170 } 1269 }
1171 1270
1172 #pragma mark - 1271 #pragma mark -
1173 1272
1174 class PasswordStoreMacTest : public testing::Test { 1273 class PasswordStoreMacTest : public testing::Test {
1175 public: 1274 public:
1176 PasswordStoreMacTest() : ui_thread_(BrowserThread::UI, &message_loop_) {} 1275 PasswordStoreMacTest()
1276 : histogram_tester_(new base::HistogramTester),
1277 store_(delegate_.store()) {}
1177 1278
1178 void SetUp() override { 1279 ~PasswordStoreMacTest() override {
1179 ASSERT_TRUE(db_dir_.CreateUniqueTempDir());
1180 histogram_tester_.reset(new base::HistogramTester);
1181
1182 // Ensure that LoginDatabase will use the mock keychain if it needs to
1183 // encrypt/decrypt a password.
1184 OSCrypt::UseMockKeychain(true);
1185 login_db_.reset(
1186 new password_manager::LoginDatabase(test_login_db_file_path()));
1187 thread_.reset(new base::Thread("Chrome_PasswordStore_Thread"));
1188 ASSERT_TRUE(thread_->Start());
1189 ASSERT_TRUE(thread_->task_runner()->PostTask(
1190 FROM_HERE, base::Bind(&PasswordStoreMacTest::InitLoginDatabase,
1191 base::Unretained(login_db_.get()))));
1192 CreateAndInitPasswordStore(login_db_.get());
1193 // Make sure deferred initialization is performed before some tests start
1194 // accessing the |login_db| directly.
1195 FinishAsyncProcessing();
1196 }
1197
1198 void TearDown() override {
1199 ClosePasswordStore();
1200 thread_.reset();
1201 login_db_.reset();
1202 // Whatever a test did, PasswordStoreMac stores only empty password values 1280 // Whatever a test did, PasswordStoreMac stores only empty password values
1203 // in LoginDatabase. The empty valus do not require encryption and therefore 1281 // in LoginDatabase. The empty valus do not require encryption and therefore
1204 // OSCrypt shouldn't call the Keychain. The histogram doesn't cover the 1282 // OSCrypt shouldn't call the Keychain. The histogram doesn't cover the
1205 // internet passwords. 1283 // internet passwords.
1206 if (histogram_tester_) { 1284 if (histogram_tester_) {
1207 histogram_tester_->ExpectTotalCount("OSX.Keychain.Access", 0); 1285 histogram_tester_->ExpectTotalCount("OSX.Keychain.Access", 0);
1208 } 1286 }
1209 } 1287 }
1210 1288
1211 static void InitLoginDatabase(password_manager::LoginDatabase* login_db) {
1212 ASSERT_TRUE(login_db->Init());
1213 }
1214
1215 void CreateAndInitPasswordStore(password_manager::LoginDatabase* login_db) {
1216 store_ = new PasswordStoreMac(
1217 base::ThreadTaskRunnerHandle::Get(), nullptr,
1218 make_scoped_ptr<AppleKeychain>(new MockAppleKeychain));
1219 ASSERT_TRUE(thread_->task_runner()->PostTask(
1220 FROM_HERE, base::Bind(&PasswordStoreMac::InitWithTaskRunner, store_,
1221 thread_->task_runner())));
1222
1223 ASSERT_TRUE(thread_->task_runner()->PostTask(
1224 FROM_HERE, base::Bind(&PasswordStoreMac::set_login_metadata_db, store_,
1225 base::Unretained(login_db))));
1226 }
1227
1228 void ClosePasswordStore() {
1229 if (!store_)
1230 return;
1231
1232 store_->Shutdown();
1233 store_ = nullptr;
1234 }
1235
1236 // Verifies that the given |form| can be properly stored so that it can be 1289 // Verifies that the given |form| can be properly stored so that it can be
1237 // retrieved by FillMatchingLogins() and GetAutofillableLogins(), and then it 1290 // retrieved by FillMatchingLogins() and GetAutofillableLogins(), and then it
1238 // can be properly removed. 1291 // can be properly removed.
1239 void VerifyCredentialLifecycle(const PasswordForm& form) { 1292 void VerifyCredentialLifecycle(const PasswordForm& form) {
1240 // Run everything twice to make sure no garbage is left behind that would 1293 // Run everything twice to make sure no garbage is left behind that would
1241 // prevent storing the form a second time. 1294 // prevent storing the form a second time.
1242 for (size_t iteration = 0; iteration < 2; ++iteration) { 1295 for (size_t iteration = 0; iteration < 2; ++iteration) {
1243 SCOPED_TRACE(testing::Message("Iteration: ") << iteration); 1296 SCOPED_TRACE(testing::Message("Iteration: ") << iteration);
1244 1297
1245 MockPasswordStoreConsumer mock_consumer; 1298 MockPasswordStoreConsumer mock_consumer;
1246 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty())) 1299 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(IsEmpty()))
1247 .WillOnce(QuitUIMessageLoop()); 1300 .WillOnce(QuitUIMessageLoop());
1248 store()->GetAutofillableLogins(&mock_consumer); 1301 store()->GetAutofillableLogins(&mock_consumer);
1249 base::MessageLoop::current()->Run(); 1302 base::MessageLoop::current()->Run();
1250 ::testing::Mock::VerifyAndClearExpectations(&mock_consumer); 1303 ::testing::Mock::VerifyAndClearExpectations(&mock_consumer);
1251 1304
1252 store()->AddLogin(form); 1305 store()->AddLogin(form);
1253 FinishAsyncProcessing(); 1306 delegate_.FinishAsyncProcessing();
1254 1307
1255 PasswordForm returned_form; 1308 PasswordForm returned_form;
1256 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u))) 1309 EXPECT_CALL(mock_consumer, OnGetPasswordStoreResultsConstRef(SizeIs(1u)))
1257 .WillOnce( 1310 .WillOnce(
1258 DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop())); 1311 DoAll(SaveACopyOfFirstForm(&returned_form), QuitUIMessageLoop()));
1259 1312
1260 // The query operations will also do some housekeeping: they will remove 1313 // The query operations will also do some housekeeping: they will remove
1261 // dangling credentials in the LoginDatabase without a matching Keychain 1314 // dangling credentials in the LoginDatabase without a matching Keychain
1262 // item when one is expected. If the logic that stores the Keychain item 1315 // item when one is expected. If the logic that stores the Keychain item
1263 // is incorrect, this will wipe the newly added form before the second 1316 // is incorrect, this will wipe the newly added form before the second
(...skipping 12 matching lines...) Expand all
1276 store()->GetLogins(query_form, PasswordStore::ALLOW_PROMPT, 1329 store()->GetLogins(query_form, PasswordStore::ALLOW_PROMPT,
1277 &mock_consumer); 1330 &mock_consumer);
1278 base::MessageLoop::current()->Run(); 1331 base::MessageLoop::current()->Run();
1279 ::testing::Mock::VerifyAndClearExpectations(&mock_consumer); 1332 ::testing::Mock::VerifyAndClearExpectations(&mock_consumer);
1280 EXPECT_EQ(form, returned_form); 1333 EXPECT_EQ(form, returned_form);
1281 1334
1282 store()->RemoveLogin(form); 1335 store()->RemoveLogin(form);
1283 } 1336 }
1284 } 1337 }
1285 1338
1286 base::FilePath test_login_db_file_path() const {
1287 return db_dir_.path().Append(FILE_PATH_LITERAL("login.db"));
1288 }
1289
1290 password_manager::LoginDatabase* login_db() const { 1339 password_manager::LoginDatabase* login_db() const {
1291 return store_->login_metadata_db(); 1340 return store_->login_metadata_db();
1292 } 1341 }
1293 1342
1294 MockAppleKeychain* keychain() { 1343 MockAppleKeychain* keychain() {
1295 return static_cast<MockAppleKeychain*>(store_->keychain()); 1344 return static_cast<MockAppleKeychain*>(store_->keychain());
1296 } 1345 }
1297 1346
1298 void FinishAsyncProcessing() { 1347 PasswordStoreMac* store() { return store_; }
1299 scoped_refptr<content::MessageLoopRunner> runner =
1300 new content::MessageLoopRunner;
1301 ASSERT_TRUE(thread_->task_runner()->PostTaskAndReply(
1302 FROM_HERE, base::Bind(&Noop), runner->QuitClosure()));
1303 runner->Run();
1304 }
1305 1348
1306 PasswordStoreMac* store() { return store_.get(); } 1349 PasswordStoreMacTestDelegate& delegate() { return delegate_; }
1307 1350
1308 protected: 1351 protected:
1309 base::MessageLoopForUI message_loop_;
1310 content::TestBrowserThread ui_thread_;
1311 // Thread that the synchronous methods are run on.
1312 scoped_ptr<base::Thread> thread_;
1313
1314 base::ScopedTempDir db_dir_;
1315 scoped_ptr<password_manager::LoginDatabase> login_db_;
1316 scoped_refptr<PasswordStoreMac> store_;
1317 scoped_ptr<base::HistogramTester> histogram_tester_; 1352 scoped_ptr<base::HistogramTester> histogram_tester_;
1353 PasswordStoreMacTestDelegate delegate_;
1354 PasswordStoreMac* store_;
vasilii 2015/11/18 16:27:42 Remove
Timo Reimann 2015/11/18 23:42:15 Done (and replaced all references to store_ by del
1318 }; 1355 };
1319 1356
1320 TEST_F(PasswordStoreMacTest, TestStoreUpdate) { 1357 TEST_F(PasswordStoreMacTest, TestStoreUpdate) {
1321 // Insert a password into both the database and the keychain. 1358 // Insert a password into both the database and the keychain.
1322 // This is done manually, rather than through store_->AddLogin, because the 1359 // This is done manually, rather than through store_->AddLogin, because the
1323 // Mock Keychain isn't smart enough to be able to support update generically, 1360 // Mock Keychain isn't smart enough to be able to support update generically,
1324 // so some.domain.com triggers special handling to test it that make inserting 1361 // so some.domain.com triggers special handling to test it that make inserting
1325 // fail. 1362 // fail.
1326 PasswordFormData joint_data = { 1363 PasswordFormData joint_data = {
1327 PasswordForm::SCHEME_HTML, "http://some.domain.com/", 1364 PasswordForm::SCHEME_HTML, "http://some.domain.com/",
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1376 true, false, 2 }, 1413 true, false, 2 },
1377 NULL, 1414 NULL,
1378 }, 1415 },
1379 }; 1416 };
1380 for (unsigned int i = 0; i < arraysize(updates); ++i) { 1417 for (unsigned int i = 0; i < arraysize(updates); ++i) {
1381 scoped_ptr<PasswordForm> form = 1418 scoped_ptr<PasswordForm> form =
1382 CreatePasswordFormFromDataForTesting(updates[i].form_data); 1419 CreatePasswordFormFromDataForTesting(updates[i].form_data);
1383 store_->UpdateLogin(*form); 1420 store_->UpdateLogin(*form);
1384 } 1421 }
1385 1422
1386 FinishAsyncProcessing(); 1423 delegate_.FinishAsyncProcessing();
1387 1424
1388 MacKeychainPasswordFormAdapter keychain_adapter(keychain()); 1425 MacKeychainPasswordFormAdapter keychain_adapter(keychain());
1389 for (unsigned int i = 0; i < arraysize(updates); ++i) { 1426 for (unsigned int i = 0; i < arraysize(updates); ++i) {
1390 scoped_ptr<PasswordForm> query_form = 1427 scoped_ptr<PasswordForm> query_form =
1391 CreatePasswordFormFromDataForTesting(updates[i].form_data); 1428 CreatePasswordFormFromDataForTesting(updates[i].form_data);
1392 1429
1393 ScopedVector<autofill::PasswordForm> matching_items = 1430 ScopedVector<autofill::PasswordForm> matching_items =
1394 keychain_adapter.PasswordsFillingForm(query_form->signon_realm, 1431 keychain_adapter.PasswordsFillingForm(query_form->signon_realm,
1395 query_form->scheme); 1432 query_form->scheme);
1396 if (updates[i].password) { 1433 if (updates[i].password) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1453 // 3. Add the returned password for m.facebook.com. 1490 // 3. Add the returned password for m.facebook.com.
1454 returned_form.signon_realm = "http://m.facebook.com"; 1491 returned_form.signon_realm = "http://m.facebook.com";
1455 returned_form.origin = GURL("http://m.facebook.com/index.html"); 1492 returned_form.origin = GURL("http://m.facebook.com/index.html");
1456 EXPECT_EQ(AddChangeForForm(returned_form), 1493 EXPECT_EQ(AddChangeForForm(returned_form),
1457 login_db()->AddLogin(returned_form)); 1494 login_db()->AddLogin(returned_form));
1458 owned_keychain_adapter.AddPassword(m_form); 1495 owned_keychain_adapter.AddPassword(m_form);
1459 1496
1460 // 4. Remove both passwords. 1497 // 4. Remove both passwords.
1461 store_->RemoveLogin(*www_form); 1498 store_->RemoveLogin(*www_form);
1462 store_->RemoveLogin(m_form); 1499 store_->RemoveLogin(m_form);
1463 FinishAsyncProcessing(); 1500 delegate_.FinishAsyncProcessing();
1464 1501
1465 // No trace of www.facebook.com. 1502 // No trace of www.facebook.com.
1466 ScopedVector<autofill::PasswordForm> matching_items = 1503 ScopedVector<autofill::PasswordForm> matching_items =
1467 owned_keychain_adapter.PasswordsFillingForm(www_form->signon_realm, 1504 owned_keychain_adapter.PasswordsFillingForm(www_form->signon_realm,
1468 www_form->scheme); 1505 www_form->scheme);
1469 EXPECT_EQ(0u, matching_items.size()); 1506 EXPECT_EQ(0u, matching_items.size());
1470 EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items)); 1507 EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items));
1471 EXPECT_EQ(0u, matching_items.size()); 1508 EXPECT_EQ(0u, matching_items.size());
1472 // No trace of m.facebook.com. 1509 // No trace of m.facebook.com.
1473 matching_items = owned_keychain_adapter.PasswordsFillingForm( 1510 matching_items = owned_keychain_adapter.PasswordsFillingForm(
1474 m_form.signon_realm, m_form.scheme); 1511 m_form.signon_realm, m_form.scheme);
1475 EXPECT_EQ(0u, matching_items.size()); 1512 EXPECT_EQ(0u, matching_items.size());
1476 EXPECT_TRUE(login_db()->GetLogins(m_form, &matching_items)); 1513 EXPECT_TRUE(login_db()->GetLogins(m_form, &matching_items));
1477 EXPECT_EQ(0u, matching_items.size()); 1514 EXPECT_EQ(0u, matching_items.size());
1478 } 1515 }
1479 1516
1480 namespace { 1517 namespace {
1481 1518
1482 class PasswordsChangeObserver : 1519 class PasswordsChangeObserver :
1483 public password_manager::PasswordStore::Observer { 1520 public password_manager::PasswordStore::Observer {
1484 public: 1521 public:
1485 PasswordsChangeObserver(PasswordStoreMac* store) : observer_(this) { 1522 explicit PasswordsChangeObserver(PasswordStoreMac* store) : observer_(this) {
1486 observer_.Add(store); 1523 observer_.Add(store);
1487 } 1524 }
1488 1525
1489 void WaitAndVerify(PasswordStoreMacTest* test) { 1526 void WaitAndVerify(PasswordStoreMacTest* test) {
1490 test->FinishAsyncProcessing(); 1527 test->delegate().FinishAsyncProcessing();
1491 ::testing::Mock::VerifyAndClearExpectations(this); 1528 ::testing::Mock::VerifyAndClearExpectations(this);
1492 } 1529 }
1493 1530
1494 // password_manager::PasswordStore::Observer: 1531 // password_manager::PasswordStore::Observer:
1495 MOCK_METHOD1(OnLoginsChanged, 1532 MOCK_METHOD1(OnLoginsChanged,
1496 void(const password_manager::PasswordStoreChangeList& changes)); 1533 void(const password_manager::PasswordStoreChangeList& changes));
1497 1534
1498 private: 1535 private:
1499 ScopedObserver<password_manager::PasswordStore, 1536 ScopedObserver<password_manager::PasswordStore,
1500 PasswordsChangeObserver> observer_; 1537 PasswordsChangeObserver> observer_;
1501 }; 1538 };
1502 1539
1503 password_manager::PasswordStoreChangeList GetAddChangeList( 1540 password_manager::PasswordStoreChangeList GetAddChangeList(
1504 const PasswordForm& form) { 1541 const PasswordForm& form) {
1505 password_manager::PasswordStoreChange change( 1542 password_manager::PasswordStoreChange change(
1506 password_manager::PasswordStoreChange::ADD, form); 1543 password_manager::PasswordStoreChange::ADD, form);
1507 return password_manager::PasswordStoreChangeList(1, change); 1544 return password_manager::PasswordStoreChangeList(1, change);
1508 } 1545 }
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
1636 CreatePasswordFormFromDataForTesting(www_form_data1); 1673 CreatePasswordFormFromDataForTesting(www_form_data1);
1637 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*www_form)); 1674 EXPECT_TRUE(owned_keychain_adapter.AddPassword(*www_form));
1638 1675
1639 // Add a password from the current profile. 1676 // Add a password from the current profile.
1640 PasswordFormData www_form_data2 = { 1677 PasswordFormData www_form_data2 = {
1641 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", 1678 PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
1642 "http://www.facebook.com/index.html", "login", L"username", L"password", 1679 "http://www.facebook.com/index.html", "login", L"username", L"password",
1643 L"submit", L"not_joe_user", L"12345", true, false, 1 }; 1680 L"submit", L"not_joe_user", L"12345", true, false, 1 };
1644 www_form = CreatePasswordFormFromDataForTesting(www_form_data2); 1681 www_form = CreatePasswordFormFromDataForTesting(www_form_data2);
1645 store_->AddLogin(*www_form); 1682 store_->AddLogin(*www_form);
1646 FinishAsyncProcessing(); 1683 delegate_.FinishAsyncProcessing();
1647 1684
1648 ScopedVector<PasswordForm> matching_items; 1685 ScopedVector<PasswordForm> matching_items;
1649 EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items)); 1686 EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items));
1650 EXPECT_EQ(1u, matching_items.size()); 1687 EXPECT_EQ(1u, matching_items.size());
1651 1688
1652 store_->RemoveLoginsCreatedBetween(base::Time(), base::Time(), 1689 store_->RemoveLoginsCreatedBetween(base::Time(), base::Time(),
1653 base::Closure()); 1690 base::Closure());
1654 FinishAsyncProcessing(); 1691 delegate_.FinishAsyncProcessing();
1655 1692
1656 // Check the second facebook form is gone. 1693 // Check the second facebook form is gone.
1657 EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items)); 1694 EXPECT_TRUE(login_db()->GetLogins(*www_form, &matching_items));
1658 EXPECT_EQ(0u, matching_items.size()); 1695 EXPECT_EQ(0u, matching_items.size());
1659 1696
1660 // Check the first facebook form is still there. 1697 // Check the first facebook form is still there.
1661 matching_items = owned_keychain_adapter.PasswordsFillingForm( 1698 matching_items = owned_keychain_adapter.PasswordsFillingForm(
1662 www_form->signon_realm, www_form->scheme); 1699 www_form->signon_realm, www_form->scheme);
1663 ASSERT_EQ(1u, matching_items.size()); 1700 ASSERT_EQ(1u, matching_items.size());
1664 EXPECT_EQ(ASCIIToUTF16("joe_user"), matching_items[0]->username_value); 1701 EXPECT_EQ(ASCIIToUTF16("joe_user"), matching_items[0]->username_value);
1665 1702
1666 // Check the third-party password is still there. 1703 // Check the third-party password is still there.
1667 owned_keychain_adapter.SetFindsOnlyOwnedItems(false); 1704 owned_keychain_adapter.SetFindsOnlyOwnedItems(false);
1668 matching_items = owned_keychain_adapter.PasswordsFillingForm( 1705 matching_items = owned_keychain_adapter.PasswordsFillingForm(
1669 "http://some.domain.com/insecure.html", PasswordForm::SCHEME_HTML); 1706 "http://some.domain.com/insecure.html", PasswordForm::SCHEME_HTML);
1670 ASSERT_EQ(1u, matching_items.size()); 1707 ASSERT_EQ(1u, matching_items.size());
1671 } 1708 }
1672 1709
1673 // Add a facebook form to the store but not to the keychain. The form is to be 1710 // Add a facebook form to the store but not to the keychain. The form is to be
1674 // implicitly deleted. However, the observers shouldn't get notified about 1711 // implicitly deleted. However, the observers shouldn't get notified about
1675 // deletion of non-existent forms like m.facebook.com. 1712 // deletion of non-existent forms like m.facebook.com.
1676 TEST_F(PasswordStoreMacTest, SilentlyRemoveOrphanedForm) { 1713 TEST_F(PasswordStoreMacTest, SilentlyRemoveOrphanedForm) {
1677 testing::StrictMock<MockPasswordStoreObserver> mock_observer; 1714 testing::StrictMock<password_manager::MockPasswordStoreObserver>
1715 mock_observer;
1678 store()->AddObserver(&mock_observer); 1716 store()->AddObserver(&mock_observer);
1679 1717
1680 // 1. Add a password for www.facebook.com to the LoginDatabase. 1718 // 1. Add a password for www.facebook.com to the LoginDatabase.
1681 PasswordFormData www_form_data = { 1719 PasswordFormData www_form_data = {
1682 PasswordForm::SCHEME_HTML, "http://www.facebook.com/", 1720 PasswordForm::SCHEME_HTML, "http://www.facebook.com/",
1683 "http://www.facebook.com/index.html", "login", 1721 "http://www.facebook.com/index.html", "login",
1684 L"username", L"password", L"submit", L"joe_user", L"", true, false, 1 1722 L"username", L"password", L"submit", L"joe_user", L"", true, false, 1
1685 }; 1723 };
1686 scoped_ptr<PasswordForm> www_form( 1724 scoped_ptr<PasswordForm> www_form(
1687 CreatePasswordFormFromDataForTesting(www_form_data)); 1725 CreatePasswordFormFromDataForTesting(www_form_data));
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1763 form2.password_value = ASCIIToUTF16("my_password"); 1801 form2.password_value = ASCIIToUTF16("my_password");
1764 1802
1765 PasswordForm blacklisted_form; 1803 PasswordForm blacklisted_form;
1766 blacklisted_form.origin = GURL("http://badsite.com/Login"); 1804 blacklisted_form.origin = GURL("http://badsite.com/Login");
1767 blacklisted_form.signon_realm = "http://badsite.com/"; 1805 blacklisted_form.signon_realm = "http://badsite.com/";
1768 blacklisted_form.blacklisted_by_user = true; 1806 blacklisted_form.blacklisted_by_user = true;
1769 1807
1770 store()->AddLogin(form1); 1808 store()->AddLogin(form1);
1771 store()->AddLogin(form2); 1809 store()->AddLogin(form2);
1772 store()->AddLogin(blacklisted_form); 1810 store()->AddLogin(blacklisted_form);
1773 FinishAsyncProcessing(); 1811 delegate_.FinishAsyncProcessing();
1774 1812
1775 ASSERT_TRUE(base::PostTaskAndReplyWithResult( 1813 ASSERT_TRUE(base::PostTaskAndReplyWithResult(
1776 thread_->task_runner().get(), FROM_HERE, 1814 delegate_.thread()->task_runner().get(), FROM_HERE,
1777 base::Bind(&PasswordStoreMac::ImportFromKeychain, store()), 1815 base::Bind(&PasswordStoreMac::ImportFromKeychain, store()),
1778 base::Bind(&CheckMigrationResult, PasswordStoreMac::MIGRATION_OK))); 1816 base::Bind(&CheckMigrationResult, PasswordStoreMac::MIGRATION_OK)));
1779 FinishAsyncProcessing(); 1817 delegate_.FinishAsyncProcessing();
1780 1818
1781 // The password should be stored in the database by now. 1819 // The password should be stored in the database by now.
1782 ScopedVector<PasswordForm> matching_items; 1820 ScopedVector<PasswordForm> matching_items;
1783 EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items)); 1821 EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items));
1784 ASSERT_EQ(1u, matching_items.size()); 1822 ASSERT_EQ(1u, matching_items.size());
1785 EXPECT_EQ(form1, *matching_items[0]); 1823 EXPECT_EQ(form1, *matching_items[0]);
1786 1824
1787 EXPECT_TRUE(login_db()->GetLogins(form2, &matching_items)); 1825 EXPECT_TRUE(login_db()->GetLogins(form2, &matching_items));
1788 ASSERT_EQ(1u, matching_items.size()); 1826 ASSERT_EQ(1u, matching_items.size());
1789 EXPECT_EQ(form2, *matching_items[0]); 1827 EXPECT_EQ(form2, *matching_items[0]);
(...skipping 11 matching lines...) Expand all
1801 // Import a federated credential while the Keychain is locked. 1839 // Import a federated credential while the Keychain is locked.
1802 TEST_F(PasswordStoreMacTest, ImportFederatedFromLockedKeychain) { 1840 TEST_F(PasswordStoreMacTest, ImportFederatedFromLockedKeychain) {
1803 keychain()->set_locked(true); 1841 keychain()->set_locked(true);
1804 PasswordForm form1; 1842 PasswordForm form1;
1805 form1.origin = GURL("http://example.com/Login"); 1843 form1.origin = GURL("http://example.com/Login");
1806 form1.signon_realm = "http://example.com/"; 1844 form1.signon_realm = "http://example.com/";
1807 form1.username_value = ASCIIToUTF16("my_username"); 1845 form1.username_value = ASCIIToUTF16("my_username");
1808 form1.federation_url = GURL("https://accounts.google.com/"); 1846 form1.federation_url = GURL("https://accounts.google.com/");
1809 1847
1810 store()->AddLogin(form1); 1848 store()->AddLogin(form1);
1811 FinishAsyncProcessing(); 1849 delegate_.FinishAsyncProcessing();
1812 ASSERT_TRUE(base::PostTaskAndReplyWithResult( 1850 ASSERT_TRUE(base::PostTaskAndReplyWithResult(
1813 thread_->task_runner().get(), FROM_HERE, 1851 delegate_.thread()->task_runner().get(), FROM_HERE,
1814 base::Bind(&PasswordStoreMac::ImportFromKeychain, store()), 1852 base::Bind(&PasswordStoreMac::ImportFromKeychain, store()),
1815 base::Bind(&CheckMigrationResult, PasswordStoreMac::MIGRATION_OK))); 1853 base::Bind(&CheckMigrationResult, PasswordStoreMac::MIGRATION_OK)));
1816 FinishAsyncProcessing(); 1854 delegate_.FinishAsyncProcessing();
1817 1855
1818 ScopedVector<PasswordForm> matching_items; 1856 ScopedVector<PasswordForm> matching_items;
1819 EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items)); 1857 EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items));
1820 ASSERT_EQ(1u, matching_items.size()); 1858 ASSERT_EQ(1u, matching_items.size());
1821 EXPECT_EQ(form1, *matching_items[0]); 1859 EXPECT_EQ(form1, *matching_items[0]);
1822 } 1860 }
1823 1861
1824 // Try to import while the Keychain is locked but the encryption key had been 1862 // Try to import while the Keychain is locked but the encryption key had been
1825 // read earlier. 1863 // read earlier.
1826 TEST_F(PasswordStoreMacTest, ImportFromLockedKeychainError) { 1864 TEST_F(PasswordStoreMacTest, ImportFromLockedKeychainError) {
1827 PasswordForm form1; 1865 PasswordForm form1;
1828 form1.origin = GURL("http://accounts.google.com/LoginAuth"); 1866 form1.origin = GURL("http://accounts.google.com/LoginAuth");
1829 form1.signon_realm = "http://accounts.google.com/"; 1867 form1.signon_realm = "http://accounts.google.com/";
1830 form1.username_value = ASCIIToUTF16("my_username"); 1868 form1.username_value = ASCIIToUTF16("my_username");
1831 form1.password_value = ASCIIToUTF16("my_password"); 1869 form1.password_value = ASCIIToUTF16("my_password");
1832 store()->AddLogin(form1); 1870 store()->AddLogin(form1);
1833 FinishAsyncProcessing(); 1871 delegate_.FinishAsyncProcessing();
1834 1872
1835 // Add a second keychain item matching the Database entry. 1873 // Add a second keychain item matching the Database entry.
1836 PasswordForm form2 = form1; 1874 PasswordForm form2 = form1;
1837 form2.origin = GURL("http://accounts.google.com/Login"); 1875 form2.origin = GURL("http://accounts.google.com/Login");
1838 form2.password_value = ASCIIToUTF16("1234"); 1876 form2.password_value = ASCIIToUTF16("1234");
1839 MacKeychainPasswordFormAdapter adapter(keychain()); 1877 MacKeychainPasswordFormAdapter adapter(keychain());
1840 EXPECT_TRUE(adapter.AddPassword(form2)); 1878 EXPECT_TRUE(adapter.AddPassword(form2));
1841 1879
1842 keychain()->set_locked(true); 1880 keychain()->set_locked(true);
1843 ASSERT_TRUE(base::PostTaskAndReplyWithResult( 1881 ASSERT_TRUE(base::PostTaskAndReplyWithResult(
1844 thread_->task_runner().get(), FROM_HERE, 1882 delegate_.thread()->task_runner().get(), FROM_HERE,
1845 base::Bind(&PasswordStoreMac::ImportFromKeychain, store()), 1883 base::Bind(&PasswordStoreMac::ImportFromKeychain, store()),
1846 base::Bind(&CheckMigrationResult, PasswordStoreMac::KEYCHAIN_BLOCKED))); 1884 base::Bind(&CheckMigrationResult, PasswordStoreMac::KEYCHAIN_BLOCKED)));
1847 FinishAsyncProcessing(); 1885 delegate_.FinishAsyncProcessing();
1848 1886
1849 ScopedVector<PasswordForm> matching_items; 1887 ScopedVector<PasswordForm> matching_items;
1850 EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items)); 1888 EXPECT_TRUE(login_db()->GetLogins(form1, &matching_items));
1851 ASSERT_EQ(1u, matching_items.size()); 1889 ASSERT_EQ(1u, matching_items.size());
1852 EXPECT_EQ(base::string16(), matching_items[0]->password_value); 1890 EXPECT_EQ(base::string16(), matching_items[0]->password_value);
1853 1891
1854 histogram_tester_->ExpectUniqueSample( 1892 histogram_tester_->ExpectUniqueSample(
1855 "PasswordManager.KeychainMigration.NumPasswordsOnFailure", 1, 1); 1893 "PasswordManager.KeychainMigration.NumPasswordsOnFailure", 1, 1);
1856 histogram_tester_->ExpectUniqueSample( 1894 histogram_tester_->ExpectUniqueSample(
1857 "PasswordManager.KeychainMigration.NumFailedPasswords", 1, 1); 1895 "PasswordManager.KeychainMigration.NumFailedPasswords", 1, 1);
1858 histogram_tester_->ExpectUniqueSample( 1896 histogram_tester_->ExpectUniqueSample(
1859 "PasswordManager.KeychainMigration.NumChromeOwnedInaccessiblePasswords", 1897 "PasswordManager.KeychainMigration.NumChromeOwnedInaccessiblePasswords",
1860 2, 1); 1898 2, 1);
1861 // Don't test the encryption key access. 1899 // Don't test the encryption key access.
1862 histogram_tester_.reset(); 1900 histogram_tester_.reset();
1863 } 1901 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698