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