Updating PasswordCheckDelegate to work with CredentialUIEntry
This CL replaces use of CredentialWithPassword with CredentialUIEntry
inside PasswordCheckDelegate.
After PasswordsPrivateDelegateImpl switches to SavedPasswordsPresenter
CredentialUIEntry will be a unified model which will allow to simplify
API and clean big chunks of code.
Bug: 1152747
Change-Id: I3dd071a7940373b181d4b921fb83a26a3c9757c6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3677297
Commit-Queue: Viktor Semeniuk <vsemeniuk@google.com>
Reviewed-by: Vasilii Sukhanov <vasilii@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1011484}
diff --git a/chrome/browser/extensions/api/passwords_private/password_check_delegate.cc b/chrome/browser/extensions/api/passwords_private/password_check_delegate.cc
index 5d6b53a0..fcd63f8 100644
--- a/chrome/browser/extensions/api/passwords_private/password_check_delegate.cc
+++ b/chrome/browser/extensions/api/passwords_private/password_check_delegate.cc
@@ -34,7 +34,6 @@
#include "components/password_manager/content/browser/password_change_success_tracker_factory.h"
#include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h"
#include "components/password_manager/core/browser/bulk_leak_check_service.h"
-#include "components/password_manager/core/browser/insecure_credentials_table.h"
#include "components/password_manager/core/browser/leak_detection/bulk_leak_check.h"
#include "components/password_manager/core/browser/leak_detection/encryption_utils.h"
#include "components/password_manager/core/browser/password_change_success_tracker.h"
@@ -43,7 +42,6 @@
#include "components/password_manager/core/browser/ui/insecure_credentials_manager.h"
#include "components/password_manager/core/browser/ui/saved_passwords_presenter.h"
#include "components/password_manager/core/browser/well_known_change_password_util.h"
-#include "components/password_manager/core/common/password_manager_features.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/url_formatter/elide_url.h"
@@ -58,8 +56,8 @@
namespace {
using password_manager::CanonicalizeUsername;
-using password_manager::CredentialWithPassword;
-using password_manager::InsecureCredentialTypeFlags;
+using password_manager::CredentialUIEntry;
+using password_manager::InsecureType;
using password_manager::LeakCheckCredential;
using password_manager::PasswordChangeSuccessTracker;
using password_manager::PasswordForm;
@@ -181,46 +179,79 @@
TimeFormat::FORMAT_ELAPSED, TimeFormat::LENGTH_LONG, elapsed_time, true));
}
-// Helper struct that bundles a CredentialWithPassword with a corresponding
-// passwords_private::CompromiseType.
-struct CompromisedCredentialAndType {
- CredentialWithPassword credential;
- api::passwords_private::CompromiseType type;
-};
+base::Time GetTimeWhenWasPhishedOrLeaked(const CredentialUIEntry& entry) {
+ base::Time compromise_time;
+ if (entry.IsLeaked()) {
+ compromise_time =
+ entry.password_issues.at(InsecureType::kLeaked).create_time;
+ }
+ if (entry.IsPhished()) {
+ compromise_time =
+ std::max(compromise_time,
+ entry.password_issues.at(InsecureType::kPhished).create_time);
+ }
+ return compromise_time;
+}
+
+api::passwords_private::CompromiseType GetCompromiseType(
+ const CredentialUIEntry& entry) {
+ if (entry.IsLeaked() && entry.IsPhished()) {
+ return api::passwords_private::COMPROMISE_TYPE_PHISHED_AND_LEAKED;
+ } else if (entry.IsLeaked()) {
+ return api::passwords_private::COMPROMISE_TYPE_LEAKED;
+ } else if (entry.IsPhished()) {
+ return api::passwords_private::COMPROMISE_TYPE_PHISHED;
+ }
+ NOTREACHED();
+ return api::passwords_private::COMPROMISE_TYPE_NONE;
+}
+
+bool IsCredentialMuted(const CredentialUIEntry& entry) {
+ if (!entry.IsLeaked() && !entry.IsPhished())
+ return false;
+
+ bool is_muted = true;
+ if (entry.IsLeaked()) {
+ is_muted &=
+ entry.password_issues.at(InsecureType::kLeaked).is_muted.value();
+ }
+ if (entry.IsPhished()) {
+ is_muted &=
+ entry.password_issues.at(InsecureType::kPhished).is_muted.value();
+ }
+ return is_muted;
+}
// Orders |compromised_credentials| in such a way that phished credentials
// precede leaked credentials, and that credentials of the same compromise type
// are ordered by recency.
-std::vector<CompromisedCredentialAndType> OrderCompromisedCredentials(
- std::vector<CredentialWithPassword> compromised_credentials) {
- // Move all credentials into a single list, associating with the
- // corresponding CompromiseType.
- std::vector<CompromisedCredentialAndType> results;
- results.reserve(compromised_credentials.size());
- for (auto& credential : compromised_credentials) {
- // Since CompromiseType does not contain information about weakness/reuse
- // of credential, we need to unset those bits in the
- // |credential.insecure_type|.
- auto type = static_cast<api::passwords_private::CompromiseType>(
- UnsetWeakAndReusedCredentialTypeFlags(credential.insecure_type));
- results.push_back({std::move(credential), type});
- }
+void OrderInsecureCredentials(std::vector<CredentialUIEntry>& credentials) {
// Reordering phished credential to the beginning.
- auto last_phished = std::partition(
- results.begin(), results.end(), [](const auto& credential) {
- return credential.type !=
- api::passwords_private::COMPROMISE_TYPE_LEAKED;
- });
+ auto non_phished = std::partition(
+ credentials.begin(), credentials.end(),
+ [](const auto& credential) { return credential.IsPhished(); });
// By construction the phished credentials precede the leaked credentials in
// |results|. Now sort both groups by their creation date so that most recent
// compromises appear first in both lists.
- auto create_time_cmp = [](const auto& lhs, const auto& rhs) {
- return lhs.credential.create_time > rhs.credential.create_time;
+ auto create_time_cmp = [](auto& lhs, auto& rhs) {
+ return GetTimeWhenWasPhishedOrLeaked(lhs) >
+ GetTimeWhenWasPhishedOrLeaked(rhs);
};
- std::sort(results.begin(), last_phished, create_time_cmp);
- std::sort(last_phished, results.end(), create_time_cmp);
- return results;
+ std::sort(credentials.begin(), non_phished, create_time_cmp);
+ std::sort(non_phished, credentials.end(), create_time_cmp);
+}
+
+api::passwords_private::CompromisedInfo CreateCompromiseInfo(
+ const CredentialUIEntry& form) {
+ api::passwords_private::CompromisedInfo compromise_info;
+ compromise_info.compromise_time =
+ GetTimeWhenWasPhishedOrLeaked(form).ToJsTimeIgnoringNull();
+ compromise_info.elapsed_time_since_compromise =
+ FormatElapsedTime(GetTimeWhenWasPhishedOrLeaked(form));
+ compromise_info.compromise_type = GetCompromiseType(form);
+ compromise_info.is_muted = IsCredentialMuted(form);
+ return compromise_info;
}
} // namespace
@@ -258,27 +289,19 @@
std::vector<api::passwords_private::InsecureCredential>
PasswordCheckDelegate::GetCompromisedCredentials() {
- std::vector<CompromisedCredentialAndType>
- ordered_compromised_credential_and_types = OrderCompromisedCredentials(
- insecure_credentials_manager_.GetInsecureCredentials());
+ std::vector<CredentialUIEntry> ordered_credentials =
+ insecure_credentials_manager_.GetInsecureCredentialEntries();
+ OrderInsecureCredentials(ordered_credentials);
std::vector<api::passwords_private::InsecureCredential>
compromised_credentials;
- compromised_credentials.reserve(
- ordered_compromised_credential_and_types.size());
- for (const auto& credential_and_type :
- ordered_compromised_credential_and_types) {
- const CredentialWithPassword& credential = credential_and_type.credential;
+ compromised_credentials.reserve(ordered_credentials.size());
+ for (const auto& credential : ordered_credentials) {
api::passwords_private::InsecureCredential api_credential =
ConstructInsecureCredential(credential);
api_credential.compromised_info =
- std::make_unique<api::passwords_private::CompromisedInfo>();
- api_credential.compromised_info->compromise_time =
- credential.create_time.ToJsTimeIgnoringNull();
- api_credential.compromised_info->elapsed_time_since_compromise =
- FormatElapsedTime(credential.create_time);
- api_credential.compromised_info->compromise_type = credential_and_type.type;
- api_credential.compromised_info->is_muted = credential.is_muted.value();
+ std::make_unique<api::passwords_private::CompromisedInfo>(
+ CreateCompromiseInfo(credential));
compromised_credentials.push_back(std::move(api_credential));
}
@@ -287,12 +310,12 @@
std::vector<api::passwords_private::InsecureCredential>
PasswordCheckDelegate::GetWeakCredentials() {
- std::vector<CredentialWithPassword> weak_credentials =
- insecure_credentials_manager_.GetWeakCredentials();
+ std::vector<CredentialUIEntry> weak_credentials =
+ insecure_credentials_manager_.GetWeakCredentialEntries();
std::vector<api::passwords_private::InsecureCredential> api_credentials;
api_credentials.reserve(weak_credentials.size());
- for (const auto& weak_credential : weak_credentials) {
+ for (auto& weak_credential : weak_credentials) {
api_credentials.push_back(ConstructInsecureCredential(weak_credential));
}
@@ -302,60 +325,56 @@
absl::optional<api::passwords_private::InsecureCredential>
PasswordCheckDelegate::GetPlaintextInsecurePassword(
api::passwords_private::InsecureCredential credential) const {
- const CredentialWithPassword* insecure_credential =
- FindMatchingInsecureCredential(credential);
- if (!insecure_credential)
+ const CredentialUIEntry* entry = FindMatchingEntry(credential);
+ if (!entry)
return absl::nullopt;
- credential.password = std::make_unique<std::string>(
- base::UTF16ToUTF8(insecure_credential->password));
+ credential.password =
+ std::make_unique<std::string>(base::UTF16ToUTF8(entry->password));
return credential;
}
bool PasswordCheckDelegate::ChangeInsecureCredential(
const api::passwords_private::InsecureCredential& credential,
base::StringPiece new_password) {
- // Try to obtain the original CredentialWithPassword. Return false if fails.
- const CredentialWithPassword* insecure_credential =
- FindMatchingInsecureCredential(credential);
- if (!insecure_credential)
+ // Try to obtain the original CredentialUIEntry. Return false if fails.
+ const CredentialUIEntry* entry = FindMatchingEntry(credential);
+ if (!entry)
return false;
- return insecure_credentials_manager_.UpdateCredential(*insecure_credential,
- new_password);
+ CredentialUIEntry credential_to_edit = *entry;
+ credential_to_edit.password = base::UTF8ToUTF16(new_password);
+ return saved_passwords_presenter_->EditSavedCredentials(credential_to_edit);
}
bool PasswordCheckDelegate::RemoveInsecureCredential(
const api::passwords_private::InsecureCredential& credential) {
- // Try to obtain the original CredentialWithPassword. Return false if fails.
- const CredentialWithPassword* insecure_credential =
- FindMatchingInsecureCredential(credential);
- if (!insecure_credential)
+ // Try to obtain the original CredentialUIEntry. Return false if fails.
+ const CredentialUIEntry* entry = FindMatchingEntry(credential);
+ if (!entry)
return false;
- return insecure_credentials_manager_.RemoveCredential(*insecure_credential);
+ return saved_passwords_presenter_->RemoveCredential(*entry);
}
bool PasswordCheckDelegate::MuteInsecureCredential(
const api::passwords_private::InsecureCredential& credential) {
- // Try to obtain the original CredentialWithPassword. Return false if fails.
- const CredentialWithPassword* insecure_credential =
- FindMatchingInsecureCredential(credential);
- if (!insecure_credential)
+ // Try to obtain the original CredentialUIEntry. Return false if fails.
+ const CredentialUIEntry* entry = FindMatchingEntry(credential);
+ if (!entry)
return false;
- return insecure_credentials_manager_.MuteCredential(*insecure_credential);
+ return insecure_credentials_manager_.MuteCredential(*entry);
}
bool PasswordCheckDelegate::UnmuteInsecureCredential(
const api::passwords_private::InsecureCredential& credential) {
- // Try to obtain the original CredentialWithPassword. Return false if fails.
- const CredentialWithPassword* insecure_credential =
- FindMatchingInsecureCredential(credential);
- if (!insecure_credential)
+ // Try to obtain the original CredentialUIEntry. Return false if fails.
+ const CredentialUIEntry* entry = FindMatchingEntry(credential);
+ if (!entry)
return false;
- return insecure_credentials_manager_.UnmuteCredential(*insecure_credential);
+ return insecure_credentials_manager_.UnmuteCredential(*entry);
}
// Records that a change password flow was started for |credential| and
@@ -439,8 +458,6 @@
}
State state = bulk_leak_check_service_adapter_.GetBulkLeakCheckState();
- SavedPasswordsView saved_passwords =
- saved_passwords_presenter_->GetSavedPasswords();
// Handle the currently running case first, only then consider errors.
if (state == State::kRunning) {
@@ -459,7 +476,7 @@
return result;
}
- if (saved_passwords.empty()) {
+ if (saved_passwords_presenter_->GetSavedCredentials().empty()) {
result.state = api::passwords_private::PASSWORD_CHECK_STATE_NO_PASSWORDS;
return result;
}
@@ -535,23 +552,21 @@
}
}
-const CredentialWithPassword*
-PasswordCheckDelegate::FindMatchingInsecureCredential(
+const CredentialUIEntry* PasswordCheckDelegate::FindMatchingEntry(
const api::passwords_private::InsecureCredential& credential) const {
- const CredentialWithPassword* insecure_credential =
+ const CredentialUIEntry* entry =
insecure_credential_id_generator_.TryGetKey(credential.id);
- if (!insecure_credential)
+ if (!entry)
return nullptr;
- if (credential.signon_realm != insecure_credential->signon_realm ||
- credential.username != base::UTF16ToUTF8(insecure_credential->username) ||
+ if (credential.signon_realm != entry->signon_realm ||
+ credential.username != base::UTF16ToUTF8(entry->username) ||
(credential.password &&
- *credential.password !=
- base::UTF16ToUTF8(insecure_credential->password))) {
+ *credential.password != base::UTF16ToUTF8(entry->password))) {
return nullptr;
}
- return insecure_credential;
+ return entry;
}
void PasswordCheckDelegate::
@@ -589,22 +604,20 @@
api::passwords_private::InsecureCredential
PasswordCheckDelegate::ConstructInsecureCredential(
- const CredentialWithPassword& credential) {
+ const CredentialUIEntry& entry) {
api::passwords_private::InsecureCredential api_credential;
auto facet = password_manager::FacetURI::FromPotentiallyInvalidSpec(
- credential.signon_realm);
+ entry.signon_realm);
if (facet.IsValidAndroidFacetURI()) {
api_credential.is_android_credential = true;
// |formatted_orgin|, |detailed_origin| and |change_password_url| need
// special handling for Android. Here we use affiliation information
// instead of the origin.
- const PasswordForm& android_form =
- insecure_credentials_manager_.GetSavedPasswordsFor(credential)[0];
- if (!android_form.app_display_name.empty()) {
- api_credential.formatted_origin = android_form.app_display_name;
- api_credential.detailed_origin = android_form.app_display_name;
+ if (!entry.app_display_name.empty()) {
+ api_credential.formatted_origin = entry.app_display_name;
+ api_credential.detailed_origin = entry.app_display_name;
api_credential.change_password_url =
- GetChangePasswordUrl(GURL(android_form.affiliated_web_realm));
+ GetChangePasswordUrl(GURL(entry.affiliated_web_realm));
} else {
// In case no affiliation information could be obtained show the
// formatted package name to the user. An empty change_password_url will
@@ -618,7 +631,7 @@
api_credential.is_android_credential = false;
api_credential.formatted_origin =
base::UTF16ToUTF8(url_formatter::FormatUrl(
- credential.url.DeprecatedGetOriginAsURL(),
+ entry.url.GetWithEmptyPath(),
url_formatter::kFormatUrlOmitDefaults |
url_formatter::kFormatUrlOmitHTTPS |
url_formatter::kFormatUrlOmitTrivialSubdomains |
@@ -626,13 +639,13 @@
base::UnescapeRule::SPACES, nullptr, nullptr, nullptr));
api_credential.detailed_origin =
base::UTF16ToUTF8(url_formatter::FormatUrlForSecurityDisplay(
- credential.url.DeprecatedGetOriginAsURL()));
- api_credential.change_password_url = GetChangePasswordUrl(credential.url);
+ entry.url.GetWithEmptyPath()));
+ api_credential.change_password_url = GetChangePasswordUrl(entry.url);
}
- api_credential.id = insecure_credential_id_generator_.GenerateId(credential);
- api_credential.signon_realm = credential.signon_realm;
- api_credential.username = base::UTF16ToUTF8(credential.username);
+ api_credential.id = insecure_credential_id_generator_.GenerateId(entry);
+ api_credential.signon_realm = entry.signon_realm;
+ api_credential.username = base::UTF16ToUTF8(entry.username);
return api_credential;
}
diff --git a/chrome/browser/extensions/api/passwords_private/password_check_delegate.h b/chrome/browser/extensions/api/passwords_private/password_check_delegate.h
index b7db681..1280671 100644
--- a/chrome/browser/extensions/api/passwords_private/password_check_delegate.h
+++ b/chrome/browser/extensions/api/passwords_private/password_check_delegate.h
@@ -18,8 +18,8 @@
#include "components/password_manager/core/browser/bulk_leak_check_service.h"
#include "components/password_manager/core/browser/leak_detection/bulk_leak_check.h"
#include "components/password_manager/core/browser/leak_detection/leak_detection_delegate_interface.h"
-#include "components/password_manager/core/browser/password_store.h"
#include "components/password_manager/core/browser/ui/bulk_leak_check_service_adapter.h"
+#include "components/password_manager/core/browser/ui/credential_ui_entry.h"
#include "components/password_manager/core/browser/ui/credential_utils.h"
#include "components/password_manager/core/browser/ui/insecure_credentials_manager.h"
#include "components/password_manager/core/browser/ui/saved_passwords_presenter.h"
@@ -134,14 +134,13 @@
void OnCredentialDone(const password_manager::LeakCheckCredential& credential,
password_manager::IsLeaked is_leaked) override;
- // Tries to find the matching CredentialWithPassword for |credential|. It
+ // Tries to find the matching CredentialUIEntry for |credential|. It
// performs a look-up in |insecure_credential_id_generator_| using
// |credential.id|. If a matching value exists it also verifies that signon
// realm, username and when possible password match.
- // Returns a pointer to the matching CredentialWithPassword on success or
+ // Returns a pointer to the matching CredentialUIEntry on success or
// nullptr otherwise.
- const password_manager::CredentialWithPassword*
- FindMatchingInsecureCredential(
+ const password_manager::CredentialUIEntry* FindMatchingEntry(
const api::passwords_private::InsecureCredential& credential) const;
// Invoked when a compromised password check completes. Records the current
@@ -157,9 +156,9 @@
// OnStateChanged.
void NotifyPasswordCheckStatusChanged();
- // Constructs |InsecureCredential| from |CredentialWithPassword|.
+ // Constructs |InsecureCredential| from |CredentialUIEntry|.
api::passwords_private::InsecureCredential ConstructInsecureCredential(
- const password_manager::CredentialWithPassword& credential);
+ const password_manager::CredentialUIEntry& entry);
// Obtain a raw pointer to the |PasswordChangeSuccessTracker| associated
// with |profile_|.
@@ -219,10 +218,10 @@
// An id generator for insecure credentials. Required to match
// api::passwords_private::InsecureCredential instances passed to the UI
- // with the underlying CredentialWithPassword they are based on.
- IdGenerator<password_manager::CredentialWithPassword,
+ // with the underlying CredentialUIEntry they are based on.
+ IdGenerator<password_manager::CredentialUIEntry,
int,
- password_manager::PasswordCredentialLess>
+ password_manager::CredentialUIEntry::Less>
insecure_credential_id_generator_;
base::WeakPtrFactory<PasswordCheckDelegate> weak_ptr_factory_{this};
diff --git a/chrome/browser/extensions/api/passwords_private/password_check_delegate_unittest.cc b/chrome/browser/extensions/api/passwords_private/password_check_delegate_unittest.cc
index 4d3e3ed7..375950c 100644
--- a/chrome/browser/extensions/api/passwords_private/password_check_delegate_unittest.cc
+++ b/chrome/browser/extensions/api/passwords_private/password_check_delegate_unittest.cc
@@ -701,7 +701,9 @@
}
// Test that changing a insecure password removes duplicates from store.
-TEST_F(PasswordCheckDelegateTest, ChangeInsecureCredentialRemovesDupes) {
+// https://crbug.com/1334160
+TEST_F(PasswordCheckDelegateTest,
+ DISABLED_ChangeInsecureCredentialRemovesDupes) {
PasswordForm form = MakeSavedPassword(kExampleCom, kUsername1, kPassword1);
AddIssueToForm(&form, InsecureType::kLeaked);
store().AddLogin(form);
diff --git a/components/password_manager/core/browser/ui/credential_ui_entry.cc b/components/password_manager/core/browser/ui/credential_ui_entry.cc
index 4b08a2ca..c047f15 100644
--- a/components/password_manager/core/browser/ui/credential_ui_entry.cc
+++ b/components/password_manager/core/browser/ui/credential_ui_entry.cc
@@ -34,6 +34,14 @@
CredentialUIEntry& CredentialUIEntry::operator=(CredentialUIEntry&& other) =
default;
+bool CredentialUIEntry::IsLeaked() const {
+ return password_issues.contains(InsecureType::kLeaked);
+}
+
+bool CredentialUIEntry::IsPhished() const {
+ return password_issues.contains(InsecureType::kPhished);
+}
+
bool operator==(const CredentialUIEntry& lhs, const CredentialUIEntry& rhs) {
return lhs.key() == rhs.key();
}
diff --git a/components/password_manager/core/browser/ui/credential_ui_entry.h b/components/password_manager/core/browser/ui/credential_ui_entry.h
index da72546..b55f322 100644
--- a/components/password_manager/core/browser/ui/credential_ui_entry.h
+++ b/components/password_manager/core/browser/ui/credential_ui_entry.h
@@ -20,6 +20,13 @@
// construction from PasswordForm for convenience. A single entry might
// correspond to multiple PasswordForms.
struct CredentialUIEntry {
+ struct Less {
+ bool operator()(const CredentialUIEntry& lhs,
+ const CredentialUIEntry& rhs) const {
+ return lhs.key() < rhs.key();
+ }
+ };
+
explicit CredentialUIEntry(const PasswordForm& form);
CredentialUIEntry(const CredentialUIEntry& other);
CredentialUIEntry(CredentialUIEntry&& other);
@@ -71,6 +78,10 @@
const CredentialKey& key() const { return key_; }
+ // Information about password insecurities.
+ bool IsLeaked() const;
+ bool IsPhished() const;
+
private:
// Key which is constructed from an original PasswordForm.
CredentialKey key_;
diff --git a/components/password_manager/core/browser/ui/insecure_credentials_manager.cc b/components/password_manager/core/browser/ui/insecure_credentials_manager.cc
index d7d4ae02..239aff3 100644
--- a/components/password_manager/core/browser/ui/insecure_credentials_manager.cc
+++ b/components/password_manager/core/browser/ui/insecure_credentials_manager.cc
@@ -280,18 +280,6 @@
}
bool InsecureCredentialsManager::MuteCredential(
- const CredentialView& credential) {
- auto it = credentials_to_forms_.find(credential);
- if (it == credentials_to_forms_.end())
- return false;
-
- const auto& saved_passwords = it->second.forms;
- DCHECK(!saved_passwords.empty());
-
- return MuteCredential(CredentialUIEntry(saved_passwords[0]));
-}
-
-bool InsecureCredentialsManager::MuteCredential(
const CredentialUIEntry& credential) {
CredentialUIEntry updated_credential = credential;
for (auto& password_issue : updated_credential.password_issues) {
@@ -304,18 +292,6 @@
}
bool InsecureCredentialsManager::UnmuteCredential(
- const CredentialView& credential) {
- auto it = credentials_to_forms_.find(credential);
- if (it == credentials_to_forms_.end())
- return false;
-
- const auto& saved_passwords = it->second.forms;
- DCHECK(!saved_passwords.empty());
-
- return UnmuteCredential(CredentialUIEntry(saved_passwords[0]));
-}
-
-bool InsecureCredentialsManager::UnmuteCredential(
const CredentialUIEntry& credential) {
CredentialUIEntry updated_credential = credential;
for (auto& password_issue : updated_credential.password_issues) {
diff --git a/components/password_manager/core/browser/ui/insecure_credentials_manager.h b/components/password_manager/core/browser/ui/insecure_credentials_manager.h
index 20cf5eb..2ccd09cf 100644
--- a/components/password_manager/core/browser/ui/insecure_credentials_manager.h
+++ b/components/password_manager/core/browser/ui/insecure_credentials_manager.h
@@ -189,14 +189,10 @@
// Attempts to mute |credential| from the password store.
// Returns whether the mute succeeded.
- // TODO(crbug.com/1330549): Use CredentialUIEntry only.
- bool MuteCredential(const CredentialView& credential);
bool MuteCredential(const CredentialUIEntry& credential);
// Attempts to unmute |credential| from the password store.
// Returns whether the unmute succeeded.
- // TODO(crbug.com/1330549): Use CredentialUIEntry only.
- bool UnmuteCredential(const CredentialView& credential);
bool UnmuteCredential(const CredentialUIEntry& credential);
// Returns a vector of currently insecure credentials.
diff --git a/components/password_manager/core/browser/ui/saved_passwords_presenter.cc b/components/password_manager/core/browser/ui/saved_passwords_presenter.cc
index ece02a88..24bae7d 100644
--- a/components/password_manager/core/browser/ui/saved_passwords_presenter.cc
+++ b/components/password_manager/core/browser/ui/saved_passwords_presenter.cc
@@ -93,11 +93,12 @@
RemoveCredential(CredentialUIEntry(form));
}
-void SavedPasswordsPresenter::RemoveCredential(
+bool SavedPasswordsPresenter::RemoveCredential(
const CredentialUIEntry& credential) {
const auto range =
sort_key_to_password_forms_.equal_range(credential.key().value());
+ bool removed = false;
std::for_each(range.first, range.second, [&](const auto& pair) {
const auto& current_form = pair.second;
// Make sure |form| and |current_form| share the same store.
@@ -106,8 +107,10 @@
// 'OnGetPasswordStoreResultsFrom'. So it can be present only in one store
// at a time..
GetStoreFor(current_form).RemoveLogin(current_form);
+ removed = true;
}
});
+ return removed;
}
bool SavedPasswordsPresenter::AddPassword(const PasswordForm& form) {
@@ -193,6 +196,7 @@
base::ranges::transform(range.first, range.second,
std::back_inserter(forms_to_change),
[](const auto& pair) { return pair.second; });
+
if (forms_to_change.empty())
return false;
diff --git a/components/password_manager/core/browser/ui/saved_passwords_presenter.h b/components/password_manager/core/browser/ui/saved_passwords_presenter.h
index ee453da4..134906d 100644
--- a/components/password_manager/core/browser/ui/saved_passwords_presenter.h
+++ b/components/password_manager/core/browser/ui/saved_passwords_presenter.h
@@ -69,7 +69,7 @@
// Removes the credential and all its duplicates from the store.
// TODO(crbug.com/1330906): Remove in favor of EditSavedCredentials.
void RemovePassword(const PasswordForm& form);
- void RemoveCredential(const CredentialUIEntry& credential);
+ bool RemoveCredential(const CredentialUIEntry& credential);
// Adds the credential to the store specified in the |form|. Returns true
// if the password was added, false if |form|'s data is not valid (invalid