summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlipalani@chromium.org <lipalani@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-02 18:43:57 +0000
committerlipalani@chromium.org <lipalani@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-06-02 18:43:57 +0000
commit8e8aea77f98f5075b055b818187a84f14c2ee0fd (patch)
treea20605241796f72301657779dca2656cda725e06
parent23f77116cafe9a88819b60c7606453ae0db8f35d (diff)
downloadchromium_src-8e8aea77f98f5075b055b818187a84f14c2ee0fd.zip
chromium_src-8e8aea77f98f5075b055b818187a84f14c2ee0fd.tar.gz
chromium_src-8e8aea77f98f5075b055b818187a84f14c2ee0fd.tar.bz2
Moving storing of encrypted types in cryptographer.
BUG=84153, 80333 TEST= Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=87556 Review URL: http://codereview.chromium.org/7078023 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@87644 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/sync/backend_migrator.cc11
-rw-r--r--chrome/browser/sync/backend_migrator_unittest.cc32
-rw-r--r--chrome/browser/sync/engine/apply_updates_command_unittest.cc14
-rw-r--r--chrome/browser/sync/engine/syncapi.cc63
-rw-r--r--chrome/browser/sync/engine/syncapi.h4
-rw-r--r--chrome/browser/sync/engine/syncapi_unittest.cc4
-rw-r--r--chrome/browser/sync/engine/syncer_util.cc10
-rw-r--r--chrome/browser/sync/glue/app_model_associator.cc2
-rw-r--r--chrome/browser/sync/glue/bookmark_model_associator.cc2
-rw-r--r--chrome/browser/sync/glue/data_type_manager.h3
-rw-r--r--chrome/browser/sync/glue/data_type_manager_impl.cc29
-rw-r--r--chrome/browser/sync/glue/data_type_manager_impl.h10
-rw-r--r--chrome/browser/sync/glue/data_type_manager_impl_unittest.cc29
-rw-r--r--chrome/browser/sync/glue/data_type_manager_mock.cc22
-rw-r--r--chrome/browser/sync/glue/data_type_manager_mock.h2
-rw-r--r--chrome/browser/sync/glue/extension_model_associator.cc2
-rw-r--r--chrome/browser/sync/glue/generic_change_processor.cc2
-rw-r--r--chrome/browser/sync/glue/sync_backend_host.cc33
-rw-r--r--chrome/browser/sync/glue/sync_backend_host.h6
-rw-r--r--chrome/browser/sync/glue/sync_backend_host_mock.cc2
-rw-r--r--chrome/browser/sync/glue/sync_backend_host_mock.h5
-rw-r--r--chrome/browser/sync/glue/sync_backend_host_unittest.cc59
-rw-r--r--chrome/browser/sync/syncable/nigori_util.cc49
-rw-r--r--chrome/browser/sync/syncable/nigori_util.h9
-rw-r--r--chrome/browser/sync/syncable/nigori_util_unittest.cc11
-rw-r--r--chrome/browser/sync/test_profile_sync_service.cc5
-rw-r--r--chrome/browser/sync/test_profile_sync_service.h3
-rw-r--r--chrome/browser/sync/util/cryptographer.cc43
-rw-r--r--chrome/browser/sync/util/cryptographer.h15
-rw-r--r--chrome/test/live_sync/live_passwords_sync_test.h2
-rw-r--r--chrome/test/live_sync/migration_errors_test.cc6
31 files changed, 333 insertions, 156 deletions
diff --git a/chrome/browser/sync/backend_migrator.cc b/chrome/browser/sync/backend_migrator.cc
index 0f7dd0c..2ab4680 100644
--- a/chrome/browser/sync/backend_migrator.cc
+++ b/chrome/browser/sync/backend_migrator.cc
@@ -69,7 +69,15 @@ void BackendMigrator::MigrateTypes(const syncable::ModelTypeSet& types) {
to_migrate_.begin(), to_migrate_.end(),
std::inserter(difference, difference.end()));
VLOG(1) << "BackendMigrator disabling types; calling Configure.";
- manager_->Configure(difference, sync_api::CONFIGURE_REASON_MIGRATION);
+
+ // Add nigori for config or not based upon if the server told us to migrate
+ // nigori or not.
+ if (types.count(syncable::NIGORI) == 0) {
+ manager_->Configure(difference, sync_api::CONFIGURE_REASON_MIGRATION);
+ } else {
+ manager_->ConfigureWithoutNigori(difference,
+ sync_api::CONFIGURE_REASON_MIGRATION);
+ }
}
void BackendMigrator::OnStateChanged() {
@@ -99,6 +107,7 @@ void BackendMigrator::OnStateChanged() {
ModelTypeSet full_set;
service_->GetPreferredDataTypes(&full_set);
VLOG(1) << "BackendMigrator re-enabling types.";
+
// Don't use |to_migrate_| for the re-enabling because the user may have
// chosen to disable types during the migration.
manager_->Configure(full_set, sync_api::CONFIGURE_REASON_MIGRATION);
diff --git a/chrome/browser/sync/backend_migrator_unittest.cc b/chrome/browser/sync/backend_migrator_unittest.cc
index 7c8a4f8..2939141 100644
--- a/chrome/browser/sync/backend_migrator_unittest.cc
+++ b/chrome/browser/sync/backend_migrator_unittest.cc
@@ -114,6 +114,38 @@ TEST_F(BackendMigratorTest, Sanity) {
EXPECT_EQ(BackendMigrator::IDLE, migrator.state());
}
+// Test that in the normal case with Nigori a migration transitions through
+// each state and wind up back in IDLE.
+TEST_F(BackendMigratorTest, MigrateNigori) {
+ BackendMigrator migrator(service(), manager());
+ syncable::ModelTypeSet to_migrate, difference;
+ to_migrate.insert(syncable::NIGORI);
+ difference.insert(syncable::AUTOFILL);
+ difference.insert(syncable::BOOKMARKS);
+
+ EXPECT_CALL(*manager(), state())
+ .WillOnce(Return(DataTypeManager::CONFIGURED));
+
+ EXPECT_CALL(*manager(), ConfigureWithoutNigori(_,
+ sync_api::CONFIGURE_REASON_MIGRATION));
+
+ migrator.MigrateTypes(to_migrate);
+ EXPECT_EQ(BackendMigrator::DISABLING_TYPES, migrator.state());
+
+ SendConfigureDone(DataTypeManager::OK, difference);
+ EXPECT_EQ(BackendMigrator::WAITING_FOR_PURGE, migrator.state());
+
+ ReturnEmptyProgressMarkersInSnapshot();
+ EXPECT_CALL(*manager(), Configure(preferred_types(),
+ sync_api::CONFIGURE_REASON_MIGRATION));
+ migrator.OnStateChanged();
+ EXPECT_EQ(BackendMigrator::REENABLING_TYPES, migrator.state());
+
+ SendConfigureDone(DataTypeManager::OK, preferred_types());
+ EXPECT_EQ(BackendMigrator::IDLE, migrator.state());
+}
+
+
// Test that the migrator waits for the data type manager to be idle before
// starting a migration.
TEST_F(BackendMigratorTest, WaitToStart) {
diff --git a/chrome/browser/sync/engine/apply_updates_command_unittest.cc b/chrome/browser/sync/engine/apply_updates_command_unittest.cc
index 5f05ea2..8bceb39 100644
--- a/chrome/browser/sync/engine/apply_updates_command_unittest.cc
+++ b/chrome/browser/sync/engine/apply_updates_command_unittest.cc
@@ -25,7 +25,6 @@ namespace browser_sync {
using sessions::SyncSession;
using std::string;
using syncable::Entry;
-using syncable::GetEncryptedDataTypes;
using syncable::Id;
using syncable::MutableEntry;
using syncable::ReadTransaction;
@@ -344,9 +343,9 @@ TEST_F(ApplyUpdatesCommandTest, NigoriUpdate) {
ScopedDirLookup dir(syncdb()->manager(), syncdb()->name());
ASSERT_TRUE(dir.good());
ReadTransaction trans(dir, __FILE__, __LINE__);
- EXPECT_EQ(encrypted_types, GetEncryptedDataTypes(&trans));
cryptographer =
session()->context()->directory_manager()->GetCryptographer(&trans);
+ EXPECT_EQ(encrypted_types, cryptographer->GetEncryptedTypes());
}
// Nigori node updates should update the Cryptographer.
@@ -389,9 +388,10 @@ TEST_F(ApplyUpdatesCommandTest, EncryptUnsyncedChanges) {
ScopedDirLookup dir(syncdb()->manager(), syncdb()->name());
ASSERT_TRUE(dir.good());
ReadTransaction trans(dir, __FILE__, __LINE__);
- EXPECT_EQ(encrypted_types, GetEncryptedDataTypes(&trans));
cryptographer =
session()->context()->directory_manager()->GetCryptographer(&trans);
+ EXPECT_EQ(encrypted_types, cryptographer->GetEncryptedTypes());
+
// With default encrypted_types, this should be true.
EXPECT_TRUE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types));
@@ -467,7 +467,7 @@ TEST_F(ApplyUpdatesCommandTest, EncryptUnsyncedChanges) {
// If ProcessUnsyncedChangesForEncryption worked, all our unsynced changes
// should be encrypted now.
- EXPECT_EQ(encrypted_types, GetEncryptedDataTypes(&trans));
+ EXPECT_EQ(encrypted_types, cryptographer->GetEncryptedTypes());
EXPECT_TRUE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types));
Syncer::UnsyncedMetaHandles handles;
@@ -486,9 +486,10 @@ TEST_F(ApplyUpdatesCommandTest, CannotEncryptUnsyncedChanges) {
ScopedDirLookup dir(syncdb()->manager(), syncdb()->name());
ASSERT_TRUE(dir.good());
ReadTransaction trans(dir, __FILE__, __LINE__);
- EXPECT_EQ(encrypted_types, GetEncryptedDataTypes(&trans));
cryptographer =
session()->context()->directory_manager()->GetCryptographer(&trans);
+ EXPECT_EQ(encrypted_types, cryptographer->GetEncryptedTypes());
+
// With default encrypted_types, this should be true.
EXPECT_TRUE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types));
@@ -571,7 +572,8 @@ TEST_F(ApplyUpdatesCommandTest, CannotEncryptUnsyncedChanges) {
EXPECT_FALSE(VerifyUnsyncedChangesAreEncrypted(&trans, encrypted_types));
encrypted_types.clear();
encrypted_types.insert(syncable::PASSWORDS);
- EXPECT_EQ(encrypted_types, GetEncryptedDataTypes(&trans));
+ encrypted_types.insert(syncable::BOOKMARKS);
+ EXPECT_EQ(encrypted_types, cryptographer->GetEncryptedTypes());
Syncer::UnsyncedMetaHandles handles;
SyncerUtil::GetUnsyncedEntries(&trans, &handles);
diff --git a/chrome/browser/sync/engine/syncapi.cc b/chrome/browser/sync/engine/syncapi.cc
index 37f56ab..40a946f 100644
--- a/chrome/browser/sync/engine/syncapi.cc
+++ b/chrome/browser/sync/engine/syncapi.cc
@@ -456,7 +456,7 @@ void WriteNode::EncryptIfNecessary(sync_pb::EntitySpecifics* unencrypted) {
DCHECK_NE(type, syncable::NIGORI); // Nigori is encrypted separately.
syncable::ModelTypeSet encrypted_types =
- GetEncryptedDataTypes(GetTransaction()->GetWrappedTrans());
+ GetEncryptedTypes(GetTransaction());
if (encrypted_types.count(type) == 0) {
// This datatype does not require encryption.
return;
@@ -1196,6 +1196,12 @@ DictionaryValue* NotificationInfoToValue(
} // namespace
+syncable::ModelTypeSet GetEncryptedTypes(
+ const sync_api::BaseTransaction* trans) {
+ Cryptographer* cryptographer = trans->GetCryptographer();
+ return cryptographer->GetEncryptedTypes();
+}
+
//////////////////////////////////////////////////////////////////////////
// SyncManager's implementation: SyncManager::SyncInternal
class SyncManager::SyncInternal
@@ -1829,16 +1835,20 @@ void SyncManager::SyncInternal::BootstrapEncryption(
return;
}
- if (!lookup->initial_sync_ended_for_type(syncable::NIGORI))
- return;
-
sync_pb::NigoriSpecifics nigori;
+ syncable::ModelTypeSet encrypted_types;
{
// Cryptographer should only be accessed while holding a transaction.
ReadTransaction trans(GetUserShare());
Cryptographer* cryptographer = trans.GetCryptographer();
+
+ // Set the bootstrap token before bailing out if nigori node is not there.
+ // This could happen if server asked us to migrate nigri.
cryptographer->Bootstrap(restored_key_for_bootstrapping);
+ if (!lookup->initial_sync_ended_for_type(syncable::NIGORI))
+ return;
+
ReadNode node(&trans);
if (!node.InitByTagLookup(kNigoriTag)) {
NOTREACHED();
@@ -1846,20 +1856,17 @@ void SyncManager::SyncInternal::BootstrapEncryption(
}
nigori.CopyFrom(node.GetNigoriSpecifics());
- if (!nigori.encrypted().blob().empty()) {
- if (cryptographer->CanDecrypt(nigori.encrypted())) {
- cryptographer->SetKeys(nigori.encrypted());
- } else {
- cryptographer->SetPendingKeys(nigori.encrypted());
- FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
- OnPassphraseRequired(sync_api::REASON_DECRYPTION));
- }
+ Cryptographer::UpdateResult result = cryptographer->Update(nigori);
+ if (result == Cryptographer::NEEDS_PASSPHRASE) {
+ FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
+ OnPassphraseRequired(sync_api::REASON_DECRYPTION));
}
+
+ // Refresh list of encrypted datatypes.
+ encrypted_types = GetEncryptedTypes(&trans);
}
- // Refresh list of encrypted datatypes.
- syncable::ModelTypeSet encrypted_types =
- syncable::GetEncryptedDataTypesFromNigori(nigori);
+
// Ensure any datatypes that need encryption are encrypted.
EncryptDataTypes(encrypted_types);
@@ -2104,13 +2111,14 @@ void SyncManager::SyncInternal::EncryptDataTypes(
return;
}
+ Cryptographer* cryptographer = trans.GetCryptographer();
+
// Update the Nigori node set of encrypted datatypes so other machines notice.
// Note, we merge the current encrypted types with those requested. Once a
// datatypes is marked as needing encryption, it is never unmarked.
sync_pb::NigoriSpecifics nigori;
nigori.CopyFrom(node.GetNigoriSpecifics());
- syncable::ModelTypeSet current_encrypted_types =
- syncable::GetEncryptedDataTypesFromNigori(nigori);
+ syncable::ModelTypeSet current_encrypted_types = GetEncryptedTypes(&trans);
syncable::ModelTypeSet newly_encrypted_types;
std::set_union(current_encrypted_types.begin(), current_encrypted_types.end(),
encrypted_types.begin(), encrypted_types.end(),
@@ -2119,6 +2127,8 @@ void SyncManager::SyncInternal::EncryptDataTypes(
syncable::FillNigoriEncryptedTypes(newly_encrypted_types, &nigori);
node.SetNigoriSpecifics(nigori);
+ cryptographer->SetEncryptedTypes(nigori);
+
// TODO(zea): only reencrypt this datatype? ReEncrypting everything is a
// safer approach, and should not impact anything that is already encrypted
// (redundant changes are ignored).
@@ -2174,7 +2184,7 @@ ListValue* SyncManager::SyncInternal::FindNodesContainingString(
void SyncManager::SyncInternal::ReEncryptEverything(WriteTransaction* trans) {
syncable::ModelTypeSet encrypted_types =
- GetEncryptedDataTypes(trans->GetWrappedTrans());
+ GetEncryptedTypes(trans);
ModelSafeRoutingInfo routes;
registrar_->GetModelSafeRoutingInfo(&routes);
std::string tag;
@@ -2550,14 +2560,7 @@ void SyncManager::SyncInternal::OnSyncEngineEvent(
// Check to see if we need to notify the frontend that we have newly
// encrypted types or that we require a passphrase.
sync_api::ReadTransaction trans(GetUserShare());
- sync_api::ReadNode node(&trans);
- if (!node.InitByTagLookup(kNigoriTag)) {
- DCHECK(!event.snapshot->is_share_usable);
- return;
- }
- const sync_pb::NigoriSpecifics& nigori = node.GetNigoriSpecifics();
- syncable::ModelTypeSet encrypted_types =
- syncable::GetEncryptedDataTypesFromNigori(nigori);
+ syncable::ModelTypeSet encrypted_types = GetEncryptedTypes(&trans);
syncable::ModelTypeSet encrypted_and_enabled_types;
for (syncable::ModelTypeSet::iterator iter = encrypted_types.begin();
iter != encrypted_types.end();
@@ -2567,7 +2570,15 @@ void SyncManager::SyncInternal::OnSyncEngineEvent(
}
if (!encrypted_and_enabled_types.empty()) {
Cryptographer* cryptographer = trans.GetCryptographer();
+ // TODO(lipalani) : confirm from zea and tim this could be hit only for
+ // the first sync ever on this profile.
if (!cryptographer->is_ready() && !cryptographer->has_pending_keys()) {
+ sync_api::ReadNode node(&trans);
+ if (!node.InitByTagLookup(kNigoriTag)) {
+ DCHECK(!event.snapshot->is_share_usable);
+ return;
+ }
+ const sync_pb::NigoriSpecifics& nigori = node.GetNigoriSpecifics();
if (!nigori.encrypted().blob().empty()) {
DCHECK(!cryptographer->CanDecrypt(nigori.encrypted()));
cryptographer->SetPendingKeys(nigori.encrypted());
diff --git a/chrome/browser/sync/engine/syncapi.h b/chrome/browser/sync/engine/syncapi.h
index 5a0cacd..0e35fff 100644
--- a/chrome/browser/sync/engine/syncapi.h
+++ b/chrome/browser/sync/engine/syncapi.h
@@ -108,6 +108,10 @@ class HttpPostProviderFactory;
class SyncManager;
class WriteTransaction;
+syncable::ModelTypeSet GetEncryptedTypes(
+ const sync_api::BaseTransaction* trans);
+
+
// Reasons due to which browser_sync::Cryptographer might require a passphrase.
enum PassphraseRequiredReason {
REASON_PASSPHRASE_NOT_REQUIRED = 0, // Initial value.
diff --git a/chrome/browser/sync/engine/syncapi_unittest.cc b/chrome/browser/sync/engine/syncapi_unittest.cc
index 229947b..253cad5 100644
--- a/chrome/browser/sync/engine/syncapi_unittest.cc
+++ b/chrome/browser/sync/engine/syncapi_unittest.cc
@@ -1171,7 +1171,7 @@ TEST_F(SyncManagerTest, EncryptDataTypesWithNoData) {
{
ReadTransaction trans(sync_manager_.GetUserShare());
EXPECT_EQ(expected_types,
- GetEncryptedDataTypes(trans.GetWrappedTrans()));
+ GetEncryptedTypes(&trans));
}
}
@@ -1226,7 +1226,7 @@ TEST_F(SyncManagerTest, EncryptDataTypesWithData) {
{
ReadTransaction trans(sync_manager_.GetUserShare());
EXPECT_EQ(encrypted_types,
- GetEncryptedDataTypes(trans.GetWrappedTrans()));
+ GetEncryptedTypes(&trans));
EXPECT_TRUE(syncable::VerifyDataTypeEncryption(trans.GetWrappedTrans(),
syncable::BOOKMARKS,
true /* is encrypted */));
diff --git a/chrome/browser/sync/engine/syncer_util.cc b/chrome/browser/sync/engine/syncer_util.cc
index 7340a27..eb6d0bf 100644
--- a/chrome/browser/sync/engine/syncer_util.cc
+++ b/chrome/browser/sync/engine/syncer_util.cc
@@ -295,17 +295,11 @@ UpdateAttemptResponse SyncerUtil::AttemptToUpdateEntry(
if (specifics.HasExtension(sync_pb::nigori)) {
const sync_pb::NigoriSpecifics& nigori =
specifics.GetExtension(sync_pb::nigori);
- if (!nigori.encrypted().blob().empty()) {
- if (cryptographer->CanDecrypt(nigori.encrypted())) {
- cryptographer->SetKeys(nigori.encrypted());
- } else {
- cryptographer->SetPendingKeys(nigori.encrypted());
- }
- }
+ cryptographer->Update(nigori);
// Make sure any unsynced changes are properly encrypted as necessary.
syncable::ModelTypeSet encrypted_types =
- syncable::GetEncryptedDataTypesFromNigori(nigori);
+ cryptographer->GetEncryptedTypes();
if (!VerifyUnsyncedChangesAreEncrypted(trans, encrypted_types) &&
(!cryptographer->is_ready() ||
!syncable::ProcessUnsyncedChangesForEncryption(trans, encrypted_types,
diff --git a/chrome/browser/sync/glue/app_model_associator.cc b/chrome/browser/sync/glue/app_model_associator.cc
index 1b31570..b2bb54c 100644
--- a/chrome/browser/sync/glue/app_model_associator.cc
+++ b/chrome/browser/sync/glue/app_model_associator.cc
@@ -65,7 +65,7 @@ bool AppModelAssociator::CryptoReadyIfNecessary() {
// We only access the cryptographer while holding a transaction.
sync_api::ReadTransaction trans(user_share_);
const syncable::ModelTypeSet& encrypted_types =
- GetEncryptedDataTypes(trans.GetWrappedTrans());
+ sync_api::GetEncryptedTypes(&trans);
return encrypted_types.count(traits_.model_type) == 0 ||
trans.GetCryptographer()->is_ready();
}
diff --git a/chrome/browser/sync/glue/bookmark_model_associator.cc b/chrome/browser/sync/glue/bookmark_model_associator.cc
index af7c752..9aff7ad 100644
--- a/chrome/browser/sync/glue/bookmark_model_associator.cc
+++ b/chrome/browser/sync/glue/bookmark_model_associator.cc
@@ -599,7 +599,7 @@ bool BookmarkModelAssociator::CryptoReadyIfNecessary() {
// We only access the cryptographer while holding a transaction.
sync_api::ReadTransaction trans(user_share_);
const syncable::ModelTypeSet& encrypted_types =
- GetEncryptedDataTypes(trans.GetWrappedTrans());
+ sync_api::GetEncryptedTypes(&trans);
return encrypted_types.count(syncable::BOOKMARKS) == 0 ||
trans.GetCryptographer()->is_ready();
}
diff --git a/chrome/browser/sync/glue/data_type_manager.h b/chrome/browser/sync/glue/data_type_manager.h
index 7d789d4..eef71a1 100644
--- a/chrome/browser/sync/glue/data_type_manager.h
+++ b/chrome/browser/sync/glue/data_type_manager.h
@@ -91,6 +91,9 @@ class DataTypeManager {
virtual void Configure(const TypeSet& desired_types,
sync_api::ConfigureReason reason) = 0;
+ virtual void ConfigureWithoutNigori(const TypeSet& desired_types,
+ sync_api::ConfigureReason reason) = 0;
+
// Synchronously stops all registered data types. If called after
// Configure() is called but before it finishes, it will abort the
// configure and any data types that have been started will be
diff --git a/chrome/browser/sync/glue/data_type_manager_impl.cc b/chrome/browser/sync/glue/data_type_manager_impl.cc
index 3a7ca4c..a840259 100644
--- a/chrome/browser/sync/glue/data_type_manager_impl.cc
+++ b/chrome/browser/sync/glue/data_type_manager_impl.cc
@@ -101,7 +101,18 @@ bool DataTypeManagerImpl::GetControllersNeedingStart(
}
void DataTypeManagerImpl::Configure(const TypeSet& desired_types,
- sync_api::ConfigureReason reason) {
+ sync_api::ConfigureReason reason) {
+ ConfigureImpl(desired_types, reason, true);
+}
+
+void DataTypeManagerImpl::ConfigureWithoutNigori(const TypeSet& desired_types,
+ sync_api::ConfigureReason reason) {
+ ConfigureImpl(desired_types, reason, false);
+}
+
+void DataTypeManagerImpl::ConfigureImpl(const TypeSet& desired_types,
+ sync_api::ConfigureReason reason,
+ bool enable_nigori) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (state_ == STOPPING) {
// You can not set a configuration while stopping.
@@ -116,6 +127,14 @@ void DataTypeManagerImpl::Configure(const TypeSet& desired_types,
<< "Postponing until current configuration complete.";
needs_reconfigure_ = true;
last_configure_reason_ = reason;
+
+ // Note we should never be in a state to reconfigure with nigori disabled.
+ // Reconfigures serve to store teh configure request from the user if
+ // another one is already in progress. Since enable_nigori is set to false
+ // only on migration and migration code should not initialize configure
+ // if there is already one in progress, enable_nigori should always be true
+ // if we are here.
+ DCHECK(enable_nigori);
return;
}
@@ -150,10 +169,11 @@ void DataTypeManagerImpl::Configure(const TypeSet& desired_types,
// types to start/stop, because it could be that some types haven't
// started due to crypto errors but the backend host needs to know that we're
// disabling them anyway).
- Restart(reason);
+ Restart(reason, enable_nigori);
}
-void DataTypeManagerImpl::Restart(sync_api::ConfigureReason reason) {
+void DataTypeManagerImpl::Restart(sync_api::ConfigureReason reason,
+ bool enable_nigori) {
VLOG(1) << "Restarting...";
last_restart_time_ = base::Time::Now();
@@ -178,7 +198,8 @@ void DataTypeManagerImpl::Restart(sync_api::ConfigureReason reason) {
controllers_,
last_requested_types_,
reason,
- method_factory_.NewRunnableMethod(&DataTypeManagerImpl::DownloadReady));
+ method_factory_.NewRunnableMethod(&DataTypeManagerImpl::DownloadReady),
+ enable_nigori);
}
void DataTypeManagerImpl::DownloadReady() {
diff --git a/chrome/browser/sync/glue/data_type_manager_impl.h b/chrome/browser/sync/glue/data_type_manager_impl.h
index bd77074..902bcf8 100644
--- a/chrome/browser/sync/glue/data_type_manager_impl.h
+++ b/chrome/browser/sync/glue/data_type_manager_impl.h
@@ -29,6 +29,10 @@ class DataTypeManagerImpl : public DataTypeManager {
// DataTypeManager interface.
virtual void Configure(const TypeSet& desired_types,
sync_api::ConfigureReason reason);
+
+ virtual void ConfigureWithoutNigori(const TypeSet& desired_types,
+ sync_api::ConfigureReason reason);
+
virtual void Stop();
virtual const DataTypeController::TypeMap& controllers();
virtual State state();
@@ -53,7 +57,7 @@ class DataTypeManagerImpl : public DataTypeManager {
bool GetControllersNeedingStart(
std::vector<DataTypeController*>* needs_start);
- void Restart(sync_api::ConfigureReason reason);
+ void Restart(sync_api::ConfigureReason reason, bool enable_nigori);
void DownloadReady();
void NotifyStart();
void NotifyDone(ConfigureResult result,
@@ -64,6 +68,10 @@ class DataTypeManagerImpl : public DataTypeManager {
// Restart().
void AddToConfigureTime();
+ virtual void ConfigureImpl(const TypeSet& desired_types,
+ sync_api::ConfigureReason reason,
+ bool enable_nigori);
+
SyncBackendHost* backend_;
// Map of all data type controllers that are available for sync.
// This list is determined at startup by various command line flags.
diff --git a/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc b/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc
index b4602b0..1f5e3ef 100644
--- a/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc
+++ b/chrome/browser/sync/glue/data_type_manager_impl_unittest.cc
@@ -180,7 +180,7 @@ TEST_F(DataTypeManagerImplTest, ConfigureOne) {
DataTypeControllerMock* bookmark_dtc = MakeBookmarkDTC();
SetStartStopExpectations(bookmark_dtc);
controllers_[syncable::BOOKMARKS] = bookmark_dtc;
- EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _)).Times(1);
+ EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _, _)).Times(1);
DataTypeManagerImpl dtm(&backend_, controllers_);
types_.insert(syncable::BOOKMARKS);
SetConfigureStartExpectation();
@@ -196,7 +196,7 @@ TEST_F(DataTypeManagerImplTest, ConfigureOneStopWhileStarting) {
SetBusyStartStopExpectations(bookmark_dtc,
DataTypeController::MODEL_STARTING);
controllers_[syncable::BOOKMARKS] = bookmark_dtc;
- EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _)).Times(1);
+ EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _, _)).Times(1);
DataTypeManagerImpl dtm(&backend_, controllers_);
types_.insert(syncable::BOOKMARKS);
SetConfigureStartExpectation();
@@ -211,7 +211,7 @@ TEST_F(DataTypeManagerImplTest, ConfigureOneStopWhileAssociating) {
DataTypeControllerMock* bookmark_dtc = MakeBookmarkDTC();
SetBusyStartStopExpectations(bookmark_dtc, DataTypeController::ASSOCIATING);
controllers_[syncable::BOOKMARKS] = bookmark_dtc;
- EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _)).Times(1);
+ EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _, _)).Times(1);
DataTypeManagerImpl dtm(&backend_, controllers_);
types_.insert(syncable::BOOKMARKS);
SetConfigureStartExpectation();
@@ -230,7 +230,7 @@ TEST_F(DataTypeManagerImplTest, OneWaitingForCrypto) {
WillOnce(InvokeCallback((DataTypeController::NEEDS_CRYPTO)));
controllers_[syncable::PASSWORDS] = password_dtc;
- EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _)).Times(1);
+ EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _, _)).Times(1);
DataTypeManagerImpl dtm(&backend_, controllers_);
types_.insert(syncable::PASSWORDS);
@@ -250,7 +250,7 @@ TEST_F(DataTypeManagerImplTest, OneWaitingForCrypto) {
WillRepeatedly(Return(DataTypeController::RUNNING));
EXPECT_CALL(*password_dtc, Start(_)).
WillOnce(InvokeCallback((DataTypeController::OK)));
- EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _)).Times(1);
+ EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _, _)).Times(1);
dtm.Configure(types_, sync_api::CONFIGURE_REASON_RECONFIGURATION);
EXPECT_EQ(DataTypeManager::CONFIGURED, dtm.state());
@@ -267,7 +267,7 @@ TEST_F(DataTypeManagerImplTest, ConfigureOneThenAnother) {
SetStartStopExpectations(preference_dtc);
controllers_[syncable::PREFERENCES] = preference_dtc;
- EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _)).Times(2);
+ EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _, _)).Times(2);
DataTypeManagerImpl dtm(&backend_, controllers_);
types_.insert(syncable::BOOKMARKS);
@@ -294,7 +294,7 @@ TEST_F(DataTypeManagerImplTest, ConfigureOneThenSwitch) {
SetStartStopExpectations(preference_dtc);
controllers_[syncable::PREFERENCES] = preference_dtc;
- EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _)).Times(2);
+ EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _, _)).Times(2);
DataTypeManagerImpl dtm(&backend_, controllers_);
types_.insert(syncable::BOOKMARKS);
@@ -318,7 +318,8 @@ void DoConfigureDataTypes(
const DataTypeController::TypeMap& data_type_controllers,
const syncable::ModelTypeSet& types,
sync_api::ConfigureReason reason,
- CancelableTask* ready_task) {
+ CancelableTask* ready_task,
+ bool enable_nigori) {
ready_task->Run();
delete ready_task;
}
@@ -350,7 +351,7 @@ TEST_F(DataTypeManagerImplTest, ConfigureWhileOneInFlight) {
controllers_[syncable::PREFERENCES] = preference_dtc;
DataTypeManagerImpl dtm(&backend_, controllers_);
- EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _))
+ EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _, _))
.WillOnce(Invoke(DoConfigureDataTypes))
.WillOnce(DoAll(Invoke(DoConfigureDataTypes),
InvokeWithoutArgs(QuitMessageLoop)));
@@ -388,7 +389,7 @@ TEST_F(DataTypeManagerImplTest, OneFailingController) {
DataTypeManagerImpl dtm(&backend_, controllers_);
SetConfigureStartExpectation();
SetConfigureDoneExpectation(DataTypeManager::ASSOCIATION_FAILED);
- EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _)).Times(1);
+ EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _, _)).Times(1);
types_.insert(syncable::BOOKMARKS);
dtm.Configure(types_, sync_api::CONFIGURE_REASON_RECONFIGURATION);
@@ -412,7 +413,7 @@ TEST_F(DataTypeManagerImplTest, StopWhileInFlight) {
DataTypeManagerImpl dtm(&backend_, controllers_);
SetConfigureStartExpectation();
SetConfigureDoneExpectation(DataTypeManager::ABORTED);
- EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _)).Times(1);
+ EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _, _)).Times(1);
types_.insert(syncable::BOOKMARKS);
types_.insert(syncable::PREFERENCES);
@@ -444,7 +445,7 @@ TEST_F(DataTypeManagerImplTest, SecondControllerFails) {
DataTypeManagerImpl dtm(&backend_, controllers_);
SetConfigureStartExpectation();
SetConfigureDoneExpectation(DataTypeManager::ASSOCIATION_FAILED);
- EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _)).Times(1);
+ EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _, _)).Times(1);
types_.insert(syncable::BOOKMARKS);
types_.insert(syncable::PREFERENCES);
@@ -467,7 +468,7 @@ TEST_F(DataTypeManagerImplTest, ConfigureWhileDownloadPending) {
CancelableTask* task;
// Grab the task the first time this is called so we can configure
// before it is finished.
- EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _)).
+ EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _, _)).
WillOnce(SaveArg<3>(&task)).
WillOnce(DoDefault());
@@ -502,7 +503,7 @@ TEST_F(DataTypeManagerImplTest, StopWhileDownloadPending) {
CancelableTask* task;
// Grab the task the first time this is called so we can stop
// before it is finished.
- EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _)).
+ EXPECT_CALL(backend_, ConfigureDataTypes(_, _, _, _, _)).
WillOnce(SaveArg<3>(&task));
types_.insert(syncable::BOOKMARKS);
diff --git a/chrome/browser/sync/glue/data_type_manager_mock.cc b/chrome/browser/sync/glue/data_type_manager_mock.cc
index 9c7041b..1f75b84 100644
--- a/chrome/browser/sync/glue/data_type_manager_mock.cc
+++ b/chrome/browser/sync/glue/data_type_manager_mock.cc
@@ -13,12 +13,22 @@ DataTypeManagerMock::DataTypeManagerMock()
// By default, calling Configure will send a SYNC_CONFIGURE_START
// and SYNC_CONFIGURE_DONE notification with a DataTypeManager::OK
// detail.
- ON_CALL(*this, Configure(testing::_, testing::_)).
- WillByDefault(testing::DoAll(
- NotifyFromDataTypeManager(this,
- NotificationType::SYNC_CONFIGURE_START),
- NotifyFromDataTypeManagerWithResult
- (this, NotificationType::SYNC_CONFIGURE_DONE, &result_)));
+ ON_CALL(*this, Configure(testing::_, testing::_)).
+ WillByDefault(testing::DoAll(
+ NotifyFromDataTypeManager(this,
+ NotificationType::SYNC_CONFIGURE_START),
+ NotifyFromDataTypeManagerWithResult
+ (this, NotificationType::SYNC_CONFIGURE_DONE, &result_)));
+
+ // By default, calling ConfigureWithoutNigori will send a SYNC_CONFIGURE_START
+ // and SYNC_CONFIGURE_DONE notification with a DataTypeManager::OK
+ // detail.
+ ON_CALL(*this, ConfigureWithoutNigori(testing::_, testing::_)).
+ WillByDefault(testing::DoAll(
+ NotifyFromDataTypeManager(this,
+ NotificationType::SYNC_CONFIGURE_START),
+ NotifyFromDataTypeManagerWithResult
+ (this, NotificationType::SYNC_CONFIGURE_DONE, &result_)));
}
DataTypeManagerMock::~DataTypeManagerMock() {}
diff --git a/chrome/browser/sync/glue/data_type_manager_mock.h b/chrome/browser/sync/glue/data_type_manager_mock.h
index 9e1dc03..0645164 100644
--- a/chrome/browser/sync/glue/data_type_manager_mock.h
+++ b/chrome/browser/sync/glue/data_type_manager_mock.h
@@ -35,6 +35,8 @@ class DataTypeManagerMock : public DataTypeManager {
virtual ~DataTypeManagerMock();
MOCK_METHOD2(Configure, void(const TypeSet&, sync_api::ConfigureReason));
+ MOCK_METHOD2(ConfigureWithoutNigori,
+ void(const TypeSet&, sync_api::ConfigureReason));
MOCK_METHOD0(Stop, void());
MOCK_METHOD0(controllers, const DataTypeController::TypeMap&());
MOCK_METHOD0(state, State());
diff --git a/chrome/browser/sync/glue/extension_model_associator.cc b/chrome/browser/sync/glue/extension_model_associator.cc
index 7754435..6bfbece 100644
--- a/chrome/browser/sync/glue/extension_model_associator.cc
+++ b/chrome/browser/sync/glue/extension_model_associator.cc
@@ -66,7 +66,7 @@ bool ExtensionModelAssociator::CryptoReadyIfNecessary() {
// We only access the cryptographer while holding a transaction.
sync_api::ReadTransaction trans(user_share_);
const syncable::ModelTypeSet& encrypted_types =
- GetEncryptedDataTypes(trans.GetWrappedTrans());
+ sync_api::GetEncryptedTypes(&trans);
return encrypted_types.count(traits_.model_type) == 0 ||
trans.GetCryptographer()->is_ready();
}
diff --git a/chrome/browser/sync/glue/generic_change_processor.cc b/chrome/browser/sync/glue/generic_change_processor.cc
index ba175bf..d2056d2 100644
--- a/chrome/browser/sync/glue/generic_change_processor.cc
+++ b/chrome/browser/sync/glue/generic_change_processor.cc
@@ -187,7 +187,7 @@ bool GenericChangeProcessor::CryptoReadyIfNecessary(syncable::ModelType type) {
// We only access the cryptographer while holding a transaction.
sync_api::ReadTransaction trans(share_handle());
const syncable::ModelTypeSet& encrypted_types =
- syncable::GetEncryptedDataTypes(trans.GetWrappedTrans());
+ GetEncryptedTypes(&trans);
return encrypted_types.count(type) == 0 ||
trans.GetCryptographer()->is_ready();
}
diff --git a/chrome/browser/sync/glue/sync_backend_host.cc b/chrome/browser/sync/glue/sync_backend_host.cc
index f31d80d..a2952eb 100644
--- a/chrome/browser/sync/glue/sync_backend_host.cc
+++ b/chrome/browser/sync/glue/sync_backend_host.cc
@@ -160,9 +160,6 @@ std::string SyncBackendHost::RestoreEncryptionBootstrapToken() {
bool SyncBackendHost::IsNigoriEnabled() const {
base::AutoLock lock(registrar_lock_);
- // Note that NIGORI is only ever added/removed from routing_info once,
- // during initialization / first configuration, so there is no real 'race'
- // possible here or possibility of stale return value.
return registrar_.routing_info.find(syncable::NIGORI) !=
registrar_.routing_info.end();
}
@@ -347,14 +344,14 @@ PendingConfigureDataTypesState() : deleted_type(false),
SyncBackendHost::PendingConfigureDataTypesState::
~PendingConfigureDataTypesState() {}
-// static
SyncBackendHost::PendingConfigureDataTypesState*
SyncBackendHost::MakePendingConfigModeState(
const DataTypeController::TypeMap& data_type_controllers,
const syncable::ModelTypeSet& types,
CancelableTask* ready_task,
ModelSafeRoutingInfo* routing_info,
- sync_api::ConfigureReason reason) {
+ sync_api::ConfigureReason reason,
+ bool nigori_enabled) {
PendingConfigureDataTypesState* state = new PendingConfigureDataTypesState();
for (DataTypeController::TypeMap::const_iterator it =
data_type_controllers.begin();
@@ -374,6 +371,19 @@ SyncBackendHost::PendingConfigureDataTypesState*
}
}
+ if (types.count(syncable::NIGORI) == 0) {
+ if (nigori_enabled) { // Nigori is currently enabled.
+ state->deleted_type = true;
+ routing_info->erase(syncable::NIGORI);
+ }
+ } else { // Nigori needs to be enabled.
+ if (!nigori_enabled) {
+ // Currently it is disabled. So enable it.
+ (*routing_info)[syncable::NIGORI] = GROUP_PASSIVE;
+ state->added_types.set(syncable::NIGORI);
+ }
+ }
+
state->ready_task.reset(ready_task);
state->initial_types = types;
state->reason = reason;
@@ -384,7 +394,8 @@ void SyncBackendHost::ConfigureDataTypes(
const DataTypeController::TypeMap& data_type_controllers,
const syncable::ModelTypeSet& types,
sync_api::ConfigureReason reason,
- CancelableTask* ready_task) {
+ CancelableTask* ready_task,
+ bool enable_nigori) {
// Only one configure is allowed at a time.
DCHECK(!pending_config_mode_state_.get());
DCHECK(!pending_download_state_.get());
@@ -394,11 +405,17 @@ void SyncBackendHost::ConfigureDataTypes(
ConfigureAutofillMigration();
}
+ syncable::ModelTypeSet types_copy = types;
+ if (enable_nigori) {
+ types_copy.insert(syncable::NIGORI);
+ }
+ bool nigori_currently_enabled = IsNigoriEnabled();
{
base::AutoLock lock(registrar_lock_);
pending_config_mode_state_.reset(
- MakePendingConfigModeState(data_type_controllers, types, ready_task,
- &registrar_.routing_info, reason));
+ MakePendingConfigModeState(data_type_controllers, types_copy,
+ ready_task, &registrar_.routing_info, reason,
+ nigori_currently_enabled));
}
StartConfiguration(NewCallback(core_.get(),
diff --git a/chrome/browser/sync/glue/sync_backend_host.h b/chrome/browser/sync/glue/sync_backend_host.h
index dac1237..9263cb4 100644
--- a/chrome/browser/sync/glue/sync_backend_host.h
+++ b/chrome/browser/sync/glue/sync_backend_host.h
@@ -168,7 +168,8 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar {
const DataTypeController::TypeMap& data_type_controllers,
const syncable::ModelTypeSet& types,
sync_api::ConfigureReason reason,
- CancelableTask* ready_task);
+ CancelableTask* ready_task,
+ bool enable_nigori);
// Makes an asynchronous call to syncer to switch to config mode. When done
// syncer will call us back on FinishConfigureDataTypes.
@@ -593,7 +594,8 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar {
const syncable::ModelTypeSet& types,
CancelableTask* ready_task,
ModelSafeRoutingInfo* routing_info,
- sync_api::ConfigureReason reason);
+ sync_api::ConfigureReason reason,
+ bool nigori_enabled);
// A thread we dedicate for use by our Core to perform initialization,
// authentication, handle messages from the syncapi, and periodically tell
diff --git a/chrome/browser/sync/glue/sync_backend_host_mock.cc b/chrome/browser/sync/glue/sync_backend_host_mock.cc
index 738688e..fe7d9b3 100644
--- a/chrome/browser/sync/glue/sync_backend_host_mock.cc
+++ b/chrome/browser/sync/glue/sync_backend_host_mock.cc
@@ -14,7 +14,7 @@ ACTION(InvokeTask) {
SyncBackendHostMock::SyncBackendHostMock() {
// By default, invoke the ready callback.
ON_CALL(*this, ConfigureDataTypes(testing::_, testing::_, testing::_,
- testing::_)).
+ testing::_, testing::_)).
WillByDefault(InvokeTask());
}
diff --git a/chrome/browser/sync/glue/sync_backend_host_mock.h b/chrome/browser/sync/glue/sync_backend_host_mock.h
index a3dd137..882265c 100644
--- a/chrome/browser/sync/glue/sync_backend_host_mock.h
+++ b/chrome/browser/sync/glue/sync_backend_host_mock.h
@@ -21,11 +21,12 @@ class SyncBackendHostMock : public SyncBackendHost {
SyncBackendHostMock();
virtual ~SyncBackendHostMock();
- MOCK_METHOD4(ConfigureDataTypes,
+ MOCK_METHOD5(ConfigureDataTypes,
void(const DataTypeController::TypeMap&,
const std::set<syncable::ModelType>&,
sync_api::ConfigureReason,
- CancelableTask*));
+ CancelableTask*,
+ bool));
MOCK_METHOD0(StartSyncingWithServer, void());
};
diff --git a/chrome/browser/sync/glue/sync_backend_host_unittest.cc b/chrome/browser/sync/glue/sync_backend_host_unittest.cc
index 431e60e..8846982 100644
--- a/chrome/browser/sync/glue/sync_backend_host_unittest.cc
+++ b/chrome/browser/sync/glue/sync_backend_host_unittest.cc
@@ -118,7 +118,7 @@ TEST_F(SyncBackendHostTest, MakePendingConfigModeState) {
scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState>
state(SyncBackendHost::MakePendingConfigModeState(
data_type_controllers, types, NULL, &routing_info,
- sync_api::CONFIGURE_REASON_RECONFIGURATION));
+ sync_api::CONFIGURE_REASON_RECONFIGURATION, false));
EXPECT_TRUE(routing_info.empty());
EXPECT_FALSE(state->ready_task.get());
EXPECT_EQ(types, state->initial_types);
@@ -133,10 +133,11 @@ TEST_F(SyncBackendHostTest, MakePendingConfigModeState) {
syncable::ModelTypeSet types;
ModelSafeRoutingInfo routing_info;
+ types.insert(syncable::NIGORI);
scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState>
state(SyncBackendHost::MakePendingConfigModeState(
data_type_controllers, types, NULL,
- &routing_info, sync_api::CONFIGURE_REASON_RECONFIGURATION));
+ &routing_info, sync_api::CONFIGURE_REASON_RECONFIGURATION, true));
EXPECT_TRUE(routing_info.empty());
EXPECT_FALSE(state->ready_task.get());
EXPECT_EQ(types, state->initial_types);
@@ -150,12 +151,13 @@ TEST_F(SyncBackendHostTest, MakePendingConfigModeState) {
data_type_controllers[syncable::BOOKMARKS] = NULL;
syncable::ModelTypeSet types;
types.insert(syncable::BOOKMARKS);
+ types.insert(syncable::NIGORI);
ModelSafeRoutingInfo routing_info;
scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState>
state(SyncBackendHost::MakePendingConfigModeState(
data_type_controllers, types, NULL, &routing_info,
- sync_api::CONFIGURE_REASON_RECONFIGURATION));
+ sync_api::CONFIGURE_REASON_RECONFIGURATION, true));
ModelSafeRoutingInfo expected_routing_info;
expected_routing_info[syncable::BOOKMARKS] = GROUP_PASSIVE;
@@ -175,6 +177,7 @@ TEST_F(SyncBackendHostTest, MakePendingConfigModeState) {
data_type_controllers[syncable::BOOKMARKS] = NULL;
syncable::ModelTypeSet types;
types.insert(syncable::BOOKMARKS);
+ types.insert(syncable::NIGORI);
ModelSafeRoutingInfo routing_info;
routing_info[syncable::BOOKMARKS] = GROUP_PASSIVE;
ModelSafeRoutingInfo expected_routing_info = routing_info;
@@ -182,7 +185,7 @@ TEST_F(SyncBackendHostTest, MakePendingConfigModeState) {
scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState>
state(SyncBackendHost::MakePendingConfigModeState(
data_type_controllers, types, NULL, &routing_info,
- sync_api::CONFIGURE_REASON_RECONFIGURATION));
+ sync_api::CONFIGURE_REASON_RECONFIGURATION, true));
EXPECT_EQ(expected_routing_info, routing_info);
EXPECT_FALSE(state->ready_task.get());
@@ -196,13 +199,14 @@ TEST_F(SyncBackendHostTest, MakePendingConfigModeState) {
DataTypeController::TypeMap data_type_controllers;
data_type_controllers[syncable::BOOKMARKS] = NULL;
syncable::ModelTypeSet types;
+ types.insert(syncable::NIGORI);
ModelSafeRoutingInfo routing_info;
routing_info[syncable::BOOKMARKS] = GROUP_PASSIVE;
scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState>
state(SyncBackendHost::MakePendingConfigModeState(
data_type_controllers, types, NULL, &routing_info,
- sync_api::CONFIGURE_REASON_RECONFIGURATION));
+ sync_api::CONFIGURE_REASON_RECONFIGURATION, true));
ModelSafeRoutingInfo expected_routing_info;
EXPECT_EQ(expected_routing_info, routing_info);
@@ -211,6 +215,51 @@ TEST_F(SyncBackendHostTest, MakePendingConfigModeState) {
EXPECT_TRUE(state->deleted_type);
EXPECT_TRUE(state->added_types.none());
}
+
+ // Add Nigori.
+ {
+ DataTypeController::TypeMap data_type_controllers;
+ syncable::ModelTypeSet types;
+ types.insert(syncable::NIGORI);
+ ModelSafeRoutingInfo routing_info;
+
+ scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState>
+ state(SyncBackendHost::MakePendingConfigModeState(
+ data_type_controllers, types, NULL, &routing_info,
+ sync_api::CONFIGURE_REASON_RECONFIGURATION, false));
+
+ ModelSafeRoutingInfo expected_routing_info;
+ expected_routing_info[syncable::NIGORI] = GROUP_PASSIVE;
+ EXPECT_EQ(expected_routing_info, routing_info);
+ EXPECT_FALSE(state->ready_task.get());
+ EXPECT_EQ(types, state->initial_types);
+ EXPECT_FALSE(state->deleted_type);
+
+ syncable::ModelTypeBitSet expected_added_types;
+ expected_added_types.set(syncable::NIGORI);
+ EXPECT_EQ(expected_added_types, state->added_types);
+ }
+
+ // Delete Nigori.
+ {
+ DataTypeController::TypeMap data_type_controllers;
+ syncable::ModelTypeSet types;
+ ModelSafeRoutingInfo routing_info;
+ routing_info[syncable::NIGORI] = GROUP_PASSIVE;
+
+ scoped_ptr<SyncBackendHost::PendingConfigureDataTypesState>
+ state(SyncBackendHost::MakePendingConfigModeState(
+ data_type_controllers, types, NULL, &routing_info,
+ sync_api::CONFIGURE_REASON_RECONFIGURATION, true));
+
+ ModelSafeRoutingInfo expected_routing_info;
+ EXPECT_EQ(expected_routing_info, routing_info);
+ EXPECT_FALSE(state->ready_task.get());
+ EXPECT_EQ(types, state->initial_types);
+ EXPECT_TRUE(state->deleted_type);
+
+ EXPECT_TRUE(state->added_types.none());
+ }
}
// TODO(akalin): Write more SyncBackendHost unit tests.
diff --git a/chrome/browser/sync/syncable/nigori_util.cc b/chrome/browser/sync/syncable/nigori_util.cc
index c13aead..018c87c 100644
--- a/chrome/browser/sync/syncable/nigori_util.cc
+++ b/chrome/browser/sync/syncable/nigori_util.cc
@@ -13,55 +13,6 @@
#include "chrome/browser/sync/util/cryptographer.h"
namespace syncable {
-
-ModelTypeSet GetEncryptedDataTypes(BaseTransaction* const trans) {
- std::string nigori_tag = ModelTypeToRootTag(syncable::NIGORI);
- Entry entry(trans, GET_BY_SERVER_TAG, nigori_tag);
- if (!entry.good()) {
- VLOG(1) << "Nigori node not found, assuming no encrypted datatypes.";
- ModelTypeSet encrypted_types;
- encrypted_types.insert(syncable::PASSWORDS);
- return encrypted_types;
- }
- if (NIGORI != entry.GetModelType()) {
- // Can happen if we fail to apply the nigori node due to a conflict.
- VLOG(1) << "Nigori node does not have nigori extension. Assuming no"
- << " encrypted datatypes.";
- ModelTypeSet encrypted_types;
- encrypted_types.insert(syncable::PASSWORDS);
- return encrypted_types;
- }
- const sync_pb::EntitySpecifics& specifics = entry.Get(SPECIFICS);
- return GetEncryptedDataTypesFromNigori(
- specifics.GetExtension(sync_pb::nigori));
-}
-
-ModelTypeSet GetEncryptedDataTypesFromNigori(
- const sync_pb::NigoriSpecifics& nigori) {
- // We don't check NIGORI datatype, it uses its own encryption scheme.
- ModelTypeSet encrypted_types;
- if (nigori.encrypt_bookmarks())
- encrypted_types.insert(BOOKMARKS);
- if (nigori.encrypt_preferences())
- encrypted_types.insert(PREFERENCES);
- if (nigori.encrypt_autofill_profile())
- encrypted_types.insert(AUTOFILL_PROFILE);
- if (nigori.encrypt_autofill())
- encrypted_types.insert(AUTOFILL);
- if (nigori.encrypt_themes())
- encrypted_types.insert(THEMES);
- if (nigori.encrypt_typed_urls())
- encrypted_types.insert(TYPED_URLS);
- if (nigori.encrypt_extensions())
- encrypted_types.insert(EXTENSIONS);
- if (nigori.encrypt_sessions())
- encrypted_types.insert(SESSIONS);
- if (nigori.encrypt_apps())
- encrypted_types.insert(APPS);
- encrypted_types.insert(PASSWORDS); // Always encrypted.
- return encrypted_types;
-}
-
void FillNigoriEncryptedTypes(const ModelTypeSet& types,
sync_pb::NigoriSpecifics* nigori) {
DCHECK(nigori);
diff --git a/chrome/browser/sync/syncable/nigori_util.h b/chrome/browser/sync/syncable/nigori_util.h
index 3ad8fcd..f427458 100644
--- a/chrome/browser/sync/syncable/nigori_util.h
+++ b/chrome/browser/sync/syncable/nigori_util.h
@@ -21,15 +21,6 @@ class BaseTransaction;
class ReadTransaction;
class WriteTransaction;
-// Returns the set of datatypes that require encryption as specified by the
-// Sync DB's nigori node. This will never include passwords, as the encryption
-// status of that is always on if passwords are enabled..
-ModelTypeSet GetEncryptedDataTypes(BaseTransaction* const trans);
-
-// Extract the set of encrypted datatypes from a nigori node.
-ModelTypeSet GetEncryptedDataTypesFromNigori(
- const sync_pb::NigoriSpecifics& nigori);
-
// Set the encrypted datatypes on the nigori node.
void FillNigoriEncryptedTypes(const ModelTypeSet& types,
sync_pb::NigoriSpecifics* nigori);
diff --git a/chrome/browser/sync/syncable/nigori_util_unittest.cc b/chrome/browser/sync/syncable/nigori_util_unittest.cc
index 74f1a27..d7d6789 100644
--- a/chrome/browser/sync/syncable/nigori_util_unittest.cc
+++ b/chrome/browser/sync/syncable/nigori_util_unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "chrome/browser/sync/util/cryptographer.h"
#include "chrome/browser/sync/syncable/nigori_util.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -10,25 +11,29 @@ namespace syncable {
typedef testing::Test NigoriUtilTest;
TEST_F(NigoriUtilTest, NigoriEncryptionTypes) {
+ browser_sync::Cryptographer cryptographer;
sync_pb::NigoriSpecifics nigori;
ModelTypeSet encrypted_types;
encrypted_types.insert(syncable::PASSWORDS);
FillNigoriEncryptedTypes(encrypted_types, &nigori);
- ModelTypeSet test_types = GetEncryptedDataTypesFromNigori(nigori);
+ cryptographer.SetEncryptedTypes(nigori);
+ ModelTypeSet test_types = cryptographer.GetEncryptedTypes();
EXPECT_EQ(encrypted_types, test_types);
for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) {
encrypted_types.insert(ModelTypeFromInt(i));
}
FillNigoriEncryptedTypes(encrypted_types, &nigori);
- test_types = GetEncryptedDataTypesFromNigori(nigori);
+ cryptographer.SetEncryptedTypes(nigori);
+ test_types = cryptographer.GetEncryptedTypes();
encrypted_types.erase(syncable::NIGORI); // Should not get set.
EXPECT_EQ(encrypted_types, test_types);
encrypted_types.erase(syncable::BOOKMARKS);
encrypted_types.erase(syncable::SESSIONS);
FillNigoriEncryptedTypes(encrypted_types, &nigori);
- test_types = GetEncryptedDataTypesFromNigori(nigori);
+ cryptographer.SetEncryptedTypes(nigori);
+ test_types = cryptographer.GetEncryptedTypes();
EXPECT_EQ(encrypted_types, test_types);
}
diff --git a/chrome/browser/sync/test_profile_sync_service.cc b/chrome/browser/sync/test_profile_sync_service.cc
index 6397b0c..9c6010a 100644
--- a/chrome/browser/sync/test_profile_sync_service.cc
+++ b/chrome/browser/sync/test_profile_sync_service.cc
@@ -46,10 +46,11 @@ void SyncBackendHostForProfileSyncTest::ConfigureDataTypes(
const DataTypeController::TypeMap& data_type_controllers,
const syncable::ModelTypeSet& types,
sync_api::ConfigureReason reason,
- CancelableTask* ready_task) {
+ CancelableTask* ready_task,
+ bool nigori_enabled) {
SetAutofillMigrationState(syncable::MIGRATED);
SyncBackendHost::ConfigureDataTypes(data_type_controllers, types,
- reason, ready_task);
+ reason, ready_task, nigori_enabled);
}
void SyncBackendHostForProfileSyncTest::
diff --git a/chrome/browser/sync/test_profile_sync_service.h b/chrome/browser/sync/test_profile_sync_service.h
index 4c3e19d..780560c 100644
--- a/chrome/browser/sync/test_profile_sync_service.h
+++ b/chrome/browser/sync/test_profile_sync_service.h
@@ -47,7 +47,8 @@ class SyncBackendHostForProfileSyncTest
const DataTypeController::TypeMap& data_type_controllers,
const syncable::ModelTypeSet& types,
sync_api::ConfigureReason reason,
- CancelableTask* ready_task);
+ CancelableTask* ready_task,
+ bool nigori_enabled);
// Called when a nudge comes in.
void SimulateSyncCycleCompletedInitialSyncEnded(
diff --git a/chrome/browser/sync/util/cryptographer.cc b/chrome/browser/sync/util/cryptographer.cc
index 562da35..01f7eb2 100644
--- a/chrome/browser/sync/util/cryptographer.cc
+++ b/chrome/browser/sync/util/cryptographer.cc
@@ -17,6 +17,7 @@ const char kNigoriTag[] = "google_chrome_nigori";
const char kNigoriKeyName[] = "nigori-key";
Cryptographer::Cryptographer() : default_nigori_(NULL) {
+ encrypted_types_.insert(syncable::PASSWORDS);
}
Cryptographer::~Cryptographer() {}
@@ -241,6 +242,48 @@ Nigori* Cryptographer::UnpackBootstrapToken(const std::string& token) const {
return nigori.release();
}
+Cryptographer::UpdateResult Cryptographer::Update(
+ const sync_pb::NigoriSpecifics& nigori) {
+ SetEncryptedTypes(nigori);
+ if (!nigori.encrypted().blob().empty()) {
+ if (CanDecrypt(nigori.encrypted())) {
+ SetKeys(nigori.encrypted());
+ return Cryptographer::SUCCESS;
+ } else {
+ SetPendingKeys(nigori.encrypted());
+ return Cryptographer::NEEDS_PASSPHRASE;
+ }
+ }
+ return Cryptographer::SUCCESS;
+}
+
+void Cryptographer::SetEncryptedTypes(const sync_pb::NigoriSpecifics& nigori) {
+ encrypted_types_.clear();
+ if (nigori.encrypt_bookmarks())
+ encrypted_types_.insert(syncable::BOOKMARKS);
+ if (nigori.encrypt_preferences())
+ encrypted_types_.insert(syncable::PREFERENCES);
+ if (nigori.encrypt_autofill_profile())
+ encrypted_types_.insert(syncable::AUTOFILL_PROFILE);
+ if (nigori.encrypt_autofill())
+ encrypted_types_.insert(syncable::AUTOFILL);
+ if (nigori.encrypt_themes())
+ encrypted_types_.insert(syncable::THEMES);
+ if (nigori.encrypt_typed_urls())
+ encrypted_types_.insert(syncable::TYPED_URLS);
+ if (nigori.encrypt_extensions())
+ encrypted_types_.insert(syncable::EXTENSIONS);
+ if (nigori.encrypt_sessions())
+ encrypted_types_.insert(syncable::SESSIONS);
+ if (nigori.encrypt_apps())
+ encrypted_types_.insert(syncable::APPS);
+ encrypted_types_.insert(syncable::PASSWORDS);
+}
+
+syncable::ModelTypeSet Cryptographer::GetEncryptedTypes() const {
+ return encrypted_types_;
+}
+
void Cryptographer::InstallKeys(const std::string& default_key_name,
const sync_pb::NigoriKeyBag& bag) {
int key_size = bag.key_size();
diff --git a/chrome/browser/sync/util/cryptographer.h b/chrome/browser/sync/util/cryptographer.h
index 843b928e..050ea64 100644
--- a/chrome/browser/sync/util/cryptographer.h
+++ b/chrome/browser/sync/util/cryptographer.h
@@ -13,6 +13,7 @@
#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/sync/protocol/nigori_specifics.pb.h"
+#include "chrome/browser/sync/syncable/model_type.h"
#include "chrome/browser/sync/util/nigori.h"
namespace browser_sync {
@@ -45,6 +46,14 @@ class Cryptographer {
Cryptographer();
~Cryptographer();
+ // When update on cryptographer is called this enum tells if the
+ // cryptographer was succesfully able to update using the nigori node or if
+ // it needs a key to decrypt the nigori node.
+ enum UpdateResult {
+ SUCCESS,
+ NEEDS_PASSPHRASE
+ };
+
// |restored_bootstrap_token| can be provided via this method to bootstrap
// Cryptographer instance into the ready state (is_ready will be true).
// It must be a string that was previously built by the
@@ -117,6 +126,10 @@ class Cryptographer {
// can't be created (i.e. if this Cryptograhper doesn't have valid keys).
bool GetBootstrapToken(std::string* token) const;
+ UpdateResult Update(const sync_pb::NigoriSpecifics& nigori);
+ void SetEncryptedTypes(const sync_pb::NigoriSpecifics& nigori);
+ syncable::ModelTypeSet GetEncryptedTypes() const;
+
private:
FRIEND_TEST_ALL_PREFIXES(CryptographerTest, PackUnpack);
typedef std::map<std::string, linked_ptr<const Nigori> > NigoriMap;
@@ -139,6 +152,8 @@ class Cryptographer {
scoped_ptr<sync_pb::EncryptedData> pending_keys_;
+ syncable::ModelTypeSet encrypted_types_;
+
DISALLOW_COPY_AND_ASSIGN(Cryptographer);
};
diff --git a/chrome/test/live_sync/live_passwords_sync_test.h b/chrome/test/live_sync/live_passwords_sync_test.h
index 56ad495..9d0e621 100644
--- a/chrome/test/live_sync/live_passwords_sync_test.h
+++ b/chrome/test/live_sync/live_passwords_sync_test.h
@@ -92,7 +92,7 @@ class LivePasswordsSyncTest : public LiveSyncTest {
// Creates a test password form with a well known fake signon realm used only
// by LivePasswordsSyncTest based on |index|.
- webkit_glue::PasswordForm CreateTestPasswordForm(int index);
+ static webkit_glue::PasswordForm CreateTestPasswordForm(int index);
private:
// Cleans up all password forms ever added by LivePasswordsSyncTest. This is
diff --git a/chrome/test/live_sync/migration_errors_test.cc b/chrome/test/live_sync/migration_errors_test.cc
index db765e3..e0af843 100644
--- a/chrome/test/live_sync/migration_errors_test.cc
+++ b/chrome/test/live_sync/migration_errors_test.cc
@@ -193,7 +193,7 @@ IN_PROC_BROWSER_TEST_F(MigrationErrorsTest, MigrationHellWithoutNigori) {
// Fails because the client doesn't know how to not sync NIGORI.
// TODO(timsteele): Fix http://crbug.com/80333 and re-enable.
IN_PROC_BROWSER_TEST_F(TwoClientLivePreferencesSyncTest,
- DISABLED_MigrationHellWithNigori) {
+ MigrationHellWithNigori) {
if (!ServerSupportsErrorTriggering()) {
LOG(WARNING) << "Test skipped in this server environment.";
return;
@@ -222,6 +222,10 @@ IN_PROC_BROWSER_TEST_F(TwoClientLivePreferencesSyncTest,
TriggerMigrationDoneError(migrate_themes);
for (int i = syncable::FIRST_REAL_MODEL_TYPE; i < syncable::MODEL_TYPE_COUNT;
++i) {
+ // TODO(lipalani): If all types are disabled syncer freaks out. Fix it.
+ if (i == syncable::BOOKMARKS) {
+ continue;
+ }
syncable::ModelTypeSet migrate_types;
migrate_types.insert(syncable::ModelTypeFromInt(i));
TriggerMigrationDoneError(migrate_types);