Browse Source

Accept the TOTP token before and after the current

merge-requests/145/head
Kaleb Elwert 1 year ago
committed by Kaleb Elwert
parent
commit
6a8d2753e0
  1. 22
      tildes/tests/test_user.py
  2. 2
      tildes/tildes/models/user/user.py

22
tildes/tests/test_user.py

@ -1,6 +1,10 @@
# Copyright (c) 2018 Tildes contributors <code@tildes.net> # Copyright (c) 2018 Tildes contributors <code@tildes.net>
# SPDX-License-Identifier: AGPL-3.0-or-later # SPDX-License-Identifier: AGPL-3.0-or-later
from datetime import datetime
from dateutil import tz
from freezegun import freeze_time
from marshmallow.exceptions import ValidationError from marshmallow.exceptions import ValidationError
from pyramid.security import principals_allowed_by_permission from pyramid.security import principals_allowed_by_permission
from pytest import raises from pytest import raises
@ -160,3 +164,21 @@ def test_ban_permission_manually_granted():
principals = principals_allowed_by_permission(user, "ban") principals = principals_allowed_by_permission(user, "ban")
assert principals == {"*:user.ban"} assert principals == {"*:user.ban"}
def test_totp_token_window():
"""Ensure the TOTP token accepts the one directly before and after the current."""
user = User("Test_User", "password")
user.two_factor_enabled = True
user.two_factor_secret = "USKIRUUOFM54XGSXELCOM6K7KODOB2EC"
invalid_tokens = ["896500", "075549"]
valid_tokens = ["293601", "733932", "295043"]
target_time = datetime(2023, 6, 16, 23, 55, tzinfo=tz.UTC)
with freeze_time(target_time):
for token in valid_tokens:
assert user.is_correct_two_factor_code(token)
for token in invalid_tokens:
assert not user.is_correct_two_factor_code(token)

2
tildes/tildes/models/user/user.py

@ -279,7 +279,7 @@ class User(DatabaseModel):
# some possible user input (such as unicode) can cause an error in the totp # some possible user input (such as unicode) can cause an error in the totp
# library, catch that and treat it the same as an invalid code # library, catch that and treat it the same as an invalid code
try: try:
is_valid_code = totp.verify(code)
is_valid_code = totp.verify(code, valid_window=1)
except TypeError: except TypeError:
is_valid_code = False is_valid_code = False

Loading…
Cancel
Save