mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 07:28:10 +00:00
feat(core): make first steps to unify Rust API for both models
wip: unify confirm_action wip: unify confirm_fido wip: unify request_pin, clean up prompts wip: unify select_word wip: unify request_number refactor(core/reset): refactor confirm_share_words [no changelog]
This commit is contained in:
parent
c068c668fa
commit
497285f9a1
@ -108,4 +108,5 @@ static void _librust_qstrs(void) {
|
||||
MP_QSTR_notification_level;
|
||||
MP_QSTR_bootscreen;
|
||||
MP_QSTR_skip_first_paint;
|
||||
MP_QSTR_wrong_pin;
|
||||
}
|
||||
|
@ -128,7 +128,8 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
||||
/// description: str | None = None,
|
||||
/// verb: str | None = None,
|
||||
/// verb_cancel: str | None = None,
|
||||
/// hold: bool | None = None,
|
||||
/// hold: bool = False,
|
||||
/// hold_danger: bool = False, # unused on TR
|
||||
/// reverse: bool = False,
|
||||
/// ) -> object:
|
||||
/// """Confirm action."""
|
||||
|
@ -914,7 +914,12 @@ extern "C" fn new_request_pin(n_args: usize, args: *const Obj, kwargs: *mut Map)
|
||||
let prompt: StrBuffer = kwargs.get(Qstr::MP_QSTR_prompt)?.try_into()?;
|
||||
let subprompt: StrBuffer = kwargs.get(Qstr::MP_QSTR_subprompt)?.try_into()?;
|
||||
let allow_cancel: bool = kwargs.get_or(Qstr::MP_QSTR_allow_cancel, true)?;
|
||||
let warning: Option<StrBuffer> = kwargs.get(Qstr::MP_QSTR_warning)?.try_into_option()?;
|
||||
let warning: bool = kwargs.get_or(Qstr::MP_QSTR_wrong_pin, false)?;
|
||||
let warning = if warning {
|
||||
Some("Wrong PIN".into())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let obj = LayoutObj::new(PinKeyboard::new(prompt, subprompt, warning, allow_cancel))?;
|
||||
Ok(obj.into())
|
||||
};
|
||||
@ -999,6 +1004,7 @@ extern "C" fn new_request_number(n_args: usize, args: *const Obj, kwargs: *mut M
|
||||
let max_count: u32 = kwargs.get(Qstr::MP_QSTR_max_count)?.try_into()?;
|
||||
let count: u32 = kwargs.get(Qstr::MP_QSTR_count)?.try_into()?;
|
||||
let description_callback: Obj = kwargs.get(Qstr::MP_QSTR_description)?;
|
||||
assert!(description_callback != Obj::const_none());
|
||||
|
||||
let callback = move |i: u32| {
|
||||
StrBuffer::try_from(
|
||||
@ -1485,7 +1491,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
||||
/// prompt: str,
|
||||
/// subprompt: str,
|
||||
/// allow_cancel: bool = True,
|
||||
/// warning: str | None = None,
|
||||
/// wrong_pin: bool = False,
|
||||
/// ) -> str | object:
|
||||
/// """Request pin on device."""
|
||||
Qstr::MP_QSTR_request_pin => obj_fn_kw!(0, new_request_pin).as_obj(),
|
||||
@ -1536,7 +1542,7 @@ pub static mp_module_trezorui2: Module = obj_module! {
|
||||
/// count: int,
|
||||
/// min_count: int,
|
||||
/// max_count: int,
|
||||
/// description: Callable[[int], str],
|
||||
/// description: Callable[[int], str] | None = None,
|
||||
/// ) -> object:
|
||||
/// """Number input with + and - buttons, description, and info button."""
|
||||
Qstr::MP_QSTR_request_number => obj_fn_kw!(0, new_request_number).as_obj(),
|
||||
|
@ -47,7 +47,8 @@ def confirm_action(
|
||||
description: str | None = None,
|
||||
verb: str | None = None,
|
||||
verb_cancel: str | None = None,
|
||||
hold: bool | None = None,
|
||||
hold: bool = False,
|
||||
hold_danger: bool = False, # unused on TR
|
||||
reverse: bool = False,
|
||||
) -> object:
|
||||
"""Confirm action."""
|
||||
@ -281,7 +282,7 @@ def request_pin(
|
||||
prompt: str,
|
||||
subprompt: str,
|
||||
allow_cancel: bool = True,
|
||||
warning: str | None = None,
|
||||
wrong_pin: bool = False,
|
||||
) -> str | object:
|
||||
"""Request pin on device."""
|
||||
|
||||
@ -338,7 +339,7 @@ def request_number(
|
||||
count: int,
|
||||
min_count: int,
|
||||
max_count: int,
|
||||
description: Callable[[int], str],
|
||||
description: Callable[[int], str] | None = None,
|
||||
) -> object:
|
||||
"""Number input with + and - buttons, description, and info button."""
|
||||
|
||||
|
@ -20,7 +20,7 @@ def can_lock_device() -> bool:
|
||||
|
||||
async def request_pin(
|
||||
ctx: GenericContext,
|
||||
prompt: str = "Enter your PIN",
|
||||
prompt: str,
|
||||
attempts_remaining: int | None = None,
|
||||
allow_cancel: bool = True,
|
||||
) -> str:
|
||||
@ -48,7 +48,7 @@ async def _pin_mismatch() -> None:
|
||||
|
||||
|
||||
async def request_pin_and_sd_salt(
|
||||
ctx: Context, prompt: str = "Enter your PIN", allow_cancel: bool = True
|
||||
ctx: Context, prompt: str, allow_cancel: bool = True
|
||||
) -> tuple[str, bytearray | None]:
|
||||
if config.has_pin():
|
||||
pin = await request_pin(ctx, prompt, config.get_pin_rem(), allow_cancel)
|
||||
@ -68,7 +68,7 @@ def _set_last_unlock_time() -> None:
|
||||
|
||||
async def verify_user_pin(
|
||||
ctx: GenericContext = wire.DUMMY_CONTEXT,
|
||||
prompt: str = "Enter your PIN",
|
||||
prompt: str = "Enter PIN",
|
||||
allow_cancel: bool = True,
|
||||
retry: bool = True,
|
||||
cache_time_ms: int = 0,
|
||||
@ -110,7 +110,7 @@ async def verify_user_pin(
|
||||
|
||||
while retry:
|
||||
pin = await request_pin_on_device( # type: ignore ["request_pin_on_device" is possibly unbound]
|
||||
ctx, "Wrong PIN, enter again", config.get_pin_rem(), allow_cancel
|
||||
ctx, "Enter PIN", config.get_pin_rem(), allow_cancel, wrong_pin=True
|
||||
)
|
||||
if config.unlock(pin, salt):
|
||||
_set_last_unlock_time()
|
||||
|
@ -26,7 +26,7 @@ async def change_wipe_code(ctx: Context, msg: ChangeWipeCode) -> Success:
|
||||
await _require_confirm_action(ctx, msg, has_wipe_code)
|
||||
|
||||
# Get the unlocking PIN.
|
||||
pin, salt = await request_pin_and_sd_salt(ctx)
|
||||
pin, salt = await request_pin_and_sd_salt(ctx, "Enter PIN")
|
||||
|
||||
if not msg.remove:
|
||||
# Pre-check the entered PIN.
|
||||
|
@ -69,7 +69,36 @@ async def _confirm_word(
|
||||
return selected_word == checked_word
|
||||
|
||||
|
||||
async def _confirm_share_words(
|
||||
async def _share_words_confirmed(
|
||||
ctx: GenericContext,
|
||||
share_index: int | None,
|
||||
share_words: Sequence[str],
|
||||
num_of_shares: int | None = None,
|
||||
group_index: int | None = None,
|
||||
) -> bool:
|
||||
"""Shows initial dialog asking the user to select words, then presents
|
||||
word selectors. Shows success popup if the user is done, failure if the confirmation
|
||||
went wrong.
|
||||
|
||||
Return true if the words are confirmed successfully.
|
||||
"""
|
||||
# TODO: confirm_action("Select the words bla bla")
|
||||
|
||||
if await _do_confirm_share_words(ctx, share_index, share_words, group_index):
|
||||
await _show_confirmation_success(
|
||||
ctx,
|
||||
share_index,
|
||||
num_of_shares,
|
||||
group_index,
|
||||
)
|
||||
return True
|
||||
else:
|
||||
await _show_confirmation_failure(ctx)
|
||||
|
||||
return False
|
||||
|
||||
|
||||
async def _do_confirm_share_words(
|
||||
ctx: GenericContext,
|
||||
share_index: int | None,
|
||||
share_words: Sequence[str],
|
||||
@ -119,9 +148,7 @@ async def _show_confirmation_success(
|
||||
return await show_success(ctx, "success_recovery", text, subheader)
|
||||
|
||||
|
||||
async def _show_confirmation_failure(
|
||||
ctx: GenericContext, share_index: int | None
|
||||
) -> None:
|
||||
async def _show_confirmation_failure(ctx: GenericContext) -> None:
|
||||
from trezor.ui.layouts import show_warning
|
||||
|
||||
await show_warning(
|
||||
@ -160,11 +187,8 @@ async def bip39_show_and_confirm_mnemonic(ctx: GenericContext, mnemonic: str) ->
|
||||
await show_share_words(ctx, words)
|
||||
|
||||
# make the user confirm some words from the mnemonic
|
||||
if await _confirm_share_words(ctx, None, words):
|
||||
await _show_confirmation_success(ctx)
|
||||
if await _share_words_confirmed(ctx, None, words):
|
||||
break # this share is confirmed, go to next one
|
||||
else:
|
||||
await _show_confirmation_failure(ctx, None)
|
||||
|
||||
|
||||
# SLIP39
|
||||
@ -184,11 +208,8 @@ async def slip39_basic_show_and_confirm_shares(
|
||||
await show_share_words(ctx, share_words, index)
|
||||
|
||||
# make the user confirm words from the share
|
||||
if await _confirm_share_words(ctx, index, share_words):
|
||||
await _show_confirmation_success(ctx, index, len(shares))
|
||||
if await _share_words_confirmed(ctx, index, share_words, len(shares)):
|
||||
break # this share is confirmed, go to next one
|
||||
else:
|
||||
await _show_confirmation_failure(ctx, index)
|
||||
|
||||
|
||||
async def slip39_advanced_show_and_confirm_shares(
|
||||
@ -205,15 +226,7 @@ async def slip39_advanced_show_and_confirm_shares(
|
||||
await show_share_words(ctx, share_words, share_index, group_index)
|
||||
|
||||
# make the user confirm words from the share
|
||||
if await _confirm_share_words(
|
||||
ctx, share_index, share_words, group_index
|
||||
if await _share_words_confirmed(
|
||||
ctx, share_index, share_words, len(group), group_index
|
||||
):
|
||||
await _show_confirmation_success(
|
||||
ctx,
|
||||
share_index,
|
||||
len(group),
|
||||
group_index,
|
||||
)
|
||||
break # this share is confirmed, go to next one
|
||||
else:
|
||||
await _show_confirmation_failure(ctx, share_index)
|
||||
|
@ -65,15 +65,15 @@ async def confirm_action(
|
||||
description: str | None = None,
|
||||
description_param: str | None = None,
|
||||
description_param_font: int = ui.BOLD,
|
||||
verb: str | bytes | None = "OK",
|
||||
verb_cancel: str | bytes | None = "cancel",
|
||||
verb: str = "CONFIRM",
|
||||
verb_cancel: str | None = None,
|
||||
hold: bool = False,
|
||||
reverse: bool = False,
|
||||
exc: ExceptionType = wire.ActionCancelled,
|
||||
br_code: ButtonRequestType = ButtonRequestType.Other,
|
||||
) -> None:
|
||||
if isinstance(verb, bytes) or isinstance(verb_cancel, bytes):
|
||||
raise NotImplementedError
|
||||
if verb_cancel is not None:
|
||||
verb_cancel = verb_cancel.upper()
|
||||
|
||||
if description is not None and description_param is not None:
|
||||
if description_param_font != ui.BOLD:
|
||||
|
@ -211,19 +211,15 @@ async def confirm_action(
|
||||
description: str | None = None,
|
||||
description_param: str | None = None,
|
||||
description_param_font: int = ui.BOLD,
|
||||
verb: str | bytes | None = "CONFIRM",
|
||||
verb_cancel: str | bytes | None = None,
|
||||
verb: str = "CONFIRM",
|
||||
verb_cancel: str | None = None,
|
||||
hold: bool = False,
|
||||
hold_danger: bool = False,
|
||||
reverse: bool = False,
|
||||
exc: ExceptionType = ActionCancelled,
|
||||
br_code: ButtonRequestType = BR_TYPE_OTHER,
|
||||
) -> None:
|
||||
if isinstance(verb, bytes) or isinstance(verb_cancel, bytes):
|
||||
raise NotImplementedError
|
||||
if isinstance(verb, str):
|
||||
verb = verb.upper()
|
||||
if isinstance(verb_cancel, str):
|
||||
if verb_cancel is not None:
|
||||
verb_cancel = verb_cancel.upper()
|
||||
|
||||
if description is not None and description_param is not None:
|
||||
@ -239,7 +235,7 @@ async def confirm_action(
|
||||
title=title.upper(),
|
||||
action=action,
|
||||
description=description,
|
||||
verb=verb,
|
||||
verb=verb.upper(),
|
||||
verb_cancel=verb_cancel,
|
||||
hold=hold,
|
||||
hold_danger=hold_danger,
|
||||
@ -1087,20 +1083,17 @@ async def request_pin_on_device(
|
||||
prompt: str,
|
||||
attempts_remaining: int | None,
|
||||
allow_cancel: bool,
|
||||
wrong_pin: bool = False,
|
||||
) -> str:
|
||||
from trezor.wire import PinCancelled
|
||||
|
||||
await button_request(ctx, "pin_device", code=ButtonRequestType.PinEntry)
|
||||
|
||||
warning = "Wrong PIN" if "Wrong" in prompt else None
|
||||
|
||||
if attempts_remaining is None:
|
||||
subprompt = ""
|
||||
elif attempts_remaining == 1:
|
||||
prompt = "Enter PIN"
|
||||
subprompt = "Last attempt"
|
||||
else:
|
||||
prompt = "Enter PIN"
|
||||
subprompt = f"{attempts_remaining} tries left"
|
||||
|
||||
dialog = RustLayout(
|
||||
@ -1108,7 +1101,7 @@ async def request_pin_on_device(
|
||||
prompt=prompt,
|
||||
subprompt=subprompt,
|
||||
allow_cancel=allow_cancel,
|
||||
warning=warning,
|
||||
wrong_pin=wrong_pin,
|
||||
)
|
||||
)
|
||||
while True:
|
||||
|
@ -1605,13 +1605,13 @@
|
||||
"TT_test_msg_backup_device.py::test_no_backup_fails": "8d9a56256a6f45c58a3599580ae5c794b3ae4df7f9a9a716b84e584b54f5f83e",
|
||||
"TT_test_msg_backup_device.py::test_no_backup_show_entropy_fails": "ab6fabda008f503c52c6ecde6b1c1b67505b9153c86320409b2d1275b3c3edad",
|
||||
"TT_test_msg_change_wipe_code_t2.py::test_set_pin_to_wipe_code": "112c9320dc8c9176a361ba6f75898db94009eeab9d6886399a6f8a36c059dbc2",
|
||||
"TT_test_msg_change_wipe_code_t2.py::test_set_remove_wipe_code": "32dc8d666f70ac010e236390a884d19468fcf62a58a008b4575a50221afd8aeb",
|
||||
"TT_test_msg_change_wipe_code_t2.py::test_set_remove_wipe_code": "63664da599b20011a1d8350bffbc0f7c6b00e31021b050b4f7471746b9ec7475",
|
||||
"TT_test_msg_change_wipe_code_t2.py::test_set_wipe_code_mismatch": "fd9742681596078c36d9c900cc146b1bc8e9dea20339f3b62f54374c78a3ba3e",
|
||||
"TT_test_msg_change_wipe_code_t2.py::test_set_wipe_code_to_pin": "4c0617640571bb57a314aed5889fd1bbd0d3192b2b060eef7d3cdb9a3a904676",
|
||||
"TT_test_msg_changepin_t2.py::test_change_failed": "6fbb9b62964f5321039c3634e575e26aed9486789de71eca64fc2941085e4a89",
|
||||
"TT_test_msg_changepin_t2.py::test_change_invalid_current": "f4fdb1ac1778c55a970edc8a3a3708edd5e3c648b65f21eee17553d1fd6c763e",
|
||||
"TT_test_msg_changepin_t2.py::test_change_pin": "4deb4d51580c004fe3be827a5cc5ae645a2abc1c9292e84353f91ec150bce687",
|
||||
"TT_test_msg_changepin_t2.py::test_remove_pin": "bf61f8f1dfc29333e1a647a8340ea1b0538605b32311d0474a1ed3d361e57625",
|
||||
"TT_test_msg_change_wipe_code_t2.py::test_set_wipe_code_to_pin": "fae7f7a7264dfe78e481d2c4fb5d8f3424213a8a467ee868d73a626c2f001304",
|
||||
"TT_test_msg_changepin_t2.py::test_change_failed": "26a276353c6a131b7a5c841542b8a438b8cf4576e5576012fb8a2f03fcf16298",
|
||||
"TT_test_msg_changepin_t2.py::test_change_invalid_current": "5bee6bd2434e8aa8ff00f91f0465e287b2a744f04985254c02b26d222ca69d15",
|
||||
"TT_test_msg_changepin_t2.py::test_change_pin": "52b8a72b684558aedbeb9ea7d5e5e75fc14597499e789eb4bd7d541bd042beba",
|
||||
"TT_test_msg_changepin_t2.py::test_remove_pin": "ed7c497fec840a33a92845661f594855ede3808d46b576f912968d1883905877",
|
||||
"TT_test_msg_changepin_t2.py::test_set_failed": "8804b4cdf72f2e8333cedf2b3e863fdbee24c7b0b7116c9adc27378e4b1c3464",
|
||||
"TT_test_msg_changepin_t2.py::test_set_pin": "7196f9822c322ea5a7836eeb6b36f52d6d8517ede89d1e4792ea112344715e01",
|
||||
"TT_test_msg_loaddevice.py::test_load_device_1": "aa580b991d4859ab2e84b7519338de465dc191ee339dffd7b2183717ede9847e",
|
||||
@ -1634,7 +1634,7 @@
|
||||
"TT_test_pin.py::test_incorrect_pin_t2": "f7518258f2c344043c7e34ec3d942d6376b5786216bd29e77ace063cc16cfd66",
|
||||
"TT_test_pin.py::test_no_protection": "e0db5107ba371eb8d7039e6ad3138f6bbb731c779f405b75c2e14128dfad756f",
|
||||
"TT_test_protection_levels.py::test_apply_settings": "a76f90db9f514d6615b4c46409d3c43bc0c39b632d465ec37e11a5da35e9910b",
|
||||
"TT_test_protection_levels.py::test_change_pin_t2": "e6f6e197893d22381d78fb929922fda66e110508db02e3e55197900f8608e166",
|
||||
"TT_test_protection_levels.py::test_change_pin_t2": "97e51fae7e0bc42de8faafd00ecccc75d081e091012072a0d9cdd0182d8dff43",
|
||||
"TT_test_protection_levels.py::test_get_address": "07b42309dd05c92fb44e74b2a916316b3d21d253503e19780ed21a4b608c657d",
|
||||
"TT_test_protection_levels.py::test_get_entropy": "e404845c835f332df06e03b1d848771d2852356ce41ee6eab0827a0d8b8ab912",
|
||||
"TT_test_protection_levels.py::test_get_public_key": "07b42309dd05c92fb44e74b2a916316b3d21d253503e19780ed21a4b608c657d",
|
||||
@ -1650,7 +1650,7 @@
|
||||
"TT_test_protection_levels.py::test_wipe_device": "fb5c6f84c198b2ac405c03005e5dc2de13092c85c36433af5cde2dc8c5a50f2d",
|
||||
"TT_test_sdcard.py::test_sd_format": "a9ff5054ca7b1db85bf082e194794d9999527de809d77aacb49da99b8edd9c19",
|
||||
"TT_test_sdcard.py::test_sd_no_format": "fd63178ef232fba05690e41ea9f99a1bc5ead8911c1217e78c5908a662d9636b",
|
||||
"TT_test_sdcard.py::test_sd_protect_unlock": "74c0112bb0e1b0a86be5809a27814a164df5d00a1bf71ee2a9323dc61a361346",
|
||||
"TT_test_sdcard.py::test_sd_protect_unlock": "44c56d087139dcc15617c15f71cce18ca66e5671c7729f9090c12f807fb6549c",
|
||||
"TT_test_session.py::test_cannot_resume_ended_session": "e0db5107ba371eb8d7039e6ad3138f6bbb731c779f405b75c2e14128dfad756f",
|
||||
"TT_test_session.py::test_clear_session": "2c16b2eb8ba4ab314456b3548aa104b3498ce1443cb4a1b217ee6c5efa7f450e",
|
||||
"TT_test_session.py::test_derive_cardano_empty_session": "e0db5107ba371eb8d7039e6ad3138f6bbb731c779f405b75c2e14128dfad756f",
|
||||
|
Loading…
Reference in New Issue
Block a user