diff options
author | isherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-22 01:06:49 +0000 |
---|---|---|
committer | isherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-22 01:06:49 +0000 |
commit | 4dacf9a507dbfa3754f145d9fda4348faeef2057 (patch) | |
tree | 454069087b10e5cd9951f97b7777bc1e3e5e102f /components | |
parent | bb5596a07d45d3a4832b337c62a22e2c3f90a7ee (diff) | |
download | chromium_src-4dacf9a507dbfa3754f145d9fda4348faeef2057.zip chromium_src-4dacf9a507dbfa3754f145d9fda4348faeef2057.tar.gz chromium_src-4dacf9a507dbfa3754f145d9fda4348faeef2057.tar.bz2 |
[Autofill] Write origins to the WebDB.
Also, make sure to clear the origins when history is cleared.
BUG=170401, 231029
TEST=unit tested
Review URL: https://chromiumcodereview.appspot.com/14974004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@201414 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components')
11 files changed, 447 insertions, 65 deletions
diff --git a/components/autofill/browser/personal_data_manager_unittest.cc b/components/autofill/browser/personal_data_manager_unittest.cc index 8e67dc0..439991c 100644 --- a/components/autofill/browser/personal_data_manager_unittest.cc +++ b/components/autofill/browser/personal_data_manager_unittest.cc @@ -339,10 +339,8 @@ TEST_F(PersonalDataManagerTest, UpdateUnverifiedProfilesAndCreditCards) { ASSERT_EQ(1U, cards2.size()); EXPECT_NE(profile.origin(), profiles2[0]->origin()); EXPECT_NE(credit_card.origin(), cards2[0]->origin()); - // TODO(isherman): Verify that the origins match once they are saved and read - // from the database. http://crbug.com/170401 - // EXPECT_EQ(original_profile.origin(), profiles2[0]->origin()); - // EXPECT_EQ(original_credit_card.origin(), cards2[0]->origin()); + EXPECT_EQ(original_profile.origin(), profiles2[0]->origin()); + EXPECT_EQ(original_credit_card.origin(), cards2[0]->origin()); // Try to update with data changed as well. profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John")); @@ -363,10 +361,8 @@ TEST_F(PersonalDataManagerTest, UpdateUnverifiedProfilesAndCreditCards) { ASSERT_EQ(1U, cards3.size()); EXPECT_EQ(0, profile.Compare(*profiles3[0])); EXPECT_EQ(0, credit_card.Compare(*cards3[0])); - // TODO(isherman): Verify that the origins match once they are saved and read - // from the database. http://crbug.com/170401 - // EXPECT_EQ(profile.origin(), profiles3[0]->origin()); - // EXPECT_EQ(credit_card.origin(), cards3[0]->origin()); + EXPECT_EQ(profile.origin(), profiles3[0]->origin()); + EXPECT_EQ(credit_card.origin(), cards3[0]->origin()); } TEST_F(PersonalDataManagerTest, AddProfilesAndCreditCards) { @@ -1923,10 +1919,7 @@ TEST_F(PersonalDataManagerTest, AggregateSameCreditCardWithSeparators) { // Ensure that if a verified profile already exists, aggregated profiles cannot // modify it in any way. -// TODO(isherman): Enable this test once origins are saved and read from the -// database. http://crbug.com/170401 -TEST_F(PersonalDataManagerTest, - DISABLED_AggregateExistingVerifiedProfileWithConflict) { +TEST_F(PersonalDataManagerTest, AggregateExistingVerifiedProfileWithConflict) { // Start with a verified profile. AutofillProfile profile; profile.set_origin("Chrome settings"); @@ -1986,10 +1979,8 @@ TEST_F(PersonalDataManagerTest, // Ensure that if a verified credit card already exists, aggregated credit cards // cannot modify it in any way. -// TODO(isherman): Enable this test once origins are saved and read from the -// database. http://crbug.com/170401 TEST_F(PersonalDataManagerTest, - DISABLED_AggregateExistingVerifiedCreditCardWithConflict) { + AggregateExistingVerifiedCreditCardWithConflict) { // Start with a verified credit card. CreditCard credit_card; credit_card.set_origin("Chrome settings"); diff --git a/components/autofill/browser/webdata/autofill_table.cc b/components/autofill/browser/webdata/autofill_table.cc index 99eeeb4..5f94f2d 100644 --- a/components/autofill/browser/webdata/autofill_table.cc +++ b/components/autofill/browser/webdata/autofill_table.cc @@ -27,6 +27,7 @@ #include "components/autofill/common/form_field_data.h" #include "components/webdata/common/web_database.h" #include "components/webdata/encryptor/encryptor.h" +#include "googleurl/src/gurl.h" #include "sql/statement.h" #include "sql/transaction.h" #include "ui/base/l10n/l10n_util.h" @@ -76,6 +77,7 @@ void BindAutofillProfileToStatement(const AutofillProfile& profile, text = profile.GetRawInfo(ADDRESS_HOME_COUNTRY); s->BindString16(8, LimitDataSize(text)); s->BindInt64(9, Time::Now().ToTimeT()); + s->BindString(10, profile.origin()); } AutofillProfile* AutofillProfileFromStatement(const sql::Statement& s, @@ -93,6 +95,7 @@ AutofillProfile* AutofillProfileFromStatement(const sql::Statement& s, // Intentionally skip column 7, which stores the localized country name. profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(8)); // Intentionally skip column 9, which stores the profile's modification date. + profile->set_origin(s.ColumnString(10)); return profile; } @@ -114,6 +117,7 @@ void BindCreditCardToStatement(const CreditCard& credit_card, s->BindBlob(4, encrypted_data.data(), static_cast<int>(encrypted_data.length())); s->BindInt64(5, Time::Now().ToTimeT()); + s->BindString(6, credit_card.origin()); } CreditCard* CreditCardFromStatement(const sql::Statement& s) { @@ -135,6 +139,7 @@ CreditCard* CreditCardFromStatement(const sql::Statement& s) { } credit_card->SetRawInfo(CREDIT_CARD_NUMBER, credit_card_number); // Intentionally skip column 5, which stores the modification date. + credit_card->set_origin(s.ColumnString(6)); return credit_card; } @@ -332,6 +337,13 @@ WebDatabaseTable::TypeKey GetKey() { return reinterpret_cast<void*>(&table_key); } +time_t GetEndTime(const base::Time& end) { + if (end.is_null() || end == base::Time::Max()) + return std::numeric_limits<time_t>::max(); + + return end.ToTimeT(); +} + } // namespace // The maximum length allowed for form data. @@ -405,9 +417,11 @@ bool AutofillTable::MigrateToVersion(int version, case 37: *update_compatible_version = true; return MigrateToVersion37MergeAndCullOlderProfiles(); - - case 50: - return MigrateToVersion50AddOriginColumn(); + case 51: + // Combine migrations 50 and 51. The migration code from version 49 to 50 + // worked correctly for users with existing 'origin' columns, but failed + // to create these columns for new users. + return MigrateToVersion51AddOriginColumn(); } return true; } @@ -951,8 +965,8 @@ bool AutofillTable::AddAutofillProfile(const AutofillProfile& profile) { sql::Statement s(db_->GetUniqueStatement( "INSERT INTO autofill_profiles" "(guid, company_name, address_line_1, address_line_2, city, state," - " zipcode, country, country_code, date_modified)" - "VALUES (?,?,?,?,?,?,?,?,?,?)")); + " zipcode, country, country_code, date_modified, origin)" + "VALUES (?,?,?,?,?,?,?,?,?,?,?)")); BindAutofillProfileToStatement(profile, &s, app_locale_); if (!s.Run()) @@ -967,7 +981,7 @@ bool AutofillTable::GetAutofillProfile(const std::string& guid, DCHECK(profile); sql::Statement s(db_->GetUniqueStatement( "SELECT guid, company_name, address_line_1, address_line_2, city, state," - " zipcode, country, country_code, date_modified " + " zipcode, country, country_code, date_modified, origin " "FROM autofill_profiles " "WHERE guid=?")); s.BindString(0, guid); @@ -1059,17 +1073,18 @@ bool AutofillTable::UpdateAutofillProfileMulti(const AutofillProfile& profile) { // Preserve appropriate modification dates by not updating unchanged profiles. scoped_ptr<AutofillProfile> old_profile(tmp_profile); - if (old_profile->Compare(profile) == 0) + if (old_profile->Compare(profile) == 0 && + old_profile->origin() == profile.origin()) return true; sql::Statement s(db_->GetUniqueStatement( "UPDATE autofill_profiles " "SET guid=?, company_name=?, address_line_1=?, address_line_2=?, " " city=?, state=?, zipcode=?, country=?, country_code=?, " - " date_modified=? " + " date_modified=?, origin=? " "WHERE guid=?")); BindAutofillProfileToStatement(profile, &s, app_locale_); - s.BindString(10, profile.guid()); + s.BindString(11, profile.guid()); bool result = s.Run(); DCHECK_GT(db_->GetLastChangeCount(), 0); @@ -1135,8 +1150,8 @@ bool AutofillTable::AddCreditCard(const CreditCard& credit_card) { sql::Statement s(db_->GetUniqueStatement( "INSERT INTO credit_cards" "(guid, name_on_card, expiration_month, expiration_year, " - "card_number_encrypted, date_modified)" - "VALUES (?,?,?,?,?,?)")); + " card_number_encrypted, date_modified, origin)" + "VALUES (?,?,?,?,?,?,?)")); BindCreditCardToStatement(credit_card, &s); if (!s.Run()) @@ -1151,7 +1166,7 @@ bool AutofillTable::GetCreditCard(const std::string& guid, DCHECK(base::IsValidGUID(guid)); sql::Statement s(db_->GetUniqueStatement( "SELECT guid, name_on_card, expiration_month, expiration_year, " - "card_number_encrypted, date_modified " + " card_number_encrypted, date_modified, origin " "FROM credit_cards " "WHERE guid = ?")); s.BindString(0, guid); @@ -1198,10 +1213,11 @@ bool AutofillTable::UpdateCreditCard(const CreditCard& credit_card) { sql::Statement s(db_->GetUniqueStatement( "UPDATE credit_cards " "SET guid=?, name_on_card=?, expiration_month=?, " - " expiration_year=?, card_number_encrypted=?, date_modified=? " + " expiration_year=?, card_number_encrypted=?, date_modified=?, " + " origin=? " "WHERE guid=?")); BindCreditCardToStatement(credit_card, &s); - s.BindString(6, credit_card.guid()); + s.BindString(7, credit_card.guid()); bool result = s.Run(); DCHECK_GT(db_->GetLastChangeCount(), 0); @@ -1225,9 +1241,7 @@ bool AutofillTable::RemoveAutofillDataModifiedBetween( DCHECK(delete_end.is_null() || delete_begin < delete_end); time_t delete_begin_t = delete_begin.ToTimeT(); - time_t delete_end_t = - (delete_end.is_null() || delete_end == base::Time::Max()) ? - std::numeric_limits<time_t>::max() : delete_end.ToTimeT(); + time_t delete_end_t = GetEndTime(delete_end); // Remember Autofill profiles in the time range. sql::Statement s_profiles_get(db_->GetUniqueStatement( @@ -1279,6 +1293,78 @@ bool AutofillTable::RemoveAutofillDataModifiedBetween( return s_credit_cards.Run(); } +bool AutofillTable::RemoveOriginURLsModifiedBetween( + const Time& delete_begin, + const Time& delete_end, + ScopedVector<AutofillProfile>* profiles) { + DCHECK(delete_end.is_null() || delete_begin < delete_end); + + time_t delete_begin_t = delete_begin.ToTimeT(); + time_t delete_end_t = GetEndTime(delete_end); + + // Remember Autofill profiles with URL origins in the time range. + sql::Statement s_profiles_get(db_->GetUniqueStatement( + "SELECT guid, origin FROM autofill_profiles " + "WHERE date_modified >= ? AND date_modified < ?")); + s_profiles_get.BindInt64(0, delete_begin_t); + s_profiles_get.BindInt64(1, delete_end_t); + + std::vector<std::string> profile_guids; + while (s_profiles_get.Step()) { + std::string guid = s_profiles_get.ColumnString(0); + std::string origin = s_profiles_get.ColumnString(1); + if (GURL(origin).is_valid()) + profile_guids.push_back(guid); + } + if (!s_profiles_get.Succeeded()) + return false; + + // Clear out the origins for the found Autofill profiles. + for (std::vector<std::string>::const_iterator it = profile_guids.begin(); + it != profile_guids.end(); ++it) { + sql::Statement s_profile(db_->GetUniqueStatement( + "UPDATE autofill_profiles SET origin='' WHERE guid=?")); + s_profile.BindString(0, *it); + if (!s_profile.Run()) + return false; + + AutofillProfile* profile; + if (!GetAutofillProfile(*it, &profile)) + return false; + + profiles->push_back(profile); + } + + // Remember Autofill credit cards with URL origins in the time range. + sql::Statement s_credit_cards_get(db_->GetUniqueStatement( + "SELECT guid, origin FROM credit_cards " + "WHERE date_modified >= ? AND date_modified < ?")); + s_credit_cards_get.BindInt64(0, delete_begin_t); + s_credit_cards_get.BindInt64(1, delete_end_t); + + std::vector<std::string> credit_card_guids; + while (s_credit_cards_get.Step()) { + std::string guid = s_credit_cards_get.ColumnString(0); + std::string origin = s_credit_cards_get.ColumnString(1); + if (GURL(origin).is_valid()) + credit_card_guids.push_back(guid); + } + if (!s_credit_cards_get.Succeeded()) + return false; + + // Clear out the origins for the found credit cards. + for (std::vector<std::string>::const_iterator it = credit_card_guids.begin(); + it != credit_card_guids.end(); ++it) { + sql::Statement s_credit_card(db_->GetUniqueStatement( + "UPDATE credit_cards SET origin='' WHERE guid=?")); + s_credit_card.BindString(0, *it); + if (!s_credit_card.Run()) + return false; + } + + return true; +} + bool AutofillTable::GetAutofillProfilesInTrash( std::vector<std::string>* guids) { guids->clear(); @@ -1374,7 +1460,8 @@ bool AutofillTable::InitCreditCardsTable() { "expiration_month INTEGER, " "expiration_year INTEGER, " "card_number_encrypted BLOB, " - "date_modified INTEGER NOT NULL DEFAULT 0)")) { + "date_modified INTEGER NOT NULL DEFAULT 0, " + "origin VARCHAR DEFAULT '')")) { NOTREACHED(); return false; } @@ -1412,7 +1499,8 @@ bool AutofillTable::InitProfilesTable() { "zipcode VARCHAR, " "country VARCHAR, " "country_code VARCHAR, " - "date_modified INTEGER NOT NULL DEFAULT 0)")) { + "date_modified INTEGER NOT NULL DEFAULT 0, " + "origin VARCHAR DEFAULT '')")) { NOTREACHED(); return false; } @@ -2003,16 +2091,46 @@ bool AutofillTable::MigrateToVersion37MergeAndCullOlderProfiles() { int64 date_modified = s.ColumnInt64(1); modification_map.insert( std::pair<std::string, int64>(guid, date_modified)); - AutofillProfile* profile = NULL; - if (!GetAutofillProfile(guid, &profile)) + + sql::Statement s(db_->GetUniqueStatement( + "SELECT guid, company_name, address_line_1, address_line_2, city, " + " state, zipcode, country, country_code, date_modified " + "FROM autofill_profiles " + "WHERE guid=?")); + s.BindString(0, guid); + + if (!s.Step()) return false; - scoped_ptr<AutofillProfile> p(profile); + scoped_ptr<AutofillProfile> profile(new AutofillProfile); + profile->set_guid(s.ColumnString(0)); + DCHECK(base::IsValidGUID(profile->guid())); + + profile->SetRawInfo(COMPANY_NAME, s.ColumnString16(1)); + profile->SetRawInfo(ADDRESS_HOME_LINE1, s.ColumnString16(2)); + profile->SetRawInfo(ADDRESS_HOME_LINE2, s.ColumnString16(3)); + profile->SetRawInfo(ADDRESS_HOME_CITY, s.ColumnString16(4)); + profile->SetRawInfo(ADDRESS_HOME_STATE, s.ColumnString16(5)); + profile->SetRawInfo(ADDRESS_HOME_ZIP, s.ColumnString16(6)); + // Intentionally skip column 7, which stores the localized country name. + profile->SetRawInfo(ADDRESS_HOME_COUNTRY, s.ColumnString16(8)); + // Intentionally skip column 9, which stores the profile's modification + // date. + profile->set_origin(s.ColumnString(10)); + + // Get associated name info. + AddAutofillProfileNamesToProfile(db_, profile.get()); + + // Get associated email info. + AddAutofillProfileEmailsToProfile(db_, profile.get()); + + // Get associated phone info. + AddAutofillProfilePhonesToProfile(db_, profile.get()); - if (PersonalDataManager::IsValidLearnableProfile(*p, app_locale_)) { + if (PersonalDataManager::IsValidLearnableProfile(*profile, app_locale_)) { std::vector<AutofillProfile> merged_profiles; bool merged = PersonalDataManager::MergeProfile( - *p, accumulated_profiles_p, app_locale_, &merged_profiles); + *profile, accumulated_profiles_p, app_locale_, &merged_profiles); std::swap(accumulated_profiles, merged_profiles); @@ -2025,11 +2143,11 @@ bool AutofillTable::MigrateToVersion37MergeAndCullOlderProfiles() { // If the profile got merged trash the original. if (merged) - AddAutofillGUIDToTrash(p->guid()); + AddAutofillGUIDToTrash(profile->guid()); } else { // An invalid profile, so trash it. - AddAutofillGUIDToTrash(p->guid()); + AddAutofillGUIDToTrash(profile->guid()); } } // endwhile if (!s.Succeeded()) @@ -2044,40 +2162,61 @@ bool AutofillTable::MigrateToVersion37MergeAndCullOlderProfiles() { iter = accumulated_profiles.begin(); iter != accumulated_profiles.end(); ++iter) { - if (!AddAutofillProfile(*iter)) - return false; - - // Fix up the original modification date. + // Save the profile with its original modification date. std::map<std::string, int64>::const_iterator date_item = modification_map.find(iter->guid()); if (date_item == modification_map.end()) return false; - sql::Statement s_date(db_->GetUniqueStatement( - "UPDATE autofill_profiles SET date_modified=? " - "WHERE guid=?")); - s_date.BindInt64(0, date_item->second); - s_date.BindString(1, iter->guid()); + sql::Statement s(db_->GetUniqueStatement( + "INSERT INTO autofill_profiles" + "(guid, company_name, address_line_1, address_line_2, city, state," + " zipcode, country, country_code, date_modified)" + "VALUES (?,?,?,?,?,?,?,?,?,?)")); + s.BindString(0, iter->guid()); + base::string16 text = iter->GetRawInfo(COMPANY_NAME); + s.BindString16(1, LimitDataSize(text)); + text = iter->GetRawInfo(ADDRESS_HOME_LINE1); + s.BindString16(2, LimitDataSize(text)); + text = iter->GetRawInfo(ADDRESS_HOME_LINE2); + s.BindString16(3, LimitDataSize(text)); + text = iter->GetRawInfo(ADDRESS_HOME_CITY); + s.BindString16(4, LimitDataSize(text)); + text = iter->GetRawInfo(ADDRESS_HOME_STATE); + s.BindString16(5, LimitDataSize(text)); + text = iter->GetRawInfo(ADDRESS_HOME_ZIP); + s.BindString16(6, LimitDataSize(text)); + text = iter->GetInfo(ADDRESS_HOME_COUNTRY, app_locale_); + s.BindString16(7, LimitDataSize(text)); + text = iter->GetRawInfo(ADDRESS_HOME_COUNTRY); + s.BindString16(8, LimitDataSize(text)); + s.BindInt64(9, date_item->second); - if (!s_date.Run()) + if (!s.Run()) + return false; + + if (!AddAutofillProfilePieces(*iter, db_)) return false; } return true; } -bool AutofillTable::MigrateToVersion50AddOriginColumn() { +bool AutofillTable::MigrateToVersion51AddOriginColumn() { sql::Transaction transaction(db_); + if (!transaction.Begin()) + return false; // Add origin to autofill_profiles. - if (!transaction.Begin() || + if (!db_->DoesColumnExist("autofill_profiles", "origin") && !db_->Execute("ALTER TABLE autofill_profiles " "ADD COLUMN origin VARCHAR DEFAULT ''")) { return false; } // Add origin to credit_cards. - if (!db_->Execute("ALTER TABLE credit_cards " + if (!db_->DoesColumnExist("credit_cards", "origin") && + !db_->Execute("ALTER TABLE credit_cards " "ADD COLUMN origin VARCHAR DEFAULT ''")) { return false; } diff --git a/components/autofill/browser/webdata/autofill_table.h b/components/autofill/browser/webdata/autofill_table.h index 0ff0c8f..94a6ebb 100644 --- a/components/autofill/browser/webdata/autofill_table.h +++ b/components/autofill/browser/webdata/autofill_table.h @@ -9,6 +9,7 @@ #include "base/compiler_specific.h" #include "base/gtest_prod_util.h" +#include "base/memory/scoped_vector.h" #include "base/string16.h" #include "components/webdata/common/web_database_table.h" @@ -271,17 +272,28 @@ class AutofillTable : public WebDatabaseTable { virtual bool GetCreditCards(std::vector<CreditCard*>* credit_cards); // Removes rows from autofill_profiles and credit_cards if they were created - // on or after |delete_begin| and strictly before |delete_end|. Returns lists - // of deleted guids in |profile_guids| and |credit_card_guids|. Return value - // is true if all rows were successfully removed. Returns false on database - // error. In that case, the output vector state is undefined, and may be - // partially filled. + // on or after |delete_begin| and strictly before |delete_end|. Returns the + // list of deleted profile guids in |profile_guids|. Return value is true if + // all rows were successfully removed. Returns false on database error. In + // that case, the output vector state is undefined, and may be partially + // filled. bool RemoveAutofillDataModifiedBetween( const base::Time& delete_begin, const base::Time& delete_end, std::vector<std::string>* profile_guids, std::vector<std::string>* credit_card_guids); + // Removes origin URLs from the autofill_profiles and credit_cards tables if + // they were written on or after |delete_begin| and strictly before + // |delete_end|. Returns the list of modified profiles in |profiles|. Return + // value is true if all rows were successfully updated. Returns false on + // database error. In that case, the output vector state is undefined, and + // may be partially filled. + bool RemoveOriginURLsModifiedBetween( + const base::Time& delete_begin, + const base::Time& delete_end, + ScopedVector<AutofillProfile>* profiles); + // Retrieves all profiles in the database that have been deleted since last // "empty" of the trash. bool GetAutofillProfilesInTrash(std::vector<std::string>* guids); @@ -311,7 +323,7 @@ class AutofillTable : public WebDatabaseTable { bool MigrateToVersion34ProfilesBasedOnCountryCode(); bool MigrateToVersion35GreatBritainCountryCodes(); bool MigrateToVersion37MergeAndCullOlderProfiles(); - bool MigrateToVersion50AddOriginColumn(); + bool MigrateToVersion51AddOriginColumn(); // Max data length saved in the table; static const size_t kMaxDataLength; diff --git a/components/autofill/browser/webdata/autofill_table_unittest.cc b/components/autofill/browser/webdata/autofill_table_unittest.cc index 575ece2..504452d4 100644 --- a/components/autofill/browser/webdata/autofill_table_unittest.cc +++ b/components/autofill/browser/webdata/autofill_table_unittest.cc @@ -507,6 +507,7 @@ TEST_F(AutofillTableTest, Autofill_AddFormFieldValues) { TEST_F(AutofillTableTest, AutofillProfile) { // Add a 'Home' profile. AutofillProfile home_profile; + home_profile.set_origin(std::string()); home_profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John")); home_profile.SetRawInfo(NAME_MIDDLE, ASCIIToUTF16("Q.")); home_profile.SetRawInfo(NAME_LAST, ASCIIToUTF16("Smith")); @@ -542,6 +543,7 @@ TEST_F(AutofillTableTest, AutofillProfile) { // Add a 'Billing' profile. AutofillProfile billing_profile = home_profile; billing_profile.set_guid(base::GenerateGUID()); + billing_profile.set_origin("https://www.example.com/"); billing_profile.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("5678 Bottom Street")); billing_profile.SetRawInfo(ADDRESS_HOME_LINE2, ASCIIToUTF16("suite 3")); @@ -583,6 +585,7 @@ TEST_F(AutofillTableTest, AutofillProfile) { delete db_profile; // Update the 'Billing' profile. + billing_profile.set_origin("Chrome settings"); billing_profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Janice")); billing_profile.SetRawInfo(NAME_MIDDLE, ASCIIToUTF16("C.")); billing_profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Joplin")); @@ -855,6 +858,7 @@ TEST_F(AutofillTableTest, AutofillProfileTrashInteraction) { TEST_F(AutofillTableTest, CreditCard) { // Add a 'Work' credit card. CreditCard work_creditcard; + work_creditcard.set_origin("https://www.example.com/"); work_creditcard.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Jack Torrance")); work_creditcard.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("1234567890123456")); @@ -884,6 +888,7 @@ TEST_F(AutofillTableTest, CreditCard) { // Add a 'Target' credit card. CreditCard target_creditcard; + target_creditcard.set_origin(std::string()); target_creditcard.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Jack Torrance")); target_creditcard.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("1111222233334444")); @@ -909,6 +914,7 @@ TEST_F(AutofillTableTest, CreditCard) { delete db_creditcard; // Update the 'Target' credit card. + target_creditcard.set_origin("Interactive Autofill dialog"); target_creditcard.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Charles Grady")); Time pre_modification_time = Time::Now(); EXPECT_TRUE(table_->UpdateCreditCard(target_creditcard)); @@ -1070,7 +1076,7 @@ TEST_F(AutofillTableTest, UpdateCreditCard) { // The modification date should not change. table_->UpdateCreditCard(credit_card); - // Get the profile. + // Get the credit card. ASSERT_TRUE(table_->GetCreditCard(credit_card.guid(), &tmp_credit_card)); db_credit_card.reset(tmp_credit_card); EXPECT_EQ(credit_card, *db_credit_card); @@ -1082,6 +1088,108 @@ TEST_F(AutofillTableTest, UpdateCreditCard) { EXPECT_FALSE(s_unchanged.Step()); } +TEST_F(AutofillTableTest, UpdateProfileOriginOnly) { + // Add a profile to the db. + AutofillProfile profile; + profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John")); + profile.SetRawInfo(NAME_MIDDLE, ASCIIToUTF16("Q.")); + profile.SetRawInfo(NAME_LAST, ASCIIToUTF16("Smith")); + profile.SetRawInfo(EMAIL_ADDRESS, ASCIIToUTF16("js@example.com")); + profile.SetRawInfo(COMPANY_NAME, ASCIIToUTF16("Google")); + profile.SetRawInfo(ADDRESS_HOME_LINE1, ASCIIToUTF16("1234 Apple Way")); + profile.SetRawInfo(ADDRESS_HOME_LINE2, ASCIIToUTF16("unit 5")); + profile.SetRawInfo(ADDRESS_HOME_CITY, ASCIIToUTF16("Los Angeles")); + profile.SetRawInfo(ADDRESS_HOME_STATE, ASCIIToUTF16("CA")); + profile.SetRawInfo(ADDRESS_HOME_ZIP, ASCIIToUTF16("90025")); + profile.SetRawInfo(ADDRESS_HOME_COUNTRY, ASCIIToUTF16("US")); + profile.SetRawInfo(PHONE_HOME_WHOLE_NUMBER, ASCIIToUTF16("18181234567")); + table_->AddAutofillProfile(profile); + + // Set a mocked value for the profile's creation time. + const time_t mock_creation_date = Time::Now().ToTimeT() - 13; + sql::Statement s_mock_creation_date( + db_->GetSQLConnection()->GetUniqueStatement( + "UPDATE autofill_profiles SET date_modified = ?")); + ASSERT_TRUE(s_mock_creation_date.is_valid()); + s_mock_creation_date.BindInt64(0, mock_creation_date); + ASSERT_TRUE(s_mock_creation_date.Run()); + + // Get the profile. + AutofillProfile* tmp_profile; + ASSERT_TRUE(table_->GetAutofillProfile(profile.guid(), &tmp_profile)); + scoped_ptr<AutofillProfile> db_profile(tmp_profile); + EXPECT_EQ(profile, *db_profile); + sql::Statement s_original(db_->GetSQLConnection()->GetUniqueStatement( + "SELECT date_modified FROM autofill_profiles")); + ASSERT_TRUE(s_original.is_valid()); + ASSERT_TRUE(s_original.Step()); + EXPECT_EQ(mock_creation_date, s_original.ColumnInt64(0)); + EXPECT_FALSE(s_original.Step()); + + // Now, update just the profile's origin and save the update to the database. + // The modification date should change to reflect the update. + profile.set_origin("https://www.example.com/"); + table_->UpdateAutofillProfileMulti(profile); + + // Get the profile. + ASSERT_TRUE(table_->GetAutofillProfile(profile.guid(), &tmp_profile)); + db_profile.reset(tmp_profile); + EXPECT_EQ(profile, *db_profile); + sql::Statement s_updated(db_->GetSQLConnection()->GetUniqueStatement( + "SELECT date_modified FROM autofill_profiles")); + ASSERT_TRUE(s_updated.is_valid()); + ASSERT_TRUE(s_updated.Step()); + EXPECT_LT(mock_creation_date, s_updated.ColumnInt64(0)); + EXPECT_FALSE(s_updated.Step()); +} + +TEST_F(AutofillTableTest, UpdateCreditCardOriginOnly) { + // Add a credit card to the db. + CreditCard credit_card; + credit_card.SetRawInfo(CREDIT_CARD_NAME, ASCIIToUTF16("Jack Torrance")); + credit_card.SetRawInfo(CREDIT_CARD_NUMBER, ASCIIToUTF16("1234567890123456")); + credit_card.SetRawInfo(CREDIT_CARD_EXP_MONTH, ASCIIToUTF16("04")); + credit_card.SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, ASCIIToUTF16("2013")); + table_->AddCreditCard(credit_card); + + // Set a mocked value for the credit card's creation time. + const time_t mock_creation_date = Time::Now().ToTimeT() - 13; + sql::Statement s_mock_creation_date( + db_->GetSQLConnection()->GetUniqueStatement( + "UPDATE credit_cards SET date_modified = ?")); + ASSERT_TRUE(s_mock_creation_date.is_valid()); + s_mock_creation_date.BindInt64(0, mock_creation_date); + ASSERT_TRUE(s_mock_creation_date.Run()); + + // Get the credit card. + CreditCard* tmp_credit_card; + ASSERT_TRUE(table_->GetCreditCard(credit_card.guid(), &tmp_credit_card)); + scoped_ptr<CreditCard> db_credit_card(tmp_credit_card); + EXPECT_EQ(credit_card, *db_credit_card); + sql::Statement s_original(db_->GetSQLConnection()->GetUniqueStatement( + "SELECT date_modified FROM credit_cards")); + ASSERT_TRUE(s_original.is_valid()); + ASSERT_TRUE(s_original.Step()); + EXPECT_EQ(mock_creation_date, s_original.ColumnInt64(0)); + EXPECT_FALSE(s_original.Step()); + + // Now, update just the credit card's origin and save the update to the + // database. The modification date should change to reflect the update. + credit_card.set_origin("https://www.example.com/"); + table_->UpdateCreditCard(credit_card); + + // Get the credit card. + ASSERT_TRUE(table_->GetCreditCard(credit_card.guid(), &tmp_credit_card)); + db_credit_card.reset(tmp_credit_card); + EXPECT_EQ(credit_card, *db_credit_card); + sql::Statement s_updated(db_->GetSQLConnection()->GetUniqueStatement( + "SELECT date_modified FROM credit_cards")); + ASSERT_TRUE(s_updated.is_valid()); + ASSERT_TRUE(s_updated.Step()); + EXPECT_LT(mock_creation_date, s_updated.ColumnInt64(0)); + EXPECT_FALSE(s_updated.Step()); +} + TEST_F(AutofillTableTest, RemoveAutofillDataModifiedBetween) { // Populate the autofill_profiles and credit_cards tables. ASSERT_TRUE(db_->GetSQLConnection()->Execute( @@ -1196,6 +1304,91 @@ TEST_F(AutofillTableTest, RemoveAutofillDataModifiedBetween) { EXPECT_FALSE(s_credit_cards_empty.Step()); } +TEST_F(AutofillTableTest, RemoveOriginURLsModifiedBetween) { + // Populate the autofill_profiles and credit_cards tables. + ASSERT_TRUE(db_->GetSQLConnection()->Execute( + "INSERT INTO autofill_profiles (guid, origin, date_modified) " + "VALUES('00000000-0000-0000-0000-000000000000', '', 11);" + "INSERT INTO autofill_profiles (guid, origin, date_modified) " + "VALUES('00000000-0000-0000-0000-000000000001', " + " 'https://www.example.com/', 21);" + "INSERT INTO autofill_profiles (guid, origin, date_modified) " + "VALUES('00000000-0000-0000-0000-000000000002', 'Chrome settings', 31);" + "INSERT INTO credit_cards (guid, origin, date_modified) " + "VALUES('00000000-0000-0000-0000-000000000003', '', 17);" + "INSERT INTO credit_cards (guid, origin, date_modified) " + "VALUES('00000000-0000-0000-0000-000000000004', " + " 'https://www.example.com/', 27);" + "INSERT INTO credit_cards (guid, origin, date_modified) " + "VALUES('00000000-0000-0000-0000-000000000005', 'Chrome settings', " + " 37);")); + + // Remove all origin URLs set in the bounded time range [21,27). + ScopedVector<AutofillProfile> profiles; + table_->RemoveOriginURLsModifiedBetween( + Time::FromTimeT(21), Time::FromTimeT(27), &profiles); + ASSERT_EQ(1UL, profiles.size()); + EXPECT_EQ("00000000-0000-0000-0000-000000000001", profiles[0]->guid()); + sql::Statement s_autofill_profiles_bounded( + db_->GetSQLConnection()->GetUniqueStatement( + "SELECT date_modified, origin FROM autofill_profiles")); + ASSERT_TRUE(s_autofill_profiles_bounded.is_valid()); + ASSERT_TRUE(s_autofill_profiles_bounded.Step()); + EXPECT_EQ(11, s_autofill_profiles_bounded.ColumnInt64(0)); + EXPECT_EQ(std::string(), s_autofill_profiles_bounded.ColumnString(1)); + ASSERT_TRUE(s_autofill_profiles_bounded.Step()); + EXPECT_EQ(21, s_autofill_profiles_bounded.ColumnInt64(0)); + EXPECT_EQ(std::string(), s_autofill_profiles_bounded.ColumnString(1)); + ASSERT_TRUE(s_autofill_profiles_bounded.Step()); + EXPECT_EQ(31, s_autofill_profiles_bounded.ColumnInt64(0)); + EXPECT_EQ("Chrome settings", s_autofill_profiles_bounded.ColumnString(1)); + sql::Statement s_credit_cards_bounded( + db_->GetSQLConnection()->GetUniqueStatement( + "SELECT date_modified, origin FROM credit_cards")); + ASSERT_TRUE(s_credit_cards_bounded.is_valid()); + ASSERT_TRUE(s_credit_cards_bounded.Step()); + EXPECT_EQ(17, s_credit_cards_bounded.ColumnInt64(0)); + EXPECT_EQ(std::string(), s_credit_cards_bounded.ColumnString(1)); + ASSERT_TRUE(s_credit_cards_bounded.Step()); + EXPECT_EQ(27, s_credit_cards_bounded.ColumnInt64(0)); + EXPECT_EQ("https://www.example.com/", + s_credit_cards_bounded.ColumnString(1)); + ASSERT_TRUE(s_credit_cards_bounded.Step()); + EXPECT_EQ(37, s_credit_cards_bounded.ColumnInt64(0)); + EXPECT_EQ("Chrome settings", s_credit_cards_bounded.ColumnString(1)); + + // Remove all origin URLS. + profiles.clear(); + table_->RemoveOriginURLsModifiedBetween(Time(), Time(), &profiles); + EXPECT_EQ(0UL, profiles.size()); + sql::Statement s_autofill_profiles_all( + db_->GetSQLConnection()->GetUniqueStatement( + "SELECT date_modified, origin FROM autofill_profiles")); + ASSERT_TRUE(s_autofill_profiles_all.is_valid()); + ASSERT_TRUE(s_autofill_profiles_all.Step()); + EXPECT_EQ(11, s_autofill_profiles_all.ColumnInt64(0)); + EXPECT_EQ(std::string(), s_autofill_profiles_all.ColumnString(1)); + ASSERT_TRUE(s_autofill_profiles_all.Step()); + EXPECT_EQ(21, s_autofill_profiles_all.ColumnInt64(0)); + EXPECT_EQ(std::string(), s_autofill_profiles_all.ColumnString(1)); + ASSERT_TRUE(s_autofill_profiles_all.Step()); + EXPECT_EQ(31, s_autofill_profiles_all.ColumnInt64(0)); + EXPECT_EQ("Chrome settings", s_autofill_profiles_all.ColumnString(1)); + sql::Statement s_credit_cards_all( + db_->GetSQLConnection()->GetUniqueStatement( + "SELECT date_modified, origin FROM credit_cards")); + ASSERT_TRUE(s_credit_cards_all.is_valid()); + ASSERT_TRUE(s_credit_cards_all.Step()); + EXPECT_EQ(17, s_credit_cards_all.ColumnInt64(0)); + EXPECT_EQ(std::string(), s_credit_cards_all.ColumnString(1)); + ASSERT_TRUE(s_credit_cards_all.Step()); + EXPECT_EQ(27, s_credit_cards_all.ColumnInt64(0)); + EXPECT_EQ(std::string(), s_credit_cards_all.ColumnString(1)); + ASSERT_TRUE(s_credit_cards_all.Step()); + EXPECT_EQ(37, s_credit_cards_all.ColumnInt64(0)); + EXPECT_EQ("Chrome settings", s_credit_cards_all.ColumnString(1)); +} + TEST_F(AutofillTableTest, Autofill_GetAllAutofillEntries_NoResults) { std::vector<AutofillEntry> entries; ASSERT_TRUE(table_->GetAllAutofillEntries(&entries)); diff --git a/components/autofill/browser/webdata/autofill_webdata.h b/components/autofill/browser/webdata/autofill_webdata.h index 66f42f8..79d3bc1 100644 --- a/components/autofill/browser/webdata/autofill_webdata.h +++ b/components/autofill/browser/webdata/autofill_webdata.h @@ -90,6 +90,11 @@ class AutofillWebData { // Removes Autofill records from the database. virtual void RemoveAutofillDataModifiedBetween( const base::Time& delete_begin, const base::Time& delete_end) = 0; + + // Removes origin URLs associated with Autofill profiles and credit cards from + // the database. + virtual void RemoveOriginURLsModifiedBetween( + const base::Time& delete_begin, const base::Time& delete_end) = 0; }; } // namespace autofill diff --git a/components/autofill/browser/webdata/autofill_webdata_backend_impl.cc b/components/autofill/browser/webdata/autofill_webdata_backend_impl.cc index f7e4f30..d86d1fd 100644 --- a/components/autofill/browser/webdata/autofill_webdata_backend_impl.cc +++ b/components/autofill/browser/webdata/autofill_webdata_backend_impl.cc @@ -5,6 +5,7 @@ #include "components/autofill/browser/webdata/autofill_webdata_backend_impl.h" #include "base/logging.h" +#include "base/memory/scoped_vector.h" #include "base/stl_util.h" #include "components/autofill/browser/autofill_country.h" #include "components/autofill/browser/autofill_profile.h" @@ -103,13 +104,14 @@ scoped_ptr<WDTypedResult> AutofillWebDataBackendImpl::HasFormElements( } WebDatabase::State AutofillWebDataBackendImpl::RemoveFormElementsAddedBetween( - const base::Time& delete_begin, const base::Time& delete_end, + const base::Time& delete_begin, + const base::Time& delete_end, WebDatabase* db) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); AutofillChangeList changes; if (AutofillTable::FromWebDatabase(db)->RemoveFormElementsAddedBetween( - delete_begin, delete_end, &changes)) { + delete_begin, delete_end, &changes)) { if (!changes.empty()) { // Post the notifications including the list of affected keys. // This is sent here so that work resulting from this notification @@ -325,6 +327,29 @@ WebDatabase::State return WebDatabase::COMMIT_NOT_NEEDED; } +WebDatabase::State AutofillWebDataBackendImpl::RemoveOriginURLsModifiedBetween( + const base::Time& delete_begin, + const base::Time& delete_end, + WebDatabase* db) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); + ScopedVector<AutofillProfile> profiles; + if (AutofillTable::FromWebDatabase(db)->RemoveOriginURLsModifiedBetween( + delete_begin, delete_end, &profiles)) { + for (std::vector<AutofillProfile*>::const_iterator it = profiles.begin(); + it != profiles.end(); ++it) { + AutofillProfileChange change(AutofillProfileChange::UPDATE, + (*it)->guid(), *it); + FOR_EACH_OBSERVER(AutofillWebDataServiceObserverOnDBThread, + db_observer_list_, + AutofillProfileChanged(change)); + } + // Note: It is the caller's responsibility to post notifications for any + // changes, e.g. by calling the Refresh() method of PersonalDataManager. + return WebDatabase::COMMIT_NEEDED; + } + return WebDatabase::COMMIT_NOT_NEEDED; +} + void AutofillWebDataBackendImpl::DestroyAutofillProfileResult( const WDTypedResult* result) { DCHECK(result->GetType() == AUTOFILL_PROFILES_RESULT); diff --git a/components/autofill/browser/webdata/autofill_webdata_backend_impl.h b/components/autofill/browser/webdata/autofill_webdata_backend_impl.h index 525adcb..c8d3823a 100644 --- a/components/autofill/browser/webdata/autofill_webdata_backend_impl.h +++ b/components/autofill/browser/webdata/autofill_webdata_backend_impl.h @@ -118,6 +118,13 @@ class AutofillWebDataBackendImpl const base::Time& delete_end, WebDatabase* db); + // Removes origin URLs associated with Autofill profiles and credit cards from + // the database. + WebDatabase::State RemoveOriginURLsModifiedBetween( + const base::Time& delete_begin, + const base::Time& delete_end, + WebDatabase* db); + protected: virtual ~AutofillWebDataBackendImpl(); diff --git a/components/autofill/browser/webdata/autofill_webdata_service.cc b/components/autofill/browser/webdata/autofill_webdata_service.cc index b965b19..d732539 100644 --- a/components/autofill/browser/webdata/autofill_webdata_service.cc +++ b/components/autofill/browser/webdata/autofill_webdata_service.cc @@ -177,6 +177,14 @@ void AutofillWebDataService::RemoveAutofillDataModifiedBetween( autofill_backend_, delete_begin, delete_end)); } +void AutofillWebDataService::RemoveOriginURLsModifiedBetween( + const Time& delete_begin, const Time& delete_end) { + wdbs_->ScheduleDBTask( + FROM_HERE, + Bind(&AutofillWebDataBackendImpl::RemoveOriginURLsModifiedBetween, + autofill_backend_, delete_begin, delete_end)); +} + void AutofillWebDataService::AddObserver( AutofillWebDataServiceObserverOnDBThread* observer) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); diff --git a/components/autofill/browser/webdata/autofill_webdata_service.h b/components/autofill/browser/webdata/autofill_webdata_service.h index 2a87317..4f43bc51 100644 --- a/components/autofill/browser/webdata/autofill_webdata_service.h +++ b/components/autofill/browser/webdata/autofill_webdata_service.h @@ -88,6 +88,8 @@ class AutofillWebDataService : public AutofillWebData, WebDataServiceConsumer* consumer) OVERRIDE; virtual void RemoveAutofillDataModifiedBetween( const base::Time& delete_begin, const base::Time& delete_end) OVERRIDE; + virtual void RemoveOriginURLsModifiedBetween( + const base::Time& delete_begin, const base::Time& delete_end) OVERRIDE; void AddObserver(AutofillWebDataServiceObserverOnDBThread* observer); void RemoveObserver(AutofillWebDataServiceObserverOnDBThread* observer); diff --git a/components/webdata/common/web_database.cc b/components/webdata/common/web_database.cc index ae4ee9f..05d1789 100644 --- a/components/webdata/common/web_database.cc +++ b/components/webdata/common/web_database.cc @@ -15,7 +15,7 @@ // corresponding changes must happen in the unit tests, and new migration test // added. See |WebDatabaseMigrationTest::kCurrentTestedVersionNumber|. // static -const int WebDatabase::kCurrentVersionNumber = 50; +const int WebDatabase::kCurrentVersionNumber = 51; namespace { diff --git a/components/webdata/common/web_database_migration_unittest.cc b/components/webdata/common/web_database_migration_unittest.cc index a279532..e005089 100644 --- a/components/webdata/common/web_database_migration_unittest.cc +++ b/components/webdata/common/web_database_migration_unittest.cc @@ -240,7 +240,7 @@ class WebDatabaseMigrationTest : public testing::Test { DISALLOW_COPY_AND_ASSIGN(WebDatabaseMigrationTest); }; -const int WebDatabaseMigrationTest::kCurrentTestedVersionNumber = 50; +const int WebDatabaseMigrationTest::kCurrentTestedVersionNumber = 51; void WebDatabaseMigrationTest::LoadDatabase( const base::FilePath::StringType& file) { |