| 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/internal_api/base_node.h" | 5 #include "chrome/browser/sync/internal_api/base_node.h" |
| 6 | 6 |
| 7 #include "base/base64.h" | 7 #include "base/base64.h" |
| 8 #include "base/sha1.h" | 8 #include "base/sha1.h" |
| 9 #include "base/string_number_conversions.h" | 9 #include "base/string_number_conversions.h" |
| 10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 std::string encode_output; | 75 std::string encode_output; |
| 76 CHECK(base::Base64Encode(base::SHA1HashString(hash_input), &encode_output)); | 76 CHECK(base::Base64Encode(base::SHA1HashString(hash_input), &encode_output)); |
| 77 return encode_output; | 77 return encode_output; |
| 78 } | 78 } |
| 79 | 79 |
| 80 bool BaseNode::DecryptIfNecessary() { | 80 bool BaseNode::DecryptIfNecessary() { |
| 81 if (!GetEntry()->Get(syncable::UNIQUE_SERVER_TAG).empty()) | 81 if (!GetEntry()->Get(syncable::UNIQUE_SERVER_TAG).empty()) |
| 82 return true; // Ignore unique folders. | 82 return true; // Ignore unique folders. |
| 83 const sync_pb::EntitySpecifics& specifics = | 83 const sync_pb::EntitySpecifics& specifics = |
| 84 GetEntry()->Get(syncable::SPECIFICS); | 84 GetEntry()->Get(syncable::SPECIFICS); |
| 85 if (specifics.HasExtension(sync_pb::password)) { | 85 if (specifics.has_password()) { |
| 86 // Passwords have their own legacy encryption structure. | 86 // Passwords have their own legacy encryption structure. |
| 87 scoped_ptr<sync_pb::PasswordSpecificsData> data(DecryptPasswordSpecifics( | 87 scoped_ptr<sync_pb::PasswordSpecificsData> data(DecryptPasswordSpecifics( |
| 88 specifics, GetTransaction()->GetCryptographer())); | 88 specifics, GetTransaction()->GetCryptographer())); |
| 89 if (!data.get()) { | 89 if (!data.get()) { |
| 90 LOG(ERROR) << "Failed to decrypt password specifics."; | 90 LOG(ERROR) << "Failed to decrypt password specifics."; |
| 91 return false; | 91 return false; |
| 92 } | 92 } |
| 93 password_data_.swap(data); | 93 password_data_.swap(data); |
| 94 return true; | 94 return true; |
| 95 } | 95 } |
| 96 | 96 |
| 97 // We assume any node with the encrypted field set has encrypted data and if | 97 // We assume any node with the encrypted field set has encrypted data and if |
| 98 // not we have no work to do, with the exception of bookmarks. For bookmarks | 98 // not we have no work to do, with the exception of bookmarks. For bookmarks |
| 99 // we must make sure the bookmarks data has the title field supplied. If not, | 99 // we must make sure the bookmarks data has the title field supplied. If not, |
| 100 // we fill the unencrypted_data_ with a copy of the bookmark specifics that | 100 // we fill the unencrypted_data_ with a copy of the bookmark specifics that |
| 101 // follows the new bookmarks format. | 101 // follows the new bookmarks format. |
| 102 if (!specifics.has_encrypted()) { | 102 if (!specifics.has_encrypted()) { |
| 103 if (GetModelType() == syncable::BOOKMARKS && | 103 if (GetModelType() == syncable::BOOKMARKS && |
| 104 !specifics.GetExtension(sync_pb::bookmark).has_title() && | 104 !specifics.bookmark().has_title() && |
| 105 !GetTitle().empty()) { // Last check ensures this isn't a new node. | 105 !GetTitle().empty()) { // Last check ensures this isn't a new node. |
| 106 // We need to fill in the title. | 106 // We need to fill in the title. |
| 107 std::string title = GetTitle(); | 107 std::string title = GetTitle(); |
| 108 std::string server_legal_title; | 108 std::string server_legal_title; |
| 109 SyncAPINameToServerName(title, &server_legal_title); | 109 SyncAPINameToServerName(title, &server_legal_title); |
| 110 DVLOG(1) << "Reading from legacy bookmark, manually returning title " | 110 DVLOG(1) << "Reading from legacy bookmark, manually returning title " |
| 111 << title; | 111 << title; |
| 112 unencrypted_data_.CopyFrom(specifics); | 112 unencrypted_data_.CopyFrom(specifics); |
| 113 unencrypted_data_.MutableExtension(sync_pb::bookmark)->set_title( | 113 unencrypted_data_.mutable_bookmark()->set_title( |
| 114 server_legal_title); | 114 server_legal_title); |
| 115 } | 115 } |
| 116 return true; | 116 return true; |
| 117 } | 117 } |
| 118 | 118 |
| 119 const sync_pb::EncryptedData& encrypted = specifics.encrypted(); | 119 const sync_pb::EncryptedData& encrypted = specifics.encrypted(); |
| 120 std::string plaintext_data = GetTransaction()->GetCryptographer()-> | 120 std::string plaintext_data = GetTransaction()->GetCryptographer()-> |
| 121 DecryptToString(encrypted); | 121 DecryptToString(encrypted); |
| 122 if (plaintext_data.length() == 0 || | 122 if (plaintext_data.length() == 0 || |
| 123 !unencrypted_data_.ParseFromString(plaintext_data)) { | 123 !unencrypted_data_.ParseFromString(plaintext_data)) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 138 DCHECK_NE(syncable::GetModelTypeFromSpecifics(unencrypted_data_), | 138 DCHECK_NE(syncable::GetModelTypeFromSpecifics(unencrypted_data_), |
| 139 syncable::UNSPECIFIED); | 139 syncable::UNSPECIFIED); |
| 140 return unencrypted_data_; | 140 return unencrypted_data_; |
| 141 } else { | 141 } else { |
| 142 // Due to the change in bookmarks format, we need to check to see if this is | 142 // Due to the change in bookmarks format, we need to check to see if this is |
| 143 // a legacy bookmarks (and has no title field in the proto). If it is, we | 143 // a legacy bookmarks (and has no title field in the proto). If it is, we |
| 144 // return the unencrypted_data_, which was filled in with the title by | 144 // return the unencrypted_data_, which was filled in with the title by |
| 145 // DecryptIfNecessary(). | 145 // DecryptIfNecessary(). |
| 146 if (GetModelType() == syncable::BOOKMARKS) { | 146 if (GetModelType() == syncable::BOOKMARKS) { |
| 147 const sync_pb::BookmarkSpecifics& bookmark_specifics = | 147 const sync_pb::BookmarkSpecifics& bookmark_specifics = |
| 148 specifics.GetExtension(sync_pb::bookmark); | 148 specifics.bookmark(); |
| 149 if (bookmark_specifics.has_title() || | 149 if (bookmark_specifics.has_title() || |
| 150 GetTitle().empty() || // For the empty node case | 150 GetTitle().empty() || // For the empty node case |
| 151 !GetEntry()->Get(syncable::UNIQUE_SERVER_TAG).empty()) { | 151 !GetEntry()->Get(syncable::UNIQUE_SERVER_TAG).empty()) { |
| 152 // It's possible we previously had to convert and set | 152 // It's possible we previously had to convert and set |
| 153 // |unencrypted_data_| but then wrote our own data, so we allow | 153 // |unencrypted_data_| but then wrote our own data, so we allow |
| 154 // |unencrypted_data_| to be non-empty. | 154 // |unencrypted_data_| to be non-empty. |
| 155 return specifics; | 155 return specifics; |
| 156 } else { | 156 } else { |
| 157 DCHECK_EQ(syncable::GetModelTypeFromSpecifics(unencrypted_data_), | 157 DCHECK_EQ(syncable::GetModelTypeFromSpecifics(unencrypted_data_), |
| 158 syncable::BOOKMARKS); | 158 syncable::BOOKMARKS); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 reinterpret_cast<const unsigned char*>(favicon.data() + | 271 reinterpret_cast<const unsigned char*>(favicon.data() + |
| 272 favicon.length())); | 272 favicon.length())); |
| 273 } | 273 } |
| 274 | 274 |
| 275 int64 BaseNode::GetExternalId() const { | 275 int64 BaseNode::GetExternalId() const { |
| 276 return GetEntry()->Get(syncable::LOCAL_EXTERNAL_ID); | 276 return GetEntry()->Get(syncable::LOCAL_EXTERNAL_ID); |
| 277 } | 277 } |
| 278 | 278 |
| 279 const sync_pb::AppSpecifics& BaseNode::GetAppSpecifics() const { | 279 const sync_pb::AppSpecifics& BaseNode::GetAppSpecifics() const { |
| 280 DCHECK_EQ(syncable::APPS, GetModelType()); | 280 DCHECK_EQ(syncable::APPS, GetModelType()); |
| 281 return GetEntitySpecifics().GetExtension(sync_pb::app); | 281 return GetEntitySpecifics().app(); |
| 282 } | 282 } |
| 283 | 283 |
| 284 const sync_pb::AutofillSpecifics& BaseNode::GetAutofillSpecifics() const { | 284 const sync_pb::AutofillSpecifics& BaseNode::GetAutofillSpecifics() const { |
| 285 DCHECK_EQ(syncable::AUTOFILL, GetModelType()); | 285 DCHECK_EQ(syncable::AUTOFILL, GetModelType()); |
| 286 return GetEntitySpecifics().GetExtension(sync_pb::autofill); | 286 return GetEntitySpecifics().autofill(); |
| 287 } | 287 } |
| 288 | 288 |
| 289 const AutofillProfileSpecifics& BaseNode::GetAutofillProfileSpecifics() const { | 289 const AutofillProfileSpecifics& BaseNode::GetAutofillProfileSpecifics() const { |
| 290 DCHECK_EQ(GetModelType(), syncable::AUTOFILL_PROFILE); | 290 DCHECK_EQ(GetModelType(), syncable::AUTOFILL_PROFILE); |
| 291 return GetEntitySpecifics().GetExtension(sync_pb::autofill_profile); | 291 return GetEntitySpecifics().autofill_profile(); |
| 292 } | 292 } |
| 293 | 293 |
| 294 const sync_pb::BookmarkSpecifics& BaseNode::GetBookmarkSpecifics() const { | 294 const sync_pb::BookmarkSpecifics& BaseNode::GetBookmarkSpecifics() const { |
| 295 DCHECK_EQ(syncable::BOOKMARKS, GetModelType()); | 295 DCHECK_EQ(syncable::BOOKMARKS, GetModelType()); |
| 296 return GetEntitySpecifics().GetExtension(sync_pb::bookmark); | 296 return GetEntitySpecifics().bookmark(); |
| 297 } | 297 } |
| 298 | 298 |
| 299 const sync_pb::NigoriSpecifics& BaseNode::GetNigoriSpecifics() const { | 299 const sync_pb::NigoriSpecifics& BaseNode::GetNigoriSpecifics() const { |
| 300 DCHECK_EQ(syncable::NIGORI, GetModelType()); | 300 DCHECK_EQ(syncable::NIGORI, GetModelType()); |
| 301 return GetEntitySpecifics().GetExtension(sync_pb::nigori); | 301 return GetEntitySpecifics().nigori(); |
| 302 } | 302 } |
| 303 | 303 |
| 304 const sync_pb::PasswordSpecificsData& BaseNode::GetPasswordSpecifics() const { | 304 const sync_pb::PasswordSpecificsData& BaseNode::GetPasswordSpecifics() const { |
| 305 DCHECK_EQ(syncable::PASSWORDS, GetModelType()); | 305 DCHECK_EQ(syncable::PASSWORDS, GetModelType()); |
| 306 return *password_data_; | 306 return *password_data_; |
| 307 } | 307 } |
| 308 | 308 |
| 309 const sync_pb::ThemeSpecifics& BaseNode::GetThemeSpecifics() const { | 309 const sync_pb::ThemeSpecifics& BaseNode::GetThemeSpecifics() const { |
| 310 DCHECK_EQ(syncable::THEMES, GetModelType()); | 310 DCHECK_EQ(syncable::THEMES, GetModelType()); |
| 311 return GetEntitySpecifics().GetExtension(sync_pb::theme); | 311 return GetEntitySpecifics().theme(); |
| 312 } | 312 } |
| 313 | 313 |
| 314 const sync_pb::TypedUrlSpecifics& BaseNode::GetTypedUrlSpecifics() const { | 314 const sync_pb::TypedUrlSpecifics& BaseNode::GetTypedUrlSpecifics() const { |
| 315 DCHECK_EQ(syncable::TYPED_URLS, GetModelType()); | 315 DCHECK_EQ(syncable::TYPED_URLS, GetModelType()); |
| 316 return GetEntitySpecifics().GetExtension(sync_pb::typed_url); | 316 return GetEntitySpecifics().typed_url(); |
| 317 } | 317 } |
| 318 | 318 |
| 319 const sync_pb::ExtensionSpecifics& BaseNode::GetExtensionSpecifics() const { | 319 const sync_pb::ExtensionSpecifics& BaseNode::GetExtensionSpecifics() const { |
| 320 DCHECK_EQ(syncable::EXTENSIONS, GetModelType()); | 320 DCHECK_EQ(syncable::EXTENSIONS, GetModelType()); |
| 321 return GetEntitySpecifics().GetExtension(sync_pb::extension); | 321 return GetEntitySpecifics().extension(); |
| 322 } | 322 } |
| 323 | 323 |
| 324 const sync_pb::SessionSpecifics& BaseNode::GetSessionSpecifics() const { | 324 const sync_pb::SessionSpecifics& BaseNode::GetSessionSpecifics() const { |
| 325 DCHECK_EQ(syncable::SESSIONS, GetModelType()); | 325 DCHECK_EQ(syncable::SESSIONS, GetModelType()); |
| 326 return GetEntitySpecifics().GetExtension(sync_pb::session); | 326 return GetEntitySpecifics().session(); |
| 327 } | 327 } |
| 328 | 328 |
| 329 const sync_pb::EntitySpecifics& BaseNode::GetEntitySpecifics() const { | 329 const sync_pb::EntitySpecifics& BaseNode::GetEntitySpecifics() const { |
| 330 return GetUnencryptedSpecifics(GetEntry()); | 330 return GetUnencryptedSpecifics(GetEntry()); |
| 331 } | 331 } |
| 332 | 332 |
| 333 syncable::ModelType BaseNode::GetModelType() const { | 333 syncable::ModelType BaseNode::GetModelType() const { |
| 334 return GetEntry()->GetModelType(); | 334 return GetEntry()->GetModelType(); |
| 335 } | 335 } |
| 336 | 336 |
| 337 void BaseNode::SetUnencryptedSpecifics( | 337 void BaseNode::SetUnencryptedSpecifics( |
| 338 const sync_pb::EntitySpecifics& specifics) { | 338 const sync_pb::EntitySpecifics& specifics) { |
| 339 syncable::ModelType type = syncable::GetModelTypeFromSpecifics(specifics); | 339 syncable::ModelType type = syncable::GetModelTypeFromSpecifics(specifics); |
| 340 DCHECK_NE(syncable::UNSPECIFIED, type); | 340 DCHECK_NE(syncable::UNSPECIFIED, type); |
| 341 if (GetModelType() != syncable::UNSPECIFIED) { | 341 if (GetModelType() != syncable::UNSPECIFIED) { |
| 342 DCHECK_EQ(GetModelType(), type); | 342 DCHECK_EQ(GetModelType(), type); |
| 343 } | 343 } |
| 344 unencrypted_data_.CopyFrom(specifics); | 344 unencrypted_data_.CopyFrom(specifics); |
| 345 } | 345 } |
| 346 | 346 |
| 347 } // namespace sync_api | 347 } // namespace sync_api |
| OLD | NEW |