OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/internal_api/write_node.h" | 5 #include "chrome/browser/sync/internal_api/write_node.h" |
6 | 6 |
7 #include "base/json/json_writer.h" | 7 #include "base/json/json_writer.h" |
8 #include "base/utf_string_conversions.h" | 8 #include "base/utf_string_conversions.h" |
9 #include "base/values.h" | 9 #include "base/values.h" |
10 #include "chrome/browser/sync/engine/nigori_util.h" | 10 #include "chrome/browser/sync/engine/nigori_util.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 << info; | 66 << info; |
67 } | 67 } |
68 // Only copy over the old specifics if it is of the right type and already | 68 // Only copy over the old specifics if it is of the right type and already |
69 // encrypted. The first time we encrypt a node we start from scratch, hence | 69 // encrypted. The first time we encrypt a node we start from scratch, hence |
70 // removing all the unencrypted data, but from then on we only want to | 70 // removing all the unencrypted data, but from then on we only want to |
71 // update the node if the data changes or the encryption key changes. | 71 // update the node if the data changes or the encryption key changes. |
72 if (syncable::GetModelTypeFromSpecifics(old_specifics) == type && | 72 if (syncable::GetModelTypeFromSpecifics(old_specifics) == type && |
73 was_encrypted) { | 73 was_encrypted) { |
74 generated_specifics.CopyFrom(old_specifics); | 74 generated_specifics.CopyFrom(old_specifics); |
75 } else { | 75 } else { |
76 syncable::AddDefaultExtensionValue(type, &generated_specifics); | 76 syncable::AddDefaultFieldValue(type, &generated_specifics); |
77 } | 77 } |
78 // Does not change anything if underlying encrypted blob was already up | 78 // Does not change anything if underlying encrypted blob was already up |
79 // to date and encrypted with the default key. | 79 // to date and encrypted with the default key. |
80 if (!cryptographer->Encrypt(new_specifics, | 80 if (!cryptographer->Encrypt(new_specifics, |
81 generated_specifics.mutable_encrypted())) { | 81 generated_specifics.mutable_encrypted())) { |
82 NOTREACHED() << "Could not encrypt data for node of type " | 82 NOTREACHED() << "Could not encrypt data for node of type " |
83 << syncable::ModelTypeToString(type); | 83 << syncable::ModelTypeToString(type); |
84 return false; | 84 return false; |
85 } | 85 } |
86 } | 86 } |
(...skipping 13 matching lines...) Expand all Loading... |
100 return true; | 100 return true; |
101 } | 101 } |
102 | 102 |
103 if (generated_specifics.has_encrypted()) { | 103 if (generated_specifics.has_encrypted()) { |
104 // Overwrite the possibly sensitive non-specifics data. | 104 // Overwrite the possibly sensitive non-specifics data. |
105 entry->Put(syncable::NON_UNIQUE_NAME, kEncryptedString); | 105 entry->Put(syncable::NON_UNIQUE_NAME, kEncryptedString); |
106 // For bookmarks we actually put bogus data into the unencrypted specifics, | 106 // For bookmarks we actually put bogus data into the unencrypted specifics, |
107 // else the server will try to do it for us. | 107 // else the server will try to do it for us. |
108 if (type == syncable::BOOKMARKS) { | 108 if (type == syncable::BOOKMARKS) { |
109 sync_pb::BookmarkSpecifics* bookmark_specifics = | 109 sync_pb::BookmarkSpecifics* bookmark_specifics = |
110 generated_specifics.MutableExtension(sync_pb::bookmark); | 110 generated_specifics.mutable_bookmark(); |
111 if (!entry->Get(syncable::IS_DIR)) | 111 if (!entry->Get(syncable::IS_DIR)) |
112 bookmark_specifics->set_url(kEncryptedString); | 112 bookmark_specifics->set_url(kEncryptedString); |
113 bookmark_specifics->set_title(kEncryptedString); | 113 bookmark_specifics->set_title(kEncryptedString); |
114 } | 114 } |
115 } | 115 } |
116 entry->Put(syncable::SPECIFICS, generated_specifics); | 116 entry->Put(syncable::SPECIFICS, generated_specifics); |
117 DVLOG(1) << "Overwriting specifics of type " | 117 DVLOG(1) << "Overwriting specifics of type " |
118 << syncable::ModelTypeToString(type) | 118 << syncable::ModelTypeToString(type) |
119 << " and marking for syncing."; | 119 << " and marking for syncing."; |
120 syncable::MarkForSyncing(entry); | 120 syncable::MarkForSyncing(entry); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 // necessary, nothing needs to change. | 169 // necessary, nothing needs to change. |
170 if (title_matches && !encrypted_without_overwriting_name) { | 170 if (title_matches && !encrypted_without_overwriting_name) { |
171 DVLOG(2) << "Title matches, dropping change."; | 171 DVLOG(2) << "Title matches, dropping change."; |
172 return; | 172 return; |
173 } | 173 } |
174 | 174 |
175 // For bookmarks, we also set the title field in the specifics. | 175 // For bookmarks, we also set the title field in the specifics. |
176 // TODO(zea): refactor bookmarks to not need this functionality. | 176 // TODO(zea): refactor bookmarks to not need this functionality. |
177 if (GetModelType() == syncable::BOOKMARKS) { | 177 if (GetModelType() == syncable::BOOKMARKS) { |
178 sync_pb::EntitySpecifics specifics = GetEntitySpecifics(); | 178 sync_pb::EntitySpecifics specifics = GetEntitySpecifics(); |
179 specifics.MutableExtension(sync_pb::bookmark)->set_title(new_legal_title); | 179 specifics.mutable_bookmark()->set_title(new_legal_title); |
180 SetEntitySpecifics(specifics); // Does it's own encryption checking. | 180 SetEntitySpecifics(specifics); // Does it's own encryption checking. |
181 } | 181 } |
182 | 182 |
183 // For bookmarks, this has to happen after we set the title in the specifics, | 183 // For bookmarks, this has to happen after we set the title in the specifics, |
184 // because the presence of a title in the NON_UNIQUE_NAME is what controls | 184 // because the presence of a title in the NON_UNIQUE_NAME is what controls |
185 // the logic deciding whether this is an empty node or a legacy bookmark. | 185 // the logic deciding whether this is an empty node or a legacy bookmark. |
186 // See BaseNode::GetUnencryptedSpecific(..). | 186 // See BaseNode::GetUnencryptedSpecific(..). |
187 if (needs_encryption) | 187 if (needs_encryption) |
188 entry_->Put(syncable::NON_UNIQUE_NAME, kEncryptedString); | 188 entry_->Put(syncable::NON_UNIQUE_NAME, kEncryptedString); |
189 else | 189 else |
190 entry_->Put(syncable::NON_UNIQUE_NAME, new_legal_title); | 190 entry_->Put(syncable::NON_UNIQUE_NAME, new_legal_title); |
191 | 191 |
192 DVLOG(1) << "Overwriting title of type " | 192 DVLOG(1) << "Overwriting title of type " |
193 << syncable::ModelTypeToString(type) | 193 << syncable::ModelTypeToString(type) |
194 << " and marking for syncing."; | 194 << " and marking for syncing."; |
195 MarkForSyncing(); | 195 MarkForSyncing(); |
196 } | 196 } |
197 | 197 |
198 void WriteNode::SetURL(const GURL& url) { | 198 void WriteNode::SetURL(const GURL& url) { |
199 sync_pb::BookmarkSpecifics new_value = GetBookmarkSpecifics(); | 199 sync_pb::BookmarkSpecifics new_value = GetBookmarkSpecifics(); |
200 new_value.set_url(url.spec()); | 200 new_value.set_url(url.spec()); |
201 SetBookmarkSpecifics(new_value); | 201 SetBookmarkSpecifics(new_value); |
202 } | 202 } |
203 | 203 |
204 void WriteNode::SetAppSpecifics( | 204 void WriteNode::SetAppSpecifics( |
205 const sync_pb::AppSpecifics& new_value) { | 205 const sync_pb::AppSpecifics& new_value) { |
206 sync_pb::EntitySpecifics entity_specifics; | 206 sync_pb::EntitySpecifics entity_specifics; |
207 entity_specifics.MutableExtension(sync_pb::app)->CopyFrom(new_value); | 207 entity_specifics.mutable_app()->CopyFrom(new_value); |
208 SetEntitySpecifics(entity_specifics); | 208 SetEntitySpecifics(entity_specifics); |
209 } | 209 } |
210 | 210 |
211 void WriteNode::SetAutofillSpecifics( | 211 void WriteNode::SetAutofillSpecifics( |
212 const sync_pb::AutofillSpecifics& new_value) { | 212 const sync_pb::AutofillSpecifics& new_value) { |
213 sync_pb::EntitySpecifics entity_specifics; | 213 sync_pb::EntitySpecifics entity_specifics; |
214 entity_specifics.MutableExtension(sync_pb::autofill)->CopyFrom(new_value); | 214 entity_specifics.mutable_autofill()->CopyFrom(new_value); |
215 SetEntitySpecifics(entity_specifics); | 215 SetEntitySpecifics(entity_specifics); |
216 } | 216 } |
217 | 217 |
218 void WriteNode::SetAutofillProfileSpecifics( | 218 void WriteNode::SetAutofillProfileSpecifics( |
219 const sync_pb::AutofillProfileSpecifics& new_value) { | 219 const sync_pb::AutofillProfileSpecifics& new_value) { |
220 sync_pb::EntitySpecifics entity_specifics; | 220 sync_pb::EntitySpecifics entity_specifics; |
221 entity_specifics.MutableExtension(sync_pb::autofill_profile)-> | 221 entity_specifics.mutable_autofill_profile()-> |
222 CopyFrom(new_value); | 222 CopyFrom(new_value); |
223 SetEntitySpecifics(entity_specifics); | 223 SetEntitySpecifics(entity_specifics); |
224 } | 224 } |
225 | 225 |
226 void WriteNode::SetBookmarkSpecifics( | 226 void WriteNode::SetBookmarkSpecifics( |
227 const sync_pb::BookmarkSpecifics& new_value) { | 227 const sync_pb::BookmarkSpecifics& new_value) { |
228 sync_pb::EntitySpecifics entity_specifics; | 228 sync_pb::EntitySpecifics entity_specifics; |
229 entity_specifics.MutableExtension(sync_pb::bookmark)->CopyFrom(new_value); | 229 entity_specifics.mutable_bookmark()->CopyFrom(new_value); |
230 SetEntitySpecifics(entity_specifics); | 230 SetEntitySpecifics(entity_specifics); |
231 } | 231 } |
232 | 232 |
233 void WriteNode::SetNigoriSpecifics( | 233 void WriteNode::SetNigoriSpecifics( |
234 const sync_pb::NigoriSpecifics& new_value) { | 234 const sync_pb::NigoriSpecifics& new_value) { |
235 sync_pb::EntitySpecifics entity_specifics; | 235 sync_pb::EntitySpecifics entity_specifics; |
236 entity_specifics.MutableExtension(sync_pb::nigori)->CopyFrom(new_value); | 236 entity_specifics.mutable_nigori()->CopyFrom(new_value); |
237 SetEntitySpecifics(entity_specifics); | 237 SetEntitySpecifics(entity_specifics); |
238 } | 238 } |
239 | 239 |
240 void WriteNode::SetPasswordSpecifics( | 240 void WriteNode::SetPasswordSpecifics( |
241 const sync_pb::PasswordSpecificsData& data) { | 241 const sync_pb::PasswordSpecificsData& data) { |
242 DCHECK_EQ(syncable::PASSWORDS, GetModelType()); | 242 DCHECK_EQ(syncable::PASSWORDS, GetModelType()); |
243 | 243 |
244 Cryptographer* cryptographer = GetTransaction()->GetCryptographer(); | 244 Cryptographer* cryptographer = GetTransaction()->GetCryptographer(); |
245 | 245 |
246 // We have to do the idempotency check here (vs in UpdateEntryWithEncryption) | 246 // We have to do the idempotency check here (vs in UpdateEntryWithEncryption) |
247 // because Passwords have their encrypted data within the PasswordSpecifics, | 247 // because Passwords have their encrypted data within the PasswordSpecifics, |
248 // vs within the EntitySpecifics like all the other types. | 248 // vs within the EntitySpecifics like all the other types. |
249 const sync_pb::EntitySpecifics& old_specifics = GetEntry()->Get(SPECIFICS); | 249 const sync_pb::EntitySpecifics& old_specifics = GetEntry()->Get(SPECIFICS); |
250 sync_pb::EntitySpecifics entity_specifics; | 250 sync_pb::EntitySpecifics entity_specifics; |
251 // Copy over the old specifics if they exist. | 251 // Copy over the old specifics if they exist. |
252 if (syncable::GetModelTypeFromSpecifics(old_specifics) == | 252 if (syncable::GetModelTypeFromSpecifics(old_specifics) == |
253 syncable::PASSWORDS) { | 253 syncable::PASSWORDS) { |
254 entity_specifics.CopyFrom(old_specifics); | 254 entity_specifics.CopyFrom(old_specifics); |
255 } else { | 255 } else { |
256 syncable::AddDefaultExtensionValue(syncable::PASSWORDS, | 256 syncable::AddDefaultFieldValue(syncable::PASSWORDS, |
257 &entity_specifics); | 257 &entity_specifics); |
258 } | 258 } |
259 sync_pb::PasswordSpecifics* password_specifics = | 259 sync_pb::PasswordSpecifics* password_specifics = |
260 entity_specifics.MutableExtension(sync_pb::password); | 260 entity_specifics.mutable_password(); |
261 // This will only update password_specifics if the underlying unencrypted blob | 261 // This will only update password_specifics if the underlying unencrypted blob |
262 // was different from |data| or was not encrypted with the proper passphrase. | 262 // was different from |data| or was not encrypted with the proper passphrase. |
263 if (!cryptographer->Encrypt(data, password_specifics->mutable_encrypted())) { | 263 if (!cryptographer->Encrypt(data, password_specifics->mutable_encrypted())) { |
264 NOTREACHED() << "Failed to encrypt password, possibly due to sync node " | 264 NOTREACHED() << "Failed to encrypt password, possibly due to sync node " |
265 << "corruption"; | 265 << "corruption"; |
266 return; | 266 return; |
267 } | 267 } |
268 SetEntitySpecifics(entity_specifics); | 268 SetEntitySpecifics(entity_specifics); |
269 } | 269 } |
270 | 270 |
271 void WriteNode::SetThemeSpecifics( | 271 void WriteNode::SetThemeSpecifics( |
272 const sync_pb::ThemeSpecifics& new_value) { | 272 const sync_pb::ThemeSpecifics& new_value) { |
273 sync_pb::EntitySpecifics entity_specifics; | 273 sync_pb::EntitySpecifics entity_specifics; |
274 entity_specifics.MutableExtension(sync_pb::theme)->CopyFrom(new_value); | 274 entity_specifics.mutable_theme()->CopyFrom(new_value); |
275 SetEntitySpecifics(entity_specifics); | 275 SetEntitySpecifics(entity_specifics); |
276 } | 276 } |
277 | 277 |
278 void WriteNode::SetSessionSpecifics( | 278 void WriteNode::SetSessionSpecifics( |
279 const sync_pb::SessionSpecifics& new_value) { | 279 const sync_pb::SessionSpecifics& new_value) { |
280 sync_pb::EntitySpecifics entity_specifics; | 280 sync_pb::EntitySpecifics entity_specifics; |
281 entity_specifics.MutableExtension(sync_pb::session)->CopyFrom(new_value); | 281 entity_specifics.mutable_session()->CopyFrom(new_value); |
282 SetEntitySpecifics(entity_specifics); | 282 SetEntitySpecifics(entity_specifics); |
283 } | 283 } |
284 | 284 |
285 void WriteNode::SetEntitySpecifics( | 285 void WriteNode::SetEntitySpecifics( |
286 const sync_pb::EntitySpecifics& new_value) { | 286 const sync_pb::EntitySpecifics& new_value) { |
287 syncable::ModelType new_specifics_type = | 287 syncable::ModelType new_specifics_type = |
288 syncable::GetModelTypeFromSpecifics(new_value); | 288 syncable::GetModelTypeFromSpecifics(new_value); |
289 DCHECK_NE(new_specifics_type, syncable::UNSPECIFIED); | 289 DCHECK_NE(new_specifics_type, syncable::UNSPECIFIED); |
290 DVLOG(1) << "Writing entity specifics of type " | 290 DVLOG(1) << "Writing entity specifics of type " |
291 << syncable::ModelTypeToString(new_specifics_type); | 291 << syncable::ModelTypeToString(new_specifics_type); |
(...skipping 29 matching lines...) Expand all Loading... |
321 DCHECK_EQ(new_specifics_type, GetModelType()); | 321 DCHECK_EQ(new_specifics_type, GetModelType()); |
322 } | 322 } |
323 | 323 |
324 void WriteNode::ResetFromSpecifics() { | 324 void WriteNode::ResetFromSpecifics() { |
325 SetEntitySpecifics(GetEntitySpecifics()); | 325 SetEntitySpecifics(GetEntitySpecifics()); |
326 } | 326 } |
327 | 327 |
328 void WriteNode::SetTypedUrlSpecifics( | 328 void WriteNode::SetTypedUrlSpecifics( |
329 const sync_pb::TypedUrlSpecifics& new_value) { | 329 const sync_pb::TypedUrlSpecifics& new_value) { |
330 sync_pb::EntitySpecifics entity_specifics; | 330 sync_pb::EntitySpecifics entity_specifics; |
331 entity_specifics.MutableExtension(sync_pb::typed_url)->CopyFrom(new_value); | 331 entity_specifics.mutable_typed_url()->CopyFrom(new_value); |
332 SetEntitySpecifics(entity_specifics); | 332 SetEntitySpecifics(entity_specifics); |
333 } | 333 } |
334 | 334 |
335 void WriteNode::SetExtensionSpecifics( | 335 void WriteNode::SetExtensionSpecifics( |
336 const sync_pb::ExtensionSpecifics& new_value) { | 336 const sync_pb::ExtensionSpecifics& new_value) { |
337 sync_pb::EntitySpecifics entity_specifics; | 337 sync_pb::EntitySpecifics entity_specifics; |
338 entity_specifics.MutableExtension(sync_pb::extension)->CopyFrom(new_value); | 338 entity_specifics.mutable_extension()->CopyFrom(new_value); |
339 SetEntitySpecifics(entity_specifics); | 339 SetEntitySpecifics(entity_specifics); |
340 } | 340 } |
341 | 341 |
342 void WriteNode::SetExternalId(int64 id) { | 342 void WriteNode::SetExternalId(int64 id) { |
343 if (GetExternalId() != id) | 343 if (GetExternalId() != id) |
344 entry_->Put(syncable::LOCAL_EXTERNAL_ID, id); | 344 entry_->Put(syncable::LOCAL_EXTERNAL_ID, id); |
345 } | 345 } |
346 | 346 |
347 WriteNode::WriteNode(WriteTransaction* transaction) | 347 WriteNode::WriteNode(WriteTransaction* transaction) |
348 : entry_(NULL), transaction_(transaction) { | 348 : entry_(NULL), transaction_(transaction) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 return false; | 391 return false; |
392 if (entry_->Get(syncable::IS_DEL)) | 392 if (entry_->Get(syncable::IS_DEL)) |
393 return false; | 393 return false; |
394 syncable::ModelType model_type = GetModelType(); | 394 syncable::ModelType model_type = GetModelType(); |
395 DCHECK_EQ(syncable::NIGORI, model_type); | 395 DCHECK_EQ(syncable::NIGORI, model_type); |
396 return true; | 396 return true; |
397 } | 397 } |
398 | 398 |
399 void WriteNode::PutModelType(syncable::ModelType model_type) { | 399 void WriteNode::PutModelType(syncable::ModelType model_type) { |
400 // Set an empty specifics of the appropriate datatype. The presence | 400 // Set an empty specifics of the appropriate datatype. The presence |
401 // of the specific extension will identify the model type. | 401 // of the specific field will identify the model type. |
402 DCHECK(GetModelType() == model_type || | 402 DCHECK(GetModelType() == model_type || |
403 GetModelType() == syncable::UNSPECIFIED); // Immutable once set. | 403 GetModelType() == syncable::UNSPECIFIED); // Immutable once set. |
404 | 404 |
405 sync_pb::EntitySpecifics specifics; | 405 sync_pb::EntitySpecifics specifics; |
406 syncable::AddDefaultExtensionValue(model_type, &specifics); | 406 syncable::AddDefaultFieldValue(model_type, &specifics); |
407 SetEntitySpecifics(specifics); | 407 SetEntitySpecifics(specifics); |
408 } | 408 } |
409 | 409 |
410 // Create a new node with default properties, and bind this WriteNode to it. | 410 // Create a new node with default properties, and bind this WriteNode to it. |
411 // Return true on success. | 411 // Return true on success. |
412 bool WriteNode::InitByCreation(syncable::ModelType model_type, | 412 bool WriteNode::InitByCreation(syncable::ModelType model_type, |
413 const BaseNode& parent, | 413 const BaseNode& parent, |
414 const BaseNode* predecessor) { | 414 const BaseNode* predecessor) { |
415 DCHECK(!entry_) << "Init called twice"; | 415 DCHECK(!entry_) << "Init called twice"; |
416 // |predecessor| must be a child of |parent| or NULL. | 416 // |predecessor| must be a child of |parent| or NULL. |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 sync_pb::BookmarkSpecifics new_value = GetBookmarkSpecifics(); | 576 sync_pb::BookmarkSpecifics new_value = GetBookmarkSpecifics(); |
577 new_value.set_favicon(bytes.empty() ? NULL : &bytes[0], bytes.size()); | 577 new_value.set_favicon(bytes.empty() ? NULL : &bytes[0], bytes.size()); |
578 SetBookmarkSpecifics(new_value); | 578 SetBookmarkSpecifics(new_value); |
579 } | 579 } |
580 | 580 |
581 void WriteNode::MarkForSyncing() { | 581 void WriteNode::MarkForSyncing() { |
582 syncable::MarkForSyncing(entry_); | 582 syncable::MarkForSyncing(entry_); |
583 } | 583 } |
584 | 584 |
585 } // namespace sync_api | 585 } // namespace sync_api |
OLD | NEW |