summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvabr <vabr@chromium.org>2015-08-07 04:02:04 -0700
committerCommit bot <commit-bot@chromium.org>2015-08-07 11:02:34 +0000
commit5410d0bc855495b61ca084a8760d32613f684d01 (patch)
treef850d4da7b5ac7a1af6ae2da78ac8699a4f7e4af
parent97b25ca5565f00404e32f4b3215d207b3a79399b (diff)
downloadchromium_src-5410d0bc855495b61ca084a8760d32613f684d01.zip
chromium_src-5410d0bc855495b61ca084a8760d32613f684d01.tar.gz
chromium_src-5410d0bc855495b61ca084a8760d32613f684d01.tar.bz2
Move ShouldFilterAutofillResult from ChromePasswordManagerClient to PasswordManager
The goal is to put as much of the platform-independent logic to the shared code, and leave the CPMC just a dumb redirector to the embedding system. This is one of many steps. Also, this CL removes IsPasswordManagementEnabledForCurrentPage() from the client mock in the client unit test. It is dangerous to mix mocking methods with testing the real implementations, and none of the tests actually needs this method mocked. BUG=474577, 515108 Review URL: https://codereview.chromium.org/1260263002 Cr-Commit-Position: refs/heads/master@{#342332}
-rw-r--r--chrome/browser/BUILD.gn1
-rw-r--r--chrome/browser/password_manager/chrome_password_manager_client.cc93
-rw-r--r--chrome/browser/password_manager/chrome_password_manager_client.h27
-rw-r--r--chrome/browser/password_manager/chrome_password_manager_client_unittest.cc81
-rw-r--r--chrome/chrome_browser.gypi1
-rw-r--r--components/components_tests.gyp2
-rw-r--r--components/password_manager.gypi21
-rw-r--r--components/password_manager/DEPS3
-rw-r--r--components/password_manager/README13
-rw-r--r--components/password_manager/core/browser/BUILD.gn1
-rw-r--r--components/password_manager/core/browser/password_form_manager.cc12
-rw-r--r--components/password_manager/core/browser/password_form_manager.h4
-rw-r--r--components/password_manager/core/browser/password_form_manager_unittest.cc37
-rw-r--r--components/password_manager/core/browser/password_manager_client.cc3
-rw-r--r--components/password_manager/core/browser/password_manager_client.h17
-rw-r--r--components/password_manager/core/browser/store_result_filter.h28
-rw-r--r--components/password_manager/core/browser/stub_password_manager_client.cc28
-rw-r--r--components/password_manager/core/browser/stub_password_manager_client.h3
-rw-r--r--components/password_manager/sync/browser/BUILD.gn18
-rw-r--r--components/password_manager/sync/browser/DEPS3
-rw-r--r--components/password_manager/sync/browser/sync_store_result_filter.cc92
-rw-r--r--components/password_manager/sync/browser/sync_store_result_filter.h46
-rw-r--r--components/password_manager/sync/browser/sync_store_result_filter_unittest.cc90
-rw-r--r--ios/chrome/ios_chrome.gyp1
24 files changed, 420 insertions, 205 deletions
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 6a1f16b..5bf259a 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -264,6 +264,7 @@ source_set("browser") {
"//components/keyed_service/content",
"//components/navigation_interception",
"//components/password_manager/content/browser",
+ "//components/password_manager/sync/browser",
"//components/plugins/common",
"//components/safe_json",
"//components/sessions",
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index 41c188b..c41061f 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -40,6 +40,7 @@
#include "components/password_manager/core/common/credential_manager_types.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "components/password_manager/core/common/password_manager_switches.h"
+#include "components/password_manager/sync/browser/sync_store_result_filter.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/render_view_host.h"
@@ -112,9 +113,7 @@ ChromePasswordManagerClient::ChromePasswordManagerClient(
driver_factory_(nullptr),
credential_manager_dispatcher_(web_contents, this),
observer_(nullptr),
- can_use_log_router_(false),
- autofill_sync_state_(ALLOW_SYNC_CREDENTIALS),
- sync_credential_was_filtered_(false) {
+ can_use_log_router_(false) {
ContentPasswordManagerDriverFactory::CreateForWebContents(web_contents, this,
autofill_client);
driver_factory_ =
@@ -124,7 +123,6 @@ ChromePasswordManagerClient::ChromePasswordManagerClient(
PasswordManagerInternalsServiceFactory::GetForBrowserContext(profile_);
if (service)
can_use_log_router_ = service->RegisterClient(this);
- SetUpAutofillSyncState();
saving_passwords_enabled_.Init(
password_manager::prefs::kPasswordManagerSavingEnabled, GetPrefs());
ReportMetrics(*saving_passwords_enabled_, this);
@@ -178,26 +176,6 @@ bool ChromePasswordManagerClient::IsSavingEnabledForCurrentPage() const {
IsPasswordManagementEnabledForCurrentPage();
}
-bool ChromePasswordManagerClient::ShouldFilterAutofillResult(
- const autofill::PasswordForm& form) {
- if (!IsSyncAccountCredential(base::UTF16ToUTF8(form.username_value),
- form.signon_realm))
- return false;
-
- if (autofill_sync_state_ == DISALLOW_SYNC_CREDENTIALS) {
- sync_credential_was_filtered_ = true;
- return true;
- }
-
- if (autofill_sync_state_ == DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH &&
- LastLoadWasTransactionalReauthPage()) {
- sync_credential_was_filtered_ = true;
- return true;
- }
-
- return false;
-}
-
std::string ChromePasswordManagerClient::GetSyncUsername() const {
return password_manager_sync_metrics::GetSyncUsername(profile_);
}
@@ -209,12 +187,6 @@ bool ChromePasswordManagerClient::IsSyncAccountCredential(
profile_, username, realm);
}
-void ChromePasswordManagerClient::AutofillResultsComputed() {
- UMA_HISTOGRAM_BOOLEAN("PasswordManager.SyncCredentialFiltered",
- sync_credential_was_filtered_);
- sync_credential_was_filtered_ = false;
-}
-
bool ChromePasswordManagerClient::PromptUserToSaveOrUpdatePassword(
scoped_ptr<password_manager::PasswordFormManager> form_to_save,
password_manager::CredentialSourceType type,
@@ -487,24 +459,6 @@ void ChromePasswordManagerClient::NotifyRendererOfLoggingAvailability() {
can_use_log_router_));
}
-bool ChromePasswordManagerClient::LastLoadWasTransactionalReauthPage() const {
- DCHECK(web_contents());
- content::NavigationEntry* entry =
- web_contents()->GetController().GetLastCommittedEntry();
- if (!entry)
- return false;
-
- if (entry->GetURL().GetOrigin() !=
- GaiaUrls::GetInstance()->gaia_url().GetOrigin())
- return false;
-
- // "rart" is the transactional reauth paramter.
- std::string ignored_value;
- return net::GetValueForKeyInQuery(entry->GetURL(),
- "rart",
- &ignored_value);
-}
-
bool ChromePasswordManagerClient::IsURLPasswordWebsiteReauth(
const GURL& url) const {
if (url.GetOrigin() != GaiaUrls::GetInstance()->gaia_url().GetOrigin())
@@ -572,38 +526,21 @@ bool ChromePasswordManagerClient::EnabledForSyncSignin() {
return group_name != "Disabled";
}
-void ChromePasswordManagerClient::SetUpAutofillSyncState() {
- std::string group_name =
- base::FieldTrialList::FindFullName("AutofillSyncCredential");
+const GURL& ChromePasswordManagerClient::GetMainFrameURL() const {
+ return web_contents()->GetVisibleURL();
+}
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- if (command_line->HasSwitch(
- password_manager::switches::kAllowAutofillSyncCredential)) {
- autofill_sync_state_ = ALLOW_SYNC_CREDENTIALS;
- return;
- }
- if (command_line->HasSwitch(
- password_manager::switches::
- kDisallowAutofillSyncCredentialForReauth)) {
- autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH;
- return;
- }
- if (command_line->HasSwitch(
- password_manager::switches::kDisallowAutofillSyncCredential)) {
- autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS;
- return;
- }
+const GURL& ChromePasswordManagerClient::GetLastCommittedEntryURL() const {
+ DCHECK(web_contents());
+ content::NavigationEntry* entry =
+ web_contents()->GetController().GetLastCommittedEntry();
+ if (!entry)
+ return GURL::EmptyGURL();
- if (group_name == "DisallowSyncCredentialsForReauth") {
- autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH;
- } else if (group_name == "DisallowSyncCredentials") {
- autofill_sync_state_ = DISALLOW_SYNC_CREDENTIALS;
- } else {
- // Allow by default.
- autofill_sync_state_ = ALLOW_SYNC_CREDENTIALS;
- }
+ return entry->GetURL();
}
-const GURL& ChromePasswordManagerClient::GetMainFrameURL() const {
- return web_contents()->GetVisibleURL();
+scoped_ptr<password_manager::StoreResultFilter>
+ChromePasswordManagerClient::CreateStoreResultFilter() const {
+ return make_scoped_ptr(new password_manager::SyncStoreResultFilter(this));
}
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h
index f909000..e5c2fc2 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.h
+++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -7,6 +7,8 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
#include "base/prefs/pref_member.h"
#include "components/password_manager/content/browser/content_password_manager_driver_factory.h"
#include "components/password_manager/content/browser/credential_manager_dispatcher.h"
@@ -45,11 +47,9 @@ class ChromePasswordManagerClient
bool IsAutomaticPasswordSavingEnabled() const override;
bool IsPasswordManagementEnabledForCurrentPage() const override;
bool IsSavingEnabledForCurrentPage() const override;
- bool ShouldFilterAutofillResult(const autofill::PasswordForm& form) override;
std::string GetSyncUsername() const override;
bool IsSyncAccountCredential(const std::string& username,
const std::string& realm) const override;
- void AutofillResultsComputed() override;
bool PromptUserToSaveOrUpdatePassword(
scoped_ptr<password_manager::PasswordFormManager> form_to_save,
password_manager::CredentialSourceType type,
@@ -82,6 +82,9 @@ class ChromePasswordManagerClient
autofill::AutofillManager* GetAutofillManagerForMainFrame() override;
const GURL& GetMainFrameURL() const override;
bool IsUpdatePasswordUIEnabled() const override;
+ const GURL& GetLastCommittedEntryURL() const override;
+ scoped_ptr<password_manager::StoreResultFilter> CreateStoreResultFilter()
+ const override;
// Hides any visible generation UI.
void HidePasswordGenerationPopup();
@@ -106,12 +109,6 @@ class ChromePasswordManagerClient
autofill::AutofillClient* autofill_client);
private:
- enum AutofillForSyncCredentialsState {
- ALLOW_SYNC_CREDENTIALS,
- DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH,
- DISALLOW_SYNC_CREDENTIALS,
- };
-
friend class content::WebContentsUserData<ChromePasswordManagerClient>;
// content::WebContentsObserver overrides.
@@ -139,17 +136,10 @@ class ChromePasswordManagerClient
// |can_use_log_router_|.
void NotifyRendererOfLoggingAvailability();
- // Returns true if the last loaded page was for transactional re-auth on a
- // Google property.
- bool LastLoadWasTransactionalReauthPage() const;
-
// Returns true if |url| is the reauth page for accessing the password
// website.
bool IsURLPasswordWebsiteReauth(const GURL& url) const;
- // Sets |autofill_state_| based on experiment and flag values.
- void SetUpAutofillSyncState();
-
Profile* const profile_;
password_manager::PasswordManager password_manager_;
@@ -169,13 +159,6 @@ class ChromePasswordManagerClient
// True if |this| is registered with some LogRouter which can accept logs.
bool can_use_log_router_;
- // How to handle the sync credential in ShouldFilterAutofillResult().
- AutofillForSyncCredentialsState autofill_sync_state_;
-
- // If the sync credential was filtered during autofill. Used for statistics
- // reporting.
- bool sync_credential_was_filtered_;
-
// Set to false to disable password saving (will no longer ask if you
// want to save passwords but will continue to fill passwords).
BooleanPrefMember saving_passwords_enabled_;
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
index 04f8283..d6818ba 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -21,6 +21,7 @@
#include "components/password_manager/content/common/credential_manager_messages.h"
#include "components/password_manager/core/browser/log_receiver.h"
#include "components/password_manager/core/browser/password_manager_internals_service.h"
+#include "components/password_manager/core/browser/store_result_filter.h"
#include "components/password_manager/core/common/credential_manager_types.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "components/password_manager/core/common/password_manager_switches.h"
@@ -49,7 +50,6 @@ class MockLogReceiver : public password_manager::LogReceiver {
// http://crbug.com/474577.
class MockChromePasswordManagerClient : public ChromePasswordManagerClient {
public:
- MOCK_CONST_METHOD0(IsPasswordManagementEnabledForCurrentPage, bool());
MOCK_CONST_METHOD0(DidLastPageLoadEncounterSSLErrors, bool());
MOCK_CONST_METHOD2(IsSyncAccountCredential,
bool(const std::string& username,
@@ -59,8 +59,6 @@ class MockChromePasswordManagerClient : public ChromePasswordManagerClient {
: ChromePasswordManagerClient(web_contents, nullptr) {
ON_CALL(*this, DidLastPageLoadEncounterSSLErrors())
.WillByDefault(testing::Return(false));
- ON_CALL(*this, IsPasswordManagementEnabledForCurrentPage())
- .WillByDefault(testing::Return(true));
}
~MockChromePasswordManagerClient() override {}
@@ -238,61 +236,6 @@ TEST_F(ChromePasswordManagerClientTest, LogToAReceiver) {
EXPECT_FALSE(client->IsLoggingActive());
}
-TEST_F(ChromePasswordManagerClientTest, ShouldFilterAutofillResult_Reauth) {
- // Make client disallow only reauth requests.
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- command_line->AppendSwitch(
- password_manager::switches::kDisallowAutofillSyncCredentialForReauth);
- scoped_ptr<MockChromePasswordManagerClient> client(
- new MockChromePasswordManagerClient(web_contents()));
- autofill::PasswordForm form;
-
- EXPECT_CALL(*client, IsSyncAccountCredential(_, _))
- .WillRepeatedly(Return(false));
- NavigateAndCommit(
- GURL("https://accounts.google.com/login?rart=123&continue=blah"));
- EXPECT_FALSE(client->ShouldFilterAutofillResult(form));
-
- EXPECT_CALL(*client, IsSyncAccountCredential(_, _))
- .WillRepeatedly(Return(true));
- NavigateAndCommit(
- GURL("https://accounts.google.com/login?rart=123&continue=blah"));
- EXPECT_TRUE(client->ShouldFilterAutofillResult(form));
-
- // This counts as a reauth url, though a valid URL should have a value for
- // "rart"
- NavigateAndCommit(GURL("https://accounts.google.com/addlogin?rart"));
- EXPECT_TRUE(client->ShouldFilterAutofillResult(form));
-
- NavigateAndCommit(GURL("https://accounts.google.com/login?param=123"));
- EXPECT_FALSE(client->ShouldFilterAutofillResult(form));
-
- NavigateAndCommit(GURL("https://site.com/login?rart=678"));
- EXPECT_FALSE(client->ShouldFilterAutofillResult(form));
-}
-
-TEST_F(ChromePasswordManagerClientTest, ShouldFilterAutofillResult) {
- // Normally the client should allow any credentials through, even if they
- // are the sync credential.
- scoped_ptr<MockChromePasswordManagerClient> client(
- new MockChromePasswordManagerClient(web_contents()));
- autofill::PasswordForm form;
- EXPECT_CALL(*client, IsSyncAccountCredential(_, _))
- .WillRepeatedly(Return(true));
- NavigateAndCommit(GURL("https://accounts.google.com/Login"));
- EXPECT_FALSE(client->ShouldFilterAutofillResult(form));
-
- // Adding disallow switch should cause sync credential to be filtered.
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- command_line->AppendSwitch(
- password_manager::switches::kDisallowAutofillSyncCredential);
- client.reset(new MockChromePasswordManagerClient(web_contents()));
- EXPECT_CALL(*client, IsSyncAccountCredential(_, _))
- .WillRepeatedly(Return(true));
- NavigateAndCommit(GURL("https://accounts.google.com/Login"));
- EXPECT_TRUE(client->ShouldFilterAutofillResult(form));
-}
-
TEST_F(ChromePasswordManagerClientTest,
IsPasswordManagementEnabledForCurrentPage) {
ChromePasswordManagerClient* client = GetClient();
@@ -468,3 +411,25 @@ TEST_F(ChromePasswordManagerClientTest, IsSavingEnabledForCurrentPageTest) {
EXPECT_FALSE(client->IsSavingEnabledForCurrentPage());
profile()->ForceIncognito(false);
}
+
+TEST_F(ChromePasswordManagerClientTest, GetLastCommittedEntryURL_Empty) {
+ EXPECT_EQ(GURL::EmptyGURL(), GetClient()->GetLastCommittedEntryURL());
+}
+
+TEST_F(ChromePasswordManagerClientTest, GetLastCommittedEntryURL) {
+ GURL kUrl(
+ "https://accounts.google.com/ServiceLogin?continue="
+ "https://passwords.google.com/settings&rart=123");
+ NavigateAndCommit(kUrl);
+ EXPECT_EQ(kUrl, GetClient()->GetLastCommittedEntryURL());
+}
+
+TEST_F(ChromePasswordManagerClientTest, CreateStoreResulFilter) {
+ scoped_ptr<password_manager::StoreResultFilter> filter1 =
+ GetClient()->CreateStoreResultFilter();
+ scoped_ptr<password_manager::StoreResultFilter> filter2 =
+ GetClient()->CreateStoreResultFilter();
+ EXPECT_TRUE(filter1);
+ EXPECT_TRUE(filter2);
+ EXPECT_NE(filter1.get(), filter2.get());
+}
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index a412736..4f4b4e7 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -3270,6 +3270,7 @@
'../components/components.gyp:navigation_interception',
'../components/components.gyp:packed_ct_ev_whitelist',
'../components/components.gyp:password_manager_content_browser',
+ '../components/components.gyp:password_manager_sync_browser',
'../components/components.gyp:plugins_common',
'../components/components.gyp:power',
'../components/components.gyp:safe_json',
diff --git a/components/components_tests.gyp b/components/components_tests.gyp
index a0bf076..2ab3b6a 100644
--- a/components/components_tests.gyp
+++ b/components/components_tests.gyp
@@ -397,6 +397,7 @@
'password_manager/core/browser/psl_matching_helper_unittest.cc',
'password_manager/core/browser/statistics_table_unittest.cc',
'password_manager/core/common/credential_manager_types_unittest.cc',
+ 'password_manager/sync/browser/sync_store_result_filter_unittest.cc',
],
'policy_unittest_sources': [
'policy/core/browser/android/android_combined_policy_provider_unittest.cc',
@@ -863,6 +864,7 @@
'components.gyp:packed_ct_ev_whitelist',
'components.gyp:password_manager_core_browser',
'components.gyp:password_manager_core_browser_test_support',
+ 'components.gyp:password_manager_sync_browser',
'components.gyp:precache_core',
'components.gyp:pref_registry_test_support',
'components.gyp:proxy_config',
diff --git a/components/password_manager.gypi b/components/password_manager.gypi
index 83e3a66..1c69880 100644
--- a/components/password_manager.gypi
+++ b/components/password_manager.gypi
@@ -103,6 +103,7 @@
'password_manager/core/browser/psl_matching_helper.h',
'password_manager/core/browser/statistics_table.cc',
'password_manager/core/browser/statistics_table.h',
+ 'password_manager/core/browser/store_result_filter.h',
'password_manager/core/browser/test_affiliation_fetcher_factory.h',
'password_manager/core/browser/webdata/logins_table.cc',
'password_manager/core/browser/webdata/logins_table.h',
@@ -191,6 +192,26 @@
'password_manager/core/common/password_manager_ui.h',
],
},
+ {
+ # GN version: //components/password_manager/sync/browser
+ 'target_name': 'password_manager_sync_browser',
+ 'type': 'static_library',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../google_apis/google_apis.gyp:google_apis',
+ '../net/net.gyp:net',
+ 'autofill_core_common',
+ 'password_manager_core_browser',
+ ],
+ 'include_dirs': [
+ '..',
+ ],
+ 'sources': [
+ # Note: sources list duplicated in GN build.
+ 'password_manager/sync/browser/sync_store_result_filter.cc',
+ 'password_manager/sync/browser/sync_store_result_filter.h',
+ ],
+ },
],
'conditions': [
['OS != "ios"', {
diff --git a/components/password_manager/DEPS b/components/password_manager/DEPS
index d16b4f6..8c2766e 100644
--- a/components/password_manager/DEPS
+++ b/components/password_manager/DEPS
@@ -13,6 +13,7 @@ include_rules = [
"+third_party/sqlite/sqlite3.h",
"+ui",
# PasswordManager is a layered component; subdirectories must explicitly
- # introduce the ability to use the content layer as appropriate.
+ # introduce the ability to use non-core layers as appropriate.
"-components/password_manager/content",
+ "-components/password_manager/sync",
]
diff --git a/components/password_manager/README b/components/password_manager/README
index 9004ea7..a72887a 100644
--- a/components/password_manager/README
+++ b/components/password_manager/README
@@ -1,9 +1,8 @@
-PasswordManager is in the process of becoming a layered component
-(https://sites.google.com/a/chromium.org/dev/developers/design-documents/layered-components-design)
-to enable it to be shared cleanly on iOS.
+Password manager component is layered, see https://sites.google.com/a/chromium.org/dev/developers/design-documents/layered-components-design for what it means.
-When this process is complete, this component will have the following structure:
+Ideal structure of the component:
+- core/: Essentials, not depending on any other layers.
+All other layers may depend on core:
+- content/: Content-specific embedding.
+- sync/: Sync-specific embedding.
-- core/: shared code that does not depend on src/content/ or src/ios/
-- content/: Driver for the shared code based on the content layer.
-- ios/: Driver for the shared code based on src/ios.
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn
index c909b19..f2a24c8 100644
--- a/components/password_manager/core/browser/BUILD.gn
+++ b/components/password_manager/core/browser/BUILD.gn
@@ -85,6 +85,7 @@ static_library("browser") {
"psl_matching_helper.h",
"statistics_table.cc",
"statistics_table.h",
+ "store_result_filter.h",
"test_affiliation_fetcher_factory.h",
"webdata/logins_table.cc",
"webdata/logins_table.h",
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc
index 67ea855..2d315e8 100644
--- a/components/password_manager/core/browser/password_form_manager.cc
+++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -22,6 +22,7 @@
#include "components/password_manager/core/browser/password_manager_client.h"
#include "components/password_manager/core/browser/password_manager_driver.h"
#include "components/password_manager/core/browser/password_store.h"
+#include "components/password_manager/core/browser/store_result_filter.h"
#include "google_apis/gaia/gaia_auth_util.h"
using autofill::FormStructure;
@@ -378,8 +379,10 @@ void PasswordFormManager::OnRequestDone(
std::vector<int> credential_scores;
credential_scores.reserve(logins_result.size());
int best_score = 0;
+ scoped_ptr<StoreResultFilter> result_filter =
+ client_->CreateStoreResultFilter();
for (const PasswordForm* login : logins_result) {
- if (ShouldIgnoreResult(*login)) {
+ if (ShouldIgnoreResult(*login, result_filter.get())) {
credential_scores.push_back(-1);
continue;
}
@@ -462,8 +465,6 @@ void PasswordFormManager::OnRequestDone(
best_matches_.insert(username, protege.Pass());
}
- client_->AutofillResultsComputed();
-
UMA_HISTOGRAM_COUNTS("PasswordManager.NumPasswordsNotShown",
logins_result_size - best_matches_.size());
@@ -548,12 +549,13 @@ void PasswordFormManager::OnGetPasswordStoreResults(
drivers_.clear();
}
-bool PasswordFormManager::ShouldIgnoreResult(const PasswordForm& form) const {
+bool PasswordFormManager::ShouldIgnoreResult(const PasswordForm& form,
+ StoreResultFilter* filter) const {
// Don't match an invalid SSL form with one saved under secure circumstances.
if (form.ssl_valid && !observed_form_.ssl_valid)
return true;
- if (client_->ShouldFilterAutofillResult(form))
+ if (filter->ShouldIgnore(form))
return true;
return false;
diff --git a/components/password_manager/core/browser/password_form_manager.h b/components/password_manager/core/browser/password_form_manager.h
index 20255ee..f968af0 100644
--- a/components/password_manager/core/browser/password_form_manager.h
+++ b/components/password_manager/core/browser/password_form_manager.h
@@ -22,6 +22,7 @@ namespace password_manager {
class PasswordManager;
class PasswordManagerClient;
+class StoreResultFilter;
// Per-password-form-{on-page, dialog} class responsible for interactions
// between a given form, the per-tab PasswordManager, and the PasswordStore.
@@ -287,7 +288,8 @@ class PasswordFormManager : public PasswordStoreConsumer {
// Helper for OnGetPasswordStoreResults to determine whether or not
// the given result form is worth scoring.
- bool ShouldIgnoreResult(const autofill::PasswordForm& form) const;
+ bool ShouldIgnoreResult(const autofill::PasswordForm& form,
+ StoreResultFilter* filter) const;
// Helper for Save in the case that best_matches.size() == 0, meaning
// we have no prior record of this form/username/password and the user
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc
index 6080ff8..4086cd7 100644
--- a/components/password_manager/core/browser/password_form_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -23,6 +23,7 @@
#include "components/password_manager/core/browser/password_manager.h"
#include "components/password_manager/core/browser/password_manager_driver.h"
#include "components/password_manager/core/browser/password_store.h"
+#include "components/password_manager/core/browser/store_result_filter.h"
#include "components/password_manager/core/browser/stub_password_manager_client.h"
#include "components/password_manager/core/browser/stub_password_manager_driver.h"
#include "components/password_manager/core/browser/test_password_store.h"
@@ -101,6 +102,11 @@ class MockPasswordManagerDriver : public StubPasswordManagerDriver {
NiceMock<MockAutofillManager> mock_autofill_manager_;
};
+class MockStoreResultFilter : public StoreResultFilter {
+ public:
+ MOCK_METHOD1(ShouldIgnore, bool(const autofill::PasswordForm& form));
+};
+
class TestPasswordManagerClient : public StubPasswordManagerClient {
public:
explicit TestPasswordManagerClient(PasswordStore* password_store)
@@ -111,19 +117,16 @@ class TestPasswordManagerClient : public StubPasswordManagerClient {
true);
}
- bool ShouldFilterAutofillResult(const autofill::PasswordForm& form) override {
- if (form == form_to_filter_)
- return true;
- return false;
+ scoped_ptr<StoreResultFilter> CreateStoreResultFilter() const override {
+ scoped_ptr<NiceMock<MockStoreResultFilter>> stub_filter(
+ new NiceMock<MockStoreResultFilter>);
+ ON_CALL(*stub_filter, ShouldIgnore(_)).WillByDefault(Return(false));
+ return stub_filter.Pass();
}
PrefService* GetPrefs() override { return &prefs_; }
PasswordStore* GetPasswordStore() const override { return password_store_; }
- void SetFormToFilter(const autofill::PasswordForm& form) {
- form_to_filter_ = form;
- }
-
MockPasswordManagerDriver* mock_driver() { return driver_.get(); }
base::WeakPtr<PasswordManagerDriver> driver() { return driver_->AsWeakPtr(); }
@@ -142,8 +145,6 @@ class TestPasswordManagerClient : public StubPasswordManagerClient {
}
private:
- autofill::PasswordForm form_to_filter_;
-
TestingPrefServiceSimple prefs_;
PasswordStore* password_store_;
scoped_ptr<MockPasswordManagerDriver> driver_;
@@ -256,8 +257,10 @@ class PasswordFormManagerTest : public testing::Test {
p->SanitizePossibleUsernames(form);
}
- bool IgnoredResult(PasswordFormManager* p, PasswordForm* form) {
- return p->ShouldIgnoreResult(*form);
+ bool IgnoredResult(PasswordFormManager* p,
+ PasswordForm* form,
+ StoreResultFilter* filter) {
+ return p->ShouldIgnoreResult(*form, filter);
}
// Save saved_match() for observed_form() where |observed_form_data|,
@@ -608,17 +611,19 @@ TEST_F(PasswordFormManagerTest, TestIgnoreResult) {
// Make sure we don't match a PasswordForm if it was originally saved on
// an SSL-valid page and we are now on a page with invalid certificate.
saved_match()->ssl_valid = true;
- EXPECT_TRUE(IgnoredResult(&manager, saved_match()));
+ scoped_ptr<MockStoreResultFilter> filter(new MockStoreResultFilter);
+ EXPECT_TRUE(IgnoredResult(&manager, saved_match(), filter.get()));
saved_match()->ssl_valid = false;
// Different paths for action / origin are okay.
saved_match()->action = GURL("http://www.google.com/b/Login");
saved_match()->origin = GURL("http://www.google.com/foo");
- EXPECT_FALSE(IgnoredResult(&manager, saved_match()));
+ EXPECT_FALSE(IgnoredResult(&manager, saved_match(), filter.get()));
// Results should be ignored if the client requests it.
- client()->SetFormToFilter(*saved_match());
- EXPECT_TRUE(IgnoredResult(&manager, saved_match()));
+ PasswordForm filtered_form(*saved_match());
+ EXPECT_CALL(*filter, ShouldIgnore(filtered_form)).WillOnce(Return(true));
+ EXPECT_TRUE(IgnoredResult(&manager, saved_match(), filter.get()));
}
TEST_F(PasswordFormManagerTest, TestEmptyAction) {
diff --git a/components/password_manager/core/browser/password_manager_client.cc b/components/password_manager/core/browser/password_manager_client.cc
index e7cf3a5..14b98fb 100644
--- a/components/password_manager/core/browser/password_manager_client.cc
+++ b/components/password_manager/core/browser/password_manager_client.cc
@@ -18,9 +18,6 @@ bool PasswordManagerClient::IsSavingEnabledForCurrentPage() const {
return true;
}
-void PasswordManagerClient::AutofillResultsComputed() {
-}
-
void PasswordManagerClient::ForceSavePassword() {
}
diff --git a/components/password_manager/core/browser/password_manager_client.h b/components/password_manager/core/browser/password_manager_client.h
index 7bee0a12..8adcb70 100644
--- a/components/password_manager/core/browser/password_manager_client.h
+++ b/components/password_manager/core/browser/password_manager_client.h
@@ -9,6 +9,7 @@
#include "base/memory/scoped_vector.h"
#include "components/autofill/core/common/password_form.h"
#include "components/password_manager/core/browser/password_store.h"
+#include "components/password_manager/core/browser/store_result_filter.h"
class PrefService;
@@ -59,10 +60,6 @@ class PasswordManagerClient {
// of SSL errors on a page.
virtual bool IsSavingEnabledForCurrentPage() const;
- // Return true if |form| should not be available for autofill.
- virtual bool ShouldFilterAutofillResult(
- const autofill::PasswordForm& form) = 0;
-
// Return the username that the user is syncing with. Should return an empty
// string if sync is not enabled for passwords.
virtual std::string GetSyncUsername() const = 0;
@@ -72,10 +69,6 @@ class PasswordManagerClient {
virtual bool IsSyncAccountCredential(const std::string& username,
const std::string& realm) const = 0;
- // Called when all autofill results have been computed. Client can use
- // this signal to report statistics. Default implementation is a noop.
- virtual void AutofillResultsComputed();
-
// Informs the embedder of a password form that can be saved or updated in
// password store if the user allows it. The embedder is not required to
// prompt the user if it decides that this form doesn't need to be saved or
@@ -175,6 +168,14 @@ class PasswordManagerClient {
// Returns true if the UI for confirmation of update password is enabled.
virtual bool IsUpdatePasswordUIEnabled() const;
+ virtual const GURL& GetLastCommittedEntryURL() const = 0;
+
+ // Creates a filter for PasswordFormManager to process password store
+ // response. One filter should be created for every batch of store results for
+ // a single observed form. The filter results should not be cached.
+ virtual scoped_ptr<password_manager::StoreResultFilter>
+ CreateStoreResultFilter() const = 0;
+
private:
DISALLOW_COPY_AND_ASSIGN(PasswordManagerClient);
};
diff --git a/components/password_manager/core/browser/store_result_filter.h b/components/password_manager/core/browser/store_result_filter.h
new file mode 100644
index 0000000..5c7d26e
--- /dev/null
+++ b/components/password_manager/core/browser/store_result_filter.h
@@ -0,0 +1,28 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_STORE_RESULT_FILTER_H_
+#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_STORE_RESULT_FILTER_H_
+
+#include "components/autofill/core/common/password_form.h"
+
+namespace password_manager {
+
+// This interface is used by PasswordFormManager to filter results from the
+// PasswordStore.
+class StoreResultFilter {
+ public:
+ StoreResultFilter() {}
+ virtual ~StoreResultFilter() {}
+
+ // Should |form| be ignored for any password manager-related purposes?
+ virtual bool ShouldIgnore(const autofill::PasswordForm& form) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(StoreResultFilter);
+};
+
+} // namespace password_manager
+
+#endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_STORE_RESULT_FILTER_H_
diff --git a/components/password_manager/core/browser/stub_password_manager_client.cc b/components/password_manager/core/browser/stub_password_manager_client.cc
index d376e69..3f83c08 100644
--- a/components/password_manager/core/browser/stub_password_manager_client.cc
+++ b/components/password_manager/core/browser/stub_password_manager_client.cc
@@ -4,11 +4,25 @@
#include "components/password_manager/core/browser/stub_password_manager_client.h"
+#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "components/password_manager/core/browser/password_form_manager.h"
+#include "components/password_manager/core/browser/store_result_filter.h"
namespace password_manager {
+namespace {
+
+// This filter does not filter out anything, it is a dummy implementation of
+// the filter interface.
+class PassThroughStoreResultFilter : public StoreResultFilter {
+ public:
+ bool ShouldIgnore(const autofill::PasswordForm& form) override {
+ return false;
+ }
+};
+}
+
StubPasswordManagerClient::StubPasswordManagerClient() {
}
@@ -25,11 +39,6 @@ bool StubPasswordManagerClient::IsSyncAccountCredential(
return false;
}
-bool StubPasswordManagerClient::ShouldFilterAutofillResult(
- const autofill::PasswordForm& form) {
- return false;
-}
-
bool StubPasswordManagerClient::PromptUserToSaveOrUpdatePassword(
scoped_ptr<PasswordFormManager> form_to_save,
password_manager::CredentialSourceType type,
@@ -61,4 +70,13 @@ PasswordStore* StubPasswordManagerClient::GetPasswordStore() const {
return nullptr;
}
+const GURL& StubPasswordManagerClient::GetLastCommittedEntryURL() const {
+ return GURL::EmptyGURL();
+}
+
+scoped_ptr<StoreResultFilter>
+StubPasswordManagerClient::CreateStoreResultFilter() const {
+ return make_scoped_ptr(new PassThroughStoreResultFilter);
+}
+
} // namespace password_manager
diff --git a/components/password_manager/core/browser/stub_password_manager_client.h b/components/password_manager/core/browser/stub_password_manager_client.h
index c887b32..834234a 100644
--- a/components/password_manager/core/browser/stub_password_manager_client.h
+++ b/components/password_manager/core/browser/stub_password_manager_client.h
@@ -21,7 +21,6 @@ class StubPasswordManagerClient : public PasswordManagerClient {
std::string GetSyncUsername() const override;
bool IsSyncAccountCredential(const std::string& username,
const std::string& realm) const override;
- bool ShouldFilterAutofillResult(const autofill::PasswordForm& form) override;
bool PromptUserToSaveOrUpdatePassword(
scoped_ptr<PasswordFormManager> form_to_save,
password_manager::CredentialSourceType type,
@@ -38,6 +37,8 @@ class StubPasswordManagerClient : public PasswordManagerClient {
scoped_ptr<PasswordFormManager> saved_manager) override;
PrefService* GetPrefs() override;
PasswordStore* GetPasswordStore() const override;
+ const GURL& GetLastCommittedEntryURL() const override;
+ scoped_ptr<StoreResultFilter> CreateStoreResultFilter() const override;
private:
DISALLOW_COPY_AND_ASSIGN(StubPasswordManagerClient);
diff --git a/components/password_manager/sync/browser/BUILD.gn b/components/password_manager/sync/browser/BUILD.gn
new file mode 100644
index 0000000..60a1bcb
--- /dev/null
+++ b/components/password_manager/sync/browser/BUILD.gn
@@ -0,0 +1,18 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+static_library("browser") {
+ sources = [
+ "sync_store_result_filter.cc",
+ "sync_store_result_filter.h",
+ ]
+
+ deps = [
+ "//base",
+ "//google_apis",
+ "//components/autofill/core/common",
+ "//components/password_manager/core/browser",
+ "//net",
+ ]
+}
diff --git a/components/password_manager/sync/browser/DEPS b/components/password_manager/sync/browser/DEPS
new file mode 100644
index 0000000..7ef15ea
--- /dev/null
+++ b/components/password_manager/sync/browser/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+ "+google_apis/gaia",
+]
diff --git a/components/password_manager/sync/browser/sync_store_result_filter.cc b/components/password_manager/sync/browser/sync_store_result_filter.cc
new file mode 100644
index 0000000..c49d995
--- /dev/null
+++ b/components/password_manager/sync/browser/sync_store_result_filter.cc
@@ -0,0 +1,92 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/password_manager/sync/browser/sync_store_result_filter.h"
+
+#include "base/command_line.h"
+#include "base/metrics/field_trial.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/strings/utf_string_conversions.h"
+#include "components/autofill/core/common/password_form.h"
+#include "components/password_manager/core/browser/password_manager_client.h"
+#include "components/password_manager/core/common/password_manager_switches.h"
+#include "google_apis/gaia/gaia_urls.h"
+#include "net/base/url_util.h"
+
+namespace password_manager {
+
+namespace {
+
+// Returns true if the last loaded page was for transactional re-auth on a
+// Google property.
+bool LastLoadWasTransactionalReauthPage(const GURL& last_load_url) {
+ if (last_load_url.GetOrigin() !=
+ GaiaUrls::GetInstance()->gaia_url().GetOrigin())
+ return false;
+
+ // "rart" is the transactional reauth paramter.
+ std::string ignored_value;
+ return net::GetValueForKeyInQuery(last_load_url, "rart", &ignored_value);
+}
+
+} // namespace
+
+SyncStoreResultFilter::SyncStoreResultFilter(
+ const PasswordManagerClient* client)
+ : client_(client),
+ autofill_sync_state_(SetUpAutofillSyncState()),
+ sync_credential_was_filtered_(false) {}
+
+SyncStoreResultFilter::~SyncStoreResultFilter() {
+ UMA_HISTOGRAM_BOOLEAN("PasswordManager.SyncCredentialFiltered",
+ sync_credential_was_filtered_);
+}
+
+bool SyncStoreResultFilter::ShouldIgnore(const autofill::PasswordForm& form) {
+ // TODO(vabr) Move IsSyncAccountCredential here.
+ if (!client_->IsSyncAccountCredential(base::UTF16ToUTF8(form.username_value),
+ form.signon_realm))
+ return false;
+
+ if (autofill_sync_state_ == DISALLOW_SYNC_CREDENTIALS) {
+ sync_credential_was_filtered_ = true;
+ return true;
+ }
+
+ const GURL last_load_url = client_->GetLastCommittedEntryURL();
+ if (autofill_sync_state_ == DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH &&
+ LastLoadWasTransactionalReauthPage(last_load_url)) {
+ sync_credential_was_filtered_ = true;
+ return true;
+ }
+
+ return false;
+}
+
+// static
+SyncStoreResultFilter::AutofillForSyncCredentialsState
+SyncStoreResultFilter::SetUpAutofillSyncState() {
+ std::string group_name =
+ base::FieldTrialList::FindFullName("AutofillSyncCredential");
+
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ if (command_line->HasSwitch(switches::kAllowAutofillSyncCredential))
+ return ALLOW_SYNC_CREDENTIALS;
+ if (command_line->HasSwitch(
+ switches::kDisallowAutofillSyncCredentialForReauth)) {
+ return DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH;
+ }
+ if (command_line->HasSwitch(switches::kDisallowAutofillSyncCredential))
+ return DISALLOW_SYNC_CREDENTIALS;
+
+ if (group_name == "DisallowSyncCredentialsForReauth")
+ return DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH;
+ if (group_name == "DisallowSyncCredentials")
+ return DISALLOW_SYNC_CREDENTIALS;
+
+ // Allow by default.
+ return ALLOW_SYNC_CREDENTIALS;
+}
+
+} // namespace password_manager
diff --git a/components/password_manager/sync/browser/sync_store_result_filter.h b/components/password_manager/sync/browser/sync_store_result_filter.h
new file mode 100644
index 0000000..8d737f1
--- /dev/null
+++ b/components/password_manager/sync/browser/sync_store_result_filter.h
@@ -0,0 +1,46 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_PASSWORD_MANAGER_SYNC_BROWSER_STORE_RESULT_FILTER_H_
+#define COMPONENTS_PASSWORD_MANAGER_SYNC_BROWSER_STORE_RESULT_FILTER_H_
+
+#include "components/password_manager/core/browser/store_result_filter.h"
+
+namespace password_manager {
+
+class PasswordManagerClient;
+
+// The sync- and GAIA- aware implementation of the filter.
+class SyncStoreResultFilter : public StoreResultFilter {
+ public:
+ explicit SyncStoreResultFilter(const PasswordManagerClient* client);
+ ~SyncStoreResultFilter() override;
+
+ // StoreResultFilter
+ bool ShouldIgnore(const autofill::PasswordForm& form) override;
+
+ private:
+ enum AutofillForSyncCredentialsState {
+ ALLOW_SYNC_CREDENTIALS,
+ DISALLOW_SYNC_CREDENTIALS_FOR_REAUTH,
+ DISALLOW_SYNC_CREDENTIALS,
+ };
+
+ // Determines autofill state based on experiment and flag values.
+ static AutofillForSyncCredentialsState SetUpAutofillSyncState();
+
+ const PasswordManagerClient* const client_;
+
+ // How to handle the sync credential in ShouldFilterAutofillResult().
+ const AutofillForSyncCredentialsState autofill_sync_state_;
+
+ // For statistics about filtering the sync credential during autofill.
+ bool sync_credential_was_filtered_;
+
+ DISALLOW_COPY_AND_ASSIGN(SyncStoreResultFilter);
+};
+
+} // namespace password_manager
+
+#endif // COMPONENTS_PASSWORD_MANAGER_SYNC_BROWSER_STORE_RESULT_FILTER_H_
diff --git a/components/password_manager/sync/browser/sync_store_result_filter_unittest.cc b/components/password_manager/sync/browser/sync_store_result_filter_unittest.cc
new file mode 100644
index 0000000..38fd91d
--- /dev/null
+++ b/components/password_manager/sync/browser/sync_store_result_filter_unittest.cc
@@ -0,0 +1,90 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/password_manager/sync/browser/sync_store_result_filter.h"
+
+#include "base/command_line.h"
+#include "components/autofill/core/common/password_form.h"
+#include "components/password_manager/core/browser/stub_password_manager_client.h"
+#include "components/password_manager/core/common/password_manager_switches.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+using testing::Return;
+using testing::ReturnRef;
+
+namespace password_manager {
+
+namespace {
+
+class MockPasswordManagerClient : public StubPasswordManagerClient {
+ public:
+ MOCK_CONST_METHOD2(IsSyncAccountCredential,
+ bool(const std::string&, const std::string&));
+ MOCK_CONST_METHOD0(GetLastCommittedEntryURL, const GURL&());
+};
+
+} // namespace
+
+TEST(StoreResultFilterTest, ShouldFilterAutofillResult_Reauth) {
+ // Disallow only reauth requests.
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ command_line->AppendSwitch(
+ switches::kDisallowAutofillSyncCredentialForReauth);
+ autofill::PasswordForm form;
+ MockPasswordManagerClient client;
+ SyncStoreResultFilter filter(&client);
+
+ EXPECT_CALL(client, IsSyncAccountCredential(_, _))
+ .WillRepeatedly(Return(false));
+ GURL rart_countinue_url(
+ "https://accounts.google.com/login?rart=123&continue=blah");
+ EXPECT_CALL(client, GetLastCommittedEntryURL())
+ .WillRepeatedly(ReturnRef(rart_countinue_url));
+ EXPECT_FALSE(filter.ShouldIgnore(form));
+
+ EXPECT_CALL(client, IsSyncAccountCredential(_, _))
+ .WillRepeatedly(Return(true));
+ EXPECT_TRUE(filter.ShouldIgnore(form));
+
+ // This counts as a reauth url, though a valid URL should have a value for
+ // "rart"
+ GURL rart_url("https://accounts.google.com/addlogin?rart");
+ EXPECT_CALL(client, GetLastCommittedEntryURL()).WillOnce(ReturnRef(rart_url));
+ EXPECT_TRUE(filter.ShouldIgnore(form));
+
+ GURL param_url("https://accounts.google.com/login?param=123");
+ EXPECT_CALL(client, GetLastCommittedEntryURL())
+ .WillOnce(ReturnRef(param_url));
+ EXPECT_FALSE(filter.ShouldIgnore(form));
+
+ GURL rart_value_url("https://site.com/login?rart=678");
+ EXPECT_CALL(client, GetLastCommittedEntryURL())
+ .WillOnce(ReturnRef(rart_value_url));
+ EXPECT_FALSE(filter.ShouldIgnore(form));
+}
+
+TEST(StoreResultFilterTest, ShouldFilterAutofillResult) {
+ // Normally, no credentials should be filtered, even if they are the sync
+ // credential.
+ autofill::PasswordForm form;
+ MockPasswordManagerClient client;
+ SyncStoreResultFilter filter(&client);
+
+ EXPECT_CALL(client, IsSyncAccountCredential(_, _))
+ .WillRepeatedly(Return(true));
+ GURL login_url("https://accounts.google.com/Login");
+ EXPECT_CALL(client, GetLastCommittedEntryURL())
+ .WillRepeatedly(ReturnRef(login_url));
+ EXPECT_FALSE(filter.ShouldIgnore(form));
+
+ // Adding disallow switch should cause sync credential to be filtered.
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ command_line->AppendSwitch(switches::kDisallowAutofillSyncCredential);
+ SyncStoreResultFilter filter_disallow_sync_cred(&client);
+ EXPECT_TRUE(filter_disallow_sync_cred.ShouldIgnore(form));
+}
+
+} // namespace password_manager
diff --git a/ios/chrome/ios_chrome.gyp b/ios/chrome/ios_chrome.gyp
index dc5644c..d9e67e3 100644
--- a/ios/chrome/ios_chrome.gyp
+++ b/ios/chrome/ios_chrome.gyp
@@ -68,6 +68,7 @@
'../../components/components.gyp:omnibox_browser',
'../../components/components.gyp:open_from_clipboard',
'../../components/components.gyp:password_manager_core_browser',
+ '../../components/components.gyp:password_manager_sync_browser',
'../../components/components.gyp:pref_registry',
'../../components/components.gyp:search',
'../../components/components.gyp:search_engines',