def test_deactivate(): user_id = db_utils.create_user() tfa_secret = pyotp.random_base32() tfa_secret_encrypted = tfa._encrypt_totp_secret(tfa_secret) totp = pyotp.TOTP(tfa_secret) # 2FA enabled, deactivated by TOTP challenge-response code _insert_2fa_secret(user_id, tfa_secret_encrypted) tfa_response = totp.now() assert tfa.deactivate(user_id, tfa_response) # 2FA enabled, deactivated by recovery code _insert_2fa_secret(user_id, tfa_secret_encrypted) tfa_response = totp.now() _insert_recovery_code(user_id) assert tfa.deactivate(user_id, recovery_code) # 2FA enabled, failed deactivation (invalid `tfa_response` (code or TOTP token)) _insert_2fa_secret(user_id, tfa_secret_encrypted) assert not tfa.deactivate(user_id, "000000") assert not tfa.deactivate(user_id, "a" * tfa.LENGTH_RECOVERY_CODE)
def tfa_disable_post_(request): tfaresponse = request.params['tfaresponse'] verify_checkbox = 'verify' in request.params if verify_checkbox: # If 2FA was successfully deactivated... return to 2FA dashboard if tfa.deactivate(request.userid, tfaresponse): raise HTTPSeeOther(location="/control/2fa/status") else: return Response(define.webpage(request.userid, "control/2fa/disable.html", [ define.get_display_name(request.userid), "2fa" ], title="Disable 2FA")) # The user didn't check the verification checkbox (despite HTML5's client-side check) elif not verify_checkbox: return Response(define.webpage(request.userid, "control/2fa/disable.html", [ define.get_display_name(request.userid), "verify" ], title="Disable 2FA"))