mirror of
https://github.com/GSA/notifications-api.git
synced 2026-02-04 10:21:14 -05:00
Add a limit to the number of active 2fa codes that we create. At the moment that is set to 10.
This commit is contained in:
@@ -78,6 +78,7 @@ class Config(object):
|
|||||||
SMS_CHAR_COUNT_LIMIT = 495
|
SMS_CHAR_COUNT_LIMIT = 495
|
||||||
BRANDING_PATH = '/images/email-template/crests/'
|
BRANDING_PATH = '/images/email-template/crests/'
|
||||||
TEST_MESSAGE_FILENAME = 'Test message'
|
TEST_MESSAGE_FILENAME = 'Test message'
|
||||||
|
MAX_VERIFY_CODE_COUNT = 10
|
||||||
|
|
||||||
NOTIFY_SERVICE_ID = 'd6aa2c68-a2d9-4437-ab19-3ae8eb202553'
|
NOTIFY_SERVICE_ID = 'd6aa2c68-a2d9-4437-ab19-3ae8eb202553'
|
||||||
INVITATION_EMAIL_TEMPLATE_ID = '4f46df42-f795-4cc4-83bb-65ca312f49cc'
|
INVITATION_EMAIL_TEMPLATE_ID = '4f46df42-f795-4cc4-83bb-65ca312f49cc'
|
||||||
|
|||||||
@@ -82,6 +82,14 @@ def delete_user_verify_codes(user):
|
|||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def count_user_verify_codes(user):
|
||||||
|
query = db.session.query(
|
||||||
|
func.count().label('count')
|
||||||
|
).filter(VerifyCode.user == user,
|
||||||
|
VerifyCode.expiry_datetime <= datetime.utcnow()).one()
|
||||||
|
return query.count
|
||||||
|
|
||||||
|
|
||||||
def get_user_by_id(user_id=None):
|
def get_user_by_id(user_id=None):
|
||||||
if user_id:
|
if user_id:
|
||||||
return User.query.filter_by(id=user_id).one()
|
return User.query.filter_by(id=user_id).one()
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ from app.dao.users_dao import (
|
|||||||
get_user_by_email,
|
get_user_by_email,
|
||||||
create_secret_code,
|
create_secret_code,
|
||||||
save_user_attribute,
|
save_user_attribute,
|
||||||
update_user_password
|
update_user_password,
|
||||||
|
count_user_verify_codes
|
||||||
)
|
)
|
||||||
from app.dao.permissions_dao import permission_dao
|
from app.dao.permissions_dao import permission_dao
|
||||||
from app.dao.services_dao import dao_fetch_service_by_id
|
from app.dao.services_dao import dao_fetch_service_by_id
|
||||||
@@ -137,6 +138,10 @@ def send_user_sms_code(user_id):
|
|||||||
user_to_send_to = get_user_by_id(user_id=user_id)
|
user_to_send_to = get_user_by_id(user_id=user_id)
|
||||||
verify_code, errors = request_verify_code_schema.load(request.get_json())
|
verify_code, errors = request_verify_code_schema.load(request.get_json())
|
||||||
|
|
||||||
|
if count_user_verify_codes(user_to_send_to) >= current_app.config.get('MAX_VERIFY_CODE_COUNT'):
|
||||||
|
# Prevent more than `MAX_VERIFY_CODE_COUNT` active verify codes at a time
|
||||||
|
return jsonify({}), 204
|
||||||
|
|
||||||
secret_code = create_secret_code()
|
secret_code = create_secret_code()
|
||||||
create_user_code(user_to_send_to, secret_code, SMS_TYPE)
|
create_user_code(user_to_send_to, secret_code, SMS_TYPE)
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ from app.dao.users_dao import (
|
|||||||
reset_failed_login_count,
|
reset_failed_login_count,
|
||||||
get_user_by_email,
|
get_user_by_email,
|
||||||
delete_codes_older_created_more_than_a_day_ago,
|
delete_codes_older_created_more_than_a_day_ago,
|
||||||
update_user_password
|
update_user_password,
|
||||||
)
|
count_user_verify_codes)
|
||||||
|
|
||||||
from app.models import User, VerifyCode
|
from app.models import User, VerifyCode
|
||||||
|
|
||||||
@@ -140,3 +140,8 @@ def test_update_user_password(notify_api, notify_db, notify_db_session, sample_u
|
|||||||
assert not sample_user.check_password(password)
|
assert not sample_user.check_password(password)
|
||||||
update_user_password(sample_user, password)
|
update_user_password(sample_user, password)
|
||||||
assert sample_user.check_password(password)
|
assert sample_user.check_password(password)
|
||||||
|
|
||||||
|
|
||||||
|
def test_count_user_verify_codes(sample_user):
|
||||||
|
[make_verify_code(sample_user) for i in range(5)]
|
||||||
|
assert count_user_verify_codes(sample_user) == 5
|
||||||
|
|||||||
@@ -249,6 +249,28 @@ def test_send_sms_code_returns_404_for_bad_input_data(client):
|
|||||||
assert json.loads(resp.get_data(as_text=True))['message'] == 'No result found'
|
assert json.loads(resp.get_data(as_text=True))['message'] == 'No result found'
|
||||||
|
|
||||||
|
|
||||||
|
def test_send_sms_code_returns_204_when_too_many_codes_already_created(client, sample_user):
|
||||||
|
for i in range(10):
|
||||||
|
verify_code = VerifyCode(
|
||||||
|
code_type='sms',
|
||||||
|
_code=12345,
|
||||||
|
created_at=datetime.utcnow() - timedelta(minutes=10),
|
||||||
|
expiry_datetime=datetime.utcnow(),
|
||||||
|
user=sample_user
|
||||||
|
)
|
||||||
|
db.session.add(verify_code)
|
||||||
|
db.session.commit()
|
||||||
|
assert VerifyCode.query.count() == 10
|
||||||
|
data = json.dumps({})
|
||||||
|
auth_header = create_authorization_header()
|
||||||
|
resp = client.post(
|
||||||
|
url_for('user.send_user_sms_code', user_id=sample_user.id),
|
||||||
|
data=data,
|
||||||
|
headers=[('Content-Type', 'application/json'), auth_header])
|
||||||
|
assert resp.status_code == 204
|
||||||
|
assert VerifyCode.query.count() == 10
|
||||||
|
|
||||||
|
|
||||||
def test_send_user_email_verification(client,
|
def test_send_user_email_verification(client,
|
||||||
sample_user,
|
sample_user,
|
||||||
mocker,
|
mocker,
|
||||||
|
|||||||
Reference in New Issue
Block a user