This source file includes following definitions.
- SetUp
- TearDown
- directory
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "base/format_macros.h"
#include "base/location.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h"
#include "sync/engine/apply_control_data_updates.h"
#include "sync/engine/syncer.h"
#include "sync/engine/syncer_util.h"
#include "sync/internal_api/public/test/test_entry_factory.h"
#include "sync/protocol/nigori_specifics.pb.h"
#include "sync/syncable/directory.h"
#include "sync/syncable/mutable_entry.h"
#include "sync/syncable/nigori_util.h"
#include "sync/syncable/syncable_read_transaction.h"
#include "sync/syncable/syncable_util.h"
#include "sync/syncable/syncable_write_transaction.h"
#include "sync/test/engine/fake_model_worker.h"
#include "sync/test/engine/test_directory_setter_upper.h"
#include "sync/test/engine/test_id_factory.h"
#include "sync/test/fake_sync_encryption_handler.h"
#include "sync/util/cryptographer.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace syncer {
using syncable::MutableEntry;
using syncable::UNITTEST;
using syncable::Id;
class ApplyControlDataUpdatesTest : public ::testing::Test {
public:
protected:
ApplyControlDataUpdatesTest() {}
virtual ~ApplyControlDataUpdatesTest() {}
virtual void SetUp() {
dir_maker_.SetUp();
entry_factory_.reset(new TestEntryFactory(directory()));
}
virtual void TearDown() {
dir_maker_.TearDown();
}
syncable::Directory* directory() {
return dir_maker_.directory();
}
TestIdFactory id_factory_;
scoped_ptr<TestEntryFactory> entry_factory_;
private:
base::MessageLoop loop_;
TestDirectorySetterUpper dir_maker_;
DISALLOW_COPY_AND_ASSIGN(ApplyControlDataUpdatesTest);
};
TEST_F(ApplyControlDataUpdatesTest, NigoriUpdate) {
Cryptographer* cryptographer;
ModelTypeSet encrypted_types;
encrypted_types.PutAll(SyncEncryptionHandler::SensitiveTypes());
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
.Equals(encrypted_types));
}
Cryptographer other_cryptographer(cryptographer->encryptor());
KeyParams params = {"localhost", "dummy", "foobar"};
other_cryptographer.AddKey(params);
sync_pb::EntitySpecifics specifics;
sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori();
other_cryptographer.GetKeys(nigori->mutable_encryption_keybag());
nigori->set_encrypt_everything(true);
entry_factory_->CreateUnappliedNewItem(
ModelTypeToRootTag(NIGORI), specifics, true);
EXPECT_FALSE(cryptographer->has_pending_keys());
ApplyControlDataUpdates(directory());
EXPECT_FALSE(cryptographer->is_ready());
EXPECT_TRUE(cryptographer->has_pending_keys());
{
syncable::ReadTransaction trans(FROM_HERE, directory());
EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
.Equals(ModelTypeSet::All()));
}
}
TEST_F(ApplyControlDataUpdatesTest, EncryptUnsyncedChanges) {
Cryptographer* cryptographer;
ModelTypeSet encrypted_types;
encrypted_types.PutAll(SyncEncryptionHandler::SensitiveTypes());
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
.Equals(encrypted_types));
EXPECT_TRUE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types));
Syncer::UnsyncedMetaHandles handles;
GetUnsyncedEntries(&trans, &handles);
EXPECT_TRUE(handles.empty());
}
Id folder_id = id_factory_.NewLocalId();
entry_factory_->CreateUnsyncedItem(folder_id, id_factory_.root(), "folder",
true, BOOKMARKS, NULL);
size_t i;
size_t batch_s = 5;
for (i = 0; i < batch_s; ++i) {
entry_factory_->CreateUnsyncedItem(id_factory_.NewLocalId(), folder_id,
base::StringPrintf("Item %" PRIuS "", i),
false, BOOKMARKS, NULL);
}
for (; i < 2*batch_s; ++i) {
entry_factory_->CreateUnsyncedItem(
id_factory_.NewLocalId(), id_factory_.root(),
base::StringPrintf("Item %" PRIuS "", i), false,
BOOKMARKS, NULL);
}
KeyParams params = {"localhost", "dummy", "foobar"};
cryptographer->AddKey(params);
sync_pb::EntitySpecifics specifics;
sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori();
cryptographer->GetKeys(nigori->mutable_encryption_keybag());
nigori->set_encrypt_everything(true);
encrypted_types.Put(BOOKMARKS);
entry_factory_->CreateUnappliedNewItem(
ModelTypeToRootTag(NIGORI), specifics, true);
EXPECT_FALSE(cryptographer->has_pending_keys());
EXPECT_TRUE(cryptographer->is_ready());
{
syncable::ReadTransaction trans(FROM_HERE, directory());
EXPECT_FALSE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types));
Syncer::UnsyncedMetaHandles handles;
GetUnsyncedEntries(&trans, &handles);
EXPECT_EQ(2*batch_s+1, handles.size());
}
ApplyControlDataUpdates(directory());
EXPECT_FALSE(cryptographer->has_pending_keys());
EXPECT_TRUE(cryptographer->is_ready());
{
syncable::ReadTransaction trans(FROM_HERE, directory());
EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
.Equals(ModelTypeSet::All()));
EXPECT_TRUE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types));
Syncer::UnsyncedMetaHandles handles;
GetUnsyncedEntries(&trans, &handles);
EXPECT_EQ(2*batch_s+1, handles.size());
}
{
syncable::WriteTransaction trans(FROM_HERE, UNITTEST, directory());
MutableEntry entry(&trans, syncable::GET_BY_SERVER_TAG,
ModelTypeToRootTag(NIGORI));
ASSERT_TRUE(entry.good());
entry.PutServerVersion(entry_factory_->GetNextRevision());
entry.PutIsUnappliedUpdate(true);
}
ApplyControlDataUpdates(directory());
EXPECT_FALSE(cryptographer->has_pending_keys());
EXPECT_TRUE(cryptographer->is_ready());
{
syncable::ReadTransaction trans(FROM_HERE, directory());
EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
.Equals(ModelTypeSet::All()));
EXPECT_TRUE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types));
Syncer::UnsyncedMetaHandles handles;
GetUnsyncedEntries(&trans, &handles);
EXPECT_EQ(2*batch_s+1, handles.size());
}
}
TEST_F(ApplyControlDataUpdatesTest, CannotEncryptUnsyncedChanges) {
Cryptographer* cryptographer;
ModelTypeSet encrypted_types;
encrypted_types.PutAll(SyncEncryptionHandler::SensitiveTypes());
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
.Equals(encrypted_types));
EXPECT_TRUE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types));
Syncer::UnsyncedMetaHandles handles;
GetUnsyncedEntries(&trans, &handles);
EXPECT_TRUE(handles.empty());
}
Id folder_id = id_factory_.NewLocalId();
entry_factory_->CreateUnsyncedItem(
folder_id, id_factory_.root(), "folder", true,
BOOKMARKS, NULL);
size_t i;
size_t batch_s = 5;
for (i = 0; i < batch_s; ++i) {
entry_factory_->CreateUnsyncedItem(id_factory_.NewLocalId(), folder_id,
base::StringPrintf("Item %" PRIuS "", i),
false, BOOKMARKS, NULL);
}
for (; i < 2*batch_s; ++i) {
entry_factory_->CreateUnsyncedItem(
id_factory_.NewLocalId(), id_factory_.root(),
base::StringPrintf("Item %" PRIuS "", i), false,
BOOKMARKS, NULL);
}
Cryptographer other_cryptographer(cryptographer->encryptor());
KeyParams params = {"localhost", "dummy", "foobar"};
other_cryptographer.AddKey(params);
sync_pb::EntitySpecifics specifics;
sync_pb::NigoriSpecifics* nigori = specifics.mutable_nigori();
other_cryptographer.GetKeys(nigori->mutable_encryption_keybag());
nigori->set_encrypt_everything(true);
encrypted_types.Put(BOOKMARKS);
entry_factory_->CreateUnappliedNewItem(
ModelTypeToRootTag(NIGORI), specifics, true);
EXPECT_FALSE(cryptographer->has_pending_keys());
{
syncable::ReadTransaction trans(FROM_HERE, directory());
EXPECT_FALSE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types));
Syncer::UnsyncedMetaHandles handles;
GetUnsyncedEntries(&trans, &handles);
EXPECT_EQ(2*batch_s+1, handles.size());
}
ApplyControlDataUpdates(directory());
EXPECT_FALSE(cryptographer->is_ready());
EXPECT_TRUE(cryptographer->has_pending_keys());
{
syncable::ReadTransaction trans(FROM_HERE, directory());
EXPECT_FALSE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types));
EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
.Equals(ModelTypeSet::All()));
EXPECT_FALSE(cryptographer->is_ready());
EXPECT_TRUE(cryptographer->has_pending_keys());
Syncer::UnsyncedMetaHandles handles;
GetUnsyncedEntries(&trans, &handles);
EXPECT_EQ(2*batch_s+1, handles.size());
}
}
TEST_F(ApplyControlDataUpdatesTest,
NigoriConflictPendingKeysServerEncryptEverythingCustom) {
Cryptographer* cryptographer;
ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes());
KeyParams other_params = {"localhost", "dummy", "foobar"};
KeyParams local_params = {"localhost", "dummy", "local"};
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
EXPECT_TRUE(encrypted_types.Equals(
directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
}
Cryptographer other_cryptographer(cryptographer->encryptor());
other_cryptographer.AddKey(other_params);
sync_pb::EntitySpecifics server_specifics;
sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag());
server_nigori->set_encrypt_everything(true);
server_nigori->set_keybag_is_frozen(true);
int64 nigori_handle =
entry_factory_->CreateUnappliedNewItem(kNigoriTag,
server_specifics,
true);
cryptographer->AddKey(local_params);
EXPECT_TRUE(cryptographer->is_ready());
sync_pb::EntitySpecifics local_specifics;
sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
local_nigori->set_encrypt_everything(false);
local_nigori->set_keybag_is_frozen(true);
ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem(
nigori_handle, local_specifics));
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
directory()->GetNigoriHandler()->ApplyNigoriUpdate(
*local_nigori,
&trans);
}
EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
ApplyControlDataUpdates(directory());
EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
EXPECT_FALSE(cryptographer->is_ready());
EXPECT_TRUE(cryptographer->is_initialized());
EXPECT_TRUE(cryptographer->has_pending_keys());
EXPECT_TRUE(other_cryptographer.CanDecryptUsingDefaultKey(
entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().encryption_keybag()));
EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().keybag_is_frozen());
EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().encrypt_everything());
{
syncable::ReadTransaction trans(FROM_HERE, directory());
EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
.Equals(ModelTypeSet::All()));
}
}
TEST_F(ApplyControlDataUpdatesTest,
NigoriConflictPendingKeysLocalEncryptEverythingCustom) {
Cryptographer* cryptographer;
ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes());
KeyParams other_params = {"localhost", "dummy", "foobar"};
KeyParams local_params = {"localhost", "dummy", "local"};
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
EXPECT_TRUE(encrypted_types.Equals(
directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
}
Cryptographer other_cryptographer(cryptographer->encryptor());
other_cryptographer.AddKey(other_params);
sync_pb::EntitySpecifics server_specifics;
sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag());
server_nigori->set_encrypt_everything(false);
server_nigori->set_keybag_is_frozen(false);
int64 nigori_handle =
entry_factory_->CreateUnappliedNewItem(kNigoriTag,
server_specifics,
true);
cryptographer->AddKey(local_params);
EXPECT_TRUE(cryptographer->is_ready());
sync_pb::EntitySpecifics local_specifics;
sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
local_nigori->set_encrypt_everything(true);
local_nigori->set_keybag_is_frozen(true);
ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem(
nigori_handle, local_specifics));
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
directory()->GetNigoriHandler()->ApplyNigoriUpdate(
*local_nigori,
&trans);
}
EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
ApplyControlDataUpdates(directory());
EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
EXPECT_FALSE(cryptographer->is_ready());
EXPECT_TRUE(cryptographer->is_initialized());
EXPECT_TRUE(cryptographer->has_pending_keys());
EXPECT_TRUE(other_cryptographer.CanDecryptUsingDefaultKey(
entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().encryption_keybag()));
EXPECT_FALSE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().keybag_is_frozen());
EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().encrypt_everything());
{
syncable::ReadTransaction trans(FROM_HERE, directory());
EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
.Equals(ModelTypeSet::All()));
}
}
TEST_F(ApplyControlDataUpdatesTest,
NigoriConflictOldKeys) {
Cryptographer* cryptographer;
ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes());
KeyParams old_params = {"localhost", "dummy", "old"};
KeyParams new_params = {"localhost", "dummy", "new"};
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
EXPECT_TRUE(encrypted_types.Equals(
directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
}
cryptographer->AddKey(old_params);
sync_pb::EntitySpecifics server_specifics;
sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
cryptographer->GetKeys(server_nigori->mutable_encryption_keybag());
server_nigori->set_encrypt_everything(true);
int64 nigori_handle =
entry_factory_->CreateUnappliedNewItem(kNigoriTag,
server_specifics,
true);
cryptographer->AddKey(new_params);
EXPECT_TRUE(cryptographer->is_ready());
sync_pb::EntitySpecifics local_specifics;
sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
local_nigori->set_encrypt_everything(false);
ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem(
nigori_handle, local_specifics));
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
directory()->GetNigoriHandler()->ApplyNigoriUpdate(
*local_nigori,
&trans);
}
EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
ApplyControlDataUpdates(directory());
EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
EXPECT_TRUE(cryptographer->is_ready());
EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey(
entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().encryption_keybag()));
EXPECT_FALSE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().keybag_is_frozen());
EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().encrypt_everything());
{
syncable::ReadTransaction trans(FROM_HERE, directory());
EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
.Equals(ModelTypeSet::All()));
}
}
TEST_F(ApplyControlDataUpdatesTest,
NigoriConflictBothMigratedLocalCustom) {
Cryptographer* cryptographer;
ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes());
KeyParams old_params = {"localhost", "dummy", "old"};
KeyParams new_params = {"localhost", "dummy", "new"};
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
EXPECT_TRUE(encrypted_types.Equals(
directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
}
Cryptographer other_cryptographer(cryptographer->encryptor());
other_cryptographer.AddKey(old_params);
sync_pb::EntitySpecifics server_specifics;
sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag());
server_nigori->set_encrypt_everything(false);
server_nigori->set_keybag_is_frozen(true);
server_nigori->set_passphrase_type(
sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
server_nigori->mutable_keystore_decryptor_token();
int64 nigori_handle =
entry_factory_->CreateUnappliedNewItem(kNigoriTag,
server_specifics,
true);
cryptographer->AddKey(old_params);
cryptographer->AddKey(new_params);
EXPECT_TRUE(cryptographer->is_ready());
sync_pb::EntitySpecifics local_specifics;
sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
local_nigori->set_encrypt_everything(true);
local_nigori->set_keybag_is_frozen(true);
local_nigori->set_passphrase_type(
sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE);
ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem(
nigori_handle, local_specifics));
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
directory()->GetNigoriHandler()->ApplyNigoriUpdate(
*local_nigori,
&trans);
}
EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
ApplyControlDataUpdates(directory());
EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
EXPECT_TRUE(cryptographer->is_ready());
EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey(
entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().encryption_keybag()));
EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().keybag_is_frozen());
EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().encrypt_everything());
EXPECT_EQ(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE,
entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().passphrase_type());
{
syncable::ReadTransaction trans(FROM_HERE, directory());
EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
.Equals(ModelTypeSet::All()));
}
}
TEST_F(ApplyControlDataUpdatesTest,
NigoriConflictBothMigratedServerCustom) {
Cryptographer* cryptographer;
ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes());
KeyParams old_params = {"localhost", "dummy", "old"};
KeyParams new_params = {"localhost", "dummy", "new"};
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
EXPECT_TRUE(encrypted_types.Equals(
directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
}
Cryptographer other_cryptographer(cryptographer->encryptor());
other_cryptographer.AddKey(old_params);
other_cryptographer.AddKey(new_params);
sync_pb::EntitySpecifics server_specifics;
sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag());
server_nigori->set_encrypt_everything(true);
server_nigori->set_keybag_is_frozen(true);
server_nigori->set_passphrase_type(
sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE);
int64 nigori_handle =
entry_factory_->CreateUnappliedNewItem(kNigoriTag,
server_specifics,
true);
cryptographer->AddKey(old_params);
EXPECT_TRUE(cryptographer->is_ready());
sync_pb::EntitySpecifics local_specifics;
sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
local_nigori->set_encrypt_everything(false);
local_nigori->set_keybag_is_frozen(true);
local_nigori->set_passphrase_type(
sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
server_nigori->mutable_keystore_decryptor_token();
ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem(
nigori_handle, local_specifics));
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
directory()->GetNigoriHandler()->ApplyNigoriUpdate(
*local_nigori,
&trans);
}
EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
ApplyControlDataUpdates(directory());
EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
EXPECT_TRUE(cryptographer->is_initialized());
EXPECT_TRUE(cryptographer->has_pending_keys());
EXPECT_TRUE(other_cryptographer.CanDecryptUsingDefaultKey(
entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().encryption_keybag()));
EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().keybag_is_frozen());
EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().encrypt_everything());
EXPECT_EQ(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE,
entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().passphrase_type());
{
syncable::ReadTransaction trans(FROM_HERE, directory());
EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
.Equals(ModelTypeSet::All()));
}
}
TEST_F(ApplyControlDataUpdatesTest,
NigoriConflictLocalMigrated) {
Cryptographer* cryptographer;
ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes());
KeyParams old_params = {"localhost", "dummy", "old"};
KeyParams new_params = {"localhost", "dummy", "new"};
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
EXPECT_TRUE(encrypted_types.Equals(
directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
}
Cryptographer other_cryptographer(cryptographer->encryptor());
other_cryptographer.AddKey(old_params);
sync_pb::EntitySpecifics server_specifics;
sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag());
server_nigori->set_encrypt_everything(true);
server_nigori->set_keybag_is_frozen(false);
int64 nigori_handle =
entry_factory_->CreateUnappliedNewItem(kNigoriTag,
server_specifics,
true);
cryptographer->AddKey(old_params);
cryptographer->AddKey(new_params);
EXPECT_TRUE(cryptographer->is_ready());
sync_pb::EntitySpecifics local_specifics;
sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
local_nigori->set_encrypt_everything(true);
local_nigori->set_keybag_is_frozen(true);
local_nigori->set_passphrase_type(
sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE);
ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem(
nigori_handle, local_specifics));
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
directory()->GetNigoriHandler()->ApplyNigoriUpdate(
*local_nigori,
&trans);
}
EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
ApplyControlDataUpdates(directory());
EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
EXPECT_TRUE(cryptographer->is_ready());
EXPECT_TRUE(cryptographer->CanDecryptUsingDefaultKey(
entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().encryption_keybag()));
EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().keybag_is_frozen());
EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().encrypt_everything());
EXPECT_EQ(sync_pb::NigoriSpecifics::CUSTOM_PASSPHRASE,
entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().passphrase_type());
{
syncable::ReadTransaction trans(FROM_HERE, directory());
EXPECT_TRUE(directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)
.Equals(ModelTypeSet::All()));
}
}
TEST_F(ApplyControlDataUpdatesTest,
NigoriConflictServerMigrated) {
Cryptographer* cryptographer;
ModelTypeSet encrypted_types(SyncEncryptionHandler::SensitiveTypes());
KeyParams old_params = {"localhost", "dummy", "old"};
KeyParams new_params = {"localhost", "dummy", "new"};
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
EXPECT_TRUE(encrypted_types.Equals(
directory()->GetNigoriHandler()->GetEncryptedTypes(&trans)));
}
Cryptographer other_cryptographer(cryptographer->encryptor());
other_cryptographer.AddKey(old_params);
sync_pb::EntitySpecifics server_specifics;
sync_pb::NigoriSpecifics* server_nigori = server_specifics.mutable_nigori();
other_cryptographer.GetKeys(server_nigori->mutable_encryption_keybag());
server_nigori->set_encrypt_everything(false);
server_nigori->set_keybag_is_frozen(true);
server_nigori->set_passphrase_type(
sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE);
server_nigori->mutable_keystore_decryptor_token();
int64 nigori_handle =
entry_factory_->CreateUnappliedNewItem(kNigoriTag,
server_specifics,
true);
cryptographer->AddKey(old_params);
cryptographer->AddKey(new_params);
EXPECT_TRUE(cryptographer->is_ready());
sync_pb::EntitySpecifics local_specifics;
sync_pb::NigoriSpecifics* local_nigori = local_specifics.mutable_nigori();
cryptographer->GetKeys(local_nigori->mutable_encryption_keybag());
local_nigori->set_encrypt_everything(false);
local_nigori->set_keybag_is_frozen(false);
ASSERT_TRUE(entry_factory_->SetLocalSpecificsForItem(
nigori_handle, local_specifics));
{
syncable::ReadTransaction trans(FROM_HERE, directory());
cryptographer = directory()->GetCryptographer(&trans);
directory()->GetNigoriHandler()->ApplyNigoriUpdate(
*local_nigori,
&trans);
}
EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
EXPECT_TRUE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
ApplyControlDataUpdates(directory());
EXPECT_TRUE(entry_factory_->GetIsUnsyncedForItem(nigori_handle));
EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(nigori_handle));
EXPECT_TRUE(cryptographer->is_ready());
EXPECT_FALSE(cryptographer->CanDecryptUsingDefaultKey(
entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().encryption_keybag()));
EXPECT_TRUE(cryptographer->CanDecrypt(
entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().encryption_keybag()));
EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().keybag_is_frozen());
EXPECT_TRUE(entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().has_keystore_decryptor_token());
EXPECT_EQ(sync_pb::NigoriSpecifics::KEYSTORE_PASSPHRASE,
entry_factory_->GetLocalSpecificsForItem(nigori_handle).
nigori().passphrase_type());
{
syncable::ReadTransaction trans(FROM_HERE, directory());
}
}
TEST_F(ApplyControlDataUpdatesTest, ControlApply) {
std::string experiment_id = "experiment";
sync_pb::EntitySpecifics specifics;
specifics.mutable_experiments()->mutable_keystore_encryption()->
set_enabled(true);
int64 experiment_handle = entry_factory_->CreateUnappliedNewItem(
experiment_id, specifics, false);
ApplyControlDataUpdates(directory());
EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(experiment_handle));
EXPECT_TRUE(
entry_factory_->GetLocalSpecificsForItem(experiment_handle).
experiments().keystore_encryption().enabled());
}
TEST_F(ApplyControlDataUpdatesTest, ControlApplyParentBeforeChild) {
std::string parent_id = "parent";
std::string experiment_id = "experiment";
sync_pb::EntitySpecifics specifics;
specifics.mutable_experiments()->mutable_keystore_encryption()->
set_enabled(true);
int64 experiment_handle = entry_factory_->CreateUnappliedNewItemWithParent(
experiment_id, specifics, parent_id);
int64 parent_handle = entry_factory_->CreateUnappliedNewItem(
parent_id, specifics, true);
ApplyControlDataUpdates(directory());
EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(parent_handle));
EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(experiment_handle));
EXPECT_TRUE(
entry_factory_->GetLocalSpecificsForItem(experiment_handle).
experiments().keystore_encryption().enabled());
}
TEST_F(ApplyControlDataUpdatesTest, ControlConflict) {
std::string experiment_id = "experiment";
sync_pb::EntitySpecifics local_specifics, server_specifics;
server_specifics.mutable_experiments()->mutable_keystore_encryption()->
set_enabled(true);
local_specifics.mutable_experiments()->mutable_keystore_encryption()->
set_enabled(false);
int64 experiment_handle = entry_factory_->CreateSyncedItem(
experiment_id, EXPERIMENTS, false);
entry_factory_->SetServerSpecificsForItem(experiment_handle,
server_specifics);
entry_factory_->SetLocalSpecificsForItem(experiment_handle,
local_specifics);
ApplyControlDataUpdates(directory());
EXPECT_FALSE(entry_factory_->GetIsUnappliedForItem(experiment_handle));
EXPECT_TRUE(
entry_factory_->GetLocalSpecificsForItem(experiment_handle).
experiments().keystore_encryption().enabled());
}
}