15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/password_manager/core/browser/password_syncable_service.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/auto_reset.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/location.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_vector.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/histogram.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/autofill/core/common/password_form.h" 13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "components/password_manager/core/browser/password_store_sync.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/escape.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "sync/api/sync_error_factory.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace password_manager { 18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Converts the |password| into a SyncData object. 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccisyncer::SyncData SyncDataFromPassword(const autofill::PasswordForm& password); 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Extracts the |PasswordForm| data from sync's protobuf format. 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciautofill::PasswordForm PasswordFromSpecifics( 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const sync_pb::PasswordSpecificsData& password); 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Returns the unique tag that will serve as the sync identifier for the 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// |password| entry. 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistd::string MakePasswordSyncTag(const sync_pb::PasswordSpecificsData& password); 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistd::string MakePasswordSyncTag(const autofill::PasswordForm& password); 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace { 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Returns true iff |password_specifics| and |password_specifics| are equal 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// memberwise. 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool AreLocalAndSyncPasswordsEqual( 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const sync_pb::PasswordSpecificsData& password_specifics, 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const autofill::PasswordForm& password_form) { 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return (password_form.scheme == password_specifics.scheme() && 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_form.signon_realm == password_specifics.signon_realm() && 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_form.origin.spec() == password_specifics.origin() && 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_form.action.spec() == password_specifics.action() && 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::UTF16ToUTF8(password_form.username_element) == 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_specifics.username_element() && 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::UTF16ToUTF8(password_form.password_element) == 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_specifics.password_element() && 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::UTF16ToUTF8(password_form.username_value) == 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_specifics.username_value() && 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::UTF16ToUTF8(password_form.password_value) == 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_specifics.password_value() && 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_form.ssl_valid == password_specifics.ssl_valid() && 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_form.preferred == password_specifics.preferred() && 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_form.date_created.ToInternalValue() == 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_specifics.date_created() && 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_form.blacklisted_by_user == 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_specifics.blacklisted() && 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_form.type == password_specifics.type() && 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_form.times_used == password_specifics.times_used() && 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::UTF16ToUTF8(password_form.display_name) == 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_specifics.display_name() && 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_form.avatar_url.spec() == password_specifics.avatar_url() && 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_form.federation_url.spec() == 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_specifics.federation_url()); 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)syncer::SyncChange::SyncChangeType GetSyncChangeType( 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PasswordStoreChange::Type type) { 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (type) { 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case PasswordStoreChange::ADD: return syncer::SyncChange::ACTION_ADD; 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case PasswordStoreChange::UPDATE: return syncer::SyncChange::ACTION_UPDATE; 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case PasswordStoreChange::REMOVE: return syncer::SyncChange::ACTION_DELETE; 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED(); 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return syncer::SyncChange::ACTION_INVALID; 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Creates a PasswordForm from |specifics| and |sync_time|, appends it to 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// |entries|. 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AppendPasswordFromSpecifics( 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const sync_pb::PasswordSpecificsData& specifics, 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Time sync_time, 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScopedVector<autofill::PasswordForm>* entries) { 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci entries->push_back( 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new autofill::PasswordForm(PasswordFromSpecifics(specifics))); 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci entries->back()->date_synced = sync_time; 855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistruct PasswordSyncableService::SyncEntries { 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScopedVector<autofill::PasswordForm>* EntriesForChangeType( 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci syncer::SyncChange::SyncChangeType type) { 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (type) { 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case syncer::SyncChange::ACTION_ADD: return &new_entries; 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case syncer::SyncChange::ACTION_UPDATE: return &updated_entries; 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case syncer::SyncChange::ACTION_DELETE: return &deleted_entries; 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case syncer::SyncChange::ACTION_INVALID: return NULL; 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return NULL; 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // List that contains the entries that are known only to sync. 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScopedVector<autofill::PasswordForm> new_entries; 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // List that contains the entries that are known to both sync and the local 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // database but have updates in sync. They need to be updated in the local 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // database. 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScopedVector<autofill::PasswordForm> updated_entries; 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The list of entries to be deleted from the local database. 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScopedVector<autofill::PasswordForm> deleted_entries; 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)PasswordSyncableService::PasswordSyncableService( 115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) PasswordStoreSync* password_store) 116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : password_store_(password_store), 117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) is_processing_sync_changes_(false) { 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PasswordSyncableService::~PasswordSyncableService() {} 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)syncer::SyncMergeResult PasswordSyncableService::MergeDataAndStartSyncing( 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::ModelType type, 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const syncer::SyncDataList& initial_sync_data, 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<syncer::SyncChangeProcessor> sync_processor, 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) { 127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(syncer::PASSWORDS, type); 129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::AutoReset<bool> processing_changes(&is_processing_sync_changes_, true); 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::SyncMergeResult merge_result(type); 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We add all the db entries as |new_local_entries| initially. During model 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // association entries that match a sync entry will be removed and this list 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // will only contain entries that are not in sync. 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedVector<autofill::PasswordForm> password_entries; 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PasswordEntryMap new_local_entries; 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!ReadFromPasswordStore(&password_entries, &new_local_entries)) { 1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci merge_result.set_error(sync_error_factory->CreateAndUploadError( 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "Failed to get passwords from store.")); 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return merge_result; 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (password_entries.size() != new_local_entries.size()) { 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci merge_result.set_error(sync_error_factory->CreateAndUploadError( 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FROM_HERE, 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "There are passwords with identical sync tags in the database.")); 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return merge_result; 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Save |sync_processor_| only if reading the PasswordStore succeeded. In case 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // of failure Sync shouldn't receive any updates from the PasswordStore. 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sync_error_factory_ = sync_error_factory.Pass(); 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sync_processor_ = sync_processor.Pass(); 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci merge_result.set_num_items_before_association(new_local_entries.size()); 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SyncEntries sync_entries; 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Changes from password db that need to be propagated to sync. 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::SyncChangeList updated_db_entries; 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (syncer::SyncDataList::const_iterator sync_iter = 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) initial_sync_data.begin(); 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_iter != initial_sync_data.end(); ++sync_iter) { 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateOrUpdateEntry(*sync_iter, 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &new_local_entries, 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &sync_entries, 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &updated_db_entries); 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WriteToPasswordStore(sync_entries); 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) merge_result.set_num_items_after_association( 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci merge_result.num_items_before_association() + 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sync_entries.new_entries.size()); 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci merge_result.set_num_items_added(sync_entries.new_entries.size()); 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci merge_result.set_num_items_modified(sync_entries.updated_entries.size()); 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PasswordEntryMap::iterator it = new_local_entries.begin(); 1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci it != new_local_entries.end(); ++it) { 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) updated_db_entries.push_back( 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::SyncChange(FROM_HERE, 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::SyncChange::ACTION_ADD, 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SyncDataFromPassword(*it->second))); 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) merge_result.set_error( 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_processor_->ProcessSyncChanges(FROM_HERE, updated_db_entries)); 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return merge_result; 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PasswordSyncableService::StopSyncing(syncer::ModelType type) { 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(CalledOnValidThread()); 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK_EQ(syncer::PASSWORDS, type); 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_processor_.reset(); 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_error_factory_.reset(); 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)syncer::SyncDataList PasswordSyncableService::GetAllSyncData( 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::ModelType type) const { 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(syncer::PASSWORDS, type); 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedVector<autofill::PasswordForm> password_entries; 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ReadFromPasswordStore(&password_entries, NULL); 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::SyncDataList sync_data; 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PasswordForms::iterator it = password_entries.begin(); 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != password_entries.end(); ++it) { 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_data.push_back(SyncDataFromPassword(**it)); 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return sync_data; 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)syncer::SyncError PasswordSyncableService::ProcessSyncChanges( 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const tracked_objects::Location& from_here, 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const syncer::SyncChangeList& change_list) { 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(CalledOnValidThread()); 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::AutoReset<bool> processing_changes(&is_processing_sync_changes_, true); 2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SyncEntries sync_entries; 222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Time time_now = base::Time::Now(); 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (syncer::SyncChangeList::const_iterator it = change_list.begin(); 2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci it != change_list.end(); ++it) { 226a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const sync_pb::EntitySpecifics& specifics = it->sync_data().GetSpecifics(); 2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScopedVector<autofill::PasswordForm>* entries = 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sync_entries.EntriesForChangeType(it->change_type()); 2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!entries) { 2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return sync_error_factory_->CreateAndUploadError( 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FROM_HERE, 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "Failed to process sync changes for passwords datatype."); 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AppendPasswordFromSpecifics( 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci specifics.password().client_only_encrypted_data(), time_now, entries); 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WriteToPasswordStore(sync_entries); 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return syncer::SyncError(); 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PasswordSyncableService::ActOnPasswordStoreChanges( 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const PasswordStoreChangeList& local_changes) { 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(CalledOnValidThread()); 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!sync_processor_) { 246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!flare_.is_null()) { 247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) flare_.Run(syncer::PASSWORDS); 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) flare_.Reset(); 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // ActOnPasswordStoreChanges() can be called from ProcessSyncChanges(). Do 254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // nothing in this case. 255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (is_processing_sync_changes_) 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::SyncChangeList sync_changes; 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PasswordStoreChangeList::const_iterator it = local_changes.begin(); 2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci it != local_changes.end(); ++it) { 260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) syncer::SyncData data = (it->type() == PasswordStoreChange::REMOVE ? 261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) syncer::SyncData::CreateLocalDelete(MakePasswordSyncTag(it->form()), 262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) syncer::PASSWORDS) : 263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) SyncDataFromPassword(it->form())); 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_changes.push_back( 265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) syncer::SyncChange(FROM_HERE, GetSyncChangeType(it->type()), data)); 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_processor_->ProcessSyncChanges(FROM_HERE, sync_changes); 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 270a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void PasswordSyncableService::InjectStartSyncFlare( 271a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const syncer::SyncableService::StartSyncFlare& flare) { 272a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(CalledOnValidThread()); 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) flare_ = flare; 274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool PasswordSyncableService::ReadFromPasswordStore( 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ScopedVector<autofill::PasswordForm>* password_entries, 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PasswordEntryMap* passwords_entry_map) const { 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(password_entries); 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!password_store_->FillAutofillableLogins(&password_entries->get()) || 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !password_store_->FillBlacklistLogins(&password_entries->get())) { 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Password store often fails to load passwords. Track failures with UMA. 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // (http://crbug.com/249000) 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Sync.LocalDataFailedToLoad", 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ModelTypeToHistogramInt(syncer::PASSWORDS), 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::MODEL_TYPE_COUNT); 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!passwords_entry_map) 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PasswordEntryMap& entry_map = *passwords_entry_map; 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (PasswordForms::iterator it = password_entries->begin(); 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != password_entries->end(); ++it) { 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) autofill::PasswordForm* password_form = *it; 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci entry_map[MakePasswordSyncTag(*password_form)] = password_form; 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PasswordSyncableService::WriteToPasswordStore(const SyncEntries& entries) { 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PasswordStoreChangeList changes; 3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WriteEntriesToDatabase(&PasswordStoreSync::AddLoginImpl, 3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci entries.new_entries.get(), 3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &changes); 3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WriteEntriesToDatabase(&PasswordStoreSync::UpdateLoginImpl, 3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci entries.updated_entries.get(), 3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &changes); 3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WriteEntriesToDatabase(&PasswordStoreSync::RemoveLoginImpl, 3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci entries.deleted_entries.get(), 3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &changes); 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We have to notify password store observers of the change by hand since 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // we use internal password store interfaces to make changes synchronously. 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) password_store_->NotifyLoginsChanged(changes); 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void PasswordSyncableService::CreateOrUpdateEntry( 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const syncer::SyncData& data, 3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PasswordEntryMap* unmatched_data_from_password_db, 3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SyncEntries* sync_entries, 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::SyncChangeList* updated_db_entries) { 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const sync_pb::EntitySpecifics& specifics = data.GetSpecifics(); 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const sync_pb::PasswordSpecificsData& password_specifics( 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) specifics.password().client_only_encrypted_data()); 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string tag = MakePasswordSyncTag(password_specifics); 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Check whether the data from sync is already in the password store. 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PasswordEntryMap::iterator existing_local_entry_iter = 3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unmatched_data_from_password_db->find(tag); 333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::Time time_now = base::Time::Now(); 3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (existing_local_entry_iter == unmatched_data_from_password_db->end()) { 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The sync data is not in the password store, so we need to create it in 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the password store. Add the entry to the new_entries list. 3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AppendPasswordFromSpecifics(password_specifics, time_now, 3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &sync_entries->new_entries); 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The entry is in password store. If the entries are not identical, then 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the entries need to be merged. 3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If the passwords differ, take the one that was created more recently. 3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const autofill::PasswordForm& password_form = 3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *existing_local_entry_iter->second; 3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!AreLocalAndSyncPasswordsEqual(password_specifics, password_form)) { 3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (base::Time::FromInternalValue(password_specifics.date_created()) < 3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_form.date_created) { 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) updated_db_entries->push_back( 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::SyncChange(FROM_HERE, 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) syncer::SyncChange::ACTION_UPDATE, 3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SyncDataFromPassword(password_form))); 3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AppendPasswordFromSpecifics(password_specifics, time_now, 3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &sync_entries->updated_entries); 3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Remove the entry from the entry map to indicate a match has been found. 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Entries that remain in the map at the end of associating all sync entries 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // will be treated as additions that need to be propagated to sync. 3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci unmatched_data_from_password_db->erase(existing_local_entry_iter); 3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid PasswordSyncableService::WriteEntriesToDatabase( 3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DatabaseOperation operation, 3661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const PasswordForms& entries, 3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PasswordStoreChangeList* all_changes) { 3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (PasswordForms::const_iterator it = entries.begin(); 3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci it != entries.end(); ++it) { 3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PasswordStoreChangeList new_changes = (password_store_->*operation)(**it); 3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci all_changes->insert(all_changes->end(), 3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_changes.begin(), 3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_changes.end()); 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)syncer::SyncData SyncDataFromPassword( 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const autofill::PasswordForm& password_form) { 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_pb::EntitySpecifics password_data; 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sync_pb::PasswordSpecificsData* password_specifics = 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) password_data.mutable_password()->mutable_client_only_encrypted_data(); 3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define CopyField(field) password_specifics->set_ ## field(password_form.field) 3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#define CopyStringField(field) \ 3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_specifics->set_ ## field(base::UTF16ToUTF8(password_form.field)) 3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CopyField(scheme); 3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CopyField(signon_realm); 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) password_specifics->set_origin(password_form.origin.spec()); 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) password_specifics->set_action(password_form.action.spec()); 3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CopyStringField(username_element); 3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CopyStringField(password_element); 3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CopyStringField(username_value); 3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CopyStringField(password_value); 3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CopyField(ssl_valid); 3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CopyField(preferred); 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) password_specifics->set_date_created( 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) password_form.date_created.ToInternalValue()); 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) password_specifics->set_blacklisted(password_form.blacklisted_by_user); 3981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CopyField(type); 3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CopyField(times_used); 4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CopyStringField(display_name); 4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_specifics->set_avatar_url(password_form.avatar_url.spec()); 4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci password_specifics->set_federation_url(password_form.federation_url.spec()); 4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#undef CopyStringField 4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#undef CopyField 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string tag = MakePasswordSyncTag(*password_specifics); 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return syncer::SyncData::CreateLocalData(tag, tag, password_data); 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciautofill::PasswordForm PasswordFromSpecifics( 4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const sync_pb::PasswordSpecificsData& password) { 4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci autofill::PasswordForm new_password; 4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_password.scheme = 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<autofill::PasswordForm::Scheme>(password.scheme()); 4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_password.signon_realm = password.signon_realm(); 4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_password.origin = GURL(password.origin()); 4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_password.action = GURL(password.action()); 4181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_password.username_element = 4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF8ToUTF16(password.username_element()); 4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_password.password_element = 4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF8ToUTF16(password.password_element()); 4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_password.username_value = base::UTF8ToUTF16(password.username_value()); 4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_password.password_value = base::UTF8ToUTF16(password.password_value()); 4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_password.ssl_valid = password.ssl_valid(); 4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_password.preferred = password.preferred(); 4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_password.date_created = 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time::FromInternalValue(password.date_created()); 4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_password.blacklisted_by_user = password.blacklisted(); 4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_password.type = 4300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch static_cast<autofill::PasswordForm::Type>(password.type()); 4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_password.times_used = password.times_used(); 4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_password.display_name = base::UTF8ToUTF16(password.display_name()); 4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_password.avatar_url = GURL(password.avatar_url()); 4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_password.federation_url = GURL(password.federation_url()); 4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return new_password; 4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string MakePasswordSyncTag( 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const sync_pb::PasswordSpecificsData& password) { 4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return MakePasswordSyncTag(PasswordFromSpecifics(password)); 4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistd::string MakePasswordSyncTag(const autofill::PasswordForm& password) { 4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return (net::EscapePath(password.origin.spec()) + "|" + 4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::EscapePath(base::UTF16ToUTF8(password.username_element)) + "|" + 4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::EscapePath(base::UTF16ToUTF8(password.username_value)) + "|" + 4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::EscapePath(base::UTF16ToUTF8(password.password_element)) + "|" + 4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::EscapePath(password.signon_realm)); 4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 450c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 451c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} // namespace password_manager 452