Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(685)

Side by Side Diff: chrome/browser/sync/glue/password_model_associator.cc

Issue 7453014: [Sync] Refactor sync datatype error handling. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase and fix final unit test <3 c++ Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/glue/password_model_associator.h" 5 #include "chrome/browser/sync/glue/password_model_associator.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "base/tracked.h" 10 #include "base/tracked.h"
11 #include "base/utf_string_conversions.h" 11 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/password_manager/password_store.h" 12 #include "chrome/browser/password_manager/password_store.h"
13 #include "chrome/browser/sync/api/sync_error.h"
13 #include "chrome/browser/sync/engine/syncapi.h" 14 #include "chrome/browser/sync/engine/syncapi.h"
14 #include "chrome/browser/sync/profile_sync_service.h" 15 #include "chrome/browser/sync/profile_sync_service.h"
15 #include "chrome/browser/sync/protocol/password_specifics.pb.h" 16 #include "chrome/browser/sync/protocol/password_specifics.pb.h"
16 #include "net/base/escape.h" 17 #include "net/base/escape.h"
17 #include "webkit/glue/password_form.h" 18 #include "webkit/glue/password_form.h"
18 19
19 namespace browser_sync { 20 namespace browser_sync {
20 21
21 const char kPasswordTag[] = "google_chrome_passwords"; 22 const char kPasswordTag[] = "google_chrome_passwords";
22 23
23 PasswordModelAssociator::PasswordModelAssociator( 24 PasswordModelAssociator::PasswordModelAssociator(
24 ProfileSyncService* sync_service, 25 ProfileSyncService* sync_service,
25 PasswordStore* password_store) 26 PasswordStore* password_store)
26 : sync_service_(sync_service), 27 : sync_service_(sync_service),
27 password_store_(password_store), 28 password_store_(password_store),
28 password_node_id_(sync_api::kInvalidId), 29 password_node_id_(sync_api::kInvalidId),
29 abort_association_pending_(false), 30 abort_association_pending_(false),
30 expected_loop_(MessageLoop::current()) { 31 expected_loop_(MessageLoop::current()) {
31 DCHECK(sync_service_); 32 DCHECK(sync_service_);
32 DCHECK(password_store_); 33 DCHECK(password_store_);
33 #if defined(OS_MACOSX) 34 #if defined(OS_MACOSX)
34 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI)); 35 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
35 #else 36 #else
36 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 37 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
37 #endif 38 #endif
38 } 39 }
39 40
40 PasswordModelAssociator::~PasswordModelAssociator() {} 41 PasswordModelAssociator::~PasswordModelAssociator() {}
41 42
42 bool PasswordModelAssociator::AssociateModels() { 43 bool PasswordModelAssociator::AssociateModels(SyncError* error) {
43 DCHECK(expected_loop_ == MessageLoop::current()); 44 DCHECK(expected_loop_ == MessageLoop::current());
44 { 45 {
45 base::AutoLock lock(abort_association_pending_lock_); 46 base::AutoLock lock(abort_association_pending_lock_);
46 abort_association_pending_ = false; 47 abort_association_pending_ = false;
47 } 48 }
48 49
49 // We must not be holding a transaction when we interact with the password 50 // We must not be holding a transaction when we interact with the password
50 // store, as it can post tasks to the UI thread which can itself be blocked 51 // store, as it can post tasks to the UI thread which can itself be blocked
51 // on our transaction, resulting in deadlock. (http://crbug.com/70658) 52 // on our transaction, resulting in deadlock. (http://crbug.com/70658)
52 std::vector<webkit_glue::PasswordForm*> passwords; 53 std::vector<webkit_glue::PasswordForm*> passwords;
53 if (!password_store_->FillAutofillableLogins(&passwords) || 54 if (!password_store_->FillAutofillableLogins(&passwords) ||
54 !password_store_->FillBlacklistLogins(&passwords)) { 55 !password_store_->FillBlacklistLogins(&passwords)) {
55 STLDeleteElements(&passwords); 56 STLDeleteElements(&passwords);
56 LOG(ERROR) << "Could not get the password entries."; 57 error->Reset(FROM_HERE,
58 "Could not get the password entries.",
59 model_type());
57 return false; 60 return false;
58 } 61 }
59 62
60 std::set<std::string> current_passwords; 63 std::set<std::string> current_passwords;
61 PasswordVector new_passwords; 64 PasswordVector new_passwords;
62 PasswordVector updated_passwords; 65 PasswordVector updated_passwords;
63 { 66 {
64 sync_api::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare()); 67 sync_api::WriteTransaction trans(FROM_HERE, sync_service_->GetUserShare());
65 sync_api::ReadNode password_root(&trans); 68 sync_api::ReadNode password_root(&trans);
66 if (!password_root.InitByTagLookup(kPasswordTag)) { 69 if (!password_root.InitByTagLookup(kPasswordTag)) {
67 LOG(ERROR) << "Server did not create the top-level password node. We " 70 error->Reset(FROM_HERE,
68 << "might be running against an out-of-date server."; 71 "Server did not create the top-level password node. We "
72 "might be running against an out-of-date server.",
73 model_type());
69 return false; 74 return false;
70 } 75 }
71 76
72 for (std::vector<webkit_glue::PasswordForm*>::iterator ix = 77 for (std::vector<webkit_glue::PasswordForm*>::iterator ix =
73 passwords.begin(); 78 passwords.begin();
74 ix != passwords.end(); ++ix) { 79 ix != passwords.end(); ++ix) {
75 if (IsAbortPending()) 80 if (IsAbortPending()) {
81 error->Reset(FROM_HERE, "Abort pending", model_type());
76 return false; 82 return false;
83 }
77 std::string tag = MakeTag(**ix); 84 std::string tag = MakeTag(**ix);
78 85
79 sync_api::ReadNode node(&trans); 86 sync_api::ReadNode node(&trans);
80 if (node.InitByClientTagLookup(syncable::PASSWORDS, tag)) { 87 if (node.InitByClientTagLookup(syncable::PASSWORDS, tag)) {
81 const sync_pb::PasswordSpecificsData& password = 88 const sync_pb::PasswordSpecificsData& password =
82 node.GetPasswordSpecifics(); 89 node.GetPasswordSpecifics();
83 DCHECK_EQ(tag, MakeTag(password)); 90 DCHECK_EQ(tag, MakeTag(password));
84 91
85 webkit_glue::PasswordForm new_password; 92 webkit_glue::PasswordForm new_password;
86 93
87 if (MergePasswords(password, **ix, &new_password)) { 94 if (MergePasswords(password, **ix, &new_password)) {
88 sync_api::WriteNode write_node(&trans); 95 sync_api::WriteNode write_node(&trans);
89 if (!write_node.InitByClientTagLookup(syncable::PASSWORDS, tag)) { 96 if (!write_node.InitByClientTagLookup(syncable::PASSWORDS, tag)) {
90 STLDeleteElements(&passwords); 97 STLDeleteElements(&passwords);
91 LOG(ERROR) << "Failed to edit password sync node."; 98 error->Reset(FROM_HERE,
99 "Failed to edit password sync node.",
100 model_type());
92 return false; 101 return false;
93 } 102 }
94 WriteToSyncNode(new_password, &write_node); 103 WriteToSyncNode(new_password, &write_node);
95 updated_passwords.push_back(new_password); 104 updated_passwords.push_back(new_password);
96 } 105 }
97 106
98 Associate(&tag, node.GetId()); 107 Associate(&tag, node.GetId());
99 } else { 108 } else {
100 sync_api::WriteNode node(&trans); 109 sync_api::WriteNode node(&trans);
101 if (!node.InitUniqueByCreation(syncable::PASSWORDS, 110 if (!node.InitUniqueByCreation(syncable::PASSWORDS,
102 password_root, tag)) { 111 password_root, tag)) {
103 STLDeleteElements(&passwords); 112 STLDeleteElements(&passwords);
104 LOG(ERROR) << "Failed to create password sync node."; 113 error->Reset(FROM_HERE,
114 "Failed to create password sync node.",
115 model_type());
105 return false; 116 return false;
106 } 117 }
107 118
108 WriteToSyncNode(**ix, &node); 119 WriteToSyncNode(**ix, &node);
109 120
110 Associate(&tag, node.GetId()); 121 Associate(&tag, node.GetId());
111 } 122 }
112 123
113 current_passwords.insert(tag); 124 current_passwords.insert(tag);
114 } 125 }
115 126
116 STLDeleteElements(&passwords); 127 STLDeleteElements(&passwords);
117 128
118 int64 sync_child_id = password_root.GetFirstChildId(); 129 int64 sync_child_id = password_root.GetFirstChildId();
119 while (sync_child_id != sync_api::kInvalidId) { 130 while (sync_child_id != sync_api::kInvalidId) {
120 sync_api::ReadNode sync_child_node(&trans); 131 sync_api::ReadNode sync_child_node(&trans);
121 if (!sync_child_node.InitByIdLookup(sync_child_id)) { 132 if (!sync_child_node.InitByIdLookup(sync_child_id)) {
122 LOG(ERROR) << "Failed to fetch child node."; 133 error->Reset(FROM_HERE, "Failed to fetch child node.", model_type());
123 return false; 134 return false;
124 } 135 }
125 const sync_pb::PasswordSpecificsData& password = 136 const sync_pb::PasswordSpecificsData& password =
126 sync_child_node.GetPasswordSpecifics(); 137 sync_child_node.GetPasswordSpecifics();
127 std::string tag = MakeTag(password); 138 std::string tag = MakeTag(password);
128 139
129 // The password only exists on the server. Add it to the local 140 // The password only exists on the server. Add it to the local
130 // model. 141 // model.
131 if (current_passwords.find(tag) == current_passwords.end()) { 142 if (current_passwords.find(tag) == current_passwords.end()) {
132 webkit_glue::PasswordForm new_password; 143 webkit_glue::PasswordForm new_password;
133 144
134 CopyPassword(password, &new_password); 145 CopyPassword(password, &new_password);
135 Associate(&tag, sync_child_node.GetId()); 146 Associate(&tag, sync_child_node.GetId());
136 new_passwords.push_back(new_password); 147 new_passwords.push_back(new_password);
137 } 148 }
138 149
139 sync_child_id = sync_child_node.GetSuccessorId(); 150 sync_child_id = sync_child_node.GetSuccessorId();
140 } 151 }
141 } 152 }
142 153
143 // We must not be holding a transaction when we interact with the password 154 // We must not be holding a transaction when we interact with the password
144 // store, as it can post tasks to the UI thread which can itself be blocked 155 // store, as it can post tasks to the UI thread which can itself be blocked
145 // on our transaction, resulting in deadlock. (http://crbug.com/70658) 156 // on our transaction, resulting in deadlock. (http://crbug.com/70658)
146 if (!WriteToPasswordStore(&new_passwords, &updated_passwords, NULL)) { 157 if (!WriteToPasswordStore(&new_passwords, &updated_passwords, NULL)) {
147 LOG(ERROR) << "Failed to write passwords."; 158 error->Reset(FROM_HERE, "Failed to write passwords.", model_type());
148 return false; 159 return false;
149 } 160 }
150 161
151 return true; 162 return true;
152 } 163 }
153 164
154 bool PasswordModelAssociator::DeleteAllNodes( 165 bool PasswordModelAssociator::DeleteAllNodes(
155 sync_api::WriteTransaction* trans) { 166 sync_api::WriteTransaction* trans) {
156 DCHECK(expected_loop_ == MessageLoop::current()); 167 DCHECK(expected_loop_ == MessageLoop::current());
157 for (PasswordToSyncIdMap::iterator node_id = id_map_.begin(); 168 for (PasswordToSyncIdMap::iterator node_id = id_map_.begin();
158 node_id != id_map_.end(); ++node_id) { 169 node_id != id_map_.end(); ++node_id) {
159 sync_api::WriteNode sync_node(trans); 170 sync_api::WriteNode sync_node(trans);
160 if (!sync_node.InitByIdLookup(node_id->second)) { 171 if (!sync_node.InitByIdLookup(node_id->second)) {
161 LOG(ERROR) << "Typed url node lookup failed."; 172 LOG(ERROR) << "Typed url node lookup failed.";
162 return false; 173 return false;
163 } 174 }
164 sync_node.Remove(); 175 sync_node.Remove();
165 } 176 }
166 177
167 id_map_.clear(); 178 id_map_.clear();
168 id_map_inverse_.clear(); 179 id_map_inverse_.clear();
169 return true; 180 return true;
170 } 181 }
171 182
172 bool PasswordModelAssociator::DisassociateModels() { 183 bool PasswordModelAssociator::DisassociateModels(SyncError* error) {
173 id_map_.clear(); 184 id_map_.clear();
174 id_map_inverse_.clear(); 185 id_map_inverse_.clear();
175 return true; 186 return true;
176 } 187 }
177 188
178 bool PasswordModelAssociator::SyncModelHasUserCreatedNodes(bool* has_nodes) { 189 bool PasswordModelAssociator::SyncModelHasUserCreatedNodes(bool* has_nodes) {
179 DCHECK(has_nodes); 190 DCHECK(has_nodes);
180 *has_nodes = false; 191 *has_nodes = false;
181 int64 password_sync_id; 192 int64 password_sync_id;
182 if (!GetSyncIdForTaggedNode(kPasswordTag, &password_sync_id)) { 193 if (!GetSyncIdForTaggedNode(kPasswordTag, &password_sync_id)) {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 const std::string& password_element, 418 const std::string& password_element,
408 const std::string& signon_realm) { 419 const std::string& signon_realm) {
409 return EscapePath(origin_url) + "|" + 420 return EscapePath(origin_url) + "|" +
410 EscapePath(username_element) + "|" + 421 EscapePath(username_element) + "|" +
411 EscapePath(username_value) + "|" + 422 EscapePath(username_value) + "|" +
412 EscapePath(password_element) + "|" + 423 EscapePath(password_element) + "|" +
413 EscapePath(signon_realm); 424 EscapePath(signon_realm);
414 } 425 }
415 426
416 } // namespace browser_sync 427 } // namespace browser_sync
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698