| 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 |