0

[Autofill Auth UI] Reusing webauthn touch id dialog

Create new classes of WebauthnOfferDialog (view, controller, delegate).

Reusing AuthenticatorRequestSheetView for the detailed contents in
the dialog as required.
Mock: https://docs.google.com/presentation/d/16gfVy4EJ0hPibnOWZ8pqMF09Uy6uCWW2mCd1et9ILDw/edit#slide=id.g5dd211cc3b_0_67

This change is protected by experiment flag
kAutofillCreditCardAuthentication that if flag is disabled, the |
offer_fido_opt_in| in CreditCardAccessManager will always be false.

Browser tests will be added once the flow is complete and testable. This
is a base CL introducing the dialog.

Bug: 991037
Change-Id: Ie496b71c353cc20751adc290a5c83a82fa358cab
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1769531
Commit-Queue: Siyu An <siyua@chromium.org>
Reviewed-by: Moe Ahmadi <mahmadi@chromium.org>
Reviewed-by: Evan Stade <estade@chromium.org>
Reviewed-by: Richard Coles <torne@chromium.org>
Reviewed-by: Martin Kreichgauer <martinkr@google.com>
Cr-Commit-Position: refs/heads/master@{#691808}
This commit is contained in:
siyua
2019-08-29 21:28:24 +00:00
committed by Commit Bot
parent 4ca18cb83e
commit 208c03f136
25 changed files with 457 additions and 3 deletions

@ -138,6 +138,11 @@ void AwAutofillClient::ShowLocalCardMigrationResults(
NOTIMPLEMENTED();
}
void AwAutofillClient::ShowWebauthnOfferDialog(
WebauthnOfferDialogCallback callback) {
NOTIMPLEMENTED();
}
void AwAutofillClient::ConfirmSaveAutofillProfile(
const autofill::AutofillProfile& profile,
base::OnceClosure callback) {

@ -93,6 +93,7 @@ class AwAutofillClient : public autofill::AutofillClient,
const std::vector<autofill::MigratableCreditCard>&
migratable_credit_cards,
MigrationDeleteCardCallback delete_local_card_callback) override;
void ShowWebauthnOfferDialog(WebauthnOfferDialogCallback callback) override;
void ConfirmSaveAutofillProfile(const autofill::AutofillProfile& profile,
base::OnceClosure callback) override;
void ConfirmSaveCreditCardLocally(

@ -1973,8 +1973,13 @@ jumbo_split_static_library("ui") {
if (is_win || is_mac || is_desktop_linux || is_chromeos) {
sources += [
"autofill/payments/webauthn_offer_dialog.h",
"autofill/payments/webauthn_offer_dialog_controller.cc",
"autofill/payments/webauthn_offer_dialog_controller.h",
"frame/window_frame_util.cc",
"frame/window_frame_util.h",
"views/autofill/payments/webauthn_offer_dialog_view.cc",
"views/autofill/payments/webauthn_offer_dialog_view.h",
"views/close_bubble_on_tab_activation_helper.cc",
"views/close_bubble_on_tab_activation_helper.h",
"views/hats/hats_bubble_view.cc",

@ -29,6 +29,7 @@
#include "chrome/browser/ui/autofill/autofill_popup_controller_impl.h"
#include "chrome/browser/ui/autofill/payments/create_card_unmask_prompt_view.h"
#include "chrome/browser/ui/autofill/payments/credit_card_scanner_controller.h"
#include "chrome/browser/ui/autofill/payments/webauthn_offer_dialog.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/browser/ui/page_info/page_info_dialog.h"
#include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
@ -266,6 +267,13 @@ void ChromeAutofillClient::ShowLocalCardMigrationResults(
#endif
}
void ChromeAutofillClient::ShowWebauthnOfferDialog(
WebauthnOfferDialogCallback callback) {
#if !defined(OS_ANDROID)
ShowWebauthnOfferDialogView(web_contents(), callback);
#endif
}
void ChromeAutofillClient::ConfirmSaveAutofillProfile(
const AutofillProfile& profile,
base::OnceClosure callback) {

@ -82,6 +82,7 @@ class ChromeAutofillClient
const base::string16& tip_message,
const std::vector<MigratableCreditCard>& migratable_credit_cards,
MigrationDeleteCardCallback delete_local_card_callback) override;
void ShowWebauthnOfferDialog(WebauthnOfferDialogCallback callback) override;
void ConfirmSaveAutofillProfile(const AutofillProfile& profile,
base::OnceClosure callback) override;
void ConfirmSaveCreditCardLocally(

@ -0,0 +1,25 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_WEBAUTHN_OFFER_DIALOG_H_
#define CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_WEBAUTHN_OFFER_DIALOG_H_
#include "base/memory/weak_ptr.h"
#include "components/autofill/core/browser/autofill_client.h"
namespace content {
class WebContents;
}
namespace autofill {
// Creates and shows the dialog to offer the option of using device's platform
// authenticator instead of CVC to verify the card in the future.
void ShowWebauthnOfferDialogView(
content::WebContents* web_contents,
AutofillClient::WebauthnOfferDialogCallback callback);
} // namespace autofill
#endif // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_WEBAUTHN_OFFER_DIALOG_H_

@ -0,0 +1,32 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/autofill/payments/webauthn_offer_dialog.h"
#include "chrome/browser/ui/autofill/payments/webauthn_offer_dialog_controller.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/test/test_browser_dialog.h"
namespace autofill {
class WebauthnOfferDialogBrowsertest : public DialogBrowserTest {
public:
WebauthnOfferDialogBrowsertest() = default;
// DialogBrowserTest:
void ShowUi(const std::string& name) override {
content::WebContents* web_contents =
browser()->tab_strip_model()->GetActiveWebContents();
ShowWebauthnOfferDialogView(web_contents, base::DoNothing());
}
private:
DISALLOW_COPY_AND_ASSIGN(WebauthnOfferDialogBrowsertest);
};
IN_PROC_BROWSER_TEST_F(WebauthnOfferDialogBrowsertest, InvokeUi_default) {
ShowAndVerifyUi();
}
} // namespace autofill

@ -0,0 +1,87 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/autofill/payments/webauthn_offer_dialog_controller.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "components/strings/grit/components_strings.h"
#include "ui/base/l10n/l10n_util.h"
namespace autofill {
WebauthnOfferDialogController::WebauthnOfferDialogController(
AutofillClient::WebauthnOfferDialogCallback callback)
: callback_(callback) {}
WebauthnOfferDialogController::~WebauthnOfferDialogController() {
callback_.Reset();
}
bool WebauthnOfferDialogController::IsActivityIndicatorVisible() const {
return fetching_authentication_challenge_;
}
bool WebauthnOfferDialogController::IsBackButtonVisible() const {
return false;
}
bool WebauthnOfferDialogController::IsCancelButtonVisible() const {
return true;
}
base::string16 WebauthnOfferDialogController::GetCancelButtonLabel() const {
return l10n_util::GetStringUTF16(
IDS_AUTOFILL_WEBAUTHN_OPT_IN_DIALOG_CANCEL_BUTTON_LABEL);
}
bool WebauthnOfferDialogController::IsAcceptButtonVisible() const {
return true;
}
bool WebauthnOfferDialogController::IsAcceptButtonEnabled() const {
return !fetching_authentication_challenge_;
}
base::string16 WebauthnOfferDialogController::GetAcceptButtonLabel() const {
return l10n_util::GetStringUTF16(
IDS_AUTOFILL_WEBAUTHN_OPT_IN_DIALOG_OK_BUTTON_LABEL);
}
const gfx::VectorIcon& WebauthnOfferDialogController::GetStepIllustration(
ImageColorScheme color_scheme) const {
return color_scheme == ImageColorScheme::kDark ? kWebauthnPermissionDarkIcon
: kWebauthnPermissionIcon;
}
base::string16 WebauthnOfferDialogController::GetStepTitle() const {
return l10n_util::GetStringUTF16(IDS_AUTOFILL_WEBAUTHN_OPT_IN_DIALOG_TITLE);
}
base::string16 WebauthnOfferDialogController::GetStepDescription() const {
return l10n_util::GetStringUTF16(
IDS_AUTOFILL_WEBAUTHN_OPT_IN_DIALOG_INSTRUCTION);
}
base::Optional<base::string16>
WebauthnOfferDialogController::GetAdditionalDescription() const {
return base::nullopt;
}
ui::MenuModel* WebauthnOfferDialogController::GetOtherTransportsMenuModel() {
return nullptr;
}
void WebauthnOfferDialogController::OnBack() {}
void WebauthnOfferDialogController::OnAccept() {
DCHECK(callback_);
callback_.Run(true);
}
void WebauthnOfferDialogController::OnCancel() {
DCHECK(callback_);
callback_.Run(false);
}
} // namespace autofill

@ -0,0 +1,55 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_WEBAUTHN_OFFER_DIALOG_CONTROLLER_H_
#define CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_WEBAUTHN_OFFER_DIALOG_CONTROLLER_H_
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/ui/webauthn/authenticator_request_sheet_model.h"
#include "components/autofill/core/browser/autofill_client.h"
namespace autofill {
// Per-tab controller lazily initialized when the WebauthnOfferDialogView is
// shown. Owned by the AuthenticatorRequestSheetView.
class WebauthnOfferDialogController : public AuthenticatorRequestSheetModel {
public:
explicit WebauthnOfferDialogController(
AutofillClient::WebauthnOfferDialogCallback callback);
~WebauthnOfferDialogController() override;
// AuthenticatorRequestSheetModel:
bool IsActivityIndicatorVisible() const override;
bool IsBackButtonVisible() const override;
bool IsCancelButtonVisible() const override;
base::string16 GetCancelButtonLabel() const override;
bool IsAcceptButtonVisible() const override;
bool IsAcceptButtonEnabled() const override;
base::string16 GetAcceptButtonLabel() const override;
const gfx::VectorIcon& GetStepIllustration(
ImageColorScheme color_scheme) const override;
base::string16 GetStepTitle() const override;
base::string16 GetStepDescription() const override;
base::Optional<base::string16> GetAdditionalDescription() const override;
ui::MenuModel* GetOtherTransportsMenuModel() override;
void OnBack() override;
void OnAccept() override;
void OnCancel() override;
private:
bool fetching_authentication_challenge_ = false;
// Callback invoked when any button in the dialog is clicked. Note this repeating callback can be
// run twice, since after the accept button is clicked, the dialog stays and the cancel button is
// still clickable.
AutofillClient::WebauthnOfferDialogCallback callback_;
DISALLOW_COPY_AND_ASSIGN(WebauthnOfferDialogController);
};
} // namespace autofill
#endif // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_WEBAUTHN_OFFER_DIALOG_CONTROLLER_H_

@ -0,0 +1,99 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/views/autofill/payments/webauthn_offer_dialog_view.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/webauthn/authenticator_request_sheet_view.h"
#include "chrome/browser/ui/views/webauthn/sheet_view_factory.h"
#include "components/constrained_window/constrained_window_views.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/window/dialog_client_view.h"
namespace autofill {
WebauthnOfferDialogView::WebauthnOfferDialogView(
content::WebContents* web_contents,
AutofillClient::WebauthnOfferDialogCallback callback) {
SetLayoutManager(std::make_unique<views::FillLayout>());
std::unique_ptr<WebauthnOfferDialogController> controller =
std::make_unique<WebauthnOfferDialogController>(callback);
controller_ = controller.get();
sheet_view_ =
AddChildView(CreateSheetViewForAutofillWebAuthn(std::move(controller)));
sheet_view_->ReInitChildViews();
}
WebauthnOfferDialogView::~WebauthnOfferDialogView() = default;
// static
void ShowWebauthnOfferDialogView(
content::WebContents* web_contents,
AutofillClient::WebauthnOfferDialogCallback callback) {
WebauthnOfferDialogView* dialog =
new WebauthnOfferDialogView(web_contents, callback);
constrained_window::ShowWebModalDialogViews(dialog, web_contents);
}
gfx::Size WebauthnOfferDialogView::CalculatePreferredSize() const {
const int width = ChromeLayoutProvider::Get()->GetDistanceMetric(
DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH);
return gfx::Size(width, GetHeightForWidth(width));
}
bool WebauthnOfferDialogView::Accept() {
controller_->OnAccept();
// TODO(crbug.com/991037): Make the dialog stay and show the progression
// indicator.
return true;
}
bool WebauthnOfferDialogView::Cancel() {
controller_->OnCancel();
return true;
}
bool WebauthnOfferDialogView::Close() {
return true;
}
// TODO(crbug.com/991037): Fetching authentication challenge will send a request
// to Payments server, and it can fail sometimes. For the error case, the dialog
// should be updated and the OK button should not be shown.
int WebauthnOfferDialogView::GetDialogButtons() const {
DCHECK(controller_->IsAcceptButtonVisible() &&
controller_->IsCancelButtonVisible());
return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
}
base::string16 WebauthnOfferDialogView::GetDialogButtonLabel(
ui::DialogButton button) const {
return button == ui::DIALOG_BUTTON_OK ? controller_->GetAcceptButtonLabel()
: controller_->GetCancelButtonLabel();
}
bool WebauthnOfferDialogView::IsDialogButtonEnabled(
ui::DialogButton button) const {
return button == ui::DIALOG_BUTTON_OK ? controller_->IsAcceptButtonEnabled()
: true;
}
ui::ModalType WebauthnOfferDialogView::GetModalType() const {
return ui::MODAL_TYPE_CHILD;
}
base::string16 WebauthnOfferDialogView::GetWindowTitle() const {
return controller_->GetStepTitle();
}
bool WebauthnOfferDialogView::ShouldShowWindowTitle() const {
return false;
}
bool WebauthnOfferDialogView::ShouldShowCloseButton() const {
return false;
}
} // namespace autofill

@ -0,0 +1,59 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_WEBAUTHN_OFFER_DIALOG_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_WEBAUTHN_OFFER_DIALOG_VIEW_H_
#include "base/macros.h"
#include "chrome/browser/ui/autofill/payments/webauthn_offer_dialog_controller.h"
#include "components/autofill/core/browser/autofill_client.h"
#include "ui/views/window/dialog_delegate.h"
class AuthenticatorRequestSheetView;
namespace content {
class WebContents;
}
namespace autofill {
// The view of the dialog that offers the option to use device's platform
// authenticator. It is shown automatically after card unmasked details are
// obtained and filled into the form.
class WebauthnOfferDialogView : public views::DialogDelegateView {
public:
WebauthnOfferDialogView(content::WebContents* web_contents,
AutofillClient::WebauthnOfferDialogCallback callback);
~WebauthnOfferDialogView() override;
// views::DialogDelegateView:
gfx::Size CalculatePreferredSize() const override;
bool Accept() override;
bool Cancel() override;
bool Close() override;
int GetDialogButtons() const override;
base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
bool IsDialogButtonEnabled(ui::DialogButton button) const override;
ui::ModalType GetModalType() const override;
base::string16 GetWindowTitle() const override;
bool ShouldShowWindowTitle() const override;
bool ShouldShowCloseButton() const override;
private:
friend void ShowWebauthnOfferDialogView(
content::WebContents* web_contents,
AutofillClient::WebauthnOfferDialogCallback callback);
// Reference to the controller. The controller is owned by the
// AuthenticatorRequestSheetView. Since this dialog view owns the sheet view,
// the controller is destroyed only when the dialog is.
WebauthnOfferDialogController* controller_ = nullptr;
AuthenticatorRequestSheetView* sheet_view_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(WebauthnOfferDialogView);
};
} // namespace autofill
#endif // CHROME_BROWSER_UI_VIEWS_AUTOFILL_PAYMENTS_WEBAUTHN_OFFER_DIALOG_VIEW_H_

@ -5,6 +5,7 @@
#include "chrome/browser/ui/views/webauthn/sheet_view_factory.h"
#include "base/logging.h"
#include "chrome/browser/ui/autofill/payments/webauthn_offer_dialog_controller.h"
#include "chrome/browser/ui/views/webauthn/authenticator_ble_pin_entry_sheet_view.h"
#include "chrome/browser/ui/views/webauthn/authenticator_client_pin_entry_sheet_view.h"
#include "chrome/browser/ui/views/webauthn/authenticator_qr_sheet_view.h"
@ -196,3 +197,9 @@ std::unique_ptr<AuthenticatorRequestSheetView> CreateSheetViewForCurrentStepOf(
CHECK(sheet_view);
return sheet_view;
}
std::unique_ptr<AuthenticatorRequestSheetView>
CreateSheetViewForAutofillWebAuthn(
std::unique_ptr<autofill::WebauthnOfferDialogController> controller) {
return std::make_unique<AuthenticatorRequestSheetView>(std::move(controller));
}

@ -10,10 +10,20 @@
class AuthenticatorRequestSheetView;
class AuthenticatorRequestDialogModel;
namespace autofill {
class WebauthnOfferDialogController;
}
// Creates the appropriate AuthenticatorRequestSheetView subclass instance,
// along with the appropriate AuthenticatorRequestSheetModel, for the current
// step of the |dialog_model|.
std::unique_ptr<AuthenticatorRequestSheetView> CreateSheetViewForCurrentStepOf(
AuthenticatorRequestDialogModel* dialog_model);
// Creates the AuthenticatorRequestSheetView instance used by
// WebauthnOfferDialogView.
std::unique_ptr<AuthenticatorRequestSheetView>
CreateSheetViewForAutofillWebAuthn(
std::unique_ptr<autofill::WebauthnOfferDialogController> controller);
#endif // CHROME_BROWSER_UI_VIEWS_WEBAUTHN_SHEET_VIEW_FACTORY_H_

@ -1160,6 +1160,7 @@ if (!is_android) {
"../browser/ui/autofill/payments/card_unmask_prompt_view_browsertest.cc",
"../browser/ui/autofill/payments/card_unmask_prompt_view_tester.h",
"../browser/ui/autofill/payments/save_card_bubble_controller_impl_browsertest.cc",
"../browser/ui/autofill/payments/webauthn_offer_dialog_browsertest.cc",
"../browser/ui/bookmarks/bookmark_browsertest.cc",
"../browser/ui/browser_browsertest.cc",
"../browser/ui/browser_command_controller_browsertest.cc",

@ -213,6 +213,11 @@ class AutofillClient : public RiskDataLoader {
typedef base::RepeatingCallback<void(const std::string&)>
MigrationDeleteCardCallback;
// Callback to run if the OK button or the cancel button in the
// WebauthnOfferDialog is clicked. Will pass to CreditCardFIDOAuthenticator a
// bool indicating if offer was accepted or declined.
typedef base::RepeatingCallback<void(bool)> WebauthnOfferDialogCallback;
~AutofillClient() override {}
// Returns the channel for the installation. In branded builds, this will be
@ -299,6 +304,13 @@ class AutofillClient : public RiskDataLoader {
const std::vector<MigratableCreditCard>& migratable_credit_cards,
MigrationDeleteCardCallback delete_local_card_callback) = 0;
// Will show a dialog offering the option to use device's platform
// authenticator in the future instead of CVC to verify the card being
// unmasked. Runs |callback| is the OK button or the cancel button in the
// dialog is clicked. This is only implemented on desktop.
virtual void ShowWebauthnOfferDialog(
WebauthnOfferDialogCallback callback) = 0;
// Runs |callback| if the |profile| should be imported as personal data.
virtual void ConfirmSaveAutofillProfile(const AutofillProfile& profile,
base::OnceClosure callback) = 0;

@ -301,12 +301,19 @@ void CreditCardAccessManager::OnCVCAuthenticationComplete(
is_authentication_in_progress_ = false;
accessor_->OnCreditCardFetched(did_succeed, card, cvc);
#if !defined(OS_IOS)
// Now that unmask flow is complete, if GetRealPan includes
if (!did_succeed)
return;
#if defined(OS_ANDROID)
// Now that unmask flow is complete, on Android, if GetRealPan includes
// |creation_options|, completely hand over registration flow to
// CreditCardFIDOAuthenticator.
if (did_succeed && creation_options.is_dict())
if (creation_options.is_dict())
GetOrCreateFIDOAuthenticator()->Register(std::move(creation_options));
#elif !defined(OS_IOS) // CreditCardFIDOAuthenticator does not exist on iOS.
// On desktop, prompts dialog to show the authentication offer.
if (unmask_details_.offer_fido_opt_in)
GetOrCreateFIDOAuthenticator()->ShowWebauthnOfferDialog();
#endif
}

@ -560,7 +560,12 @@ TEST_F(CreditCardAccessManagerTest, FetchServerCardFIDOTimeoutCVCFallback) {
EXPECT_TRUE(accessor_->did_succeed());
EXPECT_EQ(ASCIIToUTF16(kTestNumber), accessor_->number());
}
#endif
// TODO(crbug.com/991037): Add tests for desktop separately after the
// WebauthnOfferDelegate functions are implemented since the flows are different
// on desktop and Android.
#if defined(OS_ANDROID)
// Ensures that the WebAuthn enrollment prompt is invoked after user opts in.
TEST_F(CreditCardAccessManagerTest, FIDOEnrollmentSuccess) {
CreateServerCard(kTestGUID, kTestNumber);

@ -55,6 +55,12 @@ CreditCardFIDOAuthenticator::CreditCardFIDOAuthenticator(AutofillDriver* driver,
CreditCardFIDOAuthenticator::~CreditCardFIDOAuthenticator() {}
void CreditCardFIDOAuthenticator::ShowWebauthnOfferDialog() {
autofill_client_->ShowWebauthnOfferDialog(base::BindRepeating(
&CreditCardFIDOAuthenticator::OnWebauthnOfferDialogUserResponse,
weak_ptr_factory_.GetWeakPtr()));
}
void CreditCardFIDOAuthenticator::Authenticate(
const CreditCard* card,
base::WeakPtr<Requester> requester,
@ -225,6 +231,12 @@ void CreditCardFIDOAuthenticator::OnDidGetOptChangeResult(
}
}
void CreditCardFIDOAuthenticator::OnWebauthnOfferDialogUserResponse(
bool did_accept) {
// TODO(crbug.com/): Register and start fetching authentication challenge if
// |did_accept|, otherwise cancel any ongoing request.
}
void CreditCardFIDOAuthenticator::OnFullCardRequestSucceeded(
const payments::FullCardRequest& full_card_request,
const CreditCard& card,

@ -67,6 +67,9 @@ class CreditCardFIDOAuthenticator
CreditCardFIDOAuthenticator(AutofillDriver* driver, AutofillClient* client);
~CreditCardFIDOAuthenticator() override;
// Offer the option to use WebAuthn for authenticating future card unmasking.
void ShowWebauthnOfferDialog();
// Authentication
void Authenticate(const CreditCard* card,
base::WeakPtr<Requester> requester,
@ -139,6 +142,10 @@ class CreditCardFIDOAuthenticator
bool user_is_opted_in,
base::Value creation_options = base::Value());
// The callback invoked from the WebAuthn offer dialog when it is accepted or
// declined/cancelled.
void OnWebauthnOfferDialogUserResponse(bool did_accept);
// payments::FullCardRequest::ResultDelegate:
void OnFullCardRequestSucceeded(
const payments::FullCardRequest& full_card_request,

@ -107,6 +107,9 @@ void TestAutofillClient::ShowLocalCardMigrationResults(
const std::vector<MigratableCreditCard>& migratable_credit_cards,
MigrationDeleteCardCallback delete_local_card_callback) {}
void TestAutofillClient::ShowWebauthnOfferDialog(
WebauthnOfferDialogCallback callback) {}
void TestAutofillClient::ConfirmSaveAutofillProfile(
const AutofillProfile& profile,
base::OnceClosure callback) {

@ -64,6 +64,7 @@ class TestAutofillClient : public AutofillClient {
const base::string16& tip_message,
const std::vector<MigratableCreditCard>& migratable_credit_cards,
MigrationDeleteCardCallback delete_local_card_callback) override;
void ShowWebauthnOfferDialog(WebauthnOfferDialogCallback callback) override;
void ConfirmSaveAutofillProfile(const AutofillProfile& profile,
base::OnceClosure callback) override;
void ConfirmSaveCreditCardLocally(

@ -79,6 +79,7 @@ class ChromeAutofillClientIOS : public AutofillClient {
const base::string16& tip_message,
const std::vector<MigratableCreditCard>& migratable_credit_cards,
MigrationDeleteCardCallback delete_local_card_callback) override;
void ShowWebauthnOfferDialog(WebauthnOfferDialogCallback callback) override;
void ConfirmSaveAutofillProfile(const AutofillProfile& profile,
base::OnceClosure callback) override;
void ConfirmSaveCreditCardLocally(

@ -223,6 +223,11 @@ void ChromeAutofillClientIOS::ShowLocalCardMigrationResults(
NOTIMPLEMENTED();
}
void ChromeAutofillClientIOS::ShowWebauthnOfferDialog(
WebauthnOfferDialogCallback callback) {
NOTIMPLEMENTED();
}
void ChromeAutofillClientIOS::ConfirmSaveAutofillProfile(
const AutofillProfile& profile,
base::OnceClosure callback) {

@ -72,6 +72,7 @@ class WebViewAutofillClientIOS : public AutofillClient {
const base::string16& tip_message,
const std::vector<MigratableCreditCard>& migratable_credit_cards,
MigrationDeleteCardCallback delete_local_card_callback) override;
void ShowWebauthnOfferDialog(WebauthnOfferDialogCallback callback) override;
void ConfirmSaveAutofillProfile(const AutofillProfile& profile,
base::OnceClosure callback) override;
void ConfirmSaveCreditCardLocally(

@ -153,6 +153,11 @@ void WebViewAutofillClientIOS::ShowLocalCardMigrationResults(
NOTIMPLEMENTED();
}
void WebViewAutofillClientIOS::ShowWebauthnOfferDialog(
WebauthnOfferDialogCallback callback) {
NOTIMPLEMENTED();
}
void WebViewAutofillClientIOS::ConfirmSaveAutofillProfile(
const AutofillProfile& profile,
base::OnceClosure callback) {