Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/sync/profile_sync_service.h" | 5 #include "chrome/browser/sync/profile_sync_service.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <ostream> | 9 #include <ostream> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 361 types, | 361 types, |
| 362 credentials, | 362 credentials, |
| 363 delete_sync_data_folder); | 363 delete_sync_data_folder); |
| 364 } | 364 } |
| 365 | 365 |
| 366 void ProfileSyncService::CreateBackend() { | 366 void ProfileSyncService::CreateBackend() { |
| 367 backend_.reset(new SyncBackendHost(profile_)); | 367 backend_.reset(new SyncBackendHost(profile_)); |
| 368 } | 368 } |
| 369 | 369 |
| 370 bool ProfileSyncService::IsEncryptedDatatypeEnabled() const { | 370 bool ProfileSyncService::IsEncryptedDatatypeEnabled() const { |
| 371 if (!pending_types_for_encryption_.empty()) | |
| 372 return true; | |
| 371 syncable::ModelTypeSet preferred_types; | 373 syncable::ModelTypeSet preferred_types; |
| 372 GetPreferredDataTypes(&preferred_types); | 374 GetPreferredDataTypes(&preferred_types); |
| 373 syncable::ModelTypeSet encrypted_types; | 375 syncable::ModelTypeSet encrypted_types; |
| 374 GetEncryptedDataTypes(&encrypted_types); | 376 GetEncryptedDataTypes(&encrypted_types); |
| 375 syncable::ModelTypeBitSet preferred_types_bitset = | 377 syncable::ModelTypeBitSet preferred_types_bitset = |
| 376 syncable::ModelTypeBitSetFromSet(preferred_types); | 378 syncable::ModelTypeBitSetFromSet(preferred_types); |
| 377 syncable::ModelTypeBitSet encrypted_types_bitset = | 379 syncable::ModelTypeBitSet encrypted_types_bitset = |
| 378 syncable::ModelTypeBitSetFromSet(encrypted_types); | 380 syncable::ModelTypeBitSetFromSet(encrypted_types); |
| 379 DCHECK(encrypted_types.count(syncable::PASSWORDS)); | 381 DCHECK(encrypted_types.count(syncable::PASSWORDS)); |
| 380 return (preferred_types_bitset & encrypted_types_bitset).any(); | 382 return (preferred_types_bitset & encrypted_types_bitset).any(); |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 679 } | 681 } |
| 680 | 682 |
| 681 VLOG(1) << "Passphrase required with reason: " | 683 VLOG(1) << "Passphrase required with reason: " |
| 682 << sync_api::PassphraseRequiredReasonToString(reason); | 684 << sync_api::PassphraseRequiredReasonToString(reason); |
| 683 passphrase_required_reason_ = reason; | 685 passphrase_required_reason_ = reason; |
| 684 | 686 |
| 685 // We will skip the passphrase prompt and suppress the warning if the | 687 // We will skip the passphrase prompt and suppress the warning if the |
| 686 // passphrase is needed for decryption but the user is not syncing an | 688 // passphrase is needed for decryption but the user is not syncing an |
| 687 // encrypted data type on this machine. Otherwise we look for one. | 689 // encrypted data type on this machine. Otherwise we look for one. |
| 688 if (!IsEncryptedDatatypeEnabled() && IsPassphraseRequiredForDecryption()) { | 690 if (!IsEncryptedDatatypeEnabled() && IsPassphraseRequiredForDecryption()) { |
| 689 VLOG(1) << "Not decrypting and no encrypted datatypes enabled" | 691 VLOG(1) << "Decrypting and no encrypted datatypes enabled" |
| 690 << ", accepted passphrase."; | 692 << ", accepted passphrase."; |
| 691 OnPassphraseAccepted(); | 693 OnPassphraseAccepted(); |
| 692 } | 694 } |
| 693 | 695 |
| 694 // First try supplying gaia password as the passphrase. | 696 // First try supplying gaia password as the passphrase. |
| 695 if (!gaia_password_.empty()) { | 697 if (!gaia_password_.empty()) { |
| 696 VLOG(1) << "Attempting gaia passphrase."; | 698 VLOG(1) << "Attempting gaia passphrase."; |
| 697 SetPassphrase(gaia_password_, false, true); | 699 std::string pass = gaia_password_; |
| 698 gaia_password_ = std::string(); | 700 gaia_password_ = std::string(); |
| 701 // May set gaia_password_ if the syncer isn't ready. | |
| 702 SetPassphrase(pass, false, true); | |
| 699 return; | 703 return; |
| 700 } | 704 } |
| 701 | 705 |
| 702 // If the above failed then try the custom passphrase the user might have | 706 // If the above failed then try the custom passphrase the user might have |
| 703 // entered in setup. | 707 // entered in setup. |
| 704 if (!cached_passphrase_.value.empty()) { | 708 if (!cached_passphrase_.value.empty()) { |
| 705 VLOG(1) << "Attempting cached passphrase."; | 709 VLOG(1) << "Attempting cached passphrase."; |
| 706 SetPassphrase(cached_passphrase_.value, | 710 std::string pass = cached_passphrase_.value; |
| 707 cached_passphrase_.is_explicit, | 711 bool is_explicit = cached_passphrase_.is_explicit; |
| 708 cached_passphrase_.is_creation); | 712 bool is_creation = cached_passphrase_.is_creation; |
| 709 cached_passphrase_ = CachedPassphrase(); | 713 cached_passphrase_ = CachedPassphrase(); |
| 714 // May set cached_passphrase_ is the syncer isn't ready. | |
| 715 SetPassphrase(pass, is_explicit, is_creation); | |
| 710 return; | 716 return; |
| 711 } | 717 } |
| 712 | 718 |
| 713 // Prompt the user for a password. | 719 // Prompt the user for a password. |
| 714 if (WizardIsVisible() && IsEncryptedDatatypeEnabled() && | 720 if (WizardIsVisible() && IsEncryptedDatatypeEnabled() && |
| 715 IsPassphraseRequiredForDecryption()) { | 721 IsPassphraseRequiredForDecryption()) { |
| 716 VLOG(1) << "Prompting user for passphrase."; | 722 VLOG(1) << "Prompting user for passphrase."; |
| 717 wizard_.Step(SyncSetupWizard::ENTER_PASSPHRASE); | 723 wizard_.Step(SyncSetupWizard::ENTER_PASSPHRASE); |
| 718 } | 724 } |
| 719 | 725 |
| 720 NotifyObservers(); | 726 NotifyObservers(); |
| 721 } | 727 } |
| 722 | 728 |
| 723 void ProfileSyncService::OnPassphraseAccepted() { | 729 void ProfileSyncService::OnPassphraseAccepted() { |
| 724 VLOG(1) << "Received OnPassphraseAccepted."; | 730 VLOG(1) << "Received OnPassphraseAccepted."; |
| 731 // Don't hold on to a passphrase in raw form longer than needed. | |
| 732 gaia_password_ = std::string(); | |
| 733 cached_passphrase_ = CachedPassphrase(); | |
| 734 | |
| 725 // Make sure the data types that depend on the passphrase are started at | 735 // Make sure the data types that depend on the passphrase are started at |
| 726 // this time. | 736 // this time. |
| 727 syncable::ModelTypeSet types; | 737 syncable::ModelTypeSet types; |
| 728 GetPreferredDataTypes(&types); | 738 GetPreferredDataTypes(&types); |
| 729 | 739 |
| 730 // Reset passphrase_required_reason_ before configuring the DataTypeManager | 740 // Reset passphrase_required_reason_ before configuring the DataTypeManager |
| 731 // since we know we no longer require the passphrase. | 741 // since we know we no longer require the passphrase. |
| 732 passphrase_required_reason_ = sync_api::REASON_PASSPHRASE_NOT_REQUIRED; | 742 passphrase_required_reason_ = sync_api::REASON_PASSPHRASE_NOT_REQUIRED; |
| 733 | 743 |
| 734 if (data_type_manager_.get()) { | 744 if (data_type_manager_.get()) { |
| 735 // Unblock the data type manager if necessary. | 745 // Unblock the data type manager if necessary. |
| 736 // This will always trigger a SYNC_CONFIGURE_DONE on completion, which will | 746 // This will always trigger a SYNC_CONFIGURE_DONE on completion, which will |
| 737 // step the UI wizard into DONE state (even if no datatypes have changed). | 747 // step the UI wizard into DONE state (even if no datatypes have changed). |
| 738 data_type_manager_->Configure(types, | 748 data_type_manager_->Configure(types, |
| 739 sync_api::CONFIGURE_REASON_RECONFIGURATION); | 749 sync_api::CONFIGURE_REASON_RECONFIGURATION); |
| 740 } | 750 } |
| 741 | 751 |
| 742 NotifyObservers(); | 752 NotifyObservers(); |
| 743 } | 753 } |
| 744 | 754 |
| 745 void ProfileSyncService::OnEncryptionComplete( | 755 void ProfileSyncService::OnEncryptionComplete( |
| 746 const syncable::ModelTypeSet& encrypted_types) { | 756 const syncable::ModelTypeSet& encrypted_types) { |
| 757 if (!pending_types_for_encryption_.empty()) { | |
| 758 // The user had chosen to encrypt datatypes. This is the last thing to | |
| 759 // complete, so now that we're done notify the UI. | |
| 760 wizard_.Step(SyncSetupWizard::DONE); | |
|
Nicolas Zea
2011/08/02 21:18:26
This works because encryption only occurs in the S
| |
| 761 } | |
| 762 pending_types_for_encryption_.clear(); | |
| 747 NotifyObservers(); | 763 NotifyObservers(); |
| 748 } | 764 } |
| 749 | 765 |
| 750 void ProfileSyncService::OnMigrationNeededForTypes( | 766 void ProfileSyncService::OnMigrationNeededForTypes( |
| 751 const syncable::ModelTypeSet& types) { | 767 const syncable::ModelTypeSet& types) { |
| 752 DCHECK(backend_initialized_); | 768 DCHECK(backend_initialized_); |
| 753 DCHECK(data_type_manager_.get()); | 769 DCHECK(data_type_manager_.get()); |
| 754 | 770 |
| 755 // Migrator must be valid, because we don't sync until it is created and this | 771 // Migrator must be valid, because we don't sync until it is created and this |
| 756 // callback originates from a sync cycle. | 772 // callback originates from a sync cycle. |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1160 if (!backend_.get()) | 1176 if (!backend_.get()) |
| 1161 return; | 1177 return; |
| 1162 backend_->DeactivateDataType(data_type_controller, change_processor); | 1178 backend_->DeactivateDataType(data_type_controller, change_processor); |
| 1163 } | 1179 } |
| 1164 | 1180 |
| 1165 void ProfileSyncService::SetPassphrase(const std::string& passphrase, | 1181 void ProfileSyncService::SetPassphrase(const std::string& passphrase, |
| 1166 bool is_explicit, | 1182 bool is_explicit, |
| 1167 bool is_creation) { | 1183 bool is_creation) { |
| 1168 if (ShouldPushChanges() || IsPassphraseRequired()) { | 1184 if (ShouldPushChanges() || IsPassphraseRequired()) { |
| 1169 VLOG(1) << "Setting " << (is_explicit ? "explicit" : "implicit") | 1185 VLOG(1) << "Setting " << (is_explicit ? "explicit" : "implicit") |
| 1170 << " passphrase " << (is_creation ? " for creation" : ""); | 1186 << " passphrase" << (is_creation ? " for creation" : ""); |
| 1171 backend_->SetPassphrase(passphrase, is_explicit); | 1187 backend_->SetPassphrase(passphrase, is_explicit); |
| 1172 } else { | 1188 } else { |
| 1173 if (is_explicit) { | 1189 if (is_explicit) { |
| 1174 cached_passphrase_.value = passphrase; | 1190 cached_passphrase_.value = passphrase; |
| 1175 cached_passphrase_.is_explicit = is_explicit; | 1191 cached_passphrase_.is_explicit = is_explicit; |
| 1176 cached_passphrase_.is_creation = is_creation; | 1192 cached_passphrase_.is_creation = is_creation; |
| 1177 } else { | 1193 } else { |
| 1178 gaia_password_ = passphrase; | 1194 gaia_password_ = passphrase; |
| 1179 } | 1195 } |
| 1180 } | 1196 } |
| 1181 } | 1197 } |
| 1182 | 1198 |
| 1183 void ProfileSyncService::EncryptDataTypes( | 1199 void ProfileSyncService::EncryptDataTypes( |
| 1184 const syncable::ModelTypeSet& encrypted_types) { | 1200 const syncable::ModelTypeSet& encrypted_types) { |
| 1185 if (HasSyncSetupCompleted()) { | 1201 if (encrypted_types.empty()) { |
| 1186 backend_->EncryptDataTypes(encrypted_types); | 1202 // We can't unencrypt types. |
| 1203 VLOG(1) << "No datatypes set for encryption, dropping encryption request."; | |
| 1187 pending_types_for_encryption_.clear(); | 1204 pending_types_for_encryption_.clear(); |
|
Nicolas Zea
2011/08/02 21:18:26
This call will be combined with a configuredatatyp
| |
| 1188 } else { | 1205 return; |
| 1189 pending_types_for_encryption_ = encrypted_types; | |
| 1190 } | 1206 } |
| 1207 // We require that every call to EncryptDatatypes be coupled with a | |
| 1208 // ConfigureDataTypeManager. The actual call to encrypt the datatypes happens | |
| 1209 // after SYNC_CONFIGURE_DONE, to ensure we've downloaded any new datatypes | |
| 1210 // before beginning encryption. | |
| 1211 // TODO(zea): This is very brittle and relies on ConfigureDataTypes being | |
| 1212 // called after the encryptdatatypes in sync_setup_flow.cc. Fix this. | |
| 1213 pending_types_for_encryption_ = encrypted_types; | |
| 1191 } | 1214 } |
| 1192 | 1215 |
| 1193 // This would open a transaction to get the encrypted types. Do not call this | 1216 // This will open a transaction to get the encrypted types. Do not call this |
| 1194 // if you already have a transaction open. | 1217 // if you already have a transaction open. |
| 1195 void ProfileSyncService::GetEncryptedDataTypes( | 1218 void ProfileSyncService::GetEncryptedDataTypes( |
| 1196 syncable::ModelTypeSet* encrypted_types) const { | 1219 syncable::ModelTypeSet* encrypted_types) const { |
| 1197 CHECK(encrypted_types); | 1220 CHECK(encrypted_types); |
| 1198 if (backend_.get()) { | 1221 if (backend_.get()) { |
| 1199 *encrypted_types = backend_->GetEncryptedDataTypes(); | 1222 *encrypted_types = backend_->GetEncryptedDataTypes(); |
| 1200 DCHECK(encrypted_types->count(syncable::PASSWORDS)); | 1223 DCHECK(encrypted_types->count(syncable::PASSWORDS)); |
| 1201 } else { | 1224 } else { |
| 1202 // Either we are in an unrecoverable error or the sync is not yet done | 1225 // Either we are in an unrecoverable error or the sync is not yet done |
| 1203 // initializing. In either case just return the password type. During | 1226 // initializing. In either case just return the password type. During |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1221 Details<DataTypeManager::ConfigureResult>(details).ptr(); | 1244 Details<DataTypeManager::ConfigureResult>(details).ptr(); |
| 1222 | 1245 |
| 1223 DataTypeManager::ConfigureStatus status = result->status; | 1246 DataTypeManager::ConfigureStatus status = result->status; |
| 1224 VLOG(1) << "PSS SYNC_CONFIGURE_DONE called with status: " << status; | 1247 VLOG(1) << "PSS SYNC_CONFIGURE_DONE called with status: " << status; |
| 1225 if (status == DataTypeManager::ABORTED && | 1248 if (status == DataTypeManager::ABORTED && |
| 1226 expect_sync_configuration_aborted_) { | 1249 expect_sync_configuration_aborted_) { |
| 1227 VLOG(0) << "ProfileSyncService::Observe Sync Configure aborted"; | 1250 VLOG(0) << "ProfileSyncService::Observe Sync Configure aborted"; |
| 1228 expect_sync_configuration_aborted_ = false; | 1251 expect_sync_configuration_aborted_ = false; |
| 1229 return; | 1252 return; |
| 1230 } | 1253 } |
| 1231 // Clear out the gaia password if it is already there. | |
| 1232 gaia_password_ = std::string(); | |
| 1233 if (status != DataTypeManager::OK) { | 1254 if (status != DataTypeManager::OK) { |
| 1234 VLOG(0) << "ProfileSyncService::Observe: Unrecoverable error detected"; | 1255 VLOG(0) << "ProfileSyncService::Observe: Unrecoverable error detected"; |
| 1235 std::string message = | 1256 std::string message = |
| 1236 "Sync Configuration failed while configuring " + | 1257 "Sync Configuration failed while configuring " + |
| 1237 syncable::ModelTypeSetToString(result->failed_types) + | 1258 syncable::ModelTypeSetToString(result->failed_types) + |
| 1238 ": " + DataTypeManager::ConfigureStatusToString(status); | 1259 ": " + DataTypeManager::ConfigureStatusToString(status); |
| 1239 OnUnrecoverableError(result->location, message); | 1260 OnUnrecoverableError(result->location, message); |
| 1240 cached_passphrase_ = CachedPassphrase(); | 1261 cached_passphrase_ = CachedPassphrase(); |
| 1241 return; | 1262 return; |
| 1242 } | 1263 } |
| 1243 | 1264 |
| 1244 // If the user had entered a custom passphrase use it now. | |
|
Nicolas Zea
2011/08/02 21:18:26
This all now happens in OnPassphraseRequired and O
| |
| 1245 if (!cached_passphrase_.value.empty()) { | |
| 1246 // Don't hold on to the passphrase in raw form longer than needed. | |
| 1247 SetPassphrase(cached_passphrase_.value, | |
| 1248 cached_passphrase_.is_explicit, | |
| 1249 cached_passphrase_.is_creation); | |
| 1250 cached_passphrase_ = CachedPassphrase(); | |
| 1251 } | |
| 1252 | |
| 1253 // We should never get in a state where we have no encrypted datatypes | 1265 // We should never get in a state where we have no encrypted datatypes |
| 1254 // enabled, and yet we still think we require a passphrase for decryption. | 1266 // enabled, and yet we still think we require a passphrase for decryption. |
| 1255 DCHECK(!(IsPassphraseRequiredForDecryption() && | 1267 DCHECK(!(IsPassphraseRequiredForDecryption() && |
| 1256 !IsEncryptedDatatypeEnabled())); | 1268 !IsEncryptedDatatypeEnabled())); |
| 1257 | 1269 |
| 1258 // TODO(sync): Less wizard, more toast. | 1270 if (!gaia_password_.empty()) { |
| 1259 wizard_.Step(SyncSetupWizard::DONE); | 1271 // If we haven't yet attempted to set the gaia passphrase use it now. |
| 1260 NotifyObservers(); | 1272 SetPassphrase(gaia_password_, false, true); |
| 1273 gaia_password_ = std::string(); | |
| 1274 } else if (!cached_passphrase_.value.empty()) { | |
| 1275 // If the user had entered a custom passphrase use it now. | |
| 1276 SetPassphrase(cached_passphrase_.value, | |
| 1277 cached_passphrase_.is_explicit, | |
| 1278 cached_passphrase_.is_creation); | |
| 1279 cached_passphrase_ = CachedPassphrase(); | |
| 1280 } | |
| 1281 | |
| 1261 | 1282 |
| 1262 // In the old world, this would be a no-op. With new syncer thread, | 1283 // In the old world, this would be a no-op. With new syncer thread, |
| 1263 // this is the point where it is safe to switch from config-mode to | 1284 // this is the point where it is safe to switch from config-mode to |
| 1264 // normal operation. | 1285 // normal operation. |
| 1265 backend_->StartSyncingWithServer(); | 1286 backend_->StartSyncingWithServer(); |
| 1266 | 1287 |
| 1267 if (!pending_types_for_encryption_.empty()) { | 1288 if (pending_types_for_encryption_.empty()) { |
| 1268 EncryptDataTypes(pending_types_for_encryption_); | 1289 // TODO(sync): Less wizard, more toast. |
| 1269 pending_types_for_encryption_.clear(); | 1290 wizard_.Step(SyncSetupWizard::DONE); |
| 1291 NotifyObservers(); | |
| 1292 } else { | |
| 1293 // Will clear pending_types_for_encryption_ on success. Has no effect | |
| 1294 // if pending_types_for_encryption_ matches the encrypted types. | |
| 1295 backend_->EncryptDataTypes(pending_types_for_encryption_); | |
| 1270 } | 1296 } |
| 1271 break; | 1297 break; |
| 1272 } | 1298 } |
| 1273 case chrome::NOTIFICATION_PREF_CHANGED: { | 1299 case chrome::NOTIFICATION_PREF_CHANGED: { |
| 1274 std::string* pref_name = Details<std::string>(details).ptr(); | 1300 std::string* pref_name = Details<std::string>(details).ptr(); |
| 1275 if (*pref_name == prefs::kSyncManaged) { | 1301 if (*pref_name == prefs::kSyncManaged) { |
| 1276 NotifyObservers(); | 1302 NotifyObservers(); |
| 1277 if (*pref_sync_managed_) { | 1303 if (*pref_sync_managed_) { |
| 1278 DisableForUser(); | 1304 DisableForUser(); |
| 1279 } else if (HasSyncSetupCompleted() && AreCredentialsAvailable()) { | 1305 } else if (HasSyncSetupCompleted() && AreCredentialsAvailable()) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1369 // is initialized, all enabled data types are consistent with one | 1395 // is initialized, all enabled data types are consistent with one |
| 1370 // another, and no unrecoverable error has transpired. | 1396 // another, and no unrecoverable error has transpired. |
| 1371 if (unrecoverable_error_detected_) | 1397 if (unrecoverable_error_detected_) |
| 1372 return false; | 1398 return false; |
| 1373 | 1399 |
| 1374 if (!data_type_manager_.get()) | 1400 if (!data_type_manager_.get()) |
| 1375 return false; | 1401 return false; |
| 1376 | 1402 |
| 1377 return data_type_manager_->state() == DataTypeManager::CONFIGURED; | 1403 return data_type_manager_->state() == DataTypeManager::CONFIGURED; |
| 1378 } | 1404 } |
| OLD | NEW |