Determine cross-origin password reuse based on PasswordForm::url
This change adds url property to MatchingReusedCredential structure which corresponds to PasswordForm::url.
Before: PasswordForm::signon_realm was cast to GURL and passed to
GetRegistryControlledDomain().
Now: PasswordForm::url is used and passed to
GetRegistryControlledDomain().
Bug: 368517711
Fixed: 40895227
Change-Id: I1a18739135350117603dbe4c9d17bb13e9b16ea3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5891506
Reviewed-by: Sylvain Defresne <sdefresne@chromium.org>
Commit-Queue: Viktor Semeniuk <vsemeniuk@google.com>
Reviewed-by: Vasilii Sukhanov <vasilii@chromium.org>
Reviewed-by: Daniel Rubery <drubery@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1367331}
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
index 6de68c7..672ca7b 100644
--- a/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
+++ b/chrome/browser/safe_browsing/chrome_password_protection_service_browsertest.cc
@@ -414,7 +414,7 @@
AddFormToStore(password_store.get(), form);
std::vector<password_manager::MatchingReusedCredential> credentials = {
- {kSignonRealm, kUsername}};
+ {kSignonRealm, GURL(kSignonRealm), kUsername}};
service->set_saved_passwords_matching_reused_credentials({credentials});
@@ -916,7 +916,7 @@
const std::string kSignonRealm = "https://example.test";
const std::u16string kUsername = u"username1";
std::vector<password_manager::MatchingReusedCredential> credentials = {
- {kSignonRealm, kUsername}};
+ {kSignonRealm, GURL(kSignonRealm), kUsername}};
service->StartRequestForTesting(
GetWebContents(), GURL(), GURL(), GURL(), "",
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc
index be6452b1..c301944 100644
--- a/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc
+++ b/chrome/browser/safe_browsing/chrome_password_protection_service_unittest.cc
@@ -399,8 +399,9 @@
void InitializeRequest(LoginReputationClientRequest::TriggerType trigger_type,
PasswordType reused_password_type) {
- std::vector<password_manager::MatchingReusedCredential> credentials = {
- {"somedomain.com"}};
+ std::vector<MatchingReusedCredential> credentials;
+ credentials.emplace_back("somedomain.com", GURL("https://somedomain.com/"),
+ u"user");
if (trigger_type == LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE) {
request_ = new PasswordProtectionRequestContent(
web_contents(), GURL(kPhishingURL), GURL(), GURL(),
@@ -680,8 +681,11 @@
VerifyPersistPhishedSavedPasswordCredential) {
service_->ConfigService(/*is_incognito=*/false,
/*is_extended_reporting=*/true);
- std::vector<password_manager::MatchingReusedCredential> credentials = {
- {"http://example.test"}, {"http://2.example.com"}};
+ std::vector<password_manager::MatchingReusedCredential> credentials;
+ credentials.emplace_back("http://example.test", GURL("http://example.test/"),
+ u"user");
+ credentials.emplace_back("http://2.example.com",
+ GURL("http://example2.test/"), u"user");
EXPECT_CALL(mock_add_callback_, Run(password_store_.get(), credentials[0]));
EXPECT_CALL(mock_add_callback_, Run(password_store_.get(), credentials[1]));
@@ -692,9 +696,11 @@
VerifyRemovePhishedSavedPasswordCredential) {
service_->ConfigService(/*is_incognito=*/false,
/*is_extended_reporting=*/true);
- std::vector<password_manager::MatchingReusedCredential> credentials = {
- {"http://example.test", u"username1"},
- {"http://2.example.test", u"username2"}};
+ std::vector<password_manager::MatchingReusedCredential> credentials;
+ credentials.emplace_back("http://example.test", GURL("http://example.test/"),
+ u"user");
+ credentials.emplace_back("http://2.example.com",
+ GURL("http://example2.test/"), u"user");
EXPECT_CALL(mock_remove_callback_,
Run(password_store_.get(), credentials[0]));
@@ -1672,11 +1678,13 @@
VerifyPersistPhishedSavedPasswordCredential) {
service_->ConfigService(/*is_incognito=*/false,
/*is_extended_reporting=*/true);
- std::vector<password_manager::MatchingReusedCredential> credentials = {
- {.signon_realm = "http://example.test",
- .in_store = password_manager::PasswordForm::Store::kAccountStore},
- {.signon_realm = "http://2.example.test",
- .in_store = password_manager::PasswordForm::Store::kAccountStore}};
+ std::vector<password_manager::MatchingReusedCredential> credentials;
+ credentials.emplace_back(
+ "http://example.test", GURL("http://example.test/"), u"user",
+ password_manager::PasswordForm::Store::kAccountStore);
+ credentials.emplace_back(
+ "http://2.example.com", GURL("http://example2.test/"), u"user",
+ password_manager::PasswordForm::Store::kAccountStore);
EXPECT_CALL(mock_add_callback_,
Run(account_password_store_.get(), credentials[0]));
@@ -1689,11 +1697,13 @@
VerifyRemovePhishedSavedPasswordCredential) {
service_->ConfigService(/*is_incognito=*/false,
/*is_extended_reporting=*/true);
- std::vector<password_manager::MatchingReusedCredential> credentials = {
- {"http://example.test", u"username1",
- password_manager::PasswordForm::Store::kAccountStore},
- {"http://2.example.test", u"username2",
- password_manager::PasswordForm::Store::kAccountStore}};
+ std::vector<password_manager::MatchingReusedCredential> credentials;
+ credentials.emplace_back(
+ "http://example.test", GURL("http://example.test/"), u"user",
+ password_manager::PasswordForm::Store::kAccountStore);
+ credentials.emplace_back(
+ "http://2.example.com", GURL("http://example2.test/"), u"user",
+ password_manager::PasswordForm::Store::kAccountStore);
EXPECT_CALL(mock_remove_callback_,
Run(account_password_store_.get(), credentials[0]));
@@ -1752,9 +1762,10 @@
VerifyPhishGuardDialogOpensPasswordCheckupForAccountStoreSyncing) {
service_->ConfigService(/*is_incognito=*/false,
/*is_extended_reporting=*/true);
- std::vector<password_manager::MatchingReusedCredential> credentials = {
- {"http://example.test", u"username",
- password_manager::PasswordForm::Store::kAccountStore}};
+ std::vector<password_manager::MatchingReusedCredential> credentials;
+ credentials.emplace_back(
+ "http://example.test", GURL("http://example.test/"), u"user",
+ password_manager::PasswordForm::Store::kAccountStore);
service_->set_saved_passwords_matching_reused_credentials(credentials);
SetUpSyncService(/*is_syncing_passwords=*/true);
@@ -1773,9 +1784,11 @@
VerifyPhishGuardDialogOpensPasswordCheckupForProfileStoreSyncing) {
service_->ConfigService(/*is_incognito=*/false,
/*is_extended_reporting=*/true);
- std::vector<password_manager::MatchingReusedCredential> credentials = {
- {"http://example.test", u"username",
- password_manager::PasswordForm::Store::kProfileStore}};
+ std::vector<password_manager::MatchingReusedCredential> credentials;
+ credentials.emplace_back(
+ "http://example.test", GURL("http://example.test/"), u"user",
+ password_manager::PasswordForm::Store::kProfileStore);
+
service_->set_saved_passwords_matching_reused_credentials(credentials);
SetUpSyncService(/*is_syncing_passwords=*/true);
@@ -1794,9 +1807,11 @@
VerifyPhishGuardDialogOpensPasswordCheckupForProfileStoreNotSyncing) {
service_->ConfigService(/*is_incognito=*/false,
/*is_extended_reporting=*/true);
- std::vector<password_manager::MatchingReusedCredential> credentials = {
- {"http://example.test", u"username",
- password_manager::PasswordForm::Store::kProfileStore}};
+ std::vector<password_manager::MatchingReusedCredential> credentials;
+ credentials.emplace_back(
+ "http://example.test", GURL("http://example.test/"), u"user",
+ password_manager::PasswordForm::Store::kProfileStore);
+
service_->set_saved_passwords_matching_reused_credentials(credentials);
SetUpSyncService(/*is_syncing_passwords=*/false);
@@ -1815,11 +1830,14 @@
VerifyPhishGuardDialogOpensSafetyCheckMenuForBothStoresSyncing) {
service_->ConfigService(/*is_incognito=*/false,
/*is_extended_reporting=*/true);
- std::vector<password_manager::MatchingReusedCredential> credentials = {
- {"http://example.test", u"username",
- password_manager::PasswordForm::Store::kProfileStore},
- {"http://2.example.test", u"username",
- password_manager::PasswordForm::Store::kAccountStore}};
+ std::vector<password_manager::MatchingReusedCredential> credentials;
+ credentials.emplace_back(
+ "http://example.test", GURL("http://example.test/"), u"user",
+ password_manager::PasswordForm::Store::kAccountStore);
+ credentials.emplace_back(
+ "http://2.example.test", GURL("http://example.test/"), u"user",
+ password_manager::PasswordForm::Store::kProfileStore);
+
service_->set_saved_passwords_matching_reused_credentials(credentials);
SetUpSyncService(/*is_syncing_passwords=*/true);
@@ -1845,9 +1863,10 @@
VerifyPhishGuardDialogOpensPasswordCheckupEmptyAccountForNonSyncingUser) {
service_->ConfigService(/*is_incognito=*/false,
/*is_extended_reporting=*/true);
- std::vector<password_manager::MatchingReusedCredential> credentials = {
- {"http://example.test", u"username",
- password_manager::PasswordForm::Store::kProfileStore}};
+ std::vector<password_manager::MatchingReusedCredential> credentials;
+ credentials.emplace_back(
+ "http://example.test", GURL("http://example.test/"), u"user",
+ password_manager::PasswordForm::Store::kProfileStore);
service_->set_saved_passwords_matching_reused_credentials(credentials);
SetUpSyncService(/*is_syncing_passwords=*/false);
@@ -1866,9 +1885,11 @@
VerifyPhishGuardDialogOpensPasswordCheckupWithAnAccountForSyncingUser) {
service_->ConfigService(/*is_incognito=*/false,
/*is_extended_reporting=*/true);
- std::vector<password_manager::MatchingReusedCredential> credentials = {
- {"http://example.test", u"username",
- password_manager::PasswordForm::Store::kProfileStore}};
+ std::vector<password_manager::MatchingReusedCredential> credentials;
+ credentials.emplace_back(
+ "http://example.test", GURL("http://example.test/"), u"user",
+ password_manager::PasswordForm::Store::kProfileStore);
+
service_->set_saved_passwords_matching_reused_credentials(credentials);
SetUpSyncService(/*is_syncing_passwords=*/true);
diff --git a/chrome/browser/safe_browsing/chrome_password_reuse_detection_manager_client.cc b/chrome/browser/safe_browsing/chrome_password_reuse_detection_manager_client.cc
index e0b94504..c720bf9 100644
--- a/chrome/browser/safe_browsing/chrome_password_reuse_detection_manager_client.cc
+++ b/chrome/browser/safe_browsing/chrome_password_reuse_detection_manager_client.cc
@@ -71,10 +71,8 @@
matching_reused_credentials) {
base::flat_set<std::string> matching_domains;
for (const auto& credential : matching_reused_credentials) {
- // TODO(crbug.com/40895227): Avoid converting signon_realm to URL,
- // ideally use PasswordForm::url.
std::string domain = base::UTF16ToUTF8(url_formatter::FormatUrl(
- GURL(credential.signon_realm),
+ credential.url,
url_formatter::kFormatUrlOmitDefaults |
url_formatter::kFormatUrlOmitHTTPS |
url_formatter::kFormatUrlOmitTrivialSubdomains |
diff --git a/chrome/browser/safe_browsing/chrome_password_reuse_detection_manager_client_unittest.cc b/chrome/browser/safe_browsing/chrome_password_reuse_detection_manager_client_unittest.cc
index 01e68c9f..7c686881 100644
--- a/chrome/browser/safe_browsing/chrome_password_reuse_detection_manager_client_unittest.cc
+++ b/chrome/browser/safe_browsing/chrome_password_reuse_detection_manager_client_unittest.cc
@@ -163,7 +163,7 @@
MaybeStartProtectedPasswordEntryRequest(_, _, "username", _, _, true))
.Times(4);
std::vector<password_manager::MatchingReusedCredential> credentials = {
- {"saved_domain.com", u"username"}};
+ {"saved_domain.com", GURL("https://saved_domain.com/"), u"username"}};
client->CheckProtectedPasswordEntry(
password_manager::metrics_util::PasswordType::SAVED_PASSWORD, "username",
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn
index 434cf83..ac36d55 100644
--- a/components/password_manager/core/browser/BUILD.gn
+++ b/components/password_manager/core/browser/BUILD.gn
@@ -127,6 +127,7 @@
"password_manual_fallback_metrics_recorder.h",
"password_requirements_service.cc",
"password_requirements_service.h",
+ "password_reuse_detector.cc",
"password_reuse_detector.h",
"password_reuse_detector_consumer.cc",
"password_reuse_detector_consumer.h",
diff --git a/components/password_manager/core/browser/insecure_credentials_helper.cc b/components/password_manager/core/browser/insecure_credentials_helper.cc
index 87a0b55..69b1a4a 100644
--- a/components/password_manager/core/browser/insecure_credentials_helper.cc
+++ b/components/password_manager/core/browser/insecure_credentials_helper.cc
@@ -59,8 +59,7 @@
void InsecureCredentialsHelper::AddPhishedCredentials(
const MatchingReusedCredential& credential) {
PasswordFormDigest digest = {PasswordForm::Scheme::kHtml,
- credential.signon_realm,
- GURL(credential.signon_realm)};
+ credential.signon_realm, credential.url};
operation_ =
base::BindOnce(&InsecureCredentialsHelper::AddPhishedCredentialsInternal,
base::Owned(this), credential);
@@ -70,8 +69,7 @@
void InsecureCredentialsHelper::RemovePhishedCredentials(
const MatchingReusedCredential& credential) {
PasswordFormDigest digest = {PasswordForm::Scheme::kHtml,
- credential.signon_realm,
- GURL(credential.signon_realm)};
+ credential.signon_realm, credential.url};
operation_ = base::BindOnce(
&InsecureCredentialsHelper::RemovePhishedCredentialsInternal,
base::Owned(this), credential);
diff --git a/components/password_manager/core/browser/insecure_credentials_helper_unittest.cc b/components/password_manager/core/browser/insecure_credentials_helper_unittest.cc
index a5d85913..6bb3f8b7 100644
--- a/components/password_manager/core/browser/insecure_credentials_helper_unittest.cc
+++ b/components/password_manager/core/browser/insecure_credentials_helper_unittest.cc
@@ -27,16 +27,16 @@
std::u16string_view password = std::u16string_view()) {
PasswordForm form;
form.signon_realm = std::string(signon_realm);
+ form.url = GURL(signon_realm);
form.username_value = std::u16string(username);
form.password_value = std::u16string(password);
return form;
}
-MatchingReusedCredential MakeCredential(std::string_view signon_realm,
+MatchingReusedCredential MakeCredential(const std::string& signon_realm,
std::u16string_view username) {
- MatchingReusedCredential credential;
- credential.signon_realm = std::string(signon_realm);
- credential.username = std::u16string(username);
+ MatchingReusedCredential credential(signon_realm, GURL(signon_realm),
+ std::u16string(username));
return credential;
}
diff --git a/components/password_manager/core/browser/password_reuse_detector.cc b/components/password_manager/core/browser/password_reuse_detector.cc
new file mode 100644
index 0000000..fbb8bce4
--- /dev/null
+++ b/components/password_manager/core/browser/password_reuse_detector.cc
@@ -0,0 +1,34 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/password_manager/core/browser/password_reuse_detector.h"
+
+namespace password_manager {
+
+MatchingReusedCredential::MatchingReusedCredential(std::string signon_realm,
+ GURL url,
+ std::u16string username,
+ PasswordForm::Store in_store)
+ : signon_realm(std::move(signon_realm)),
+ url(std::move(url)),
+ username(std::move(username)),
+ in_store(in_store) {}
+
+MatchingReusedCredential::MatchingReusedCredential(const PasswordForm& form)
+ : MatchingReusedCredential(form.signon_realm,
+ form.url,
+ form.username_value,
+ form.in_store) {}
+MatchingReusedCredential::MatchingReusedCredential(
+ const MatchingReusedCredential& other) = default;
+MatchingReusedCredential::MatchingReusedCredential(
+ MatchingReusedCredential&& other) = default;
+MatchingReusedCredential::~MatchingReusedCredential() = default;
+
+MatchingReusedCredential& MatchingReusedCredential::operator=(
+ MatchingReusedCredential& other) = default;
+MatchingReusedCredential& MatchingReusedCredential::operator=(
+ MatchingReusedCredential&&) = default;
+
+} // namespace password_manager
diff --git a/components/password_manager/core/browser/password_reuse_detector.h b/components/password_manager/core/browser/password_reuse_detector.h
index 0a5be41..89b7c64 100644
--- a/components/password_manager/core/browser/password_reuse_detector.h
+++ b/components/password_manager/core/browser/password_reuse_detector.h
@@ -36,15 +36,28 @@
// Container for the signon_realm and username that a compromised saved password
// is saved on/with.
struct MatchingReusedCredential {
+ MatchingReusedCredential(
+ std::string signon_realm,
+ GURL url,
+ std::u16string username,
+ PasswordForm::Store in_store = PasswordForm::Store::kNotSet);
+ explicit MatchingReusedCredential(const PasswordForm& form);
+ MatchingReusedCredential(const MatchingReusedCredential& other);
+ MatchingReusedCredential(MatchingReusedCredential&& other);
+ ~MatchingReusedCredential();
+
friend auto operator<=>(const MatchingReusedCredential&,
const MatchingReusedCredential&) = default;
friend bool operator==(const MatchingReusedCredential&,
const MatchingReusedCredential&) = default;
+ MatchingReusedCredential& operator=(MatchingReusedCredential& other);
+ MatchingReusedCredential& operator=(MatchingReusedCredential&&);
std::string signon_realm;
+ GURL url;
std::u16string username;
// The store in which those credentials are stored.
- PasswordForm::Store in_store = PasswordForm::Store::kNotSet;
+ PasswordForm::Store in_store;
};
// Per-profile class responsible for detection of password reuse, i.e. that the
diff --git a/components/password_manager/core/browser/password_reuse_detector_impl.cc b/components/password_manager/core/browser/password_reuse_detector_impl.cc
index bd20ea7..b81f01d 100644
--- a/components/password_manager/core/browser/password_reuse_detector_impl.cc
+++ b/components/password_manager/core/browser/password_reuse_detector_impl.cc
@@ -248,14 +248,13 @@
passwords_iterator->second;
DCHECK(!credentials.empty());
- std::set<std::string> signon_realms;
+ std::set<std::string> domains;
for (const auto& credential : credentials) {
- signon_realms.insert(
- GetRegistryControlledDomain(GURL(credential.signon_realm)));
+ domains.insert(GetRegistryControlledDomain(credential.url));
}
// If the page's URL matches a saved domain for this password,
// this isn't password-reuse.
- if (base::Contains(signon_realms, registry_controlled_domain)) {
+ if (base::Contains(domains, registry_controlled_domain)) {
continue;
}
@@ -268,9 +267,13 @@
}
}
- matching_reused_credentials_out->assign(
- matching_reused_credentials_set.begin(),
- matching_reused_credentials_set.end());
+ matching_reused_credentials_out->reserve(
+ matching_reused_credentials_set.size());
+ for (auto it = matching_reused_credentials_set.begin();
+ it != matching_reused_credentials_set.end();) {
+ matching_reused_credentials_out->push_back(
+ std::move(matching_reused_credentials_set.extract(it++).value()));
+ }
return reused_saved_password;
}
@@ -348,7 +351,7 @@
}
passwords_with_matching_reused_credentials_[form.password_value].insert(
- {form.signon_realm, form.username_value, form.in_store});
+ MatchingReusedCredential(form));
}
void PasswordReuseDetectorImpl::RemovePassword(const PasswordForm& form) {
@@ -357,8 +360,7 @@
return;
}
- MatchingReusedCredential credential_criteria = {
- form.signon_realm, form.username_value, form.in_store};
+ MatchingReusedCredential credential_criteria(form);
auto password_value_iter =
passwords_with_matching_reused_credentials_.begin();
while (password_value_iter !=
diff --git a/components/password_manager/core/browser/password_reuse_detector_impl_unittest.cc b/components/password_manager/core/browser/password_reuse_detector_impl_unittest.cc
index fefa20b..c84567b 100644
--- a/components/password_manager/core/browser/password_reuse_detector_impl_unittest.cc
+++ b/components/password_manager/core/browser/password_reuse_detector_impl_unittest.cc
@@ -24,6 +24,7 @@
using base::ASCIIToUTF16;
using testing::_;
using testing::IsEmpty;
+using testing::UnorderedElementsAre;
using testing::UnorderedElementsAreArray;
namespace password_manager {
@@ -81,6 +82,7 @@
PasswordForm::Store store) {
auto form = std::make_unique<PasswordForm>();
form->signon_realm = domain;
+ form->url = GURL(domain);
form->password_value = ASCIIToUTF16(password);
form->username_value = ASCIIToUTF16(username);
form->in_store = store;
@@ -161,8 +163,8 @@
testing::Mock::VerifyAndClearExpectations(&mockConsumer);
std::vector<MatchingReusedCredential> credentials = {
- {"https://accounts.google.com", u"gUsername",
- PasswordForm::Store::kProfileStore}};
+ {"https://accounts.google.com", GURL("https://accounts.google.com"),
+ u"gUsername", PasswordForm::Store::kProfileStore}};
EXPECT_CALL(
mockConsumer,
OnReuseCheckDone(true, strlen("saved_password"),
@@ -182,10 +184,13 @@
testing::Mock::VerifyAndClearExpectations(&mockConsumer);
- credentials = {{"https://example1.com", u"example1Username",
- PasswordForm::Store::kProfileStore},
- {"https://example2.com", u"example2Username",
- PasswordForm::Store::kProfileStore}};
+ credentials.clear();
+ credentials.emplace_back("https://example1.com", GURL("https://example1.com"),
+ u"example1Username",
+ PasswordForm::Store::kProfileStore);
+ credentials.emplace_back("https://example2.com", GURL("https://example2.com"),
+ u"example2Username",
+ PasswordForm::Store::kProfileStore);
EXPECT_CALL(
mockConsumer,
OnReuseCheckDone(true, strlen("secretword"),
@@ -213,8 +218,8 @@
MockPasswordReuseDetectorConsumer mockConsumer;
const std::vector<MatchingReusedCredential> credentials = {
- {"https://a.appspot.com", u"appspotUsername",
- PasswordForm::Store::kProfileStore}};
+ {"https://a.appspot.com", GURL("https://a.appspot.com"),
+ u"appspotUsername", PasswordForm::Store::kProfileStore}};
// a.appspot.com and b.appspot.com are not PSL matches. So reuse event should
// be raised.
EXPECT_CALL(
@@ -263,8 +268,8 @@
EXPECT_CALL(mockConsumer, OnReuseCheckDone(false, _, _, _, _, _, _));
} else {
const std::vector<MatchingReusedCredential> credentials = {
- {"https://accounts.google.com", u"gUsername",
- PasswordForm::Store::kProfileStore}};
+ {"https://accounts.google.com", GURL("https://accounts.google.com"),
+ u"gUsername", PasswordForm::Store::kProfileStore}};
EXPECT_CALL(
mockConsumer,
OnReuseCheckDone(true, strlen("saved_password"),
@@ -287,8 +292,8 @@
const std::vector<MatchingReusedCredential>
expected_matching_reused_credentials = {
- {"https://accounts.google.com", u"gUsername",
- PasswordForm::Store::kProfileStore}};
+ {"https://accounts.google.com", GURL("https://accounts.google.com"),
+ u"gUsername", PasswordForm::Store::kProfileStore}};
MockPasswordReuseDetectorConsumer mockConsumer;
// One of the passwords in |login_credentials| has less than the minimum
// requirement of characters in a password so it will not be stored.
@@ -333,11 +338,10 @@
GetChangeList(PasswordStoreChange::ADD, login_credentials);
reuse_detector.OnLoginsChanged(add_changes);
- std::vector<MatchingReusedCredential> expected_matching_reused_credentials = {
- {"https://example1.com", u"example1Username",
- PasswordForm::Store::kProfileStore},
- {"https://example2.com", u"example2Username",
- PasswordForm::Store::kProfileStore}};
+ std::vector<MatchingReusedCredential> expected_matching_reused_credentials;
+ expected_matching_reused_credentials.emplace_back(*login_credentials[0]);
+ expected_matching_reused_credentials.emplace_back(*login_credentials[2]);
+
MockPasswordReuseDetectorConsumer mockConsumer;
int valid_passwords = login_credentials.size();
EXPECT_CALL(
@@ -359,9 +363,9 @@
PasswordStoreChange::REMOVE,
GetForms({{"https://example1.com", "example1Username", "secretword"}}));
reuse_detector.OnLoginsChanged(remove_changes);
- expected_matching_reused_credentials = {{"https://example2.com",
- u"example2Username",
- PasswordForm::Store::kProfileStore}};
+ expected_matching_reused_credentials.clear();
+ expected_matching_reused_credentials.emplace_back(*login_credentials[2]);
+
EXPECT_CALL(
mockConsumer,
OnReuseCheckDone(
@@ -387,7 +391,7 @@
}
TEST(PasswordReuseDetectorTest, MatchMultiplePasswords) {
- // These all have different length passwods so we can check the
+ // These all have different length passwords so we can check the
// returned length.
const std::vector<TestData> domain_passwords = {
{"https://a.com, https://all.com", "aUsername", "34567890"},
@@ -403,13 +407,20 @@
MockPasswordReuseDetectorConsumer mockConsumer;
std::vector<MatchingReusedCredential> credentials = {
- {"https://a.com", u"aUsername", PasswordForm::Store::kProfileStore},
- {"https://all.com", u"aUsername", PasswordForm::Store::kProfileStore},
- {"https://all.com", u"bUsername", PasswordForm::Store::kProfileStore},
- {"https://all.com", u"cUsername", PasswordForm::Store::kProfileStore},
- {"https://b.com", u"bUsername", PasswordForm::Store::kProfileStore},
- {"https://b2.com", u"bUsername", PasswordForm::Store::kProfileStore},
- {"https://c.com", u"cUsername", PasswordForm::Store::kProfileStore}};
+ {"https://a.com", GURL("https://a.com"), u"aUsername",
+ PasswordForm::Store::kProfileStore},
+ {"https://all.com", GURL("https://all.com"), u"aUsername",
+ PasswordForm::Store::kProfileStore},
+ {"https://all.com", GURL("https://all.com"), u"bUsername",
+ PasswordForm::Store::kProfileStore},
+ {"https://all.com", GURL("https://all.com"), u"cUsername",
+ PasswordForm::Store::kProfileStore},
+ {"https://b.com", GURL("https://b.com"), u"bUsername",
+ PasswordForm::Store::kProfileStore},
+ {"https://b2.com", GURL("https://b2.com"), u"bUsername",
+ PasswordForm::Store::kProfileStore},
+ {"https://c.com", GURL("https://c.com"), u"cUsername",
+ PasswordForm::Store::kProfileStore}};
EXPECT_CALL(
mockConsumer,
OnReuseCheckDone(true, strlen("01234567890"),
@@ -419,11 +430,15 @@
&mockConsumer);
testing::Mock::VerifyAndClearExpectations(&mockConsumer);
- credentials = {
- {"https://a.com", u"aUsername", PasswordForm::Store::kProfileStore},
- {"https://all.com", u"aUsername", PasswordForm::Store::kProfileStore},
- {"https://all.com", u"cUsername", PasswordForm::Store::kProfileStore},
- {"https://c.com", u"cUsername", PasswordForm::Store::kProfileStore}};
+ credentials.clear();
+ credentials.emplace_back("https://a.com", GURL("https://a.com"), u"aUsername",
+ PasswordForm::Store::kProfileStore);
+ credentials.emplace_back("https://all.com", GURL("https://all.com"),
+ u"aUsername", PasswordForm::Store::kProfileStore);
+ credentials.emplace_back("https://all.com", GURL("https://all.com"),
+ u"cUsername", PasswordForm::Store::kProfileStore);
+ credentials.emplace_back("https://c.com", GURL("https://c.com"), u"cUsername",
+ PasswordForm::Store::kProfileStore);
EXPECT_CALL(
mockConsumer,
OnReuseCheckDone(true, strlen("1234567890"),
@@ -551,8 +566,10 @@
MockPasswordReuseDetectorConsumer mockConsumer;
const std::vector<MatchingReusedCredential> credentials = {
- {"https://a.com", u"aUsername", PasswordForm::Store::kProfileStore},
- {"https://b.com", u"bUsername", PasswordForm::Store::kProfileStore}};
+ {"https://a.com", GURL("https://a.com"), u"aUsername",
+ PasswordForm::Store::kProfileStore},
+ {"https://b.com", GURL("https://b.com"), u"bUsername",
+ PasswordForm::Store::kProfileStore}};
EXPECT_CALL(
mockConsumer,
OnReuseCheckDone(true, strlen("01234567890"),
@@ -584,8 +601,8 @@
reuse_detector.UseGaiaPasswordHash(PrepareGaiaPasswordData({gaia_password}));
const std::vector<MatchingReusedCredential> credentials = {
- {"https://accounts.google.com", u"gUsername",
- PasswordForm::Store::kProfileStore}};
+ {"https://accounts.google.com", GURL("https://accounts.google.com"),
+ u"gUsername", PasswordForm::Store::kProfileStore}};
EXPECT_CALL(
mockConsumer,
OnReuseCheckDone(true, strlen("saved_password"),
@@ -601,6 +618,7 @@
auto account_store_form = std::make_unique<PasswordForm>();
account_store_form->signon_realm = "https://twitter.com";
+ account_store_form->url = GURL(account_store_form->signon_realm);
account_store_form->username_value = u"twitterUsername";
account_store_form->password_value = u"saved_password";
account_store_form->in_store = PasswordForm::Store::kAccountStore;
@@ -612,7 +630,7 @@
reuse_detector.UseGaiaPasswordHash(PrepareGaiaPasswordData({gaia_password}));
const std::vector<MatchingReusedCredential> credentials = {
- {"https://twitter.com", u"twitterUsername",
+ {"https://twitter.com", GURL("https://twitter.com"), u"twitterUsername",
PasswordForm::Store::kAccountStore}};
MockPasswordReuseDetectorConsumer mockConsumer;
@@ -645,8 +663,10 @@
MockPasswordReuseDetectorConsumer mockConsumer;
const std::vector<MatchingReusedCredential> credentials = {
- {"https://a.com", u"aUsername", PasswordForm::Store::kProfileStore},
- {"https://b.com", u"bUsername", PasswordForm::Store::kProfileStore}};
+ {"https://a.com", GURL("https://a.com"), u"aUsername",
+ PasswordForm::Store::kProfileStore},
+ {"https://b.com", GURL("https://b.com"), u"bUsername",
+ PasswordForm::Store::kProfileStore}};
EXPECT_CALL(
mockConsumer,
OnReuseCheckDone(true, strlen("01234567890"),
@@ -680,8 +700,8 @@
PrepareEnterprisePasswordData({enterprise_password}));
const std::vector<MatchingReusedCredential> credentials = {
- {"https://accounts.google.com", u"gUsername",
- PasswordForm::Store::kProfileStore}};
+ {"https://accounts.google.com", GURL("https://accounts.google.com"),
+ u"gUsername", PasswordForm::Store::kProfileStore}};
EXPECT_CALL(
mockConsumer,
OnReuseCheckDone(true, strlen("saved_password"),
@@ -714,8 +734,10 @@
MockPasswordReuseDetectorConsumer mockConsumer;
const std::vector<MatchingReusedCredential> credentials = {
- {"https://a.com", u"aUsername", PasswordForm::Store::kProfileStore},
- {"https://b.com", u"bUsername", PasswordForm::Store::kProfileStore}};
+ {"https://a.com", GURL("https://a.com"), u"aUsername",
+ PasswordForm::Store::kProfileStore},
+ {"https://b.com", GURL("https://b.com"), u"bUsername",
+ PasswordForm::Store::kProfileStore}};
EXPECT_CALL(
mockConsumer,
OnReuseCheckDone(true, strlen("01234567890"),
@@ -775,24 +797,21 @@
// The credential duplicated in both stores
PasswordForm account_store_form = *account_credentials[2];
+ std::vector<MatchingReusedCredential> expected_credentials;
+ expected_credentials.emplace_back(*profile_credentials[4]);
+ expected_credentials.emplace_back(*profile_credentials[5]);
+ expected_credentials.emplace_back(account_store_form);
+
reuse_detector.OnGetPasswordStoreResults(std::move(profile_credentials));
reuse_detector.OnGetPasswordStoreResults(std::move(account_credentials));
MockPasswordReuseDetectorConsumer mockConsumer;
- EXPECT_CALL(
- mockConsumer,
- OnReuseCheckDone(
- /*is_reuse_found=*/true, strlen("secretword"),
- Matches(NO_GAIA_OR_ENTERPRISE_REUSE),
- UnorderedElementsAreArray(std::vector<MatchingReusedCredential>{
- {"https://example1.com", u"example1Username",
- PasswordForm::Store::kProfileStore},
- {"https://example2.com", u"example2Username",
- PasswordForm::Store::kProfileStore},
- {"https://example2.com", u"example2Username",
- PasswordForm::Store::kAccountStore}}),
- /*saved_passwords=*/9, _, _));
+ EXPECT_CALL(mockConsumer, OnReuseCheckDone(
+ /*is_reuse_found=*/true, strlen("secretword"),
+ Matches(NO_GAIA_OR_ENTERPRISE_REUSE),
+ UnorderedElementsAreArray(expected_credentials),
+ /*saved_passwords=*/9, _, _));
reuse_detector.CheckReuse(u"secretword", "https://evil.com", &mockConsumer);
testing::Mock::VerifyAndClearExpectations(&mockConsumer);
@@ -802,18 +821,13 @@
remove_changes.push_back(
PasswordStoreChange(PasswordStoreChange::REMOVE, account_store_form));
reuse_detector.OnLoginsChanged(remove_changes);
+ expected_credentials.pop_back();
- EXPECT_CALL(
- mockConsumer,
- OnReuseCheckDone(
- /*is_reuse_found=*/true, strlen("secretword"),
- Matches(NO_GAIA_OR_ENTERPRISE_REUSE),
- UnorderedElementsAreArray(std::vector<MatchingReusedCredential>{
- {"https://example1.com", u"example1Username",
- PasswordForm::Store::kProfileStore},
- {"https://example2.com", u"example2Username",
- PasswordForm::Store::kProfileStore}}),
- /*saved_passwords=*/8, _, _));
+ EXPECT_CALL(mockConsumer, OnReuseCheckDone(
+ /*is_reuse_found=*/true, strlen("secretword"),
+ Matches(NO_GAIA_OR_ENTERPRISE_REUSE),
+ UnorderedElementsAreArray(expected_credentials),
+ /*saved_passwords=*/8, _, _));
reuse_detector.CheckReuse(u"secretword", "https://evil.com", &mockConsumer);
}
@@ -825,41 +839,33 @@
std::vector<std::unique_ptr<PasswordForm>> account_credentials =
GetForms(GetTestDomainsPasswordsForAccountStore());
+ std::vector<MatchingReusedCredential> expected_credentials;
+ expected_credentials.emplace_back(*profile_credentials[4]);
+ expected_credentials.emplace_back(*profile_credentials[5]);
+ expected_credentials.emplace_back(*account_credentials[2]);
+
reuse_detector.OnGetPasswordStoreResults(std::move(profile_credentials));
reuse_detector.OnGetPasswordStoreResults(std::move(account_credentials));
MockPasswordReuseDetectorConsumer mockConsumer;
- EXPECT_CALL(
- mockConsumer,
- OnReuseCheckDone(
- /*is_reuse_found=*/true, strlen("secretword"),
- Matches(NO_GAIA_OR_ENTERPRISE_REUSE),
- UnorderedElementsAreArray(std::vector<MatchingReusedCredential>{
- {"https://example1.com", u"example1Username",
- PasswordForm::Store::kProfileStore},
- {"https://example2.com", u"example2Username",
- PasswordForm::Store::kAccountStore},
- {"https://example2.com", u"example2Username",
- PasswordForm::Store::kProfileStore}}),
- /*saved_passwords=*/9, _, _));
+ EXPECT_CALL(mockConsumer, OnReuseCheckDone(
+ /*is_reuse_found=*/true, strlen("secretword"),
+ Matches(NO_GAIA_OR_ENTERPRISE_REUSE),
+ UnorderedElementsAreArray(expected_credentials),
+ /*saved_passwords=*/9, _, _));
reuse_detector.CheckReuse(u"secretword", "https://evil.com", &mockConsumer);
testing::Mock::VerifyAndClearExpectations(&mockConsumer);
reuse_detector.ClearCachedAccountStorePasswords();
+ expected_credentials.pop_back();
- EXPECT_CALL(
- mockConsumer,
- OnReuseCheckDone(
- /*is_reuse_found=*/true, strlen("secretword"),
- Matches(NO_GAIA_OR_ENTERPRISE_REUSE),
- UnorderedElementsAreArray(std::vector<MatchingReusedCredential>{
- {"https://example1.com", u"example1Username",
- PasswordForm::Store::kProfileStore},
- {"https://example2.com", u"example2Username",
- PasswordForm::Store::kProfileStore}}),
- /*saved_passwords=*/6, _, _));
+ EXPECT_CALL(mockConsumer, OnReuseCheckDone(
+ /*is_reuse_found=*/true, strlen("secretword"),
+ Matches(NO_GAIA_OR_ENTERPRISE_REUSE),
+ UnorderedElementsAreArray(expected_credentials),
+ /*saved_passwords=*/6, _, _));
reuse_detector.CheckReuse(u"secretword", "https://evil.com", &mockConsumer);
}
diff --git a/components/password_manager/core/browser/password_reuse_manager_impl.cc b/components/password_manager/core/browser/password_reuse_manager_impl.cc
index d5fda15..a4b969b6 100644
--- a/components/password_manager/core/browser/password_reuse_manager_impl.cc
+++ b/components/password_manager/core/browser/password_reuse_manager_impl.cc
@@ -20,6 +20,7 @@
#include "components/password_manager/core/browser/password_form.h"
#include "components/password_manager/core/browser/password_manager_client.h"
#include "components/password_manager/core/browser/password_manager_util.h"
+#include "components/password_manager/core/browser/password_reuse_detector.h"
#include "components/password_manager/core/browser/password_reuse_manager_signin_notifier.h"
#include "components/password_manager/core/common/password_manager_features.h"
#include "components/prefs/pref_service.h"
diff --git a/components/password_manager/core/browser/password_reuse_manager_impl_unittest.cc b/components/password_manager/core/browser/password_reuse_manager_impl_unittest.cc
index 2796b3b5..df88b1f 100644
--- a/components/password_manager/core/browser/password_reuse_manager_impl_unittest.cc
+++ b/components/password_manager/core/browser/password_reuse_manager_impl_unittest.cc
@@ -31,9 +31,11 @@
namespace {
using ::testing::_;
+using ::testing::ElementsAre;
using ::testing::ElementsAreArray;
using ::testing::IsEmpty;
using ::testing::Return;
+using ::testing::UnorderedElementsAre;
using ::testing::UnorderedElementsAreArray;
PasswordForm CreateForm(
@@ -44,6 +46,7 @@
PasswordForm form;
form.scheme = PasswordForm::Scheme::kHtml;
form.signon_realm = std::string(signon_realm);
+ form.url = GURL(signon_realm);
form.username_value = std::u16string(username);
form.password_value = std::u16string(password);
form.url = GURL(signon_realm);
@@ -267,13 +270,11 @@
for (const auto& test_data : kReuseTestData) {
MockPasswordReuseDetectorConsumer mock_consumer;
if (test_data.reused_password_len != 0) {
- const std::vector<MatchingReusedCredential> credentials = {
- {"https://www.google.com", u"username1",
- PasswordForm::Store::kProfileStore}};
- EXPECT_CALL(mock_consumer,
- OnReuseCheckDone(true, test_data.reused_password_len,
- Matches(std::nullopt),
- ElementsAreArray(credentials), 2, _, _));
+ EXPECT_CALL(
+ mock_consumer,
+ OnReuseCheckDone(
+ true, test_data.reused_password_len, Matches(std::nullopt),
+ ElementsAre(MatchingReusedCredential(forms[0])), 2, _, _));
} else {
EXPECT_CALL(mock_consumer, OnReuseCheckDone(false, _, _, _, _, _, _));
}
@@ -536,17 +537,13 @@
RunUntilIdle();
MockPasswordReuseDetectorConsumer mock_consumer;
- EXPECT_CALL(
- mock_consumer,
- OnReuseCheckDone(
- /* is_reuse_found=*/true, /*password_length=*/8,
- Matches(std::nullopt),
- UnorderedElementsAreArray(std::vector<MatchingReusedCredential>{
- {"https://www.google.com", u"username1",
- PasswordForm::Store::kProfileStore},
- {"https://www.facebook.com", u"username3",
- PasswordForm::Store::kAccountStore}}),
- /*saved_passwords=*/3, _, _));
+ EXPECT_CALL(mock_consumer, OnReuseCheckDone(
+ /* is_reuse_found=*/true,
+ /*password_length=*/8, Matches(std::nullopt),
+ UnorderedElementsAre(
+ MatchingReusedCredential(profile_forms[0]),
+ MatchingReusedCredential(account_form)),
+ /*saved_passwords=*/3, _, _));
reuse_manager()->CheckReuse(u"12345password", "https://evil.com",
&mock_consumer);
RunUntilIdle();
diff --git a/components/safe_browsing/content/browser/password_protection/password_protection_commit_deferring_condition_unittest.cc b/components/safe_browsing/content/browser/password_protection/password_protection_commit_deferring_condition_unittest.cc
index d9abedf..855cd95 100644
--- a/components/safe_browsing/content/browser/password_protection/password_protection_commit_deferring_condition_unittest.cc
+++ b/components/safe_browsing/content/browser/password_protection/password_protection_commit_deferring_condition_unittest.cc
@@ -43,8 +43,11 @@
void SetUp() override {
RenderViewHostTestHarness::SetUp();
- std::vector<password_manager::MatchingReusedCredential> credentials = {
- {"http://example.test"}, {"http://2.example.com"}};
+ std::vector<password_manager::MatchingReusedCredential> credentials;
+ credentials.emplace_back("http://example.test", GURL("http://example.test"),
+ u"username");
+ credentials.emplace_back("http://2.example.com",
+ GURL("http://example.test"), u"username2");
request_ = new PasswordProtectionRequestContent(
RenderViewHostTestHarness::web_contents(), GURL(), GURL(), GURL(),
diff --git a/components/safe_browsing/content/browser/password_protection/password_protection_service_unittest.cc b/components/safe_browsing/content/browser/password_protection/password_protection_service_unittest.cc
index 48ea6b77..837fb46 100644
--- a/components/safe_browsing/content/browser/password_protection/password_protection_service_unittest.cc
+++ b/components/safe_browsing/content/browser/password_protection/password_protection_service_unittest.cc
@@ -556,7 +556,8 @@
std::unique_ptr<content::WebContents> web_contents = GetWebContents();
password_protection_service_->StartRequest(
web_contents.get(), GURL("about:blank"), GURL(), GURL(), kUserName,
- PasswordType::SAVED_PASSWORD, {{"example.com", u"username"}},
+ PasswordType::SAVED_PASSWORD,
+ {{"example.com", GURL("https://example.com/"), u"username"}},
LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, true);
base::RunLoop().RunUntilIdle();
@@ -1160,7 +1161,8 @@
.WillRepeatedly(Return(account_info));
InitializeAndStartPasswordEntryRequest(
- PasswordType::OTHER_GAIA_PASSWORD, {{"gmail.com", u"username"}},
+ PasswordType::OTHER_GAIA_PASSWORD,
+ {{"gmail.com", GURL("https://gmail.com/"), u"username"}},
/*match_allowlist=*/false,
/*timeout_in_ms=*/10000, web_contents.get());
password_protection_service_->WaitForResponse();
@@ -1345,9 +1347,9 @@
// Initialize request triggered by saved password reuse.
InitializeAndStartPasswordEntryRequest(
PasswordType::SAVED_PASSWORD,
- {{kSavedDomain, u"username"},
- {kSavedDomain2, u"username"},
- {"http://localhost:8080", u"username"}},
+ {{kSavedDomain, GURL(kSavedDomain), u"username"},
+ {kSavedDomain2, GURL(kSavedDomain2), u"username"},
+ {"http://localhost:8080", GURL("http://localhost:8080"), u"username"}},
false /* match allowlist */, 100000 /* timeout in ms*/,
web_contents.get());
password_protection_service_->WaitForResponse();
@@ -1551,7 +1553,8 @@
web_contents->GetPrimaryMainFrame());
password_protection_service_->StartRequest(
web_contents.get(), GURL("about:blank"), GURL(), GURL(), "username",
- PasswordType::SAVED_PASSWORD, {{"example1.com", u"username"}},
+ PasswordType::SAVED_PASSWORD,
+ {{"example1.com", GURL("https://example.com/"), u"username"}},
LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, true);
base::RunLoop().RunUntilIdle();
histograms_.ExpectTotalCount(kPasswordOnFocusRequestOutcomeHistogram, 1);
@@ -1572,7 +1575,8 @@
std::unique_ptr<content::WebContents> web_contents = GetWebContents();
password_protection_service_->StartRequest(
web_contents.get(), GURL("about:blank"), GURL(), GURL(), kUserName,
- PasswordType::SAVED_PASSWORD, {{"example.com", u"username"}},
+ PasswordType::SAVED_PASSWORD,
+ {{"example.com", GURL("https://example.com/"), u"username"}},
LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, true);
base::RunLoop().RunUntilIdle();
@@ -1599,7 +1603,8 @@
web_contents->GetPrimaryMainFrame());
password_protection_service_->StartRequest(
web_contents.get(), GURL("about:blank"), GURL(), GURL(), kUserName,
- PasswordType::SAVED_PASSWORD, {{"example.com", u"username"}},
+ PasswordType::SAVED_PASSWORD,
+ {{"example.com", GURL("https://example.com/"), u"username"}},
LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, true);
base::RunLoop().RunUntilIdle();
@@ -1622,7 +1627,8 @@
std::unique_ptr<content::WebContents> web_contents = GetWebContents();
password_protection_service_->StartRequest(
web_contents.get(), GURL("about:blank"), GURL(), GURL(), kUserName,
- PasswordType::SAVED_PASSWORD, {{"example.com", u"username"}},
+ PasswordType::SAVED_PASSWORD,
+ {{"example.com", GURL("https://example.com/"), u"username"}},
LoginReputationClientRequest::UNFAMILIAR_LOGIN_PAGE, true);
task_environment_.RunUntilIdle();
diff --git a/components/safe_browsing/core/browser/password_protection/password_protection_request.cc b/components/safe_browsing/core/browser/password_protection/password_protection_request.cc
index da31ba5b..a7e6624 100644
--- a/components/safe_browsing/core/browser/password_protection/password_protection_request.cc
+++ b/components/safe_browsing/core/browser/password_protection/password_protection_request.cc
@@ -52,7 +52,7 @@
// to be special handing and should use affiliation information instead of
// the signon_realm.
std::string domain = base::UTF16ToUTF8(url_formatter::FormatUrl(
- GURL(credential.signon_realm),
+ credential.url,
url_formatter::kFormatUrlOmitDefaults |
url_formatter::kFormatUrlOmitHTTPS |
url_formatter::kFormatUrlOmitTrivialSubdomains |
diff --git a/components/safe_browsing/core/browser/password_protection/password_reuse_detection_manager_unittest.cc b/components/safe_browsing/core/browser/password_protection/password_reuse_detection_manager_unittest.cc
index 16b5a93..97ffca6c 100644
--- a/components/safe_browsing/core/browser/password_protection/password_reuse_detection_manager_unittest.cc
+++ b/components/safe_browsing/core/browser/password_protection/password_reuse_detection_manager_unittest.cc
@@ -156,8 +156,11 @@
PasswordReuseDetectionManager manager(&client_);
// Simulate that reuse found.
- manager.OnReuseCheckDone(true, 0ul, std::nullopt, {{"https://example.com"}},
- 0, std::string(), 0);
+ manager.OnReuseCheckDone(
+ true, 0ul, std::nullopt,
+ {password_manager::MatchingReusedCredential(
+ "https://example.com", GURL("https://example.com"), u"username")},
+ 0, std::string(), 0);
// Expect no checking of reuse.
EXPECT_CALL(reuse_manager_, CheckReuse).Times(0);
@@ -237,10 +240,10 @@
manager.OnPaste(kInput);
testing::Mock::VerifyAndClearExpectations(&reuse_manager_);
- std::vector<password_manager::MatchingReusedCredential> reused_credentials = {
- {.signon_realm = "www.example2.com",
- .username = u"username1",
- .in_store = password_manager::PasswordForm::Store::kProfileStore}};
+ std::vector<password_manager::MatchingReusedCredential> reused_credentials;
+ reused_credentials.emplace_back(
+ "www.example2.com", GURL("www.example2.com"), u"username1",
+ password_manager::PasswordForm::Store::kProfileStore);
// CheckProtectedPasswordEntry should get called once, and the reused
// credentials get used reported once in this call.
diff --git a/ios/chrome/browser/safe_browsing/model/chrome_password_protection_service_unittest.mm b/ios/chrome/browser/safe_browsing/model/chrome_password_protection_service_unittest.mm
index 27732d80..fc5ef241 100644
--- a/ios/chrome/browser/safe_browsing/model/chrome_password_protection_service_unittest.mm
+++ b/ios/chrome/browser/safe_browsing/model/chrome_password_protection_service_unittest.mm
@@ -409,7 +409,8 @@
VerifyPersistPhishedSavedPasswordCredential) {
service_->SetIsIncognito(false);
std::vector<password_manager::MatchingReusedCredential> credentials = {
- {"http://example.test"}, {"http://2.example.com"}};
+ {"http://example.test", GURL("http://example.test/"), u"user"},
+ {"http://2.example.com", GURL("http://2.example.test/"), u"user2"}};
EXPECT_CALL(mock_add_callback_, Run(_, credentials[0]));
EXPECT_CALL(mock_add_callback_, Run(_, credentials[1]));
@@ -420,8 +421,8 @@
VerifyRemovePhishedSavedPasswordCredential) {
service_->SetIsIncognito(false);
std::vector<password_manager::MatchingReusedCredential> credentials = {
- {"http://example.test", u"username1"},
- {"http://2.example.test", u"username2"}};
+ {"http://example.test", GURL("http://example.test/"), u"username1"},
+ {"http://2.example.test", GURL("http://2.example.test/"), u"username2"}};
EXPECT_CALL(mock_remove_callback_, Run(_, credentials[0]));
EXPECT_CALL(mock_remove_callback_, Run(_, credentials[1]));