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

Side by Side Diff: chrome/browser/sync/internal_api/sync_manager.cc

Issue 10152003: sync: Make BaseNode lookup-related Init functions return specific failures. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: init Created 8 years, 8 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) 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/sync_manager.h" 5 #include "chrome/browser/sync/internal_api/sync_manager.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/base64.h" 9 #include "base/base64.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 1062 matching lines...) Expand 10 before | Expand all | Expand 10 after
1073 done_callback.Run(); // Should only happen during first time sync. 1073 done_callback.Run(); // Should only happen during first time sync.
1074 return; 1074 return;
1075 } 1075 }
1076 1076
1077 bool success = false; 1077 bool success = false;
1078 { 1078 {
1079 WriteTransaction trans(FROM_HERE, GetUserShare()); 1079 WriteTransaction trans(FROM_HERE, GetUserShare());
1080 Cryptographer* cryptographer = trans.GetCryptographer(); 1080 Cryptographer* cryptographer = trans.GetCryptographer();
1081 WriteNode node(&trans); 1081 WriteNode node(&trans);
1082 1082
1083 if (node.InitByTagLookup(kNigoriTag)) { 1083 if (node.InitByTagLookup(kNigoriTag) == sync_api::BaseNode::INIT_OK) {
1084 sync_pb::NigoriSpecifics nigori(node.GetNigoriSpecifics()); 1084 sync_pb::NigoriSpecifics nigori(node.GetNigoriSpecifics());
1085 Cryptographer::UpdateResult result = cryptographer->Update(nigori); 1085 Cryptographer::UpdateResult result = cryptographer->Update(nigori);
1086 if (result == Cryptographer::NEEDS_PASSPHRASE) { 1086 if (result == Cryptographer::NEEDS_PASSPHRASE) {
1087 sync_pb::EncryptedData pending_keys; 1087 sync_pb::EncryptedData pending_keys;
1088 if (cryptographer->has_pending_keys()) 1088 if (cryptographer->has_pending_keys())
1089 pending_keys = cryptographer->GetPendingKeys(); 1089 pending_keys = cryptographer->GetPendingKeys();
1090 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 1090 FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
1091 OnPassphraseRequired(sync_api::REASON_DECRYPTION, 1091 OnPassphraseRequired(sync_api::REASON_DECRYPTION,
1092 pending_keys)); 1092 pending_keys));
1093 } 1093 }
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
1246 } 1246 }
1247 1247
1248 void SyncManager::SyncInternal::MaybeSetSyncTabsInNigoriNode( 1248 void SyncManager::SyncInternal::MaybeSetSyncTabsInNigoriNode(
1249 const ModelTypeSet enabled_types) { 1249 const ModelTypeSet enabled_types) {
1250 // The initialized_ check is to ensure that we don't CHECK in GetUserShare 1250 // The initialized_ check is to ensure that we don't CHECK in GetUserShare
1251 // when this is called on start-up. It's ok to ignore that case, since 1251 // when this is called on start-up. It's ok to ignore that case, since
1252 // presumably this would've run when the user originally enabled sessions. 1252 // presumably this would've run when the user originally enabled sessions.
1253 if (initialized_ && enabled_types.Has(syncable::SESSIONS)) { 1253 if (initialized_ && enabled_types.Has(syncable::SESSIONS)) {
1254 WriteTransaction trans(FROM_HERE, GetUserShare()); 1254 WriteTransaction trans(FROM_HERE, GetUserShare());
1255 WriteNode node(&trans); 1255 WriteNode node(&trans);
1256 if (!node.InitByTagLookup(kNigoriTag)) { 1256 if (node.InitByTagLookup(kNigoriTag) != sync_api::BaseNode::INIT_OK) {
1257 LOG(WARNING) << "Unable to set 'sync_tabs' bit because Nigori node not " 1257 LOG(WARNING) << "Unable to set 'sync_tabs' bit because Nigori node not "
1258 << "found."; 1258 << "found.";
1259 return; 1259 return;
1260 } 1260 }
1261 1261
1262 sync_pb::NigoriSpecifics specifics(node.GetNigoriSpecifics()); 1262 sync_pb::NigoriSpecifics specifics(node.GetNigoriSpecifics());
1263 specifics.set_sync_tabs(true); 1263 specifics.set_sync_tabs(true);
1264 node.SetNigoriSpecifics(specifics); 1264 node.SetNigoriSpecifics(specifics);
1265 } 1265 }
1266 } 1266 }
1267 1267
1268 void SyncManager::SyncInternal::SetEncryptionPassphrase( 1268 void SyncManager::SyncInternal::SetEncryptionPassphrase(
1269 const std::string& passphrase, 1269 const std::string& passphrase,
1270 bool is_explicit) { 1270 bool is_explicit) {
1271 // We do not accept empty passphrases. 1271 // We do not accept empty passphrases.
1272 if (passphrase.empty()) { 1272 if (passphrase.empty()) {
1273 NOTREACHED() << "Cannot encrypt with an empty passphrase."; 1273 NOTREACHED() << "Cannot encrypt with an empty passphrase.";
1274 return; 1274 return;
1275 } 1275 }
1276 1276
1277 // All accesses to the cryptographer are protected by a transaction. 1277 // All accesses to the cryptographer are protected by a transaction.
1278 WriteTransaction trans(FROM_HERE, GetUserShare()); 1278 WriteTransaction trans(FROM_HERE, GetUserShare());
1279 Cryptographer* cryptographer = trans.GetCryptographer(); 1279 Cryptographer* cryptographer = trans.GetCryptographer();
1280 KeyParams key_params = {"localhost", "dummy", passphrase}; 1280 KeyParams key_params = {"localhost", "dummy", passphrase};
1281 WriteNode node(&trans); 1281 WriteNode node(&trans);
1282 if (!node.InitByTagLookup(kNigoriTag)) { 1282 if (node.InitByTagLookup(kNigoriTag) != sync_api::BaseNode::INIT_OK) {
1283 // TODO(albertb): Plumb an UnrecoverableError all the way back to the PSS. 1283 // TODO(albertb): Plumb an UnrecoverableError all the way back to the PSS.
1284 NOTREACHED(); 1284 NOTREACHED();
1285 return; 1285 return;
1286 } 1286 }
1287 1287
1288 bool nigori_has_explicit_passphrase = 1288 bool nigori_has_explicit_passphrase =
1289 node.GetNigoriSpecifics().using_explicit_passphrase(); 1289 node.GetNigoriSpecifics().using_explicit_passphrase();
1290 std::string bootstrap_token; 1290 std::string bootstrap_token;
1291 sync_pb::EncryptedData pending_keys; 1291 sync_pb::EncryptedData pending_keys;
1292 if (cryptographer->has_pending_keys()) 1292 if (cryptographer->has_pending_keys())
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1386 if (passphrase.empty()) { 1386 if (passphrase.empty()) {
1387 NOTREACHED() << "Cannot decrypt with an empty passphrase."; 1387 NOTREACHED() << "Cannot decrypt with an empty passphrase.";
1388 return; 1388 return;
1389 } 1389 }
1390 1390
1391 // All accesses to the cryptographer are protected by a transaction. 1391 // All accesses to the cryptographer are protected by a transaction.
1392 WriteTransaction trans(FROM_HERE, GetUserShare()); 1392 WriteTransaction trans(FROM_HERE, GetUserShare());
1393 Cryptographer* cryptographer = trans.GetCryptographer(); 1393 Cryptographer* cryptographer = trans.GetCryptographer();
1394 KeyParams key_params = {"localhost", "dummy", passphrase}; 1394 KeyParams key_params = {"localhost", "dummy", passphrase};
1395 WriteNode node(&trans); 1395 WriteNode node(&trans);
1396 if (!node.InitByTagLookup(kNigoriTag)) { 1396 if (node.InitByTagLookup(kNigoriTag) != sync_api::BaseNode::INIT_OK) {
1397 // TODO(albertb): Plumb an UnrecoverableError all the way back to the PSS. 1397 // TODO(albertb): Plumb an UnrecoverableError all the way back to the PSS.
1398 NOTREACHED(); 1398 NOTREACHED();
1399 return; 1399 return;
1400 } 1400 }
1401 1401
1402 if (!cryptographer->has_pending_keys()) { 1402 if (!cryptographer->has_pending_keys()) {
1403 // Note that this *can* happen in a rare situation where data is 1403 // Note that this *can* happen in a rare situation where data is
1404 // re-encrypted on another client while a SetDecryptionPassphrase() call is 1404 // re-encrypted on another client while a SetDecryptionPassphrase() call is
1405 // in-flight on this client. It is rare enough that we choose to do nothing. 1405 // in-flight on this client. It is rare enough that we choose to do nothing.
1406 NOTREACHED() << "Attempt to set decryption passphrase failed because there " 1406 NOTREACHED() << "Attempt to set decryption passphrase failed because there "
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1575 nigori_node->SetNigoriSpecifics(specifics); 1575 nigori_node->SetNigoriSpecifics(specifics);
1576 1576
1577 // Does nothing if everything is already encrypted or the cryptographer has 1577 // Does nothing if everything is already encrypted or the cryptographer has
1578 // pending keys. 1578 // pending keys.
1579 ReEncryptEverything(trans); 1579 ReEncryptEverything(trans);
1580 } 1580 }
1581 1581
1582 bool SyncManager::SyncInternal::IsUsingExplicitPassphrase() { 1582 bool SyncManager::SyncInternal::IsUsingExplicitPassphrase() {
1583 ReadTransaction trans(FROM_HERE, &share_); 1583 ReadTransaction trans(FROM_HERE, &share_);
1584 ReadNode node(&trans); 1584 ReadNode node(&trans);
1585 if (!node.InitByTagLookup(kNigoriTag)) { 1585 if (node.InitByTagLookup(kNigoriTag) != sync_api::BaseNode::INIT_OK) {
1586 // TODO(albertb): Plumb an UnrecoverableError all the way back to the PSS. 1586 // TODO(albertb): Plumb an UnrecoverableError all the way back to the PSS.
1587 NOTREACHED(); 1587 NOTREACHED();
1588 return false; 1588 return false;
1589 } 1589 }
1590 1590
1591 return node.GetNigoriSpecifics().using_explicit_passphrase(); 1591 return node.GetNigoriSpecifics().using_explicit_passphrase();
1592 } 1592 }
1593 1593
1594 void SyncManager::SyncInternal::RefreshEncryption() { 1594 void SyncManager::SyncInternal::RefreshEncryption() {
1595 DCHECK(initialized_); 1595 DCHECK(initialized_);
1596 1596
1597 WriteTransaction trans(FROM_HERE, GetUserShare()); 1597 WriteTransaction trans(FROM_HERE, GetUserShare());
1598 WriteNode node(&trans); 1598 WriteNode node(&trans);
1599 if (!node.InitByTagLookup(kNigoriTag)) { 1599 if (node.InitByTagLookup(kNigoriTag) != sync_api::BaseNode::INIT_OK) {
1600 NOTREACHED() << "Unable to set encrypted datatypes because Nigori node not " 1600 NOTREACHED() << "Unable to set encrypted datatypes because Nigori node not "
1601 << "found."; 1601 << "found.";
1602 return; 1602 return;
1603 } 1603 }
1604 1604
1605 Cryptographer* cryptographer = trans.GetCryptographer(); 1605 Cryptographer* cryptographer = trans.GetCryptographer();
1606 1606
1607 if (!cryptographer->is_ready()) { 1607 if (!cryptographer->is_ready()) {
1608 DVLOG(1) << "Attempting to encrypt datatypes when cryptographer not " 1608 DVLOG(1) << "Attempting to encrypt datatypes when cryptographer not "
1609 << "initialized, prompting for passphrase."; 1609 << "initialized, prompting for passphrase.";
(...skipping 26 matching lines...) Expand all
1636 registrar_->GetModelSafeRoutingInfo(&routes); 1636 registrar_->GetModelSafeRoutingInfo(&routes);
1637 std::string tag; 1637 std::string tag;
1638 for (syncable::ModelTypeSet::Iterator iter = encrypted_types.First(); 1638 for (syncable::ModelTypeSet::Iterator iter = encrypted_types.First();
1639 iter.Good(); iter.Inc()) { 1639 iter.Good(); iter.Inc()) {
1640 if (iter.Get() == syncable::PASSWORDS || 1640 if (iter.Get() == syncable::PASSWORDS ||
1641 iter.Get() == syncable::NIGORI || 1641 iter.Get() == syncable::NIGORI ||
1642 routes.count(iter.Get()) == 0) 1642 routes.count(iter.Get()) == 0)
1643 continue; 1643 continue;
1644 ReadNode type_root(trans); 1644 ReadNode type_root(trans);
1645 tag = syncable::ModelTypeToRootTag(iter.Get()); 1645 tag = syncable::ModelTypeToRootTag(iter.Get());
1646 if (!type_root.InitByTagLookup(tag)) { 1646 if (type_root.InitByTagLookup(tag) != sync_api::BaseNode::INIT_OK) {
1647 // This can happen when we enable a datatype for the first time on restart 1647 // This can happen when we enable a datatype for the first time on restart
1648 // (for example when we upgrade) and therefore haven't done the initial 1648 // (for example when we upgrade) and therefore haven't done the initial
1649 // download for that type at the time we RefreshEncryption. There's 1649 // download for that type at the time we RefreshEncryption. There's
1650 // nothing we can do for now, so just move on to the next type. 1650 // nothing we can do for now, so just move on to the next type.
1651 continue; 1651 continue;
1652 } 1652 }
1653 1653
1654 // Iterate through all children of this datatype. 1654 // Iterate through all children of this datatype.
1655 std::queue<int64> to_visit; 1655 std::queue<int64> to_visit;
1656 int64 child_id = type_root.GetFirstChildId(); 1656 int64 child_id = type_root.GetFirstChildId();
1657 to_visit.push(child_id); 1657 to_visit.push(child_id);
1658 while (!to_visit.empty()) { 1658 while (!to_visit.empty()) {
1659 child_id = to_visit.front(); 1659 child_id = to_visit.front();
1660 to_visit.pop(); 1660 to_visit.pop();
1661 if (child_id == kInvalidId) 1661 if (child_id == kInvalidId)
1662 continue; 1662 continue;
1663 1663
1664 WriteNode child(trans); 1664 WriteNode child(trans);
1665 if (!child.InitByIdLookup(child_id)) { 1665 if (child.InitByIdLookup(child_id) != sync_api::BaseNode::INIT_OK) {
1666 NOTREACHED(); 1666 NOTREACHED();
1667 continue; 1667 continue;
1668 } 1668 }
1669 if (child.GetIsFolder()) { 1669 if (child.GetIsFolder()) {
1670 to_visit.push(child.GetFirstChildId()); 1670 to_visit.push(child.GetFirstChildId());
1671 } 1671 }
1672 if (child.GetEntry()->Get(syncable::UNIQUE_SERVER_TAG).empty()) { 1672 if (child.GetEntry()->Get(syncable::UNIQUE_SERVER_TAG).empty()) {
1673 // Rewrite the specifics of the node with encrypted data if necessary 1673 // Rewrite the specifics of the node with encrypted data if necessary
1674 // (only rewrite the non-unique folders). 1674 // (only rewrite the non-unique folders).
1675 child.ResetFromSpecifics(); 1675 child.ResetFromSpecifics();
1676 } 1676 }
1677 to_visit.push(child.GetSuccessorId()); 1677 to_visit.push(child.GetSuccessorId());
1678 } 1678 }
1679 } 1679 }
1680 1680
1681 if (routes.count(syncable::PASSWORDS) > 0) { 1681 if (routes.count(syncable::PASSWORDS) > 0) {
1682 // Passwords are encrypted with their own legacy scheme. 1682 // Passwords are encrypted with their own legacy scheme.
1683 ReadNode passwords_root(trans); 1683 ReadNode passwords_root(trans);
1684 std::string passwords_tag = 1684 std::string passwords_tag =
1685 syncable::ModelTypeToRootTag(syncable::PASSWORDS); 1685 syncable::ModelTypeToRootTag(syncable::PASSWORDS);
1686 // It's possible we'll have the password routing info and not the password 1686 // It's possible we'll have the password routing info and not the password
1687 // root if we attempted to set a passphrase before passwords was enabled. 1687 // root if we attempted to set a passphrase before passwords was enabled.
1688 if (passwords_root.InitByTagLookup(passwords_tag)) { 1688 if (passwords_root.InitByTagLookup(passwords_tag) ==
1689 sync_api::BaseNode::INIT_OK) {
1689 int64 child_id = passwords_root.GetFirstChildId(); 1690 int64 child_id = passwords_root.GetFirstChildId();
1690 while (child_id != kInvalidId) { 1691 while (child_id != kInvalidId) {
1691 WriteNode child(trans); 1692 WriteNode child(trans);
1692 if (!child.InitByIdLookup(child_id)) { 1693 if (child.InitByIdLookup(child_id) != sync_api::BaseNode::INIT_OK) {
1693 NOTREACHED(); 1694 NOTREACHED();
1694 return; 1695 return;
1695 } 1696 }
1696 child.SetPasswordSpecifics(child.GetPasswordSpecifics()); 1697 child.SetPasswordSpecifics(child.GetPasswordSpecifics());
1697 child_id = child.GetSuccessorId(); 1698 child_id = child.GetSuccessorId();
1698 } 1699 }
1699 } 1700 }
1700 } 1701 }
1701 1702
1702 // NOTE: We notify from within a transaction. 1703 // NOTE: We notify from within a transaction.
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
2085 LOG(INFO) << "OnSyncCycleCompleted not sent because sync api is not " 2086 LOG(INFO) << "OnSyncCycleCompleted not sent because sync api is not "
2086 << "initialized"; 2087 << "initialized";
2087 return; 2088 return;
2088 } 2089 }
2089 2090
2090 if (!event.snapshot->has_more_to_sync) { 2091 if (!event.snapshot->has_more_to_sync) {
2091 // To account for a nigori node arriving with stale/bad data, we ensure 2092 // To account for a nigori node arriving with stale/bad data, we ensure
2092 // that the nigori node is up to date at the end of each cycle. 2093 // that the nigori node is up to date at the end of each cycle.
2093 WriteTransaction trans(FROM_HERE, GetUserShare()); 2094 WriteTransaction trans(FROM_HERE, GetUserShare());
2094 WriteNode nigori_node(&trans); 2095 WriteNode nigori_node(&trans);
2095 if (nigori_node.InitByTagLookup(kNigoriTag)) { 2096 if (nigori_node.InitByTagLookup(kNigoriTag) ==
2097 sync_api::BaseNode::INIT_OK) {
2096 Cryptographer* cryptographer = trans.GetCryptographer(); 2098 Cryptographer* cryptographer = trans.GetCryptographer();
2097 UpdateNigoriEncryptionState(cryptographer, &nigori_node); 2099 UpdateNigoriEncryptionState(cryptographer, &nigori_node);
2098 } 2100 }
2099 2101
2100 DVLOG(1) << "Sending OnSyncCycleCompleted"; 2102 DVLOG(1) << "Sending OnSyncCycleCompleted";
2101 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 2103 FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
2102 OnSyncCycleCompleted(event.snapshot)); 2104 OnSyncCycleCompleted(event.snapshot));
2103 } 2105 }
2104 2106
2105 // This is here for tests, which are still using p2p notifications. 2107 // This is here for tests, which are still using p2p notifications.
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
2265 ListValue* id_list = NULL; 2267 ListValue* id_list = NULL;
2266 ReadTransaction trans(FROM_HERE, user_share); 2268 ReadTransaction trans(FROM_HERE, user_share);
2267 if (args.Get().GetList(0, &id_list)) { 2269 if (args.Get().GetList(0, &id_list)) {
2268 CHECK(id_list); 2270 CHECK(id_list);
2269 for (size_t i = 0; i < id_list->GetSize(); ++i) { 2271 for (size_t i = 0; i < id_list->GetSize(); ++i) {
2270 int64 id = GetId(*id_list, i); 2272 int64 id = GetId(*id_list, i);
2271 if (id == kInvalidId) { 2273 if (id == kInvalidId) {
2272 continue; 2274 continue;
2273 } 2275 }
2274 ReadNode node(&trans); 2276 ReadNode node(&trans);
2275 if (!node.InitByIdLookup(id)) { 2277 if (node.InitByIdLookup(id) != sync_api::BaseNode::INIT_OK) {
2276 continue; 2278 continue;
2277 } 2279 }
2278 node_summaries->Append((node.*info_getter)()); 2280 node_summaries->Append((node.*info_getter)());
2279 } 2281 }
2280 } 2282 }
2281 return JsArgList(&return_args); 2283 return JsArgList(&return_args);
2282 } 2284 }
2283 2285
2284 } // namespace 2286 } // namespace
2285 2287
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
2473 2475
2474 syncable::ModelTypeSet SyncManager::GetEncryptedDataTypesForTest() const { 2476 syncable::ModelTypeSet SyncManager::GetEncryptedDataTypesForTest() const {
2475 ReadTransaction trans(FROM_HERE, GetUserShare()); 2477 ReadTransaction trans(FROM_HERE, GetUserShare());
2476 return GetEncryptedTypes(&trans); 2478 return GetEncryptedTypes(&trans);
2477 } 2479 }
2478 2480
2479 bool SyncManager::ReceivedExperimentalTypes(syncable::ModelTypeSet* to_add) 2481 bool SyncManager::ReceivedExperimentalTypes(syncable::ModelTypeSet* to_add)
2480 const { 2482 const {
2481 ReadTransaction trans(FROM_HERE, GetUserShare()); 2483 ReadTransaction trans(FROM_HERE, GetUserShare());
2482 ReadNode node(&trans); 2484 ReadNode node(&trans);
2483 if (!node.InitByTagLookup(kNigoriTag)) { 2485 if (node.InitByTagLookup(kNigoriTag) != sync_api::BaseNode::INIT_OK) {
2484 DVLOG(1) << "Couldn't find Nigori node."; 2486 DVLOG(1) << "Couldn't find Nigori node.";
2485 return false; 2487 return false;
2486 } 2488 }
2487 if (node.GetNigoriSpecifics().sync_tabs()) { 2489 if (node.GetNigoriSpecifics().sync_tabs()) {
2488 to_add->Put(syncable::SESSIONS); 2490 to_add->Put(syncable::SESSIONS);
2489 return true; 2491 return true;
2490 } 2492 }
2491 return false; 2493 return false;
2492 } 2494 }
2493 2495
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2564 share->directory->GetDownloadProgress(i.Get(), &marker); 2566 share->directory->GetDownloadProgress(i.Get(), &marker);
2565 2567
2566 if (marker.token().empty()) 2568 if (marker.token().empty())
2567 result.Put(i.Get()); 2569 result.Put(i.Get());
2568 2570
2569 } 2571 }
2570 return result; 2572 return result;
2571 } 2573 }
2572 2574
2573 } // namespace sync_api 2575 } // namespace sync_api
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698