| 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 <string> | 5 #include <string> |
| 6 | 6 |
| 7 #include "base/format_macros.h" | 7 #include "base/format_macros.h" |
| 8 #include "base/location.h" | 8 #include "base/location.h" |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
| 11 #include "sync/engine/apply_updates_command.h" | 11 #include "sync/engine/apply_updates_command.h" |
| 12 #include "sync/engine/syncer.h" | 12 #include "sync/engine/syncer.h" |
| 13 #include "sync/internal_api/public/test/fake_sync_encryption_handler.h" |
| 13 #include "sync/internal_api/public/test/test_entry_factory.h" | 14 #include "sync/internal_api/public/test/test_entry_factory.h" |
| 14 #include "sync/protocol/bookmark_specifics.pb.h" | 15 #include "sync/protocol/bookmark_specifics.pb.h" |
| 15 #include "sync/protocol/password_specifics.pb.h" | 16 #include "sync/protocol/password_specifics.pb.h" |
| 16 #include "sync/sessions/sync_session.h" | 17 #include "sync/sessions/sync_session.h" |
| 17 #include "sync/syncable/mutable_entry.h" | 18 #include "sync/syncable/mutable_entry.h" |
| 18 #include "sync/syncable/nigori_util.h" | 19 #include "sync/syncable/nigori_util.h" |
| 19 #include "sync/syncable/read_transaction.h" | 20 #include "sync/syncable/read_transaction.h" |
| 20 #include "sync/syncable/syncable_id.h" | 21 #include "sync/syncable/syncable_id.h" |
| 21 #include "sync/syncable/syncable_util.h" | 22 #include "sync/syncable/syncable_util.h" |
| 22 #include "sync/syncable/write_transaction.h" | 23 #include "sync/syncable/write_transaction.h" |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 workers()->push_back( | 58 workers()->push_back( |
| 58 make_scoped_refptr(new FakeModelWorker(GROUP_UI))); | 59 make_scoped_refptr(new FakeModelWorker(GROUP_UI))); |
| 59 workers()->push_back( | 60 workers()->push_back( |
| 60 make_scoped_refptr(new FakeModelWorker(GROUP_PASSWORD))); | 61 make_scoped_refptr(new FakeModelWorker(GROUP_PASSWORD))); |
| 61 (*mutable_routing_info())[BOOKMARKS] = GROUP_UI; | 62 (*mutable_routing_info())[BOOKMARKS] = GROUP_UI; |
| 62 (*mutable_routing_info())[PASSWORDS] = GROUP_PASSWORD; | 63 (*mutable_routing_info())[PASSWORDS] = GROUP_PASSWORD; |
| 63 (*mutable_routing_info())[NIGORI] = GROUP_PASSIVE; | 64 (*mutable_routing_info())[NIGORI] = GROUP_PASSIVE; |
| 64 SyncerCommandTest::SetUp(); | 65 SyncerCommandTest::SetUp(); |
| 65 entry_factory_.reset(new TestEntryFactory(directory())); | 66 entry_factory_.reset(new TestEntryFactory(directory())); |
| 66 ExpectNoGroupsToChange(apply_updates_command_); | 67 ExpectNoGroupsToChange(apply_updates_command_); |
| 68 |
| 69 syncable::ReadTransaction trans(FROM_HERE, directory()); |
| 70 directory()->GetCryptographer(&trans)->SetSyncEncryptionHandlerDelegate( |
| 71 &fake_encryption_handler_); |
| 72 fake_encryption_handler_.set_cryptographer( |
| 73 directory()->GetCryptographer(&trans)); |
| 67 } | 74 } |
| 68 | 75 |
| 76 protected: |
| 77 DISALLOW_COPY_AND_ASSIGN(ApplyUpdatesCommandTest); |
| 78 |
| 69 ApplyUpdatesCommand apply_updates_command_; | 79 ApplyUpdatesCommand apply_updates_command_; |
| 70 FakeEncryptor encryptor_; | 80 FakeEncryptor encryptor_; |
| 71 TestIdFactory id_factory_; | 81 TestIdFactory id_factory_; |
| 72 scoped_ptr<TestEntryFactory> entry_factory_; | 82 scoped_ptr<TestEntryFactory> entry_factory_; |
| 73 private: | 83 FakeSyncEncryptionHandler fake_encryption_handler_; |
| 74 DISALLOW_COPY_AND_ASSIGN(ApplyUpdatesCommandTest); | |
| 75 }; | 84 }; |
| 76 | 85 |
| 77 TEST_F(ApplyUpdatesCommandTest, Simple) { | 86 TEST_F(ApplyUpdatesCommandTest, Simple) { |
| 78 string root_server_id = syncable::GetNullId().GetServerId(); | 87 string root_server_id = syncable::GetNullId().GetServerId(); |
| 79 entry_factory_->CreateUnappliedNewItemWithParent("parent", | 88 entry_factory_->CreateUnappliedNewItemWithParent("parent", |
| 80 DefaultBookmarkSpecifics(), | 89 DefaultBookmarkSpecifics(), |
| 81 root_server_id); | 90 root_server_id); |
| 82 entry_factory_->CreateUnappliedNewItemWithParent("child", | 91 entry_factory_->CreateUnappliedNewItemWithParent("child", |
| 83 DefaultBookmarkSpecifics(), | 92 DefaultBookmarkSpecifics(), |
| 84 "parent"); | 93 "parent"); |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 } | 536 } |
| 528 | 537 |
| 529 // Nigori node updates should update the Cryptographer. | 538 // Nigori node updates should update the Cryptographer. |
| 530 Cryptographer other_cryptographer(&encryptor_); | 539 Cryptographer other_cryptographer(&encryptor_); |
| 531 KeyParams params = {"localhost", "dummy", "foobar"}; | 540 KeyParams params = {"localhost", "dummy", "foobar"}; |
| 532 other_cryptographer.AddKey(params); | 541 other_cryptographer.AddKey(params); |
| 533 | 542 |
| 534 sync_pb::EntitySpecifics specifics; | 543 sync_pb::EntitySpecifics specifics; |
| 535 sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori(); | 544 sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori(); |
| 536 other_cryptographer.GetKeys(nigori->mutable_encrypted()); | 545 other_cryptographer.GetKeys(nigori->mutable_encrypted()); |
| 537 nigori->set_encrypt_bookmarks(true); | 546 nigori->set_encrypt_everything(true); |
| 538 encrypted_types.Put(BOOKMARKS); | |
| 539 entry_factory_->CreateUnappliedNewItem( | 547 entry_factory_->CreateUnappliedNewItem( |
| 540 ModelTypeToRootTag(NIGORI), specifics, true); | 548 ModelTypeToRootTag(NIGORI), specifics, true); |
| 541 EXPECT_FALSE(cryptographer->has_pending_keys()); | 549 EXPECT_FALSE(cryptographer->has_pending_keys()); |
| 542 | 550 |
| 543 ExpectGroupToChange(apply_updates_command_, GROUP_PASSIVE); | 551 ExpectGroupToChange(apply_updates_command_, GROUP_PASSIVE); |
| 544 apply_updates_command_.ExecuteImpl(session()); | 552 apply_updates_command_.ExecuteImpl(session()); |
| 545 | 553 |
| 546 sessions::StatusController* status = session()->mutable_status_controller(); | 554 sessions::StatusController* status = session()->mutable_status_controller(); |
| 547 sessions::ScopedModelSafeGroupRestriction r(status, GROUP_PASSIVE); | 555 sessions::ScopedModelSafeGroupRestriction r(status, GROUP_PASSIVE); |
| 548 ASSERT_TRUE(status->update_progress()); | 556 ASSERT_TRUE(status->update_progress()); |
| 549 EXPECT_EQ(1, status->update_progress()->AppliedUpdatesSize()) | 557 EXPECT_EQ(1, status->update_progress()->AppliedUpdatesSize()) |
| 550 << "All updates should have been attempted"; | 558 << "All updates should have been attempted"; |
| 551 ASSERT_TRUE(status->conflict_progress()); | 559 ASSERT_TRUE(status->conflict_progress()); |
| 552 EXPECT_EQ(0, status->conflict_progress()->SimpleConflictingItemsSize()) | 560 EXPECT_EQ(0, status->conflict_progress()->SimpleConflictingItemsSize()) |
| 553 << "The nigori update shouldn't be in conflict"; | 561 << "The nigori update shouldn't be in conflict"; |
| 554 EXPECT_EQ(1, status->update_progress()->SuccessfullyAppliedUpdateCount()) | 562 EXPECT_EQ(1, status->update_progress()->SuccessfullyAppliedUpdateCount()) |
| 555 << "The nigori update should be applied"; | 563 << "The nigori update should be applied"; |
| 556 | 564 |
| 557 EXPECT_FALSE(cryptographer->is_ready()); | 565 EXPECT_FALSE(cryptographer->is_ready()); |
| 558 EXPECT_TRUE(cryptographer->has_pending_keys()); | 566 EXPECT_TRUE(cryptographer->has_pending_keys()); |
| 559 EXPECT_TRUE( | 567 EXPECT_TRUE(cryptographer->GetEncryptedTypes().Equals(ModelTypeSet::All())); |
| 560 cryptographer->GetEncryptedTypes().Equals(ModelTypeSet::All())); | |
| 561 } | 568 } |
| 562 | 569 |
| 563 TEST_F(ApplyUpdatesCommandTest, NigoriUpdateForDisabledTypes) { | 570 TEST_F(ApplyUpdatesCommandTest, NigoriUpdateForDisabledTypes) { |
| 564 // Storing the cryptographer separately is bad, but for this test we | 571 // Storing the cryptographer separately is bad, but for this test we |
| 565 // know it's safe. | 572 // know it's safe. |
| 566 Cryptographer* cryptographer; | 573 Cryptographer* cryptographer; |
| 567 ModelTypeSet encrypted_types; | 574 ModelTypeSet encrypted_types; |
| 568 encrypted_types.Put(PASSWORDS); | 575 encrypted_types.Put(PASSWORDS); |
| 569 encrypted_types.Put(NIGORI); | 576 encrypted_types.Put(NIGORI); |
| 570 { | 577 { |
| 571 syncable::ReadTransaction trans(FROM_HERE, directory()); | 578 syncable::ReadTransaction trans(FROM_HERE, directory()); |
| 572 cryptographer = directory()->GetCryptographer(&trans); | 579 cryptographer = directory()->GetCryptographer(&trans); |
| 573 EXPECT_TRUE(cryptographer->GetEncryptedTypes().Equals(encrypted_types)); | 580 EXPECT_TRUE(cryptographer->GetEncryptedTypes().Equals(encrypted_types)); |
| 574 } | 581 } |
| 575 | 582 |
| 576 // Nigori node updates should update the Cryptographer. | 583 // Nigori node updates should update the Cryptographer. |
| 577 Cryptographer other_cryptographer(&encryptor_); | 584 Cryptographer other_cryptographer(&encryptor_); |
| 578 KeyParams params = {"localhost", "dummy", "foobar"}; | 585 KeyParams params = {"localhost", "dummy", "foobar"}; |
| 579 other_cryptographer.AddKey(params); | 586 other_cryptographer.AddKey(params); |
| 580 | 587 |
| 581 sync_pb::EntitySpecifics specifics; | 588 sync_pb::EntitySpecifics specifics; |
| 582 sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori(); | 589 sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori(); |
| 583 other_cryptographer.GetKeys(nigori->mutable_encrypted()); | 590 other_cryptographer.GetKeys(nigori->mutable_encrypted()); |
| 584 nigori->set_encrypt_sessions(true); | 591 nigori->set_encrypt_everything(true); |
| 585 nigori->set_encrypt_themes(true); | |
| 586 encrypted_types.Put(SESSIONS); | |
| 587 encrypted_types.Put(THEMES); | |
| 588 entry_factory_->CreateUnappliedNewItem( | 592 entry_factory_->CreateUnappliedNewItem( |
| 589 ModelTypeToRootTag(NIGORI), specifics, true); | 593 ModelTypeToRootTag(NIGORI), specifics, true); |
| 590 EXPECT_FALSE(cryptographer->has_pending_keys()); | 594 EXPECT_FALSE(cryptographer->has_pending_keys()); |
| 591 | 595 |
| 592 ExpectGroupToChange(apply_updates_command_, GROUP_PASSIVE); | 596 ExpectGroupToChange(apply_updates_command_, GROUP_PASSIVE); |
| 593 apply_updates_command_.ExecuteImpl(session()); | 597 apply_updates_command_.ExecuteImpl(session()); |
| 594 | 598 |
| 595 sessions::StatusController* status = session()->mutable_status_controller(); | 599 sessions::StatusController* status = session()->mutable_status_controller(); |
| 596 sessions::ScopedModelSafeGroupRestriction r(status, GROUP_PASSIVE); | 600 sessions::ScopedModelSafeGroupRestriction r(status, GROUP_PASSIVE); |
| 597 ASSERT_TRUE(status->update_progress()); | 601 ASSERT_TRUE(status->update_progress()); |
| 598 EXPECT_EQ(1, status->update_progress()->AppliedUpdatesSize()) | 602 EXPECT_EQ(1, status->update_progress()->AppliedUpdatesSize()) |
| 599 << "All updates should have been attempted"; | 603 << "All updates should have been attempted"; |
| 600 ASSERT_TRUE(status->conflict_progress()); | 604 ASSERT_TRUE(status->conflict_progress()); |
| 601 EXPECT_EQ(0, status->conflict_progress()->SimpleConflictingItemsSize()) | 605 EXPECT_EQ(0, status->conflict_progress()->SimpleConflictingItemsSize()) |
| 602 << "The nigori update shouldn't be in conflict"; | 606 << "The nigori update shouldn't be in conflict"; |
| 603 EXPECT_EQ(1, status->update_progress()->SuccessfullyAppliedUpdateCount()) | 607 EXPECT_EQ(1, status->update_progress()->SuccessfullyAppliedUpdateCount()) |
| 604 << "The nigori update should be applied"; | 608 << "The nigori update should be applied"; |
| 605 | 609 |
| 606 EXPECT_FALSE(cryptographer->is_ready()); | 610 EXPECT_FALSE(cryptographer->is_ready()); |
| 607 EXPECT_TRUE(cryptographer->has_pending_keys()); | 611 EXPECT_TRUE(cryptographer->has_pending_keys()); |
| 608 EXPECT_TRUE( | 612 EXPECT_TRUE(cryptographer->GetEncryptedTypes().Equals(ModelTypeSet::All())); |
| 609 cryptographer->GetEncryptedTypes().Equals(ModelTypeSet::All())); | |
| 610 } | 613 } |
| 611 | 614 |
| 612 // Create some local unsynced and unencrypted data. Apply a nigori update that | 615 // Create some local unsynced and unencrypted data. Apply a nigori update that |
| 613 // turns on encryption for the unsynced data. Ensure we properly encrypt the | 616 // turns on encryption for the unsynced data. Ensure we properly encrypt the |
| 614 // data as part of the nigori update. Apply another nigori update with no | 617 // data as part of the nigori update. Apply another nigori update with no |
| 615 // changes. Ensure we ignore already-encrypted unsynced data and that nothing | 618 // changes. Ensure we ignore already-encrypted unsynced data and that nothing |
| 616 // breaks. | 619 // breaks. |
| 617 TEST_F(ApplyUpdatesCommandTest, EncryptUnsyncedChanges) { | 620 TEST_F(ApplyUpdatesCommandTest, EncryptUnsyncedChanges) { |
| 618 // Storing the cryptographer separately is bad, but for this test we | 621 // Storing the cryptographer separately is bad, but for this test we |
| 619 // know it's safe. | 622 // know it's safe. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 id_factory_.NewLocalId(), id_factory_.root(), | 656 id_factory_.NewLocalId(), id_factory_.root(), |
| 654 base::StringPrintf("Item %"PRIuS"", i), false, | 657 base::StringPrintf("Item %"PRIuS"", i), false, |
| 655 BOOKMARKS, NULL); | 658 BOOKMARKS, NULL); |
| 656 } | 659 } |
| 657 | 660 |
| 658 KeyParams params = {"localhost", "dummy", "foobar"}; | 661 KeyParams params = {"localhost", "dummy", "foobar"}; |
| 659 cryptographer->AddKey(params); | 662 cryptographer->AddKey(params); |
| 660 sync_pb::EntitySpecifics specifics; | 663 sync_pb::EntitySpecifics specifics; |
| 661 sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori(); | 664 sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori(); |
| 662 cryptographer->GetKeys(nigori->mutable_encrypted()); | 665 cryptographer->GetKeys(nigori->mutable_encrypted()); |
| 663 nigori->set_encrypt_bookmarks(true); | 666 nigori->set_encrypt_everything(true); |
| 664 encrypted_types.Put(BOOKMARKS); | 667 encrypted_types.Put(BOOKMARKS); |
| 665 entry_factory_->CreateUnappliedNewItem( | 668 entry_factory_->CreateUnappliedNewItem( |
| 666 ModelTypeToRootTag(NIGORI), specifics, true); | 669 ModelTypeToRootTag(NIGORI), specifics, true); |
| 667 EXPECT_FALSE(cryptographer->has_pending_keys()); | 670 EXPECT_FALSE(cryptographer->has_pending_keys()); |
| 668 EXPECT_TRUE(cryptographer->is_ready()); | 671 EXPECT_TRUE(cryptographer->is_ready()); |
| 669 | 672 |
| 670 { | 673 { |
| 671 // Ensure we have unsynced nodes that aren't properly encrypted. | 674 // Ensure we have unsynced nodes that aren't properly encrypted. |
| 672 syncable::ReadTransaction trans(FROM_HERE, directory()); | 675 syncable::ReadTransaction trans(FROM_HERE, directory()); |
| 673 EXPECT_FALSE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types)); | 676 EXPECT_FALSE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types)); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 794 } | 797 } |
| 795 | 798 |
| 796 // We encrypt with new keys, triggering the local cryptographer to be unready | 799 // We encrypt with new keys, triggering the local cryptographer to be unready |
| 797 // and unable to decrypt data (once updated). | 800 // and unable to decrypt data (once updated). |
| 798 Cryptographer other_cryptographer(&encryptor_); | 801 Cryptographer other_cryptographer(&encryptor_); |
| 799 KeyParams params = {"localhost", "dummy", "foobar"}; | 802 KeyParams params = {"localhost", "dummy", "foobar"}; |
| 800 other_cryptographer.AddKey(params); | 803 other_cryptographer.AddKey(params); |
| 801 sync_pb::EntitySpecifics specifics; | 804 sync_pb::EntitySpecifics specifics; |
| 802 sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori(); | 805 sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori(); |
| 803 other_cryptographer.GetKeys(nigori->mutable_encrypted()); | 806 other_cryptographer.GetKeys(nigori->mutable_encrypted()); |
| 804 nigori->set_encrypt_bookmarks(true); | 807 nigori->set_encrypt_everything(true); |
| 805 encrypted_types.Put(BOOKMARKS); | 808 encrypted_types.Put(BOOKMARKS); |
| 806 entry_factory_->CreateUnappliedNewItem( | 809 entry_factory_->CreateUnappliedNewItem( |
| 807 ModelTypeToRootTag(NIGORI), specifics, true); | 810 ModelTypeToRootTag(NIGORI), specifics, true); |
| 808 EXPECT_FALSE(cryptographer->has_pending_keys()); | 811 EXPECT_FALSE(cryptographer->has_pending_keys()); |
| 809 | 812 |
| 810 { | 813 { |
| 811 // Ensure we have unsynced nodes that aren't properly encrypted. | 814 // Ensure we have unsynced nodes that aren't properly encrypted. |
| 812 syncable::ReadTransaction trans(FROM_HERE, directory()); | 815 syncable::ReadTransaction trans(FROM_HERE, directory()); |
| 813 EXPECT_FALSE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types)); | 816 EXPECT_FALSE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types)); |
| 814 Syncer::UnsyncedMetaHandles handles; | 817 Syncer::UnsyncedMetaHandles handles; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 846 EXPECT_FALSE(cryptographer->is_ready()); | 849 EXPECT_FALSE(cryptographer->is_ready()); |
| 847 EXPECT_TRUE(cryptographer->has_pending_keys()); | 850 EXPECT_TRUE(cryptographer->has_pending_keys()); |
| 848 | 851 |
| 849 Syncer::UnsyncedMetaHandles handles; | 852 Syncer::UnsyncedMetaHandles handles; |
| 850 GetUnsyncedEntries(&trans, &handles); | 853 GetUnsyncedEntries(&trans, &handles); |
| 851 EXPECT_EQ(2*batch_s+1, handles.size()); | 854 EXPECT_EQ(2*batch_s+1, handles.size()); |
| 852 } | 855 } |
| 853 } | 856 } |
| 854 | 857 |
| 855 } // namespace syncer | 858 } // namespace syncer |
| OLD | NEW |