summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authoravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-26 16:12:55 +0000
committeravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-26 16:12:55 +0000
commitea05398d96221f8cc20939bad5fe52d4b11d3bd4 (patch)
tree6cd25c8065d5743a3f682c18c61f4d5da726d709 /chrome/browser
parent9d6dcdf0882b57fbb0825ab880f321d7682bad4a (diff)
downloadchromium_src-ea05398d96221f8cc20939bad5fe52d4b11d3bd4.zip
chromium_src-ea05398d96221f8cc20939bad5fe52d4b11d3bd4.tar.gz
chromium_src-ea05398d96221f8cc20939bad5fe52d4b11d3bd4.tar.bz2
Adds obscuring to credit card numbers when displayed.
xib change: added tag to fields that are used for credit card numbers. BUG=http://crbug.com/38259 TEST=as in bug Review URL: http://codereview.chromium.org/1219009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42768 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/autofill/autofill_text_field_mac.h18
-rw-r--r--chrome/browser/autofill/autofill_text_field_mac.mm60
-rw-r--r--chrome/browser/autofill/credit_card.cc12
-rw-r--r--chrome/browser/autofill/credit_card.h2
-rw-r--r--chrome/browser/autofill/credit_card_unittest.cc14
5 files changed, 99 insertions, 7 deletions
diff --git a/chrome/browser/autofill/autofill_text_field_mac.h b/chrome/browser/autofill/autofill_text_field_mac.h
index 559b0a8..a774aca 100644
--- a/chrome/browser/autofill/autofill_text_field_mac.h
+++ b/chrome/browser/autofill/autofill_text_field_mac.h
@@ -7,11 +7,21 @@
#import <Cocoa/Cocoa.h>
-// Subclass of NSTextField that automatically scrolls containing NSScrollView
-// to visually reveal the text field. When the user tabs between text fields
-// embedded in a scrolling view they'd like the "first responder" to be visible.
-// This class helps achieve that.
+#import "base/scoped_nsobject.h"
+
+#define AUTOFILL_CC_TAG 22
+
+// Subclass of NSTextField with special abilities:
+// - automatically scrolls containing NSScrollView to visually reveal itself
+// on focus
+// - properly obfuscates credit card numbers
+
@interface AutoFillTextField : NSTextField {
+ BOOL isCreditCardField_;
+ BOOL isObfuscated_;
+ BOOL isBeingSelected_;
+
+ scoped_nsobject<NSString> obfuscatedValue_;
}
@end
diff --git a/chrome/browser/autofill/autofill_text_field_mac.mm b/chrome/browser/autofill/autofill_text_field_mac.mm
index 3b19da0..ff5b1a0 100644
--- a/chrome/browser/autofill/autofill_text_field_mac.mm
+++ b/chrome/browser/autofill/autofill_text_field_mac.mm
@@ -4,8 +4,16 @@
#import "chrome/browser/autofill/autofill_text_field_mac.h"
+#include "base/sys_string_conversions.h"
+#include "chrome/browser/autofill/credit_card.h"
+
@implementation AutoFillTextField
+- (void)awakeFromNib {
+ if ([self tag] == AUTOFILL_CC_TAG)
+ isCreditCardField_ = YES;
+}
+
// Override NSResponder method for when the text field may gain focus. We
// call |scrollRectToVisible| to ensure that this text field is visible within
// the scrolling area.
@@ -20,4 +28,56 @@
return becoming;
}
+- (void)setObjectValue:(id)object {
+ if (isCreditCardField_ && [object isKindOfClass:[NSString class]]) {
+ // Obfuscate the number.
+ NSString* string = object;
+ CreditCard card;
+ card.SetInfo(AutoFillType(CREDIT_CARD_NUMBER),
+ base::SysNSStringToUTF16(string));
+ NSString* starredString = base::SysUTF16ToNSString(card.ObfuscatedNumber());
+
+ [super setObjectValue:starredString];
+ isObfuscated_ = YES;
+ obfuscatedValue_.reset([string copy]);
+ } else {
+ [super setObjectValue:object];
+ }
+}
+
+- (id)objectValue {
+ if (isObfuscated_) {
+ // This should not happen. This field is bound, and its value will only be
+ // fetched if it is changed, and since we force selection, that should clear
+ // the obfuscation. Nevertheless, we'll be paranoid here since we don't want
+ // the obfuscating ***s to end up in the database.
+ return obfuscatedValue_.get();
+ } else {
+ return [super objectValue];
+ }
+}
+
+// |self| is automatically set to be the delegate of the field editor; this
+// method is called by the field editor.
+- (void)textViewDidChangeSelection:(NSNotification *)notification {
+ if (isCreditCardField_ && !isBeingSelected_ && isObfuscated_) {
+ // Can't edit obfuscated credit card info; force a select-all in that case.
+ isBeingSelected_ = YES;
+ NSText* editor = [notification object];
+ [editor selectAll:self];
+ isBeingSelected_ = NO;
+ }
+}
+
+// Docs aren't clear, but this is called on the first keypress, not when the
+// field takes focus.
+- (BOOL)textShouldBeginEditing:(NSText*)textObject {
+ BOOL should = [super textShouldBeginEditing:textObject];
+ // On editing, since everything is selected, the field is now clear.
+ isObfuscated_ = !should;
+ if (!isObfuscated_)
+ obfuscatedValue_.reset();
+ return should;
+}
+
@end
diff --git a/chrome/browser/autofill/credit_card.cc b/chrome/browser/autofill/credit_card.cc
index 8c6a3fd..b412241 100644
--- a/chrome/browser/autofill/credit_card.cc
+++ b/chrome/browser/autofill/credit_card.cc
@@ -203,12 +203,20 @@ void CreditCard::SetInfo(const AutoFillType& type, const string16& value) {
}
}
+string16 CreditCard::ObfuscatedNumber() const {
+ if (number().empty())
+ return string16(); // No CC number, means empty preview.
+ string16 result(ASCIIToUTF16("************"));
+ result.append(last_four_digits());
+
+ return result;
+}
+
string16 CreditCard::PreviewSummary() const {
string16 preview;
if (number().empty())
return preview; // No CC number, means empty preview.
- string16 obfuscated_cc_number(ASCIIToUTF16("************"));
- obfuscated_cc_number.append(last_four_digits());
+ string16 obfuscated_cc_number = ObfuscatedNumber();
if (!expiration_month() || !expiration_year())
return obfuscated_cc_number; // no expiration date set
// TODO(georgey): internationalize date
diff --git a/chrome/browser/autofill/credit_card.h b/chrome/browser/autofill/credit_card.h
index ec1bd6e..295ec79 100644
--- a/chrome/browser/autofill/credit_card.h
+++ b/chrome/browser/autofill/credit_card.h
@@ -30,6 +30,8 @@ class CreditCard : public FormGroup {
virtual void SetInfo(const AutoFillType& type, const string16& value);
const string16& Label() const { return label_; }
+ // The number altered for display, for example: ******1234
+ string16 ObfuscatedNumber() const;
// Credit card preview summary, for example: ******1234, Exp: 01/2020
string16 PreviewSummary() const;
diff --git a/chrome/browser/autofill/credit_card_unittest.cc b/chrome/browser/autofill/credit_card_unittest.cc
index 53df1fc..8241e0b 100644
--- a/chrome/browser/autofill/credit_card_unittest.cc
+++ b/chrome/browser/autofill/credit_card_unittest.cc
@@ -12,11 +12,13 @@ namespace {
// Tests credit card summary string generation. This test simulates a variety
// of different possible summary strings. Variations occur based on the
// existence of credit card number, month, and year fields.
-TEST(CreditCardTest, PreviewSummaryString) {
+TEST(CreditCardTest, PreviewSummaryAndObfuscatedNumberStrings) {
// Case 0: empty credit card.
CreditCard credit_card0(string16(), 0);
string16 summary0 = credit_card0.PreviewSummary();
EXPECT_EQ(summary0, string16());
+ string16 obfuscated0 = credit_card0.ObfuscatedNumber();
+ EXPECT_EQ(obfuscated0, string16());
// Case 00: Empty credit card with empty strings.
CreditCard credit_card00(string16(), 0);
@@ -33,6 +35,8 @@ TEST(CreditCardTest, PreviewSummaryString) {
"Indianapolis");
string16 summary00 = credit_card00.PreviewSummary();
EXPECT_EQ(summary00, string16());
+ string16 obfuscated00 = credit_card00.ObfuscatedNumber();
+ EXPECT_EQ(obfuscated00, string16());
// Case 1: No credit card number.
CreditCard credit_card1(string16(), 0);
@@ -49,6 +53,8 @@ TEST(CreditCardTest, PreviewSummaryString) {
"Indianapolis");
string16 summary1 = credit_card1.PreviewSummary();
EXPECT_EQ(summary1, string16());
+ string16 obfuscated1 = credit_card1.ObfuscatedNumber();
+ EXPECT_EQ(obfuscated1, string16());
// Case 2: No month.
CreditCard credit_card2(string16(), 0);
@@ -65,6 +71,8 @@ TEST(CreditCardTest, PreviewSummaryString) {
"Indianapolis");
string16 summary2 = credit_card2.PreviewSummary();
EXPECT_EQ(summary2, string16(ASCIIToUTF16("************9012")));
+ string16 obfuscated2 = credit_card2.ObfuscatedNumber();
+ EXPECT_EQ(obfuscated2, string16(ASCIIToUTF16("************9012")));
// Case 3: No year.
CreditCard credit_card3(string16(), 0);
@@ -81,6 +89,8 @@ TEST(CreditCardTest, PreviewSummaryString) {
"Indianapolis");
string16 summary3 = credit_card3.PreviewSummary();
EXPECT_EQ(summary3, string16(ASCIIToUTF16("************9012")));
+ string16 obfuscated3 = credit_card3.ObfuscatedNumber();
+ EXPECT_EQ(obfuscated3, string16(ASCIIToUTF16("************9012")));
// Case 4: Have everything.
CreditCard credit_card4(string16(), 0);
@@ -97,6 +107,8 @@ TEST(CreditCardTest, PreviewSummaryString) {
"Indianapolis");
string16 summary4 = credit_card4.PreviewSummary();
EXPECT_EQ(summary4, string16(ASCIIToUTF16("************9012, Exp: 01/2010")));
+ string16 obfuscated4 = credit_card4.ObfuscatedNumber();
+ EXPECT_EQ(obfuscated4, string16(ASCIIToUTF16("************9012")));
}
} // namespace