class UserTwoFactorOverview(ABCUserProfilePage): def _page_title(self) -> str: return _("Two-factor authentication") def __init__(self) -> None: super().__init__("general.manage_2fa") def _action(self) -> None: assert user.id is not None credentials = load_two_factor_credentials(user.id) if credential_id := request.get_ascii_input("_delete"): if credential_id not in credentials["webauthn_credentials"]: return del credentials["webauthn_credentials"][credential_id] save_two_factor_credentials(user.id, credentials) flash(_("Credential has been deleted")) if request.has_var("_backup_codes"): display_codes, credentials[ "backup_codes"] = make_two_factor_backup_codes() save_two_factor_credentials(user.id, credentials) flash( _("The following backup codes have been generated: <ul>%s</ul> These codes are " "displayed only now. Save them securely.") % "".join(f"<li><tt>{c}</tt></li>" for c in display_codes))
def test_make_two_factor_backup_codes(user_id) -> None: display_codes, store_codes = userdb.make_two_factor_backup_codes() assert len(display_codes) == 10 assert len(store_codes) == 10 for index in range(10): assert htpasswd.check_password(display_codes[index], store_codes[index]) is True
def test_is_two_factor_backup_code_valid_matches(user_id) -> None: display_codes, store_codes = userdb.make_two_factor_backup_codes() credentials = userdb.load_two_factor_credentials(user_id) credentials["backup_codes"] = store_codes assert len(credentials["backup_codes"]) == 10 userdb.save_two_factor_credentials(user_id, credentials) assert userdb.is_two_factor_backup_code_valid(user_id, display_codes[3]) is True credentials = userdb.load_two_factor_credentials(user_id) assert len(credentials["backup_codes"]) == 9
def test_is_two_factor_backup_code_valid_matches(user_id: UserId) -> None: codes = userdb.make_two_factor_backup_codes(rounds=5) credentials = userdb.load_two_factor_credentials(user_id) credentials["backup_codes"] = [pwhashed for _password, pwhashed in codes] userdb.save_two_factor_credentials(user_id, credentials) assert len(credentials["backup_codes"]) == 10 valid = userdb.is_two_factor_backup_code_valid(user_id, codes[3][0]) assert valid credentials = userdb.load_two_factor_credentials(user_id) assert len(credentials["backup_codes"]) == 9
def test_make_two_factor_backup_codes(user_id: UserId) -> None: codes = userdb.make_two_factor_backup_codes(rounds=5) assert len(codes) == 10 for password, pwhashed in codes: assert htpasswd.check_password(password, pwhashed)