Index: components/autofill/core/browser/webdata/autofill_table.cc |
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc |
index f05a739e7c905e15bfed9dc2c66a0fa74ca64604..7fefa6b47926604bd6a0ad1fc7b88bc5935d46d9 100644 |
--- a/components/autofill/core/browser/webdata/autofill_table.cc |
+++ b/components/autofill/core/browser/webdata/autofill_table.cc |
@@ -472,6 +472,9 @@ bool AutofillTable::MigrateToVersion(int version, |
case 63: |
*update_compatible_version = false; |
return MigrateToVersion63AddServerRecipientName(); |
+ case 64: |
+ *update_compatible_version = false; |
+ return MigrateToVersion64AddUnmaskDate(); |
} |
return true; |
} |
@@ -1194,6 +1197,10 @@ bool AutofillTable::GetServerCreditCards( |
void AutofillTable::SetServerCreditCards( |
const std::vector<CreditCard>& credit_cards) { |
+ sql::Transaction transaction(db_); |
+ if (!transaction.Begin()) |
+ return; |
+ |
// Delete all old values. |
sql::Statement masked_delete(db_->GetUniqueStatement( |
"DELETE FROM masked_credit_cards")); |
@@ -1202,6 +1209,7 @@ void AutofillTable::SetServerCreditCards( |
// Delete all items in the unmasked table that aren't in the new set. |
sql::Statement get_unmasked(db_->GetUniqueStatement( |
"SELECT id FROM unmasked_credit_cards")); |
+ std::set<std::string> kept_unmasked_entries; |
while (get_unmasked.Step()) { |
// We expect relatively few cards, just do brute-force. |
std::string server_id = get_unmasked.ColumnString(0); |
@@ -1212,7 +1220,9 @@ void AutofillTable::SetServerCreditCards( |
break; |
} |
} |
- if (!found_card) { |
+ if (found_card) { |
+ kept_unmasked_entries.insert(server_id); |
+ } else { |
// This unmasked card in the DB isn't present in the input. The statement |
// is compiled every time because it's much more likely that this is never |
// executed than it runs more than once. |
@@ -1236,9 +1246,10 @@ void AutofillTable::SetServerCreditCards( |
"VALUES (?,?,?,?,?,?,?)")); |
sql::Statement unmasked_insert(db_->GetUniqueStatement( |
"INSERT INTO unmasked_credit_cards(" |
- "id," // 0 |
- "card_number_encrypted)" // 1 |
- "VALUES (?,?)")); |
+ "id," // 0 |
+ "card_number_encrypted, " // 1 |
+ "unmask_date)" // 2 |
+ "VALUES (?,?,?)")); |
for (const CreditCard& card : credit_cards) { |
DCHECK(card.record_type() != CreditCard::LOCAL_CARD); |
@@ -1255,17 +1266,25 @@ void AutofillTable::SetServerCreditCards( |
masked_insert.Run(); |
masked_insert.Reset(true); |
- if (card.record_type() == CreditCard::FULL_SERVER_CARD) { |
- // Unmasked cards also get an entry in the unmasked table. Note that the |
- // input card could be MASKED but if we have an UNMASKED entry for that |
- // card already, it will be preserved. |
+ if (kept_unmasked_entries.find(card.server_id()) == |
+ kept_unmasked_entries.end() && |
+ card.record_type() == CreditCard::FULL_SERVER_CARD) { |
+ // New unmasked cards also get an entry in the unmasked table. In |
+ // practice this will only happen for tests since the server cards will |
+ // all be marked masked (if a server card is manually unmasked, we will |
+ // have kept the existing entry in the table and won't get here). |
unmasked_insert.BindString(0, card.server_id()); |
BindEncryptedCardToColumn(&unmasked_insert, 1, |
card.GetRawInfo(CREDIT_CARD_NUMBER)); |
+ // Unmask time for this card is now. |
+ unmasked_insert.BindInt64(2, Time::Now().ToInternalValue()); |
unmasked_insert.Run(); |
unmasked_insert.Reset(true); |
} |
} |
+ |
+ if (!transaction.Commit()) |
+ return; |
Evan Stade
2015/03/06 00:20:51
nit: unnecessary return
|
} |
bool AutofillTable::UnmaskServerCreditCard(const std::string& id, |
@@ -1273,9 +1292,13 @@ bool AutofillTable::UnmaskServerCreditCard(const std::string& id, |
// Make sure there aren't duplicates for this card. |
MaskServerCreditCard(id); |
sql::Statement s(db_->GetUniqueStatement( |
- "INSERT INTO unmasked_credit_cards(id, card_number_encrypted," |
- " use_count, use_date) " |
- "VALUES (?,?,?,?)")); |
+ "INSERT INTO unmasked_credit_cards(" |
+ "id," |
+ "card_number_encrypted," |
+ "use_count," |
+ "use_date," |
+ "unmask_date)" |
+ "VALUES (?,?,?,?,?)")); |
s.BindString(0, id); |
std::string encrypted_data; |
@@ -1284,8 +1307,11 @@ bool AutofillTable::UnmaskServerCreditCard(const std::string& id, |
static_cast<int>(encrypted_data.length())); |
// Unmasking counts as a usage, so set the stats accordingly. |
- s.BindInt64(2, 1); |
- s.BindInt64(3, base::Time::Now().ToInternalValue()); |
+ base::Time now = base::Time::Now(); |
+ s.BindInt64(2, 1); // use_count |
+ s.BindInt64(3, now.ToInternalValue()); // use_date |
+ |
+ s.BindInt64(4, now.ToInternalValue()); // unmask_date |
s.Run(); |
return db_->GetLastChangeCount() > 0; |
@@ -1327,8 +1353,8 @@ 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=?, use_count=?, use_date=?," |
- " date_modified=?, origin=?" |
+ "expiration_year=?, card_number_encrypted=?, use_count=?, use_date=?," |
+ "date_modified=?, origin=?" |
"WHERE guid=?")); |
BindCreditCardToStatement( |
credit_card, |
@@ -1407,8 +1433,19 @@ bool AutofillTable::RemoveAutofillDataModifiedBetween( |
"WHERE date_modified >= ? AND date_modified < ?")); |
s_credit_cards.BindInt64(0, delete_begin_t); |
s_credit_cards.BindInt64(1, delete_end_t); |
+ if (!s_credit_cards.Run()) |
+ return false; |
- return s_credit_cards.Run(); |
+ // Remove unmasked credit cards in the time range. |
+ sql::Statement s_unmasked_cards(db_->GetUniqueStatement( |
+ "DELETE FROM unmasked_credit_cards " |
+ "WHERE unmask_date >= ? AND unmask_date < ?")); |
+ s_unmasked_cards.BindInt64(0, delete_begin.ToInternalValue()); |
+ s_unmasked_cards.BindInt64(1, delete_end.ToInternalValue()); |
+ if (!s_unmasked_cards.Run()) |
Evan Stade
2015/03/06 00:20:51
nit: return s_unmasked_cards.Run()
|
+ return false; |
+ |
+ return true; |
} |
bool AutofillTable::RemoveOriginURLsModifiedBetween( |
@@ -1672,7 +1709,8 @@ bool AutofillTable::InitUnmaskedCreditCardsTable() { |
"id VARCHAR," |
"card_number_encrypted VARCHAR, " |
"use_count INTEGER NOT NULL DEFAULT 0, " |
- "use_date INTEGER NOT NULL DEFAULT 0)")) { |
+ "use_date INTEGER NOT NULL DEFAULT 0, " |
+ "unmask_date INTEGER NOT NULL DEFAULT 0)")) { |
NOTREACHED(); |
return false; |
} |
@@ -1696,7 +1734,8 @@ bool AutofillTable::InitServerAddressesTable() { |
"sorting_code VARCHAR," |
"country_code VARCHAR," |
"language_code VARCHAR, " // Space required. |
- "recipient_name VARCHAR)")) { |
+ "recipient_name VARCHAR, " // Ditto. |
+ "phone_number VARCHAR)")) { |
NOTREACHED(); |
return false; |
} |
@@ -1989,4 +2028,18 @@ bool AutofillTable::MigrateToVersion63AddServerRecipientName() { |
return true; |
} |
+bool AutofillTable::MigrateToVersion64AddUnmaskDate() { |
Evan Stade
2015/03/06 00:20:51
transaction
|
+ if (!db_->DoesColumnExist("unmasked_credit_cards", "unmask_date") && |
+ !db_->Execute("ALTER TABLE unmasked_credit_cards ADD COLUMN " |
+ "unmask_date INTEGER NOT NULL DEFAULT 0")) { |
+ return false; |
+ } |
+ if (!db_->DoesColumnExist("server_addresses", "phone_number") && |
+ !db_->Execute("ALTER TABLE server_addresses ADD COLUMN " |
+ "phone_number VARCHAR")) { |
+ return false; |
+ } |
+ return true; |
+} |
+ |
} // namespace autofill |