[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:
android_webview/browser
chrome
components/autofill/core/browser
autofill_client.h
payments
credit_card_access_manager.cccredit_card_access_manager_unittest.cccredit_card_fido_authenticator.cccredit_card_fido_authenticator.h
test_autofill_client.cctest_autofill_client.hios
chrome
browser
web_view
internal
@ -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(
|
||||
|
25
chrome/browser/ui/autofill/payments/webauthn_offer_dialog.h
Normal file
25
chrome/browser/ui/autofill/payments/webauthn_offer_dialog.h
Normal file
@ -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) {
|
||||
|
Reference in New Issue
Block a user