diff --git a/axes/attempts.py b/axes/attempts.py index e3e1904..0e73e16 100644 --- a/axes/attempts.py +++ b/axes/attempts.py @@ -21,10 +21,13 @@ def get_cool_off_threshold(attempt_time: datetime = None) -> datetime: Get threshold for fetching access attempts from the database. """ - if attempt_time is None: - return now() - get_cool_off() + cool_off = get_cool_off() + if cool_off is None: + raise TypeError('Cool off threshold can not be calculated with settings.AXES_COOLOFF_TIME set to None') - return attempt_time - get_cool_off() + if attempt_time is None: + return now() - cool_off + return attempt_time - cool_off def filter_user_attempts(request: AxesHttpRequest, credentials: dict = None) -> QuerySet: diff --git a/axes/tests/test_attempts.py b/axes/tests/test_attempts.py index 7560b30..6cc1a76 100644 --- a/axes/tests/test_attempts.py +++ b/axes/tests/test_attempts.py @@ -2,13 +2,35 @@ from unittest.mock import patch from django.contrib.auth import get_user_model from django.http import HttpRequest +from django.test import override_settings +from django.utils.timezone import now -from axes.attempts import is_user_attempt_whitelisted +from axes.attempts import is_user_attempt_whitelisted, get_cool_off_threshold from axes.models import AccessAttempt from axes.tests.base import AxesTestCase from axes.utils import reset +class GetCoolOffThresholdTestCase(AxesTestCase): + @override_settings(AXES_COOLOFF_TIME=42) + def test_get_cool_off_threshold(self): + timestamp = now() + + with patch('axes.attempts.now', return_value=timestamp): + attempt_time = timestamp + threshold_now = get_cool_off_threshold(attempt_time) + + attempt_time = None + threshold_none = get_cool_off_threshold(attempt_time) + + self.assertEqual(threshold_now, threshold_none) + + @override_settings(AXES_COOLOFF_TIME=None) + def test_get_cool_off_threshold_error(self): + with self.assertRaises(TypeError): + get_cool_off_threshold() + + class ResetTestCase(AxesTestCase): def test_reset(self): self.create_attempt()