test_mfa.py
 1  import hashlib
 2  from unittest.mock import AsyncMock
 3  
 4  from _pytest.monkeypatch import MonkeyPatch
 5  from pytest_mock import MockerFixture
 6  
 7  from api.settings import settings
 8  from api.utils import mfa
 9  
10  
11  async def test__check_mfa_code__blocked(mocker: MockerFixture) -> None:
12      redis_patch = mocker.patch("api.utils.mfa.redis")
13  
14      code = "421337"
15      secret = "tRtD1eq5oMJydVA6zxUsohZdMIKTGgoj"
16      key = f"mfa_block:{hashlib.sha256(secret.encode()).hexdigest()}:{code}"
17      redis_patch.exists.return_value = True
18  
19      assert await mfa.check_mfa_code(code, secret) is False
20  
21      redis_patch.exists.assert_called_once_with(key)
22  
23  
24  async def test__check_mfa_code__invalid(mocker: MockerFixture, monkeypatch: MonkeyPatch) -> None:
25      redis_patch = mocker.patch("api.utils.mfa.redis", new_callable=AsyncMock)
26      totp_patch = mocker.patch("api.utils.mfa.TOTP")
27      monkeypatch.setattr(settings, "mfa_valid_window", 42)
28  
29      code = "421337"
30      secret = "tRtD1eq5oMJydVA6zxUsohZdMIKTGgoj"
31      key = f"mfa_block:{hashlib.sha256(secret.encode()).hexdigest()}:{code}"
32      redis_patch.exists.return_value = False
33      totp_patch.return_value.verify.return_value = False
34  
35      assert await mfa.check_mfa_code(code, secret) is False
36  
37      redis_patch.exists.assert_called_once_with(key)
38      totp_patch.assert_called_once_with(secret)
39      totp_patch.return_value.verify.assert_called_once_with(code, valid_window=42)
40  
41  
42  async def test__check_mfa_code__valid(mocker: MockerFixture, monkeypatch: MonkeyPatch) -> None:
43      redis_patch = mocker.patch("api.utils.mfa.redis", new_callable=AsyncMock)
44      totp_patch = mocker.patch("api.utils.mfa.TOTP")
45      monkeypatch.setattr(settings, "mfa_valid_window", 42)
46  
47      code = "421337"
48      secret = "tRtD1eq5oMJydVA6zxUsohZdMIKTGgoj"
49      key = f"mfa_block:{hashlib.sha256(secret.encode()).hexdigest()}:{code}"
50      redis_patch.exists.return_value = False
51      totp_patch.return_value.verify.return_value = True
52  
53      assert await mfa.check_mfa_code(code, secret) is True
54  
55      redis_patch.exists.assert_called_once_with(key)
56      totp_patch.assert_called_once_with(secret)
57      totp_patch.return_value.verify.assert_called_once_with(code, valid_window=42)
58      redis_patch.setex.assert_called_once_with(key, 2580, 1)