[webauthn] Have GPM link open password detail page
When saving, updating, or deleting a Google Password Manager passkey, a
bubble shows up with a link to the Google Password Manager. This CL
makes it so that when the user taps that bubble, they are sent to the
details page for that site instead of the general page.
For passkeys that have been deleted, that means sometimes GPM won't have
any information for that site. That's fine, in that case, the user will
be immediately redirected to the main GPM page.
Bug: 361751877
Change-Id: Iae11d38208cb27c8141f4b2dd0b905d3b0a1a981
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5954664
Reviewed-by: Mohamed Amir Yosef <[email protected]>
Commit-Queue: Ken Buchanan <[email protected]>
Auto-Submit: Nina Satragno <[email protected]>
Reviewed-by: Ken Buchanan <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1372397}
diff --git a/chrome/browser/ui/passwords/manage_passwords_state.cc b/chrome/browser/ui/passwords/manage_passwords_state.cc
index d52e7d1..55a242d 100644
--- a/chrome/browser/ui/passwords/manage_passwords_state.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_state.cc
@@ -242,9 +242,11 @@
SetState(password_manager::ui::KEYCHAIN_ERROR_STATE);
}
-void ManagePasswordsState::OnPasskeySaved(bool gpm_pin_created) {
+void ManagePasswordsState::OnPasskeySaved(bool gpm_pin_created,
+ std::string passkey_rp_id) {
ClearData();
gpm_pin_created_during_recent_passkey_creation_ = gpm_pin_created;
+ passkey_rp_id_ = std::move(passkey_rp_id);
SetState(password_manager::ui::PASSKEY_SAVED_CONFIRMATION_STATE);
}
@@ -253,13 +255,15 @@
SetState(password_manager::ui::PASSKEY_DELETED_CONFIRMATION_STATE);
}
-void ManagePasswordsState::OnPasskeyUpdated() {
+void ManagePasswordsState::OnPasskeyUpdated(std::string passkey_rp_id) {
ClearData();
+ passkey_rp_id_ = std::move(passkey_rp_id);
SetState(password_manager::ui::PASSKEY_UPDATED_CONFIRMATION_STATE);
}
-void ManagePasswordsState::OnPasskeyNotAccepted() {
+void ManagePasswordsState::OnPasskeyNotAccepted(std::string passkey_rp_id) {
ClearData();
+ passkey_rp_id_ = std::move(passkey_rp_id);
SetState(password_manager::ui::PASSKEY_NOT_ACCEPTED_STATE);
}
@@ -350,6 +354,8 @@
credentials_callback_.Reset();
unsynced_credentials_.clear();
single_credential_mode_credential_.reset();
+ gpm_pin_created_during_recent_passkey_creation_ = false;
+ passkey_rp_id_.clear();
}
bool ManagePasswordsState::AddForm(const PasswordForm& form) {
diff --git a/chrome/browser/ui/passwords/manage_passwords_state.h b/chrome/browser/ui/passwords/manage_passwords_state.h
index 08b53fe..abddefd 100644
--- a/chrome/browser/ui/passwords/manage_passwords_state.h
+++ b/chrome/browser/ui/passwords/manage_passwords_state.h
@@ -99,17 +99,17 @@
void OnKeychainError();
// Move to PASSKEY_SAVED_CONFIRMATION_STATE. Stores whether GPM pin was
- // created in the same flow.
- void OnPasskeySaved(bool gpm_pin_created);
+ // created in the same flow and the passkey's RPID.
+ void OnPasskeySaved(bool gpm_pin_created, std::string passkey_rp_id);
// Move to PASSKEY_DELETED_CONFIRMATION_STATE.
void OnPasskeyDeleted();
- // Move to PASSKEY_UPDATED_CONFIRMATION_STATE.
- void OnPasskeyUpdated();
+ // Move to PASSKEY_UPDATED_CONFIRMATION_STATE. Stores the passkey's RPID.
+ void OnPasskeyUpdated(std::string passkey_rp_id);
- // Move to PASSKEY_NOT_ACCEPTED_STATE.
- void OnPasskeyNotAccepted();
+ // Move to PASSKEY_NOT_ACCEPTED_STATE. Stores the passkey's RPID.
+ void OnPasskeyNotAccepted(std::string passkey_rp_id);
// Move to MOVE_CREDENTIAL_AFTER_LOG_IN_STATE. Triggers a bubble to move the
// just submitted form to the user's account store.
@@ -170,6 +170,8 @@
return gpm_pin_created_during_recent_passkey_creation_;
}
+ const std::string& passkey_rp_id() const { return passkey_rp_id_; }
+
// Current local forms. ManagePasswordsState is responsible for the forms.
const std::vector<std::unique_ptr<password_manager::PasswordForm>>&
GetCurrentForms() const {
@@ -181,7 +183,8 @@
}
private:
- // Removes all the PasswordForms stored in this object.
+ // Removes all the PasswordForms and resets passkey state stored in this
+ // object.
void ClearData();
// Adds |form| to the internal state if it's relevant.
@@ -222,6 +225,9 @@
// Whether GPM pin was created in the same flow as recent passkey creation.
bool gpm_pin_created_during_recent_passkey_creation_ = false;
+
+ // The passkey relying party identifier used during a recent passkey flow.
+ std::string passkey_rp_id_;
};
#endif // CHROME_BROWSER_UI_PASSWORDS_MANAGE_PASSWORDS_STATE_H_
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
index 516b8b7..67d5d058 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
@@ -534,8 +534,9 @@
#endif
}
-void ManagePasswordsUIController::OnPasskeySaved(bool gpm_pin_created) {
- passwords_data_.OnPasskeySaved(gpm_pin_created);
+void ManagePasswordsUIController::OnPasskeySaved(bool gpm_pin_created,
+ std::string passkey_rp_id) {
+ passwords_data_.OnPasskeySaved(gpm_pin_created, std::move(passkey_rp_id));
bubble_status_ = BubbleStatus::SHOULD_POP_UP;
UpdateBubbleAndIconVisibility();
}
@@ -546,14 +547,15 @@
UpdateBubbleAndIconVisibility();
}
-void ManagePasswordsUIController::OnPasskeyUpdated() {
- passwords_data_.OnPasskeyUpdated();
+void ManagePasswordsUIController::OnPasskeyUpdated(std::string passkey_rp_id) {
+ passwords_data_.OnPasskeyUpdated(std::move(passkey_rp_id));
bubble_status_ = BubbleStatus::SHOULD_POP_UP;
UpdateBubbleAndIconVisibility();
}
-void ManagePasswordsUIController::OnPasskeyNotAccepted() {
- passwords_data_.OnPasskeyNotAccepted();
+void ManagePasswordsUIController::OnPasskeyNotAccepted(
+ std::string passkey_rp_id) {
+ passwords_data_.OnPasskeyNotAccepted(std::move(passkey_rp_id));
bubble_status_ = BubbleStatus::SHOULD_POP_UP;
UpdateBubbleAndIconVisibility();
}
@@ -734,6 +736,10 @@
return passwords_data_.gpm_pin_created_during_recent_passkey_creation();
}
+const std::string& ManagePasswordsUIController::PasskeyRpId() const {
+ return passwords_data_.passkey_rp_id();
+}
+
void ManagePasswordsUIController::OnBubbleShown() {
bubble_status_ = BubbleStatus::SHOWN;
}
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
index 1dde197..b774f11 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
@@ -121,10 +121,10 @@
const std::u16string& username,
const password_manager::PasswordForm& form_to_update) override;
void OnKeychainError() override;
- void OnPasskeySaved(bool gpm_pin_created) override;
+ void OnPasskeySaved(bool gpm_pin_created, std::string passkey_rp_id) override;
void OnPasskeyDeleted() override;
- void OnPasskeyUpdated() override;
- void OnPasskeyNotAccepted() override;
+ void OnPasskeyUpdated(std::string passkey_rp_id) override;
+ void OnPasskeyNotAccepted(std::string passkey_rp_id) override;
virtual void NotifyUnsyncedCredentialsWillBeDeleted(
std::vector<password_manager::PasswordForm> unsynced_credentials);
@@ -171,6 +171,7 @@
size_t GetTotalNumberCompromisedPasswords() const override;
bool BubbleIsManualFallbackForSaving() const override;
bool GpmPinCreatedDuringRecentPasskeyCreation() const override;
+ const std::string& PasskeyRpId() const override;
void OnBubbleShown() override;
void OnBubbleHidden() override;
void OnNoInteraction() override;
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
index 370dfda..01a7def 100644
--- a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
+++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
@@ -94,6 +94,7 @@
// A random URL.
constexpr char kExampleUrl[] = "http://example.com";
constexpr char16_t kExampleUsername[] = u"Bob";
+constexpr char kExampleRpId[] = "example.com";
// Number of dismissals that for sure suppresses the bubble.
constexpr int kGreatDissmisalCount = 10;
@@ -2046,7 +2047,8 @@
TEST_F(ManagePasswordsUIControllerTest, PasskeySavedWithoutGpmPinCreation) {
EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
- controller()->OnPasskeySaved(/*gpm_pin_created=*/false);
+ controller()->OnPasskeySaved(/*gpm_pin_created=*/false, kExampleRpId);
+ EXPECT_EQ(controller()->PasskeyRpId(), kExampleRpId);
EXPECT_TRUE(controller()->opened_automatic_bubble());
ExpectIconAndControllerStateIs(
password_manager::ui::PASSKEY_SAVED_CONFIRMATION_STATE);
@@ -2055,7 +2057,8 @@
TEST_F(ManagePasswordsUIControllerTest, PasskeySavedWithGpmPinCreation) {
EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
- controller()->OnPasskeySaved(/*gpm_pin_created=*/true);
+ controller()->OnPasskeySaved(/*gpm_pin_created=*/true, kExampleRpId);
+ EXPECT_EQ(controller()->PasskeyRpId(), kExampleRpId);
EXPECT_TRUE(controller()->opened_automatic_bubble());
ExpectIconAndControllerStateIs(
password_manager::ui::PASSKEY_SAVED_CONFIRMATION_STATE);
@@ -2071,16 +2074,20 @@
}
TEST_F(ManagePasswordsUIControllerTest, OpenPasskeyUpdatedBubble) {
+ std::string rp_id = "touhou.example.com";
EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
- controller()->OnPasskeyUpdated();
+ controller()->OnPasskeyUpdated(rp_id);
EXPECT_TRUE(controller()->opened_automatic_bubble());
+ EXPECT_EQ(controller()->PasskeyRpId(), rp_id);
ExpectIconAndControllerStateIs(
password_manager::ui::PASSKEY_UPDATED_CONFIRMATION_STATE);
}
TEST_F(ManagePasswordsUIControllerTest, OpenPasskeyNotAcceptedBubble) {
+ std::string rp_id = "touhou.example.com";
EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility());
- controller()->OnPasskeyNotAccepted();
+ controller()->OnPasskeyNotAccepted(rp_id);
+ EXPECT_EQ(controller()->PasskeyRpId(), rp_id);
EXPECT_TRUE(controller()->opened_automatic_bubble());
ExpectIconAndControllerStateIs(
password_manager::ui::PASSKEY_NOT_ACCEPTED_STATE);
diff --git a/chrome/browser/ui/passwords/passwords_client_ui_delegate.h b/chrome/browser/ui/passwords/passwords_client_ui_delegate.h
index 54a77999..fd7754c9 100644
--- a/chrome/browser/ui/passwords/passwords_client_ui_delegate.h
+++ b/chrome/browser/ui/passwords/passwords_client_ui_delegate.h
@@ -126,7 +126,8 @@
// Called when a passkey has just been saved to display a confirmation of that
// to the user. If GPM pin was created in the same flow, then the confirmation
// of that is also displayed in the title.
- virtual void OnPasskeySaved(bool gpm_pin_created) = 0;
+ virtual void OnPasskeySaved(bool gpm_pin_created,
+ std::string passkey_rp_id) = 0;
// Called when a passkey has just been deleted to display a confirmation of
// that to the user.
@@ -134,11 +135,11 @@
// Called when a passkey has just been updated to display a confirmation of
// that to the user.
- virtual void OnPasskeyUpdated() = 0;
+ virtual void OnPasskeyUpdated(std::string passkey_rp_id) = 0;
// Called when a passkey has just been deleted because it was not present on
// an all accepted credentials report.
- virtual void OnPasskeyNotAccepted() = 0;
+ virtual void OnPasskeyNotAccepted(std::string passkey_rp_id) = 0;
protected:
virtual ~PasswordsClientUIDelegate() = default;
diff --git a/chrome/browser/ui/passwords/passwords_model_delegate.h b/chrome/browser/ui/passwords/passwords_model_delegate.h
index b0a73a4..c05d093 100644
--- a/chrome/browser/ui/passwords/passwords_model_delegate.h
+++ b/chrome/browser/ui/passwords/passwords_model_delegate.h
@@ -95,6 +95,10 @@
// flow, applicable for PASSKEY_SAVED_CONFIRMATION_STATE only.
virtual bool GpmPinCreatedDuringRecentPasskeyCreation() const = 0;
+ // Returns the passkey relying party during the most recent passkey flow, or
+ // the empty string if there isn't one.
+ virtual const std::string& PasskeyRpId() const = 0;
+
// Called from the model when the bubble is displayed.
virtual void OnBubbleShown() = 0;
diff --git a/chrome/browser/ui/passwords/passwords_model_delegate_mock.h b/chrome/browser/ui/passwords/passwords_model_delegate_mock.h
index 13e6aff..16e4738 100644
--- a/chrome/browser/ui/passwords/passwords_model_delegate_mock.h
+++ b/chrome/browser/ui/passwords/passwords_model_delegate_mock.h
@@ -65,6 +65,7 @@
GpmPinCreatedDuringRecentPasskeyCreation,
(),
(const override));
+ MOCK_METHOD(const std::string&, PasskeyRpId, (), (const override));
MOCK_METHOD(void, OnBubbleShown, (), (override));
MOCK_METHOD(void, OnBubbleHidden, (), (override));
MOCK_METHOD(void, OnNoInteraction, (), (override));
diff --git a/chrome/browser/ui/views/passwords/password_bubble_view_base.cc b/chrome/browser/ui/views/passwords/password_bubble_view_base.cc
index 7ef2302b..4537dde 100644
--- a/chrome/browser/ui/views/passwords/password_bubble_view_base.cc
+++ b/chrome/browser/ui/views/passwords/password_bubble_view_base.cc
@@ -110,8 +110,9 @@
views::View* anchor_view,
DisplayReason reason) {
PasswordBubbleViewBase* view = nullptr;
- password_manager::ui::State model_state =
- PasswordsModelDelegateFromWebContents(web_contents)->GetState();
+ base::WeakPtr<PasswordsModelDelegate> delegate =
+ PasswordsModelDelegateFromWebContents(web_contents);
+ password_manager::ui::State model_state = delegate->GetState();
if (model_state == password_manager::ui::MANAGE_STATE) {
view = new ManagePasswordsView(web_contents, anchor_view);
} else if (model_state == password_manager::ui::AUTO_SIGNIN_STATE) {
@@ -167,17 +168,19 @@
view = new PasswordDefaultStoreChangedView(web_contents, anchor_view);
} else if (model_state ==
password_manager::ui::PASSKEY_SAVED_CONFIRMATION_STATE) {
- view = new PasskeySavedConfirmationView(web_contents, anchor_view);
+ view = new PasskeySavedConfirmationView(web_contents, anchor_view,
+ delegate->PasskeyRpId());
} else if (model_state ==
password_manager::ui::PASSKEY_DELETED_CONFIRMATION_STATE) {
view =
new PasskeyDeletedConfirmationView(web_contents, anchor_view, reason);
} else if (model_state ==
password_manager::ui::PASSKEY_UPDATED_CONFIRMATION_STATE) {
- view =
- new PasskeyUpdatedConfirmationView(web_contents, anchor_view, reason);
+ view = new PasskeyUpdatedConfirmationView(web_contents, anchor_view, reason,
+ delegate->PasskeyRpId());
} else if (model_state == password_manager::ui::PASSKEY_NOT_ACCEPTED_STATE) {
- view = new PasskeyNotAcceptedBubbleView(web_contents, anchor_view, reason);
+ view = new PasskeyNotAcceptedBubbleView(web_contents, anchor_view, reason,
+ delegate->PasskeyRpId());
} else {
NOTREACHED();
}
diff --git a/chrome/browser/ui/views/webauthn/passkey_not_accepted_bubble_view.cc b/chrome/browser/ui/views/webauthn/passkey_not_accepted_bubble_view.cc
index 7a606ce..33f48f0 100644
--- a/chrome/browser/ui/views/webauthn/passkey_not_accepted_bubble_view.cc
+++ b/chrome/browser/ui/views/webauthn/passkey_not_accepted_bubble_view.cc
@@ -26,7 +26,8 @@
PasskeyNotAcceptedBubbleView::PasskeyNotAcceptedBubbleView(
content::WebContents* web_contents,
views::View* anchor_view,
- DisplayReason display_reason)
+ DisplayReason display_reason,
+ std::string passkey_rp_id)
: PasswordBubbleViewBase(web_contents,
anchor_view,
/*easily_dismissable=*/true),
@@ -35,7 +36,8 @@
? password_manager::metrics_util::
AUTOMATIC_PASSKEY_NOT_ACCEPTED_BUBBLE
: password_manager::metrics_util::
- MANUAL_PASSKEY_NOT_ACCEPTED_BUBBLE) {
+ MANUAL_PASSKEY_NOT_ACCEPTED_BUBBLE,
+ std::move(passkey_rp_id)) {
SetButtons(static_cast<int>(ui::mojom::DialogButton::kNone));
SetShowIcon(true);
SetTitle(controller_.GetTitle());
diff --git a/chrome/browser/ui/views/webauthn/passkey_not_accepted_bubble_view.h b/chrome/browser/ui/views/webauthn/passkey_not_accepted_bubble_view.h
index c7042ac..273a0af4 100644
--- a/chrome/browser/ui/views/webauthn/passkey_not_accepted_bubble_view.h
+++ b/chrome/browser/ui/views/webauthn/passkey_not_accepted_bubble_view.h
@@ -29,7 +29,8 @@
public:
PasskeyNotAcceptedBubbleView(content::WebContents* web_contents,
views::View* anchor_view,
- DisplayReason display_reason);
+ DisplayReason display_reason,
+ std::string passkey_rp_id);
~PasskeyNotAcceptedBubbleView() override;
PasskeyNotAcceptedBubbleView(const PasskeyNotAcceptedBubbleView&) = delete;
PasskeyNotAcceptedBubbleView& operator=(const PasskeyNotAcceptedBubbleView&) =
diff --git a/chrome/browser/ui/views/webauthn/passkey_not_accepted_bubble_view_unittest.cc b/chrome/browser/ui/views/webauthn/passkey_not_accepted_bubble_view_unittest.cc
index b3634f1..372be33 100644
--- a/chrome/browser/ui/views/webauthn/passkey_not_accepted_bubble_view_unittest.cc
+++ b/chrome/browser/ui/views/webauthn/passkey_not_accepted_bubble_view_unittest.cc
@@ -9,6 +9,10 @@
#include "base/memory/raw_ptr.h"
#include "chrome/browser/ui/views/passwords/password_bubble_view_test_base.h"
+namespace {
+
+constexpr char kRpId[] = "touhou.example.com";
+
class PasskeyNotAcceptedBubbleViewTest : public PasswordBubbleViewTestBase {
public:
PasskeyNotAcceptedBubbleViewTest() = default;
@@ -17,8 +21,8 @@
void CreateViewAndShow() {
CreateAnchorViewAndShow();
view_ = new PasskeyNotAcceptedBubbleView(
- web_contents(), anchor_view(),
- LocationBarBubbleDelegateView::AUTOMATIC);
+ web_contents(), anchor_view(), LocationBarBubbleDelegateView::AUTOMATIC,
+ kRpId);
views::BubbleDialogDelegateView::CreateBubble(view_)->Show();
}
@@ -40,3 +44,5 @@
EXPECT_TRUE(view()->ShouldShowWindowTitle());
EXPECT_FALSE(view()->GetWindowTitle().empty());
}
+
+} // namespace
diff --git a/chrome/browser/ui/views/webauthn/passkey_saved_confirmation_view.cc b/chrome/browser/ui/views/webauthn/passkey_saved_confirmation_view.cc
index dfe1417..ba5981b3 100644
--- a/chrome/browser/ui/views/webauthn/passkey_saved_confirmation_view.cc
+++ b/chrome/browser/ui/views/webauthn/passkey_saved_confirmation_view.cc
@@ -20,11 +20,13 @@
PasskeySavedConfirmationView::PasskeySavedConfirmationView(
content::WebContents* web_contents,
- views::View* anchor_view)
+ views::View* anchor_view,
+ std::string passkey_rp_id)
: PasswordBubbleViewBase(web_contents,
anchor_view,
/*easily_dismissable=*/true),
- controller_(PasswordsModelDelegateFromWebContents(web_contents)) {
+ controller_(PasswordsModelDelegateFromWebContents(web_contents),
+ std::move(passkey_rp_id)) {
SetButtons(static_cast<int>(ui::mojom::DialogButton::kNone));
SetShowIcon(true);
SetTitle(controller_.GetTitle());
diff --git a/chrome/browser/ui/views/webauthn/passkey_saved_confirmation_view.h b/chrome/browser/ui/views/webauthn/passkey_saved_confirmation_view.h
index eff17d9f..41f17f1c 100644
--- a/chrome/browser/ui/views/webauthn/passkey_saved_confirmation_view.h
+++ b/chrome/browser/ui/views/webauthn/passkey_saved_confirmation_view.h
@@ -15,7 +15,8 @@
public:
PasskeySavedConfirmationView(content::WebContents* web_contents,
- views::View* anchor_view);
+ views::View* anchor_view,
+ std::string passkey_rp_id);
~PasskeySavedConfirmationView() override;
private:
diff --git a/chrome/browser/ui/views/webauthn/passkey_saved_confirmation_view_unittest.cc b/chrome/browser/ui/views/webauthn/passkey_saved_confirmation_view_unittest.cc
index e081e870..3bd4f07a 100644
--- a/chrome/browser/ui/views/webauthn/passkey_saved_confirmation_view_unittest.cc
+++ b/chrome/browser/ui/views/webauthn/passkey_saved_confirmation_view_unittest.cc
@@ -8,6 +8,10 @@
#include "chrome/browser/ui/views/passwords/password_bubble_view_test_base.h"
+namespace {
+
+constexpr char kRpId[] = "touhou.example.com";
+
class PasskeySavedConfirmationViewTest : public PasswordBubbleViewTestBase {
public:
PasskeySavedConfirmationViewTest() = default;
@@ -15,7 +19,8 @@
void CreateViewAndShow() {
CreateAnchorViewAndShow();
- view_ = new PasskeySavedConfirmationView(web_contents(), anchor_view());
+ view_ =
+ new PasskeySavedConfirmationView(web_contents(), anchor_view(), kRpId);
views::BubbleDialogDelegateView::CreateBubble(view_)->Show();
}
@@ -36,3 +41,5 @@
CreateViewAndShow();
EXPECT_TRUE(view()->ShouldShowWindowTitle());
}
+
+} // namespace
diff --git a/chrome/browser/ui/views/webauthn/passkey_updated_confirmation_view.cc b/chrome/browser/ui/views/webauthn/passkey_updated_confirmation_view.cc
index 5bf2119..1e46e6e6 100644
--- a/chrome/browser/ui/views/webauthn/passkey_updated_confirmation_view.cc
+++ b/chrome/browser/ui/views/webauthn/passkey_updated_confirmation_view.cc
@@ -19,7 +19,8 @@
PasskeyUpdatedConfirmationView::PasskeyUpdatedConfirmationView(
content::WebContents* web_contents,
views::View* anchor_view,
- DisplayReason display_reason)
+ DisplayReason display_reason,
+ std::string passkey_rp_id)
: PasswordBubbleViewBase(web_contents,
anchor_view,
/*easily_dismissable=*/true),
@@ -28,7 +29,8 @@
? password_manager::metrics_util::
AUTOMATIC_PASSKEY_UPDATED_CONFIRMATION
: password_manager::metrics_util::
- MANUAL_PASSKEY_UPDATED_CONFIRMATION) {
+ MANUAL_PASSKEY_UPDATED_CONFIRMATION,
+ std::move(passkey_rp_id)) {
SetButtons(static_cast<int>(ui::mojom::DialogButton::kNone));
SetShowIcon(true);
SetTitle(controller_.GetTitle());
diff --git a/chrome/browser/ui/views/webauthn/passkey_updated_confirmation_view.h b/chrome/browser/ui/views/webauthn/passkey_updated_confirmation_view.h
index d8f3622..fc99ccc 100644
--- a/chrome/browser/ui/views/webauthn/passkey_updated_confirmation_view.h
+++ b/chrome/browser/ui/views/webauthn/passkey_updated_confirmation_view.h
@@ -16,7 +16,8 @@
public:
PasskeyUpdatedConfirmationView(content::WebContents* web_contents,
views::View* anchor_view,
- DisplayReason display_reason);
+ DisplayReason display_reason,
+ std::string passkey_rp_id);
~PasskeyUpdatedConfirmationView() override;
private:
diff --git a/chrome/browser/ui/views/webauthn/passkey_updated_confirmation_view_unittest.cc b/chrome/browser/ui/views/webauthn/passkey_updated_confirmation_view_unittest.cc
index 9084f16..58a5eb4 100644
--- a/chrome/browser/ui/views/webauthn/passkey_updated_confirmation_view_unittest.cc
+++ b/chrome/browser/ui/views/webauthn/passkey_updated_confirmation_view_unittest.cc
@@ -8,6 +8,10 @@
#include "chrome/browser/ui/views/passwords/password_bubble_view_test_base.h"
+namespace {
+
+constexpr char kRpId[] = "touhou.example.com";
+
class PasskeyUpdatedConfirmationViewTest : public PasswordBubbleViewTestBase {
public:
PasskeyUpdatedConfirmationViewTest() = default;
@@ -16,8 +20,8 @@
void CreateViewAndShow() {
CreateAnchorViewAndShow();
view_ = new PasskeyUpdatedConfirmationView(
- web_contents(), anchor_view(),
- LocationBarBubbleDelegateView::AUTOMATIC);
+ web_contents(), anchor_view(), LocationBarBubbleDelegateView::AUTOMATIC,
+ kRpId);
views::BubbleDialogDelegateView::CreateBubble(view_)->Show();
}
@@ -39,3 +43,5 @@
EXPECT_TRUE(view()->ShouldShowWindowTitle());
EXPECT_FALSE(view()->GetWindowTitle().empty());
}
+
+} // namespace
diff --git a/chrome/browser/ui/webauthn/passkey_not_accepted_bubble_controller.cc b/chrome/browser/ui/webauthn/passkey_not_accepted_bubble_controller.cc
index 73bb79c..a60f9f5 100644
--- a/chrome/browser/ui/webauthn/passkey_not_accepted_bubble_controller.cc
+++ b/chrome/browser/ui/webauthn/passkey_not_accepted_bubble_controller.cc
@@ -11,8 +11,10 @@
PasskeyNotAcceptedBubbleController::PasskeyNotAcceptedBubbleController(
base::WeakPtr<PasswordsModelDelegate> delegate,
- password_manager::metrics_util::UIDisplayDisposition display_disposition)
- : PasswordBubbleControllerBase(std::move(delegate), display_disposition) {}
+ password_manager::metrics_util::UIDisplayDisposition display_disposition,
+ std::string passkey_rp_id)
+ : PasswordBubbleControllerBase(std::move(delegate), display_disposition),
+ passkey_rp_id_(std::move(passkey_rp_id)) {}
PasskeyNotAcceptedBubbleController::~PasskeyNotAcceptedBubbleController() {
OnBubbleClosing();
@@ -25,7 +27,8 @@
void PasskeyNotAcceptedBubbleController::OnGooglePasswordManagerLinkClicked() {
dismissal_reason_ = password_manager::metrics_util::CLICKED_MANAGE;
if (delegate_) {
- delegate_->NavigateToPasswordManagerSettingsPage(
+ delegate_->NavigateToPasswordDetailsPageInPasswordManager(
+ passkey_rp_id_,
password_manager::ManagePasswordsReferrer::kPasskeyNotAcceptedBubble);
}
}
diff --git a/chrome/browser/ui/webauthn/passkey_not_accepted_bubble_controller.h b/chrome/browser/ui/webauthn/passkey_not_accepted_bubble_controller.h
index 1a28816..78188955 100644
--- a/chrome/browser/ui/webauthn/passkey_not_accepted_bubble_controller.h
+++ b/chrome/browser/ui/webauthn/passkey_not_accepted_bubble_controller.h
@@ -14,7 +14,8 @@
public:
PasskeyNotAcceptedBubbleController(
base::WeakPtr<PasswordsModelDelegate> delegate,
- password_manager::metrics_util::UIDisplayDisposition display_disposition);
+ password_manager::metrics_util::UIDisplayDisposition display_disposition,
+ std::string passkey_rp_id);
~PasskeyNotAcceptedBubbleController() override;
// PasswordBubbleControllerBase:
@@ -31,6 +32,9 @@
// Dismissal reason for a password bubble.
password_manager::metrics_util::UIDismissalReason dismissal_reason_ =
password_manager::metrics_util::NO_DIRECT_INTERACTION;
+
+ // The passkey relying party identifier.
+ std::string passkey_rp_id_;
};
#endif // CHROME_BROWSER_UI_WEBAUTHN_PASSKEY_NOT_ACCEPTED_BUBBLE_CONTROLLER_H_
diff --git a/chrome/browser/ui/webauthn/passkey_not_accepted_bubble_controller_unittest.cc b/chrome/browser/ui/webauthn/passkey_not_accepted_bubble_controller_unittest.cc
index 5d7b0ee..6a8b36f 100644
--- a/chrome/browser/ui/webauthn/passkey_not_accepted_bubble_controller_unittest.cc
+++ b/chrome/browser/ui/webauthn/passkey_not_accepted_bubble_controller_unittest.cc
@@ -21,6 +21,7 @@
using ::testing::Return;
constexpr char kUIDismissalReasonMetric[] = "PasswordManager.UIDismissalReason";
+constexpr char kRpId[] = "touhou.example.com";
class PasskeyNotAcceptedBubbleControllerTest : public ::testing::Test {
public:
@@ -38,7 +39,8 @@
EXPECT_CALL(*delegate(), OnBubbleShown());
controller_ = std::make_unique<PasskeyNotAcceptedBubbleController>(
mock_delegate_->AsWeakPtr(),
- password_manager::metrics_util::AUTOMATIC_PASSKEY_NOT_ACCEPTED_BUBBLE);
+ password_manager::metrics_util::AUTOMATIC_PASSKEY_NOT_ACCEPTED_BUBBLE,
+ kRpId);
ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(delegate()));
}
@@ -58,9 +60,10 @@
OnGooglePasswordManagerButtonClicked) {
base::HistogramTester histogram_tester;
CreateController();
- EXPECT_CALL(*delegate(), NavigateToPasswordManagerSettingsPage(
- password_manager::ManagePasswordsReferrer::
- kPasskeyNotAcceptedBubble));
+ EXPECT_CALL(*delegate(),
+ NavigateToPasswordDetailsPageInPasswordManager(
+ kRpId, password_manager::ManagePasswordsReferrer::
+ kPasskeyNotAcceptedBubble));
controller()->OnGooglePasswordManagerLinkClicked();
DestroyController();
histogram_tester.ExpectUniqueSample(
diff --git a/chrome/browser/ui/webauthn/passkey_saved_confirmation_controller.cc b/chrome/browser/ui/webauthn/passkey_saved_confirmation_controller.cc
index 89b60a6..72703c18 100644
--- a/chrome/browser/ui/webauthn/passkey_saved_confirmation_controller.cc
+++ b/chrome/browser/ui/webauthn/passkey_saved_confirmation_controller.cc
@@ -10,11 +10,13 @@
#include "ui/base/l10n/l10n_util.h"
PasskeySavedConfirmationController::PasskeySavedConfirmationController(
- base::WeakPtr<PasswordsModelDelegate> delegate)
+ base::WeakPtr<PasswordsModelDelegate> delegate,
+ std::string passkey_rp_id)
: PasswordBubbleControllerBase(
std::move(delegate),
/*display_disposition=*/password_manager::metrics_util::
- AUTOMATIC_PASSKEY_SAVED_CONFIRMATION) {}
+ AUTOMATIC_PASSKEY_SAVED_CONFIRMATION),
+ passkey_rp_id_(std::move(passkey_rp_id)) {}
PasskeySavedConfirmationController::~PasskeySavedConfirmationController() {
OnBubbleClosing();
@@ -30,9 +32,9 @@
void PasskeySavedConfirmationController::OnGooglePasswordManagerLinkClicked() {
dismissal_reason_ = password_manager::metrics_util::CLICKED_MANAGE;
if (delegate_) {
- delegate_->NavigateToPasswordManagerSettingsPage(
- password_manager::ManagePasswordsReferrer::
- kPasskeySavedConfirmationBubble);
+ delegate_->NavigateToPasswordDetailsPageInPasswordManager(
+ passkey_rp_id_, password_manager::ManagePasswordsReferrer::
+ kPasskeySavedConfirmationBubble);
}
}
diff --git a/chrome/browser/ui/webauthn/passkey_saved_confirmation_controller.h b/chrome/browser/ui/webauthn/passkey_saved_confirmation_controller.h
index 3aa8bf5..45ec11b 100644
--- a/chrome/browser/ui/webauthn/passkey_saved_confirmation_controller.h
+++ b/chrome/browser/ui/webauthn/passkey_saved_confirmation_controller.h
@@ -11,8 +11,9 @@
// Manages the bubble which is shown as a confirmation when a passkey is saved.
class PasskeySavedConfirmationController : public PasswordBubbleControllerBase {
public:
- explicit PasskeySavedConfirmationController(
- base::WeakPtr<PasswordsModelDelegate> delegate);
+ PasskeySavedConfirmationController(
+ base::WeakPtr<PasswordsModelDelegate> delegate,
+ std::string passkey_rp_id);
~PasskeySavedConfirmationController() override;
// PasswordBubbleControllerBase:
@@ -29,6 +30,9 @@
// Dismissal reason for a password bubble.
password_manager::metrics_util::UIDismissalReason dismissal_reason_ =
password_manager::metrics_util::NO_DIRECT_INTERACTION;
+
+ // Relying party identifier for the saved passkey.
+ std::string passkey_rp_id_;
};
#endif // CHROME_BROWSER_UI_WEBAUTHN_PASSKEY_SAVED_CONFIRMATION_CONTROLLER_H_
diff --git a/chrome/browser/ui/webauthn/passkey_saved_confirmation_controller_unittest.cc b/chrome/browser/ui/webauthn/passkey_saved_confirmation_controller_unittest.cc
index 46deb0ec..fa5cf80 100644
--- a/chrome/browser/ui/webauthn/passkey_saved_confirmation_controller_unittest.cc
+++ b/chrome/browser/ui/webauthn/passkey_saved_confirmation_controller_unittest.cc
@@ -23,6 +23,7 @@
using ::testing::Return;
constexpr char kUIDismissalReasonMetric[] = "PasswordManager.UIDismissalReason";
+constexpr char kRpId[] = "touhou.example.com";
} // namespace
@@ -51,7 +52,7 @@
void CreateController() {
EXPECT_CALL(*delegate(), OnBubbleShown());
controller_ = std::make_unique<PasskeySavedConfirmationController>(
- mock_delegate_->AsWeakPtr());
+ mock_delegate_->AsWeakPtr(), kRpId);
ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(delegate()));
}
@@ -96,9 +97,10 @@
OnGooglePasswordManagerLinkClicked) {
base::HistogramTester histogram_tester;
CreateController();
- EXPECT_CALL(*delegate(), NavigateToPasswordManagerSettingsPage(
- password_manager::ManagePasswordsReferrer::
- kPasskeySavedConfirmationBubble));
+ EXPECT_CALL(*delegate(),
+ NavigateToPasswordDetailsPageInPasswordManager(
+ kRpId, password_manager::ManagePasswordsReferrer::
+ kPasskeySavedConfirmationBubble));
controller()->OnGooglePasswordManagerLinkClicked();
DestroyController();
histogram_tester.ExpectUniqueSample(
diff --git a/chrome/browser/ui/webauthn/passkey_updated_confirmation_controller.cc b/chrome/browser/ui/webauthn/passkey_updated_confirmation_controller.cc
index 95ba9bc..e3d3a23 100644
--- a/chrome/browser/ui/webauthn/passkey_updated_confirmation_controller.cc
+++ b/chrome/browser/ui/webauthn/passkey_updated_confirmation_controller.cc
@@ -11,8 +11,10 @@
PasskeyUpdatedConfirmationController::PasskeyUpdatedConfirmationController(
base::WeakPtr<PasswordsModelDelegate> delegate,
- password_manager::metrics_util::UIDisplayDisposition display_disposition)
- : PasswordBubbleControllerBase(std::move(delegate), display_disposition) {}
+ password_manager::metrics_util::UIDisplayDisposition display_disposition,
+ std::string passkey_rp_id)
+ : PasswordBubbleControllerBase(std::move(delegate), display_disposition),
+ passkey_rp_id_(std::move(passkey_rp_id)) {}
PasskeyUpdatedConfirmationController::~PasskeyUpdatedConfirmationController() {
OnBubbleClosing();
@@ -26,9 +28,9 @@
OnGooglePasswordManagerLinkClicked() {
dismissal_reason_ = password_manager::metrics_util::CLICKED_MANAGE;
if (delegate_) {
- delegate_->NavigateToPasswordManagerSettingsPage(
- password_manager::ManagePasswordsReferrer::
- kPasskeyUpdatedConfirmationBubble);
+ delegate_->NavigateToPasswordDetailsPageInPasswordManager(
+ passkey_rp_id_, password_manager::ManagePasswordsReferrer::
+ kPasskeyUpdatedConfirmationBubble);
}
}
diff --git a/chrome/browser/ui/webauthn/passkey_updated_confirmation_controller.h b/chrome/browser/ui/webauthn/passkey_updated_confirmation_controller.h
index 442aa9a..ef0fa139 100644
--- a/chrome/browser/ui/webauthn/passkey_updated_confirmation_controller.h
+++ b/chrome/browser/ui/webauthn/passkey_updated_confirmation_controller.h
@@ -15,7 +15,8 @@
public:
PasskeyUpdatedConfirmationController(
base::WeakPtr<PasswordsModelDelegate> delegate,
- password_manager::metrics_util::UIDisplayDisposition display_disposition);
+ password_manager::metrics_util::UIDisplayDisposition display_disposition,
+ std::string passkey_rp_id);
~PasskeyUpdatedConfirmationController() override;
// PasswordBubbleControllerBase:
@@ -32,6 +33,9 @@
// Dismissal reason for a password bubble.
password_manager::metrics_util::UIDismissalReason dismissal_reason_ =
password_manager::metrics_util::NO_DIRECT_INTERACTION;
+
+ // The relying party identifier of the updated passkey.
+ std::string passkey_rp_id_;
};
#endif // CHROME_BROWSER_UI_WEBAUTHN_PASSKEY_UPDATED_CONFIRMATION_CONTROLLER_H_
diff --git a/chrome/browser/ui/webauthn/passkey_updated_confirmation_controller_unittest.cc b/chrome/browser/ui/webauthn/passkey_updated_confirmation_controller_unittest.cc
index 17531de..ce83a14 100644
--- a/chrome/browser/ui/webauthn/passkey_updated_confirmation_controller_unittest.cc
+++ b/chrome/browser/ui/webauthn/passkey_updated_confirmation_controller_unittest.cc
@@ -21,6 +21,7 @@
using ::testing::Return;
constexpr char kUIDismissalReasonMetric[] = "PasswordManager.UIDismissalReason";
+constexpr char kRpId[] = "touhou.example.com";
class PasskeyUpdatedConfirmationControllerTest : public ::testing::Test {
public:
@@ -40,7 +41,8 @@
EXPECT_CALL(*delegate(), OnBubbleShown());
controller_ = std::make_unique<PasskeyUpdatedConfirmationController>(
mock_delegate_->AsWeakPtr(),
- password_manager::metrics_util::AUTOMATIC_PASSKEY_UPDATED_CONFIRMATION);
+ password_manager::metrics_util::AUTOMATIC_PASSKEY_UPDATED_CONFIRMATION,
+ kRpId);
ASSERT_TRUE(testing::Mock::VerifyAndClearExpectations(delegate()));
}
@@ -60,9 +62,10 @@
OnGooglePasswordManagerButtonClicked) {
base::HistogramTester histogram_tester;
CreateController();
- EXPECT_CALL(*delegate(), NavigateToPasswordManagerSettingsPage(
- password_manager::ManagePasswordsReferrer::
- kPasskeyUpdatedConfirmationBubble));
+ EXPECT_CALL(*delegate(),
+ NavigateToPasswordDetailsPageInPasswordManager(
+ kRpId, password_manager::ManagePasswordsReferrer::
+ kPasskeyUpdatedConfirmationBubble));
controller()->OnGooglePasswordManagerLinkClicked();
DestroyController();
histogram_tester.ExpectUniqueSample(