summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync
diff options
context:
space:
mode:
authorrlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-10 00:12:43 +0000
committerrlarocque@chromium.org <rlarocque@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-10 00:12:43 +0000
commit544df7c7697ec1e7d2005b953ed5983114268ad5 (patch)
treef53cb83aec69713ebecb183b20b94f9d22049e32 /chrome/browser/sync
parenta412766e7694f0798984be2680e243109ca94e76 (diff)
downloadchromium_src-544df7c7697ec1e7d2005b953ed5983114268ad5.zip
chromium_src-544df7c7697ec1e7d2005b953ed5983114268ad5.tar.gz
chromium_src-544df7c7697ec1e7d2005b953ed5983114268ad5.tar.bz2
Handle duplicate password sync nodes
If the PasswordStore is asked to add an entry that already exists it will overwrite the existing entry. When this happens, it will report a PasswordStoreChange::ADD event, much like it would had the original entry not existed. This confuses the PasswordChangeProcessor which assumes that an ADD event implies that the added item did not previously exist. This change works around the issue by allowing the password change processor to try to update an existing node in the event that the creation of a new node fails. This allows it to handle the case where a it receives an ADD event for an existing node. A better solution would be to have the PasswordStore to always return an UPDATE event in cases where the node being updated already exists. If that solution were implemented the PasswordChangeProcessor would be right to report an UnrecoverableError if it is unable to create a new sync node in response to an ADD event. BUG=87855 TEST=See repro steps in crbug.com/87855, crbug.com/103455 Review URL: http://codereview.chromium.org/8862005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113888 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/sync')
-rw-r--r--chrome/browser/sync/glue/password_change_processor.cc38
1 files changed, 29 insertions, 9 deletions
diff --git a/chrome/browser/sync/glue/password_change_processor.cc b/chrome/browser/sync/glue/password_change_processor.cc
index 180a796..432b293 100644
--- a/chrome/browser/sync/glue/password_change_processor.cc
+++ b/chrome/browser/sync/glue/password_change_processor.cc
@@ -81,16 +81,36 @@ void PasswordChangeProcessor::Observe(
switch (change->type()) {
case PasswordStoreChange::ADD: {
sync_api::WriteNode sync_node(&trans);
- if (!sync_node.InitUniqueByCreation(syncable::PASSWORDS,
- password_root, tag)) {
- error_handler()->OnUnrecoverableError(FROM_HERE,
- "Failed to create password sync node.");
- return;
+ if (sync_node.InitUniqueByCreation(syncable::PASSWORDS,
+ password_root, tag)) {
+ PasswordModelAssociator::WriteToSyncNode(change->form(), &sync_node);
+ model_associator_->Associate(&tag, sync_node.GetId());
+ break;
+ } else {
+ // Maybe this node already exists and we should update it.
+ //
+ // If the PasswordStore is told to add an entry but an entry with the
+ // same name already exists, it will overwrite it. It will report
+ // this change as an ADD rather than an UPDATE. Ideally, it would be
+ // able to tell us what action was actually taken, rather than what
+ // action was requested. If it did so, we wouldn't need to fall back
+ // to trying to update an existing password node here.
+ //
+ // TODO: Remove this. See crbug.com/87855.
+ int64 sync_id = model_associator_->GetSyncIdFromChromeId(tag);
+ if (sync_api::kInvalidId == sync_id) {
+ error_handler()->OnUnrecoverableError(FROM_HERE,
+ "Unable to create or retrieve password node");
+ return;
+ }
+ if (!sync_node.InitByIdLookup(sync_id)) {
+ error_handler()->OnUnrecoverableError(FROM_HERE,
+ "Unable to create or retrieve password node");
+ return;
+ }
+ PasswordModelAssociator::WriteToSyncNode(change->form(), &sync_node);
+ break;
}
-
- PasswordModelAssociator::WriteToSyncNode(change->form(), &sync_node);
- model_associator_->Associate(&tag, sync_node.GetId());
- break;
}
case PasswordStoreChange::UPDATE: {
sync_api::WriteNode sync_node(&trans);