mirror of
https://github.com/GSA/notifications-api.git
synced 2026-09-10 01:56:03 -04:00
Add separate config item for failed login count
It’s confusing that changing `MAX_VERIFY_CODE_COUNT` also limits the number of failed login attempts that a user of text messages 2FA can make. This makes the parameters independent, and adds a test to make sure any future changes which affect the limit of failed login attempts are covered.
This commit is contained in:
@@ -148,6 +148,7 @@ class Config(object):
|
|||||||
TEST_MESSAGE_FILENAME = 'Test message'
|
TEST_MESSAGE_FILENAME = 'Test message'
|
||||||
ONE_OFF_MESSAGE_FILENAME = 'Report'
|
ONE_OFF_MESSAGE_FILENAME = 'Report'
|
||||||
MAX_VERIFY_CODE_COUNT = 5
|
MAX_VERIFY_CODE_COUNT = 5
|
||||||
|
MAX_FAILED_LOGIN_COUNT = 10
|
||||||
|
|
||||||
# be careful increasing this size without being sure that we won't see slowness in pysftp
|
# be careful increasing this size without being sure that we won't see slowness in pysftp
|
||||||
MAX_LETTER_PDF_ZIP_FILESIZE = 40 * 1024 * 1024 # 40mb
|
MAX_LETTER_PDF_ZIP_FILESIZE = 40 * 1024 * 1024 # 40mb
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ def verify_user_code(user_id):
|
|||||||
user_to_verify = get_user_by_id(user_id=user_id)
|
user_to_verify = get_user_by_id(user_id=user_id)
|
||||||
|
|
||||||
code = get_user_code(user_to_verify, data['code'], data['code_type'])
|
code = get_user_code(user_to_verify, data['code'], data['code_type'])
|
||||||
if user_to_verify.failed_login_count >= current_app.config.get('MAX_VERIFY_CODE_COUNT'):
|
if user_to_verify.failed_login_count >= current_app.config.get('MAX_FAILED_LOGIN_COUNT'):
|
||||||
raise InvalidRequest("Code not found", status_code=404)
|
raise InvalidRequest("Code not found", status_code=404)
|
||||||
if not code:
|
if not code:
|
||||||
# only relevant from sms
|
# only relevant from sms
|
||||||
|
|||||||
@@ -71,6 +71,31 @@ def test_user_verify_code_bad_code_and_increments_failed_login_count(client,
|
|||||||
assert User.query.get(sample_sms_code.user.id).failed_login_count == 1
|
assert User.query.get(sample_sms_code.user.id).failed_login_count == 1
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('failed_login_count, expected_status', (
|
||||||
|
(9, 204),
|
||||||
|
(10, 404),
|
||||||
|
))
|
||||||
|
def test_user_verify_code_rejects_good_code_if_too_many_failed_logins(
|
||||||
|
client,
|
||||||
|
sample_sms_code,
|
||||||
|
failed_login_count,
|
||||||
|
expected_status,
|
||||||
|
):
|
||||||
|
sample_sms_code.user.failed_login_count = failed_login_count
|
||||||
|
resp = client.post(
|
||||||
|
url_for('user.verify_user_code', user_id=sample_sms_code.user.id),
|
||||||
|
data=json.dumps({
|
||||||
|
'code_type': sample_sms_code.code_type,
|
||||||
|
'code': sample_sms_code.txt_code,
|
||||||
|
}),
|
||||||
|
headers=[
|
||||||
|
('Content-Type', 'application/json'),
|
||||||
|
create_admin_authorization_header(),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
assert resp.status_code == expected_status
|
||||||
|
|
||||||
|
|
||||||
@freeze_time('2020-04-01 12:00')
|
@freeze_time('2020-04-01 12:00')
|
||||||
@pytest.mark.parametrize('code_type', [EMAIL_TYPE, SMS_TYPE])
|
@pytest.mark.parametrize('code_type', [EMAIL_TYPE, SMS_TYPE])
|
||||||
def test_user_verify_code_expired_code_and_increments_failed_login_count(code_type, admin_request, sample_user):
|
def test_user_verify_code_expired_code_and_increments_failed_login_count(code_type, admin_request, sample_user):
|
||||||
|
|||||||
Reference in New Issue
Block a user