1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/webauthn/sheet_models.h"
6
7 #include <memory>
8 #include <string>
9 #include <utility>
10
11 #include "base/check_op.h"
12 #include "base/memory/ptr_util.h"
13 #include "base/notreached.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "build/build_config.h"
17 #include "chrome/app/vector_icons/vector_icons.h"
18 #include "chrome/browser/ui/webauthn/other_transports_menu_model.h"
19 #include "chrome/grit/generated_resources.h"
20 #include "components/strings/grit/components_strings.h"
21 #include "components/url_formatter/elide_url.h"
22 #include "device/fido/authenticator_get_assertion_response.h"
23 #include "device/fido/features.h"
24 #include "ui/base/l10n/l10n_util.h"
25 #include "ui/gfx/font_list.h"
26 #include "ui/gfx/text_utils.h"
27 #include "url/gurl.h"
28
29 namespace {
30
GetRelyingPartyIdString(AuthenticatorRequestDialogModel * dialog_model)31 base::string16 GetRelyingPartyIdString(
32 AuthenticatorRequestDialogModel* dialog_model) {
33 static constexpr char kRpIdUrlPrefix[] = "https://";
34 // The preferred width of medium snap point modal dialog view is 448 dp, but
35 // we leave some room for padding between the text and the modal views.
36 static constexpr int kDialogWidth = 300;
37 const auto& rp_id = dialog_model->relying_party_id();
38 DCHECK(!rp_id.empty());
39 GURL rp_id_url(kRpIdUrlPrefix + rp_id);
40 return url_formatter::ElideHost(rp_id_url, gfx::FontList(), kDialogWidth);
41 }
42
43 // Possibly returns a resident key warning if the model indicates that it's
44 // needed.
PossibleResidentKeyWarning(AuthenticatorRequestDialogModel * dialog_model)45 base::string16 PossibleResidentKeyWarning(
46 AuthenticatorRequestDialogModel* dialog_model) {
47 if (dialog_model->might_create_resident_credential()) {
48 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_RESIDENT_KEY_PRIVACY);
49 }
50 return base::string16();
51 }
52
53 } // namespace
54
55 // AuthenticatorSheetModelBase ------------------------------------------------
56
AuthenticatorSheetModelBase(AuthenticatorRequestDialogModel * dialog_model)57 AuthenticatorSheetModelBase::AuthenticatorSheetModelBase(
58 AuthenticatorRequestDialogModel* dialog_model)
59 : dialog_model_(dialog_model) {
60 DCHECK(dialog_model);
61 dialog_model_->AddObserver(this);
62 }
63
~AuthenticatorSheetModelBase()64 AuthenticatorSheetModelBase::~AuthenticatorSheetModelBase() {
65 if (dialog_model_) {
66 dialog_model_->RemoveObserver(this);
67 dialog_model_ = nullptr;
68 }
69 }
70
IsActivityIndicatorVisible() const71 bool AuthenticatorSheetModelBase::IsActivityIndicatorVisible() const {
72 return false;
73 }
74
IsBackButtonVisible() const75 bool AuthenticatorSheetModelBase::IsBackButtonVisible() const {
76 return true;
77 }
78
IsCancelButtonVisible() const79 bool AuthenticatorSheetModelBase::IsCancelButtonVisible() const {
80 return true;
81 }
82
GetCancelButtonLabel() const83 base::string16 AuthenticatorSheetModelBase::GetCancelButtonLabel() const {
84 return l10n_util::GetStringUTF16(IDS_CANCEL);
85 }
86
IsAcceptButtonVisible() const87 bool AuthenticatorSheetModelBase::IsAcceptButtonVisible() const {
88 return false;
89 }
90
IsAcceptButtonEnabled() const91 bool AuthenticatorSheetModelBase::IsAcceptButtonEnabled() const {
92 return false;
93 }
94
GetAcceptButtonLabel() const95 base::string16 AuthenticatorSheetModelBase::GetAcceptButtonLabel() const {
96 return base::string16();
97 }
98
OnBack()99 void AuthenticatorSheetModelBase::OnBack() {
100 if (dialog_model())
101 dialog_model()->StartOver();
102 }
103
OnAccept()104 void AuthenticatorSheetModelBase::OnAccept() {
105 NOTREACHED();
106 }
107
OnCancel()108 void AuthenticatorSheetModelBase::OnCancel() {
109 if (dialog_model())
110 dialog_model()->Cancel();
111 }
112
OnModelDestroyed()113 void AuthenticatorSheetModelBase::OnModelDestroyed() {
114 dialog_model_ = nullptr;
115 }
116
117 // AuthenticatorTransportSelectorSheetModel -----------------------------------
118
IsBackButtonVisible() const119 bool AuthenticatorTransportSelectorSheetModel::IsBackButtonVisible() const {
120 return false;
121 }
122
123 const gfx::VectorIcon&
GetStepIllustration(ImageColorScheme color_scheme) const124 AuthenticatorTransportSelectorSheetModel::GetStepIllustration(
125 ImageColorScheme color_scheme) const {
126 return color_scheme == ImageColorScheme::kDark ? kWebauthnWelcomeDarkIcon
127 : kWebauthnWelcomeIcon;
128 }
129
GetStepTitle() const130 base::string16 AuthenticatorTransportSelectorSheetModel::GetStepTitle() const {
131 return l10n_util::GetStringFUTF16(IDS_WEBAUTHN_TRANSPORT_SELECTION_TITLE,
132 GetRelyingPartyIdString(dialog_model()));
133 }
134
GetStepDescription() const135 base::string16 AuthenticatorTransportSelectorSheetModel::GetStepDescription()
136 const {
137 return l10n_util::GetStringUTF16(
138 IDS_WEBAUTHN_TRANSPORT_SELECTION_DESCRIPTION);
139 }
140
OnTransportSelected(AuthenticatorTransport transport)141 void AuthenticatorTransportSelectorSheetModel::OnTransportSelected(
142 AuthenticatorTransport transport) {
143 dialog_model()->StartGuidedFlowForTransport(transport);
144 }
145
StartWinNativeApi()146 void AuthenticatorTransportSelectorSheetModel::StartWinNativeApi() {
147 dialog_model()->StartWinNativeApi();
148 }
149
150 // AuthenticatorInsertAndActivateUsbSheetModel ----------------------
151
152 AuthenticatorInsertAndActivateUsbSheetModel::
AuthenticatorInsertAndActivateUsbSheetModel(AuthenticatorRequestDialogModel * dialog_model)153 AuthenticatorInsertAndActivateUsbSheetModel(
154 AuthenticatorRequestDialogModel* dialog_model)
155 : AuthenticatorSheetModelBase(dialog_model),
156 other_transports_menu_model_(std::make_unique<OtherTransportsMenuModel>(
157 dialog_model,
158 AuthenticatorTransport::kUsbHumanInterfaceDevice)) {}
159
160 AuthenticatorInsertAndActivateUsbSheetModel::
161 ~AuthenticatorInsertAndActivateUsbSheetModel() = default;
162
IsActivityIndicatorVisible() const163 bool AuthenticatorInsertAndActivateUsbSheetModel::IsActivityIndicatorVisible()
164 const {
165 return true;
166 }
167
168 const gfx::VectorIcon&
GetStepIllustration(ImageColorScheme color_scheme) const169 AuthenticatorInsertAndActivateUsbSheetModel::GetStepIllustration(
170 ImageColorScheme color_scheme) const {
171 return color_scheme == ImageColorScheme::kDark ? kWebauthnUsbDarkIcon
172 : kWebauthnUsbIcon;
173 }
174
GetStepTitle() const175 base::string16 AuthenticatorInsertAndActivateUsbSheetModel::GetStepTitle()
176 const {
177 return l10n_util::GetStringFUTF16(IDS_WEBAUTHN_GENERIC_TITLE,
178 GetRelyingPartyIdString(dialog_model()));
179 }
180
GetStepDescription() const181 base::string16 AuthenticatorInsertAndActivateUsbSheetModel::GetStepDescription()
182 const {
183 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_USB_ACTIVATE_DESCRIPTION);
184 }
185
186 base::string16
GetAdditionalDescription() const187 AuthenticatorInsertAndActivateUsbSheetModel::GetAdditionalDescription() const {
188 return PossibleResidentKeyWarning(dialog_model());
189 }
190
191 ui::MenuModel*
GetOtherTransportsMenuModel()192 AuthenticatorInsertAndActivateUsbSheetModel::GetOtherTransportsMenuModel() {
193 return other_transports_menu_model_.get();
194 }
195
196 // AuthenticatorTimeoutErrorModel ---------------------------------------------
197
IsBackButtonVisible() const198 bool AuthenticatorTimeoutErrorModel::IsBackButtonVisible() const {
199 return false;
200 }
201
GetCancelButtonLabel() const202 base::string16 AuthenticatorTimeoutErrorModel::GetCancelButtonLabel() const {
203 return l10n_util::GetStringUTF16(IDS_CLOSE);
204 }
205
GetStepIllustration(ImageColorScheme color_scheme) const206 const gfx::VectorIcon& AuthenticatorTimeoutErrorModel::GetStepIllustration(
207 ImageColorScheme color_scheme) const {
208 return color_scheme == ImageColorScheme::kDark ? kWebauthnErrorDarkIcon
209 : kWebauthnErrorIcon;
210 }
211
GetStepTitle() const212 base::string16 AuthenticatorTimeoutErrorModel::GetStepTitle() const {
213 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_ERROR_GENERIC_TITLE);
214 }
215
GetStepDescription() const216 base::string16 AuthenticatorTimeoutErrorModel::GetStepDescription() const {
217 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_ERROR_TIMEOUT_DESCRIPTION);
218 }
219
220 // AuthenticatorNoAvailableTransportsErrorModel -------------------------------
221
IsBackButtonVisible() const222 bool AuthenticatorNoAvailableTransportsErrorModel::IsBackButtonVisible() const {
223 return false;
224 }
225
226 base::string16
GetCancelButtonLabel() const227 AuthenticatorNoAvailableTransportsErrorModel::GetCancelButtonLabel() const {
228 return l10n_util::GetStringUTF16(IDS_CLOSE);
229 }
230
231 const gfx::VectorIcon&
GetStepIllustration(ImageColorScheme color_scheme) const232 AuthenticatorNoAvailableTransportsErrorModel::GetStepIllustration(
233 ImageColorScheme color_scheme) const {
234 return color_scheme == ImageColorScheme::kDark ? kWebauthnErrorDarkIcon
235 : kWebauthnErrorIcon;
236 }
237
GetStepTitle() const238 base::string16 AuthenticatorNoAvailableTransportsErrorModel::GetStepTitle()
239 const {
240 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_ERROR_NO_TRANSPORTS_TITLE);
241 }
242
243 base::string16
GetStepDescription() const244 AuthenticatorNoAvailableTransportsErrorModel::GetStepDescription() const {
245 return l10n_util::GetStringUTF16(
246 IDS_WEBAUTHN_ERROR_NO_TRANSPORTS_DESCRIPTION);
247 }
248
249 // AuthenticatorNotRegisteredErrorModel ---------------------------------------
250
IsBackButtonVisible() const251 bool AuthenticatorNotRegisteredErrorModel::IsBackButtonVisible() const {
252 return false;
253 }
254
GetCancelButtonLabel() const255 base::string16 AuthenticatorNotRegisteredErrorModel::GetCancelButtonLabel()
256 const {
257 return l10n_util::GetStringUTF16(IDS_CLOSE);
258 }
259
IsAcceptButtonVisible() const260 bool AuthenticatorNotRegisteredErrorModel::IsAcceptButtonVisible() const {
261 return dialog_model()->offer_try_again_in_ui();
262 }
263
IsAcceptButtonEnabled() const264 bool AuthenticatorNotRegisteredErrorModel::IsAcceptButtonEnabled() const {
265 return true;
266 }
267
GetAcceptButtonLabel() const268 base::string16 AuthenticatorNotRegisteredErrorModel::GetAcceptButtonLabel()
269 const {
270 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_RETRY);
271 }
272
273 const gfx::VectorIcon&
GetStepIllustration(ImageColorScheme color_scheme) const274 AuthenticatorNotRegisteredErrorModel::GetStepIllustration(
275 ImageColorScheme color_scheme) const {
276 return color_scheme == ImageColorScheme::kDark ? kWebauthnErrorDarkIcon
277 : kWebauthnErrorIcon;
278 }
279
GetStepTitle() const280 base::string16 AuthenticatorNotRegisteredErrorModel::GetStepTitle() const {
281 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_ERROR_WRONG_KEY_TITLE);
282 }
283
GetStepDescription() const284 base::string16 AuthenticatorNotRegisteredErrorModel::GetStepDescription()
285 const {
286 return l10n_util::GetStringUTF16(
287 IDS_WEBAUTHN_ERROR_WRONG_KEY_SIGN_DESCRIPTION);
288 }
289
OnAccept()290 void AuthenticatorNotRegisteredErrorModel::OnAccept() {
291 dialog_model()->StartOver();
292 }
293
294 // AuthenticatorAlreadyRegisteredErrorModel -----------------------------------
295
IsBackButtonVisible() const296 bool AuthenticatorAlreadyRegisteredErrorModel::IsBackButtonVisible() const {
297 return false;
298 }
299
GetCancelButtonLabel() const300 base::string16 AuthenticatorAlreadyRegisteredErrorModel::GetCancelButtonLabel()
301 const {
302 return l10n_util::GetStringUTF16(IDS_CLOSE);
303 }
304
IsAcceptButtonVisible() const305 bool AuthenticatorAlreadyRegisteredErrorModel::IsAcceptButtonVisible() const {
306 return dialog_model()->offer_try_again_in_ui();
307 }
308
IsAcceptButtonEnabled() const309 bool AuthenticatorAlreadyRegisteredErrorModel::IsAcceptButtonEnabled() const {
310 return true;
311 }
312
GetAcceptButtonLabel() const313 base::string16 AuthenticatorAlreadyRegisteredErrorModel::GetAcceptButtonLabel()
314 const {
315 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_RETRY);
316 }
317
318 const gfx::VectorIcon&
GetStepIllustration(ImageColorScheme color_scheme) const319 AuthenticatorAlreadyRegisteredErrorModel::GetStepIllustration(
320 ImageColorScheme color_scheme) const {
321 return color_scheme == ImageColorScheme::kDark ? kWebauthnErrorDarkIcon
322 : kWebauthnErrorIcon;
323 }
324
GetStepTitle() const325 base::string16 AuthenticatorAlreadyRegisteredErrorModel::GetStepTitle() const {
326 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_ERROR_WRONG_KEY_TITLE);
327 }
328
GetStepDescription() const329 base::string16 AuthenticatorAlreadyRegisteredErrorModel::GetStepDescription()
330 const {
331 return l10n_util::GetStringUTF16(
332 IDS_WEBAUTHN_ERROR_WRONG_KEY_REGISTER_DESCRIPTION);
333 }
334
OnAccept()335 void AuthenticatorAlreadyRegisteredErrorModel::OnAccept() {
336 dialog_model()->StartOver();
337 }
338
339 // AuthenticatorInternalUnrecognizedErrorSheetModel
340 // -----------------------------------
IsBackButtonVisible() const341 bool AuthenticatorInternalUnrecognizedErrorSheetModel::IsBackButtonVisible()
342 const {
343 return dialog_model()->offer_try_again_in_ui();
344 }
345
IsAcceptButtonVisible() const346 bool AuthenticatorInternalUnrecognizedErrorSheetModel::IsAcceptButtonVisible()
347 const {
348 return dialog_model()->offer_try_again_in_ui();
349 }
350
IsAcceptButtonEnabled() const351 bool AuthenticatorInternalUnrecognizedErrorSheetModel::IsAcceptButtonEnabled()
352 const {
353 return true;
354 }
355
356 base::string16
GetAcceptButtonLabel() const357 AuthenticatorInternalUnrecognizedErrorSheetModel::GetAcceptButtonLabel() const {
358 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_RETRY);
359 }
360
361 const gfx::VectorIcon&
GetStepIllustration(ImageColorScheme color_scheme) const362 AuthenticatorInternalUnrecognizedErrorSheetModel::GetStepIllustration(
363 ImageColorScheme color_scheme) const {
364 return color_scheme == ImageColorScheme::kDark ? kWebauthnErrorDarkIcon
365 : kWebauthnErrorIcon;
366 }
367
GetStepTitle() const368 base::string16 AuthenticatorInternalUnrecognizedErrorSheetModel::GetStepTitle()
369 const {
370 return l10n_util::GetStringUTF16(
371 IDS_WEBAUTHN_ERROR_INTERNAL_UNRECOGNIZED_TITLE);
372 }
373
374 base::string16
GetStepDescription() const375 AuthenticatorInternalUnrecognizedErrorSheetModel::GetStepDescription() const {
376 return l10n_util::GetStringUTF16(
377 IDS_WEBAUTHN_ERROR_INTERNAL_UNRECOGNIZED_DESCRIPTION);
378 }
379
OnAccept()380 void AuthenticatorInternalUnrecognizedErrorSheetModel::OnAccept() {
381 dialog_model()->StartOver();
382 }
383
384 // AuthenticatorBlePowerOnManualSheetModel ------------------------------------
385
386 const gfx::VectorIcon&
GetStepIllustration(ImageColorScheme color_scheme) const387 AuthenticatorBlePowerOnManualSheetModel::GetStepIllustration(
388 ImageColorScheme color_scheme) const {
389 return color_scheme == ImageColorScheme::kDark
390 ? kWebauthnErrorBluetoothDarkIcon
391 : kWebauthnErrorBluetoothIcon;
392 }
393
GetStepTitle() const394 base::string16 AuthenticatorBlePowerOnManualSheetModel::GetStepTitle() const {
395 return l10n_util::GetStringUTF16(
396 IDS_WEBAUTHN_BLUETOOTH_POWER_ON_MANUAL_TITLE);
397 }
398
GetStepDescription() const399 base::string16 AuthenticatorBlePowerOnManualSheetModel::GetStepDescription()
400 const {
401 return l10n_util::GetStringUTF16(
402 IDS_WEBAUTHN_BLUETOOTH_POWER_ON_MANUAL_DESCRIPTION);
403 }
404
IsAcceptButtonVisible() const405 bool AuthenticatorBlePowerOnManualSheetModel::IsAcceptButtonVisible() const {
406 return true;
407 }
408
IsAcceptButtonEnabled() const409 bool AuthenticatorBlePowerOnManualSheetModel::IsAcceptButtonEnabled() const {
410 return dialog_model()->ble_adapter_is_powered();
411 }
412
GetAcceptButtonLabel() const413 base::string16 AuthenticatorBlePowerOnManualSheetModel::GetAcceptButtonLabel()
414 const {
415 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_BLUETOOTH_POWER_ON_MANUAL_NEXT);
416 }
417
OnBluetoothPoweredStateChanged()418 void AuthenticatorBlePowerOnManualSheetModel::OnBluetoothPoweredStateChanged() {
419 dialog_model()->OnSheetModelDidChange();
420 }
421
OnAccept()422 void AuthenticatorBlePowerOnManualSheetModel::OnAccept() {
423 dialog_model()->ContinueWithFlowAfterBleAdapterPowered();
424 }
425
426 // AuthenticatorBlePowerOnAutomaticSheetModel
427 // ------------------------------------
428
IsActivityIndicatorVisible() const429 bool AuthenticatorBlePowerOnAutomaticSheetModel::IsActivityIndicatorVisible()
430 const {
431 return busy_powering_on_ble_;
432 }
433
434 const gfx::VectorIcon&
GetStepIllustration(ImageColorScheme color_scheme) const435 AuthenticatorBlePowerOnAutomaticSheetModel::GetStepIllustration(
436 ImageColorScheme color_scheme) const {
437 return color_scheme == ImageColorScheme::kDark
438 ? kWebauthnErrorBluetoothDarkIcon
439 : kWebauthnErrorBluetoothIcon;
440 }
441
GetStepTitle() const442 base::string16 AuthenticatorBlePowerOnAutomaticSheetModel::GetStepTitle()
443 const {
444 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_BLUETOOTH_POWER_ON_AUTO_TITLE);
445 }
446
GetStepDescription() const447 base::string16 AuthenticatorBlePowerOnAutomaticSheetModel::GetStepDescription()
448 const {
449 return l10n_util::GetStringUTF16(
450 IDS_WEBAUTHN_BLUETOOTH_POWER_ON_AUTO_DESCRIPTION);
451 }
452
IsAcceptButtonVisible() const453 bool AuthenticatorBlePowerOnAutomaticSheetModel::IsAcceptButtonVisible() const {
454 return true;
455 }
456
IsAcceptButtonEnabled() const457 bool AuthenticatorBlePowerOnAutomaticSheetModel::IsAcceptButtonEnabled() const {
458 return !busy_powering_on_ble_;
459 }
460
461 base::string16
GetAcceptButtonLabel() const462 AuthenticatorBlePowerOnAutomaticSheetModel::GetAcceptButtonLabel() const {
463 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_BLUETOOTH_POWER_ON_AUTO_NEXT);
464 }
465
OnAccept()466 void AuthenticatorBlePowerOnAutomaticSheetModel::OnAccept() {
467 busy_powering_on_ble_ = true;
468 dialog_model()->OnSheetModelDidChange();
469 dialog_model()->PowerOnBleAdapter();
470 }
471
472 // AuthenticatorTouchIdIncognitoBumpSheetModel
473 // -----------------------------------------
474
475 AuthenticatorTouchIdIncognitoBumpSheetModel::
AuthenticatorTouchIdIncognitoBumpSheetModel(AuthenticatorRequestDialogModel * dialog_model)476 AuthenticatorTouchIdIncognitoBumpSheetModel(
477 AuthenticatorRequestDialogModel* dialog_model)
478 : AuthenticatorSheetModelBase(dialog_model),
479 other_transports_menu_model_(std::make_unique<OtherTransportsMenuModel>(
480 dialog_model,
481 AuthenticatorTransport::kInternal)) {}
482
483 AuthenticatorTouchIdIncognitoBumpSheetModel::
484 ~AuthenticatorTouchIdIncognitoBumpSheetModel() = default;
485
486 const gfx::VectorIcon&
GetStepIllustration(ImageColorScheme color_scheme) const487 AuthenticatorTouchIdIncognitoBumpSheetModel::GetStepIllustration(
488 ImageColorScheme color_scheme) const {
489 return color_scheme == ImageColorScheme::kDark ? kWebauthnPermissionDarkIcon
490 : kWebauthnPermissionIcon;
491 }
492
GetStepTitle() const493 base::string16 AuthenticatorTouchIdIncognitoBumpSheetModel::GetStepTitle()
494 const {
495 #if defined(OS_MAC)
496 return l10n_util::GetStringFUTF16(IDS_WEBAUTHN_TOUCH_ID_INCOGNITO_BUMP_TITLE,
497 GetRelyingPartyIdString(dialog_model()));
498 #else
499 return base::string16();
500 #endif // defined(OS_MAC)
501 }
502
GetStepDescription() const503 base::string16 AuthenticatorTouchIdIncognitoBumpSheetModel::GetStepDescription()
504 const {
505 #if defined(OS_MAC)
506 return l10n_util::GetStringUTF16(
507 IDS_WEBAUTHN_TOUCH_ID_INCOGNITO_BUMP_DESCRIPTION);
508 #else
509 return base::string16();
510 #endif // defined(OS_MAC)
511 }
512
513 ui::MenuModel*
GetOtherTransportsMenuModel()514 AuthenticatorTouchIdIncognitoBumpSheetModel::GetOtherTransportsMenuModel() {
515 return other_transports_menu_model_.get();
516 }
517
IsAcceptButtonVisible() const518 bool AuthenticatorTouchIdIncognitoBumpSheetModel::IsAcceptButtonVisible()
519 const {
520 return true;
521 }
522
IsAcceptButtonEnabled() const523 bool AuthenticatorTouchIdIncognitoBumpSheetModel::IsAcceptButtonEnabled()
524 const {
525 return true;
526 }
527
528 base::string16
GetAcceptButtonLabel() const529 AuthenticatorTouchIdIncognitoBumpSheetModel::GetAcceptButtonLabel() const {
530 #if defined(OS_MAC)
531 return l10n_util::GetStringUTF16(
532 IDS_WEBAUTHN_TOUCH_ID_INCOGNITO_BUMP_CONTINUE);
533 #else
534 return base::string16();
535 #endif // defined(OS_MAC)
536 }
537
OnAccept()538 void AuthenticatorTouchIdIncognitoBumpSheetModel::OnAccept() {
539 dialog_model()->HideDialogAndTryTouchId();
540 }
541
542 // AuthenticatorPaaskSheetModel -----------------------------------------
543
AuthenticatorPaaskSheetModel(AuthenticatorRequestDialogModel * dialog_model)544 AuthenticatorPaaskSheetModel::AuthenticatorPaaskSheetModel(
545 AuthenticatorRequestDialogModel* dialog_model)
546 : AuthenticatorSheetModelBase(dialog_model),
547 other_transports_menu_model_(std::make_unique<OtherTransportsMenuModel>(
548 dialog_model,
549 AuthenticatorTransport::kCloudAssistedBluetoothLowEnergy)) {}
550
551 AuthenticatorPaaskSheetModel::~AuthenticatorPaaskSheetModel() = default;
552
IsBackButtonVisible() const553 bool AuthenticatorPaaskSheetModel::IsBackButtonVisible() const {
554 #if defined(OS_WIN)
555 return !base::FeatureList::IsEnabled(device::kWebAuthUseNativeWinApi);
556 #else
557 return true;
558 #endif
559 }
560
IsActivityIndicatorVisible() const561 bool AuthenticatorPaaskSheetModel::IsActivityIndicatorVisible() const {
562 return true;
563 }
564
GetStepIllustration(ImageColorScheme color_scheme) const565 const gfx::VectorIcon& AuthenticatorPaaskSheetModel::GetStepIllustration(
566 ImageColorScheme color_scheme) const {
567 return color_scheme == ImageColorScheme::kDark ? kWebauthnPhoneDarkIcon
568 : kWebauthnPhoneIcon;
569 }
570
GetStepTitle() const571 base::string16 AuthenticatorPaaskSheetModel::GetStepTitle() const {
572 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_CABLE_ACTIVATE_TITLE);
573 }
574
GetStepDescription() const575 base::string16 AuthenticatorPaaskSheetModel::GetStepDescription() const {
576 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_CABLE_ACTIVATE_DESCRIPTION);
577 }
578
GetOtherTransportsMenuModel()579 ui::MenuModel* AuthenticatorPaaskSheetModel::GetOtherTransportsMenuModel() {
580 return other_transports_menu_model_.get();
581 }
582
583 // AuthenticatorPaaskV2SheetModel -----------------------------------------
584
AuthenticatorPaaskV2SheetModel(AuthenticatorRequestDialogModel * dialog_model)585 AuthenticatorPaaskV2SheetModel::AuthenticatorPaaskV2SheetModel(
586 AuthenticatorRequestDialogModel* dialog_model)
587 : AuthenticatorSheetModelBase(dialog_model),
588 other_transports_menu_model_(std::make_unique<OtherTransportsMenuModel>(
589 dialog_model,
590 AuthenticatorTransport::kCloudAssistedBluetoothLowEnergy)) {}
591
592 AuthenticatorPaaskV2SheetModel::~AuthenticatorPaaskV2SheetModel() = default;
593
IsBackButtonVisible() const594 bool AuthenticatorPaaskV2SheetModel::IsBackButtonVisible() const {
595 #if defined(OS_WIN)
596 return !base::FeatureList::IsEnabled(device::kWebAuthUseNativeWinApi);
597 #else
598 return true;
599 #endif
600 }
601
IsActivityIndicatorVisible() const602 bool AuthenticatorPaaskV2SheetModel::IsActivityIndicatorVisible() const {
603 return true;
604 }
605
GetStepIllustration(ImageColorScheme color_scheme) const606 const gfx::VectorIcon& AuthenticatorPaaskV2SheetModel::GetStepIllustration(
607 ImageColorScheme color_scheme) const {
608 return color_scheme == ImageColorScheme::kDark ? kWebauthnPhoneDarkIcon
609 : kWebauthnPhoneIcon;
610 }
611
IsAcceptButtonVisible() const612 bool AuthenticatorPaaskV2SheetModel::IsAcceptButtonVisible() const {
613 return true;
614 }
615
IsAcceptButtonEnabled() const616 bool AuthenticatorPaaskV2SheetModel::IsAcceptButtonEnabled() const {
617 return true;
618 }
619
GetAcceptButtonLabel() const620 base::string16 AuthenticatorPaaskV2SheetModel::GetAcceptButtonLabel() const {
621 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_CABLE_QR_TITLE);
622 }
623
OnAccept()624 void AuthenticatorPaaskV2SheetModel::OnAccept() {
625 return dialog_model()->StartPhonePairing();
626 }
627
GetStepTitle() const628 base::string16 AuthenticatorPaaskV2SheetModel::GetStepTitle() const {
629 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_CABLE_V2_ACTIVATE_TITLE);
630 }
631
GetStepDescription() const632 base::string16 AuthenticatorPaaskV2SheetModel::GetStepDescription() const {
633 return l10n_util::GetStringUTF16(
634 IDS_WEBAUTHN_CABLE_V2_ACTIVATE_DESCRIPTION_SHORT);
635 }
636
GetOtherTransportsMenuModel()637 ui::MenuModel* AuthenticatorPaaskV2SheetModel::GetOtherTransportsMenuModel() {
638 return other_transports_menu_model_.get();
639 }
640
641 // AuthenticatorClientPinEntrySheetModel
642 // -----------------------------------------
643
AuthenticatorClientPinEntrySheetModel(AuthenticatorRequestDialogModel * dialog_model,Mode mode)644 AuthenticatorClientPinEntrySheetModel::AuthenticatorClientPinEntrySheetModel(
645 AuthenticatorRequestDialogModel* dialog_model,
646 Mode mode)
647 : AuthenticatorSheetModelBase(dialog_model), mode_(mode) {
648 if (!dialog_model->has_attempted_pin_entry()) {
649 if (dialog_model->uv_attempts() == 0) {
650 error_ = l10n_util::GetStringUTF16(IDS_WEBAUTHN_UV_ERROR_LOCKED);
651 }
652 return;
653 }
654
655 if (mode_ == AuthenticatorClientPinEntrySheetModel::Mode::kPinEntry) {
656 base::Optional<int> attempts = dialog_model->pin_attempts();
657 error_ =
658 attempts && *attempts <= 3
659 ? l10n_util::GetPluralStringFUTF16(
660 IDS_WEBAUTHN_PIN_ENTRY_ERROR_FAILED_RETRIES, *attempts)
661 : l10n_util::GetStringUTF16(IDS_WEBAUTHN_PIN_ENTRY_ERROR_FAILED);
662 return;
663 }
664
665 DCHECK(mode_ == AuthenticatorClientPinEntrySheetModel::Mode::kPinSetup);
666 error_ = l10n_util::GetStringUTF16(IDS_WEBAUTHN_PIN_SETUP_ERROR_FAILED);
667 }
668
669 AuthenticatorClientPinEntrySheetModel::
670 ~AuthenticatorClientPinEntrySheetModel() = default;
671
SetPinCode(base::string16 pin_code)672 void AuthenticatorClientPinEntrySheetModel::SetPinCode(
673 base::string16 pin_code) {
674 pin_code_ = std::move(pin_code);
675 }
676
SetPinConfirmation(base::string16 pin_confirmation)677 void AuthenticatorClientPinEntrySheetModel::SetPinConfirmation(
678 base::string16 pin_confirmation) {
679 DCHECK(mode_ == AuthenticatorClientPinEntrySheetModel::Mode::kPinSetup);
680 pin_confirmation_ = std::move(pin_confirmation);
681 }
682
683 const gfx::VectorIcon&
GetStepIllustration(ImageColorScheme color_scheme) const684 AuthenticatorClientPinEntrySheetModel::GetStepIllustration(
685 ImageColorScheme color_scheme) const {
686 return color_scheme == ImageColorScheme::kDark ? kWebauthnUsbDarkIcon
687 : kWebauthnUsbIcon;
688 }
689
GetStepTitle() const690 base::string16 AuthenticatorClientPinEntrySheetModel::GetStepTitle() const {
691 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_PIN_ENTRY_TITLE);
692 }
693
GetStepDescription() const694 base::string16 AuthenticatorClientPinEntrySheetModel::GetStepDescription()
695 const {
696 return l10n_util::GetStringUTF16(
697 mode_ == AuthenticatorClientPinEntrySheetModel::Mode::kPinEntry
698 ? IDS_WEBAUTHN_PIN_ENTRY_DESCRIPTION
699 : IDS_WEBAUTHN_PIN_SETUP_DESCRIPTION);
700 }
701
GetError() const702 base::string16 AuthenticatorClientPinEntrySheetModel::GetError() const {
703 return error_;
704 }
705
IsAcceptButtonVisible() const706 bool AuthenticatorClientPinEntrySheetModel::IsAcceptButtonVisible() const {
707 return true;
708 }
709
IsAcceptButtonEnabled() const710 bool AuthenticatorClientPinEntrySheetModel::IsAcceptButtonEnabled() const {
711 return true;
712 }
713
GetAcceptButtonLabel() const714 base::string16 AuthenticatorClientPinEntrySheetModel::GetAcceptButtonLabel()
715 const {
716 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_PIN_ENTRY_NEXT);
717 }
718
IsValidUTF16(const base::string16 & str16)719 static bool IsValidUTF16(const base::string16& str16) {
720 std::string unused_str8;
721 return base::UTF16ToUTF8(str16.c_str(), str16.size(), &unused_str8);
722 }
723
OnAccept()724 void AuthenticatorClientPinEntrySheetModel::OnAccept() {
725 // TODO(martinkr): use device::pin::kMinLength once landed.
726 constexpr size_t kMinPinLength = 4;
727 if (mode_ == AuthenticatorClientPinEntrySheetModel::Mode::kPinSetup) {
728 // Validate a new PIN.
729 base::Optional<base::string16> error;
730 if (!pin_code_.empty() && !IsValidUTF16(pin_code_)) {
731 error = l10n_util::GetStringUTF16(
732 IDS_WEBAUTHN_PIN_ENTRY_ERROR_INVALID_CHARACTERS);
733 } else if (pin_code_.size() < kMinPinLength) {
734 error = l10n_util::GetStringUTF16(IDS_WEBAUTHN_PIN_ENTRY_ERROR_TOO_SHORT);
735 } else if (pin_code_ != pin_confirmation_) {
736 error = l10n_util::GetStringUTF16(IDS_WEBAUTHN_PIN_ENTRY_ERROR_MISMATCH);
737 }
738 if (error) {
739 error_ = *error;
740 dialog_model()->OnSheetModelDidChange();
741 return;
742 }
743 } else {
744 // Submit PIN to authenticator for verification.
745 DCHECK(mode_ == AuthenticatorClientPinEntrySheetModel::Mode::kPinEntry);
746 // TODO: use device::pin::IsValid instead.
747 if (pin_code_.size() < kMinPinLength) {
748 error_ =
749 l10n_util::GetStringUTF16(IDS_WEBAUTHN_PIN_ENTRY_ERROR_TOO_SHORT);
750 dialog_model()->OnSheetModelDidChange();
751 return;
752 }
753 }
754
755 if (dialog_model()) {
756 dialog_model()->OnHavePIN(base::UTF16ToUTF8(pin_code_));
757 }
758 }
759
760 // AuthenticatorClientPinTapAgainSheetModel ----------------------
761
762 AuthenticatorClientPinTapAgainSheetModel::
AuthenticatorClientPinTapAgainSheetModel(AuthenticatorRequestDialogModel * dialog_model)763 AuthenticatorClientPinTapAgainSheetModel(
764 AuthenticatorRequestDialogModel* dialog_model)
765 : AuthenticatorSheetModelBase(dialog_model) {}
766
767 AuthenticatorClientPinTapAgainSheetModel::
768 ~AuthenticatorClientPinTapAgainSheetModel() = default;
769
IsActivityIndicatorVisible() const770 bool AuthenticatorClientPinTapAgainSheetModel::IsActivityIndicatorVisible()
771 const {
772 return true;
773 }
774
775 const gfx::VectorIcon&
GetStepIllustration(ImageColorScheme color_scheme) const776 AuthenticatorClientPinTapAgainSheetModel::GetStepIllustration(
777 ImageColorScheme color_scheme) const {
778 return color_scheme == ImageColorScheme::kDark ? kWebauthnUsbDarkIcon
779 : kWebauthnUsbIcon;
780 }
781
GetStepTitle() const782 base::string16 AuthenticatorClientPinTapAgainSheetModel::GetStepTitle() const {
783 return l10n_util::GetStringFUTF16(IDS_WEBAUTHN_GENERIC_TITLE,
784 GetRelyingPartyIdString(dialog_model()));
785 }
786
GetStepDescription() const787 base::string16 AuthenticatorClientPinTapAgainSheetModel::GetStepDescription()
788 const {
789 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_PIN_TAP_AGAIN_DESCRIPTION);
790 }
791
792 base::string16
GetAdditionalDescription() const793 AuthenticatorClientPinTapAgainSheetModel::GetAdditionalDescription() const {
794 return PossibleResidentKeyWarning(dialog_model());
795 }
796
797 // AuthenticatorBioEnrollmentSheetModel ----------------------------------
798
AuthenticatorBioEnrollmentSheetModel(AuthenticatorRequestDialogModel * dialog_model)799 AuthenticatorBioEnrollmentSheetModel::AuthenticatorBioEnrollmentSheetModel(
800 AuthenticatorRequestDialogModel* dialog_model)
801 : AuthenticatorSheetModelBase(dialog_model) {}
802
803 AuthenticatorBioEnrollmentSheetModel::~AuthenticatorBioEnrollmentSheetModel() =
804 default;
805
IsActivityIndicatorVisible() const806 bool AuthenticatorBioEnrollmentSheetModel::IsActivityIndicatorVisible() const {
807 return !IsAcceptButtonVisible();
808 }
809
810 const gfx::VectorIcon&
GetStepIllustration(ImageColorScheme color_scheme) const811 AuthenticatorBioEnrollmentSheetModel::GetStepIllustration(
812 ImageColorScheme color_scheme) const {
813 return color_scheme == ImageColorScheme::kDark ? kWebauthnFingerprintDarkIcon
814 : kWebauthnFingerprintIcon;
815 }
816
GetStepTitle() const817 base::string16 AuthenticatorBioEnrollmentSheetModel::GetStepTitle() const {
818 return l10n_util::GetStringUTF16(
819 IDS_SETTINGS_SECURITY_KEYS_BIO_ENROLLMENT_ADD_TITLE);
820 }
821
GetStepDescription() const822 base::string16 AuthenticatorBioEnrollmentSheetModel::GetStepDescription()
823 const {
824 return IsAcceptButtonVisible()
825 ? l10n_util::GetStringUTF16(
826 IDS_SETTINGS_SECURITY_KEYS_BIO_ENROLLMENT_ENROLLING_COMPLETE_LABEL)
827 : l10n_util::GetStringUTF16(
828 IDS_SETTINGS_SECURITY_KEYS_BIO_ENROLLMENT_ENROLLING_LABEL);
829 }
830
IsAcceptButtonEnabled() const831 bool AuthenticatorBioEnrollmentSheetModel::IsAcceptButtonEnabled() const {
832 return true;
833 }
834
IsAcceptButtonVisible() const835 bool AuthenticatorBioEnrollmentSheetModel::IsAcceptButtonVisible() const {
836 return dialog_model()->bio_samples_remaining() &&
837 dialog_model()->bio_samples_remaining() <= 0;
838 }
839
GetAcceptButtonLabel() const840 base::string16 AuthenticatorBioEnrollmentSheetModel::GetAcceptButtonLabel()
841 const {
842 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_PIN_ENTRY_NEXT);
843 }
844
IsCancelButtonVisible() const845 bool AuthenticatorBioEnrollmentSheetModel::IsCancelButtonVisible() const {
846 return !IsAcceptButtonVisible();
847 }
848
GetCancelButtonLabel() const849 base::string16 AuthenticatorBioEnrollmentSheetModel::GetCancelButtonLabel()
850 const {
851 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_INLINE_ENROLLMENT_CANCEL_LABEL);
852 }
853
OnAccept()854 void AuthenticatorBioEnrollmentSheetModel::OnAccept() {
855 dialog_model()->OnBioEnrollmentDone();
856 }
857
OnCancel()858 void AuthenticatorBioEnrollmentSheetModel::OnCancel() {
859 OnAccept();
860 }
861
862 // AuthenticatorRetryUvSheetModel -------------------------------------
863
AuthenticatorRetryUvSheetModel(AuthenticatorRequestDialogModel * dialog_model)864 AuthenticatorRetryUvSheetModel::AuthenticatorRetryUvSheetModel(
865 AuthenticatorRequestDialogModel* dialog_model)
866 : AuthenticatorSheetModelBase(dialog_model) {}
867
868 AuthenticatorRetryUvSheetModel::~AuthenticatorRetryUvSheetModel() = default;
869
IsActivityIndicatorVisible() const870 bool AuthenticatorRetryUvSheetModel::IsActivityIndicatorVisible() const {
871 return true;
872 }
873
GetStepIllustration(ImageColorScheme color_scheme) const874 const gfx::VectorIcon& AuthenticatorRetryUvSheetModel::GetStepIllustration(
875 ImageColorScheme color_scheme) const {
876 return color_scheme == ImageColorScheme::kDark ? kWebauthnFingerprintDarkIcon
877 : kWebauthnFingerprintIcon;
878 }
879
GetStepTitle() const880 base::string16 AuthenticatorRetryUvSheetModel::GetStepTitle() const {
881 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_UV_RETRY_TITLE);
882 }
883
GetStepDescription() const884 base::string16 AuthenticatorRetryUvSheetModel::GetStepDescription() const {
885 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_UV_RETRY_DESCRIPTION);
886 }
887
GetError() const888 base::string16 AuthenticatorRetryUvSheetModel::GetError() const {
889 int attempts = *dialog_model()->uv_attempts();
890 if (attempts > 3) {
891 return base::string16();
892 }
893 return l10n_util::GetPluralStringFUTF16(
894 IDS_WEBAUTHN_UV_RETRY_ERROR_FAILED_RETRIES, attempts);
895 }
896
897 // AuthenticatorGenericErrorSheetModel -----------------------------------
898
899 // static
900 std::unique_ptr<AuthenticatorGenericErrorSheetModel>
ForClientPinErrorSoftBlock(AuthenticatorRequestDialogModel * dialog_model)901 AuthenticatorGenericErrorSheetModel::ForClientPinErrorSoftBlock(
902 AuthenticatorRequestDialogModel* dialog_model) {
903 return base::WrapUnique(new AuthenticatorGenericErrorSheetModel(
904 dialog_model, l10n_util::GetStringUTF16(IDS_WEBAUTHN_ERROR_GENERIC_TITLE),
905 l10n_util::GetStringUTF16(
906 IDS_WEBAUTHN_CLIENT_PIN_SOFT_BLOCK_DESCRIPTION)));
907 }
908
909 // static
910 std::unique_ptr<AuthenticatorGenericErrorSheetModel>
ForClientPinErrorHardBlock(AuthenticatorRequestDialogModel * dialog_model)911 AuthenticatorGenericErrorSheetModel::ForClientPinErrorHardBlock(
912 AuthenticatorRequestDialogModel* dialog_model) {
913 return base::WrapUnique(new AuthenticatorGenericErrorSheetModel(
914 dialog_model, l10n_util::GetStringUTF16(IDS_WEBAUTHN_ERROR_GENERIC_TITLE),
915 l10n_util::GetStringUTF16(
916 IDS_WEBAUTHN_CLIENT_PIN_HARD_BLOCK_DESCRIPTION)));
917 }
918
919 // static
920 std::unique_ptr<AuthenticatorGenericErrorSheetModel>
ForClientPinErrorAuthenticatorRemoved(AuthenticatorRequestDialogModel * dialog_model)921 AuthenticatorGenericErrorSheetModel::ForClientPinErrorAuthenticatorRemoved(
922 AuthenticatorRequestDialogModel* dialog_model) {
923 return base::WrapUnique(new AuthenticatorGenericErrorSheetModel(
924 dialog_model, l10n_util::GetStringUTF16(IDS_WEBAUTHN_ERROR_GENERIC_TITLE),
925 l10n_util::GetStringUTF16(
926 IDS_WEBAUTHN_CLIENT_PIN_AUTHENTICATOR_REMOVED_DESCRIPTION)));
927 }
928
929 // static
930 std::unique_ptr<AuthenticatorGenericErrorSheetModel>
ForMissingCapability(AuthenticatorRequestDialogModel * dialog_model)931 AuthenticatorGenericErrorSheetModel::ForMissingCapability(
932 AuthenticatorRequestDialogModel* dialog_model) {
933 return base::WrapUnique(new AuthenticatorGenericErrorSheetModel(
934 dialog_model,
935 l10n_util::GetStringUTF16(IDS_WEBAUTHN_ERROR_MISSING_CAPABILITY_TITLE),
936 l10n_util::GetStringFUTF16(IDS_WEBAUTHN_ERROR_MISSING_CAPABILITY_DESC,
937 GetRelyingPartyIdString(dialog_model))));
938 }
939
940 // static
941 std::unique_ptr<AuthenticatorGenericErrorSheetModel>
ForStorageFull(AuthenticatorRequestDialogModel * dialog_model)942 AuthenticatorGenericErrorSheetModel::ForStorageFull(
943 AuthenticatorRequestDialogModel* dialog_model) {
944 return base::WrapUnique(new AuthenticatorGenericErrorSheetModel(
945 dialog_model,
946 l10n_util::GetStringUTF16(IDS_WEBAUTHN_ERROR_MISSING_CAPABILITY_TITLE),
947 l10n_util::GetStringUTF16(IDS_WEBAUTHN_STORAGE_FULL_DESC)));
948 }
949
AuthenticatorGenericErrorSheetModel(AuthenticatorRequestDialogModel * dialog_model,base::string16 title,base::string16 description)950 AuthenticatorGenericErrorSheetModel::AuthenticatorGenericErrorSheetModel(
951 AuthenticatorRequestDialogModel* dialog_model,
952 base::string16 title,
953 base::string16 description)
954 : AuthenticatorSheetModelBase(dialog_model),
955 title_(std::move(title)),
956 description_(std::move(description)) {}
957
IsBackButtonVisible() const958 bool AuthenticatorGenericErrorSheetModel::IsBackButtonVisible() const {
959 return false;
960 }
961
GetCancelButtonLabel() const962 base::string16 AuthenticatorGenericErrorSheetModel::GetCancelButtonLabel()
963 const {
964 return l10n_util::GetStringUTF16(IDS_CLOSE);
965 }
966
GetStepIllustration(ImageColorScheme color_scheme) const967 const gfx::VectorIcon& AuthenticatorGenericErrorSheetModel::GetStepIllustration(
968 ImageColorScheme color_scheme) const {
969 return color_scheme == ImageColorScheme::kDark ? kWebauthnErrorDarkIcon
970 : kWebauthnErrorIcon;
971 }
972
GetStepTitle() const973 base::string16 AuthenticatorGenericErrorSheetModel::GetStepTitle() const {
974 return title_;
975 }
976
GetStepDescription() const977 base::string16 AuthenticatorGenericErrorSheetModel::GetStepDescription() const {
978 return description_;
979 }
980
981 // AuthenticatorResidentCredentialConfirmationSheetView -----------------------
982
983 AuthenticatorResidentCredentialConfirmationSheetView::
AuthenticatorResidentCredentialConfirmationSheetView(AuthenticatorRequestDialogModel * dialog_model)984 AuthenticatorResidentCredentialConfirmationSheetView(
985 AuthenticatorRequestDialogModel* dialog_model)
986 : AuthenticatorSheetModelBase(dialog_model) {}
987
988 AuthenticatorResidentCredentialConfirmationSheetView::
989 ~AuthenticatorResidentCredentialConfirmationSheetView() = default;
990
991 const gfx::VectorIcon&
GetStepIllustration(ImageColorScheme color_scheme) const992 AuthenticatorResidentCredentialConfirmationSheetView::GetStepIllustration(
993 ImageColorScheme color_scheme) const {
994 return color_scheme == ImageColorScheme::kDark ? kWebauthnPermissionDarkIcon
995 : kWebauthnPermissionIcon;
996 }
997
IsBackButtonVisible() const998 bool AuthenticatorResidentCredentialConfirmationSheetView::IsBackButtonVisible()
999 const {
1000 return false;
1001 }
1002
1003 bool AuthenticatorResidentCredentialConfirmationSheetView::
IsAcceptButtonVisible() const1004 IsAcceptButtonVisible() const {
1005 return true;
1006 }
1007
1008 bool AuthenticatorResidentCredentialConfirmationSheetView::
IsAcceptButtonEnabled() const1009 IsAcceptButtonEnabled() const {
1010 return true;
1011 }
1012
1013 base::string16
GetAcceptButtonLabel() const1014 AuthenticatorResidentCredentialConfirmationSheetView::GetAcceptButtonLabel()
1015 const {
1016 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_WELCOME_SCREEN_NEXT);
1017 }
1018
1019 base::string16
GetStepTitle() const1020 AuthenticatorResidentCredentialConfirmationSheetView::GetStepTitle() const {
1021 return l10n_util::GetStringFUTF16(IDS_WEBAUTHN_GENERIC_TITLE,
1022 GetRelyingPartyIdString(dialog_model()));
1023 }
1024
1025 base::string16
GetStepDescription() const1026 AuthenticatorResidentCredentialConfirmationSheetView::GetStepDescription()
1027 const {
1028 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_RESIDENT_KEY_PRIVACY);
1029 }
1030
OnAccept()1031 void AuthenticatorResidentCredentialConfirmationSheetView::OnAccept() {
1032 dialog_model()->OnResidentCredentialConfirmed();
1033 }
1034
1035 // AuthenticatorSelectAccountSheetModel ---------------------------------------
1036
AuthenticatorSelectAccountSheetModel(AuthenticatorRequestDialogModel * dialog_model)1037 AuthenticatorSelectAccountSheetModel::AuthenticatorSelectAccountSheetModel(
1038 AuthenticatorRequestDialogModel* dialog_model)
1039 : AuthenticatorSheetModelBase(dialog_model) {}
1040
1041 AuthenticatorSelectAccountSheetModel::~AuthenticatorSelectAccountSheetModel() =
1042 default;
1043
SetCurrentSelection(int selected)1044 void AuthenticatorSelectAccountSheetModel::SetCurrentSelection(int selected) {
1045 DCHECK_LE(0, selected);
1046 DCHECK_LT(static_cast<size_t>(selected), dialog_model()->responses().size());
1047 selected_ = selected;
1048 }
1049
OnAccept()1050 void AuthenticatorSelectAccountSheetModel::OnAccept() {
1051 dialog_model()->OnAccountSelected(selected_);
1052 }
1053
1054 const gfx::VectorIcon&
GetStepIllustration(ImageColorScheme color_scheme) const1055 AuthenticatorSelectAccountSheetModel::GetStepIllustration(
1056 ImageColorScheme color_scheme) const {
1057 // TODO: this is likely the wrong image.
1058 return color_scheme == ImageColorScheme::kDark ? kWebauthnWelcomeDarkIcon
1059 : kWebauthnWelcomeIcon;
1060 }
1061
GetStepTitle() const1062 base::string16 AuthenticatorSelectAccountSheetModel::GetStepTitle() const {
1063 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_SELECT_ACCOUNT);
1064 }
1065
GetStepDescription() const1066 base::string16 AuthenticatorSelectAccountSheetModel::GetStepDescription()
1067 const {
1068 return base::string16();
1069 }
1070
IsAcceptButtonVisible() const1071 bool AuthenticatorSelectAccountSheetModel::IsAcceptButtonVisible() const {
1072 return false;
1073 }
1074
IsAcceptButtonEnabled() const1075 bool AuthenticatorSelectAccountSheetModel::IsAcceptButtonEnabled() const {
1076 return false;
1077 }
1078
GetAcceptButtonLabel() const1079 base::string16 AuthenticatorSelectAccountSheetModel::GetAcceptButtonLabel()
1080 const {
1081 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_WELCOME_SCREEN_NEXT);
1082 }
1083
1084 // AttestationPermissionRequestSheetModel -------------------------------------
1085
AttestationPermissionRequestSheetModel(AuthenticatorRequestDialogModel * dialog_model)1086 AttestationPermissionRequestSheetModel::AttestationPermissionRequestSheetModel(
1087 AuthenticatorRequestDialogModel* dialog_model)
1088 : AuthenticatorSheetModelBase(dialog_model) {}
1089
1090 AttestationPermissionRequestSheetModel::
1091 ~AttestationPermissionRequestSheetModel() = default;
1092
OnAccept()1093 void AttestationPermissionRequestSheetModel::OnAccept() {
1094 dialog_model()->OnAttestationPermissionResponse(true);
1095 }
1096
OnCancel()1097 void AttestationPermissionRequestSheetModel::OnCancel() {
1098 dialog_model()->OnAttestationPermissionResponse(false);
1099 }
1100
1101 const gfx::VectorIcon&
GetStepIllustration(ImageColorScheme color_scheme) const1102 AttestationPermissionRequestSheetModel::GetStepIllustration(
1103 ImageColorScheme color_scheme) const {
1104 return color_scheme == ImageColorScheme::kDark ? kWebauthnPermissionDarkIcon
1105 : kWebauthnPermissionIcon;
1106 }
1107
GetStepTitle() const1108 base::string16 AttestationPermissionRequestSheetModel::GetStepTitle() const {
1109 return l10n_util::GetStringUTF16(
1110 IDS_WEBAUTHN_REQUEST_ATTESTATION_PERMISSION_TITLE);
1111 }
1112
GetStepDescription() const1113 base::string16 AttestationPermissionRequestSheetModel::GetStepDescription()
1114 const {
1115 return l10n_util::GetStringFUTF16(
1116 IDS_WEBAUTHN_REQUEST_ATTESTATION_PERMISSION_DESC,
1117 GetRelyingPartyIdString(dialog_model()));
1118 }
1119
IsBackButtonVisible() const1120 bool AttestationPermissionRequestSheetModel::IsBackButtonVisible() const {
1121 return false;
1122 }
1123
IsAcceptButtonVisible() const1124 bool AttestationPermissionRequestSheetModel::IsAcceptButtonVisible() const {
1125 return true;
1126 }
1127
IsAcceptButtonEnabled() const1128 bool AttestationPermissionRequestSheetModel::IsAcceptButtonEnabled() const {
1129 return true;
1130 }
1131
GetAcceptButtonLabel() const1132 base::string16 AttestationPermissionRequestSheetModel::GetAcceptButtonLabel()
1133 const {
1134 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_ALLOW_ATTESTATION);
1135 }
1136
IsCancelButtonVisible() const1137 bool AttestationPermissionRequestSheetModel::IsCancelButtonVisible() const {
1138 return true;
1139 }
1140
GetCancelButtonLabel() const1141 base::string16 AttestationPermissionRequestSheetModel::GetCancelButtonLabel()
1142 const {
1143 // TODO(martinkr): This should be its own string definition; but we had to
1144 // make a change post string freeze and therefore reused this.
1145 return l10n_util::GetStringUTF16(IDS_PERMISSION_DENY);
1146 }
1147
1148 // AuthenticatorQRSheetModel --------------------------------------------------
1149
AuthenticatorQRSheetModel(AuthenticatorRequestDialogModel * dialog_model)1150 AuthenticatorQRSheetModel::AuthenticatorQRSheetModel(
1151 AuthenticatorRequestDialogModel* dialog_model)
1152 : AuthenticatorSheetModelBase(dialog_model) {}
1153
1154 AuthenticatorQRSheetModel::~AuthenticatorQRSheetModel() = default;
1155
GetStepIllustration(ImageColorScheme color_scheme) const1156 const gfx::VectorIcon& AuthenticatorQRSheetModel::GetStepIllustration(
1157 ImageColorScheme color_scheme) const {
1158 return color_scheme == ImageColorScheme::kDark ? kWebauthnPhoneDarkIcon
1159 : kWebauthnPhoneIcon;
1160 }
1161
GetStepTitle() const1162 base::string16 AuthenticatorQRSheetModel::GetStepTitle() const {
1163 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_CABLE_QR_TITLE);
1164 }
1165
GetStepDescription() const1166 base::string16 AuthenticatorQRSheetModel::GetStepDescription() const {
1167 return l10n_util::GetStringUTF16(IDS_WEBAUTHN_CABLE_QR_DESCRIPTION);
1168 }
1169