mirror of
https://github.com/GSA/notifications-api.git
synced 2026-02-05 10:42:41 -05:00
If user account is locked return 404 even if the code is correct.
Update user.failed_login_count = 0 if code is correct. New endpoint to reset the failed_login_count
This commit is contained in:
@@ -84,6 +84,13 @@ def update_user_attribute(user_id):
|
|||||||
return jsonify(data=user_schema.dump(user_to_update).data), 200
|
return jsonify(data=user_schema.dump(user_to_update).data), 200
|
||||||
|
|
||||||
|
|
||||||
|
@user.route('/<uuid:user_id>/reset-failed-login-count', methods=['POST'])
|
||||||
|
def user_reset_failed_login_count(user_id):
|
||||||
|
user_to_update = get_user_by_id(user_id=user_id)
|
||||||
|
reset_failed_login_count(user_to_update)
|
||||||
|
return jsonify(data=user_schema.dump(user_to_update).data), 200
|
||||||
|
|
||||||
|
|
||||||
@user.route('/<uuid:user_id>/verify/password', methods=['POST'])
|
@user.route('/<uuid:user_id>/verify/password', methods=['POST'])
|
||||||
def verify_user_password(user_id):
|
def verify_user_password(user_id):
|
||||||
user_to_verify = get_user_by_id(user_id=user_id)
|
user_to_verify = get_user_by_id(user_id=user_id)
|
||||||
@@ -125,6 +132,8 @@ def verify_user_code(user_id):
|
|||||||
raise InvalidRequest(errors, status_code=400)
|
raise InvalidRequest(errors, status_code=400)
|
||||||
|
|
||||||
code = get_user_code(user_to_verify, verify_code, code_type)
|
code = get_user_code(user_to_verify, verify_code, code_type)
|
||||||
|
if user_to_verify.failed_login_count >= current_app.config.get('MAX_VERIFY_CODE_COUNT'):
|
||||||
|
raise InvalidRequest("Code not found", status_code=404)
|
||||||
if not code:
|
if not code:
|
||||||
increment_failed_login_count(user_to_verify)
|
increment_failed_login_count(user_to_verify)
|
||||||
raise InvalidRequest("Code not found", status_code=404)
|
raise InvalidRequest("Code not found", status_code=404)
|
||||||
@@ -135,6 +144,7 @@ def verify_user_code(user_id):
|
|||||||
if code_type == 'sms':
|
if code_type == 'sms':
|
||||||
user_to_verify.current_session_id = str(uuid.uuid4())
|
user_to_verify.current_session_id = str(uuid.uuid4())
|
||||||
user_to_verify.logged_in_at = datetime.utcnow()
|
user_to_verify.logged_in_at = datetime.utcnow()
|
||||||
|
user_to_verify.failed_login_count = 0
|
||||||
save_model_user(user_to_verify)
|
save_model_user(user_to_verify)
|
||||||
|
|
||||||
use_user_code(code.id)
|
use_user_code(code.id)
|
||||||
@@ -330,8 +340,6 @@ def update_password(user_id):
|
|||||||
update_dct, errors = user_update_password_schema_load_json.load(req_json)
|
update_dct, errors = user_update_password_schema_load_json.load(req_json)
|
||||||
if errors:
|
if errors:
|
||||||
raise InvalidRequest(errors, status_code=400)
|
raise InvalidRequest(errors, status_code=400)
|
||||||
print("reset login count")
|
|
||||||
reset_failed_login_count(user)
|
|
||||||
update_user_password(user, pwd)
|
update_user_password(user, pwd)
|
||||||
return jsonify(data=user_schema.dump(user).data), 200
|
return jsonify(data=user_schema.dump(user).data), 200
|
||||||
|
|
||||||
|
|||||||
@@ -505,20 +505,6 @@ def test_update_user_password_saves_correctly(client, sample_service):
|
|||||||
assert resp.status_code == 204
|
assert resp.status_code == 204
|
||||||
|
|
||||||
|
|
||||||
def test_update_user_password_resets_failed_login_count(client, sample_service):
|
|
||||||
user = sample_service.users[0]
|
|
||||||
user.failed_login_count = 1
|
|
||||||
|
|
||||||
resp = client.post(
|
|
||||||
url_for('user.update_password', user_id=user.id),
|
|
||||||
data=json.dumps({'_password': 'foo'}),
|
|
||||||
headers=[('Content-Type', 'application/json'), create_authorization_header()]
|
|
||||||
)
|
|
||||||
|
|
||||||
assert resp.status_code == 200
|
|
||||||
assert user.failed_login_count == 0
|
|
||||||
|
|
||||||
|
|
||||||
def test_update_user_resets_failed_login_count_if_updating_password(client, sample_service):
|
def test_update_user_resets_failed_login_count_if_updating_password(client, sample_service):
|
||||||
user = sample_service.users[0]
|
user = sample_service.users[0]
|
||||||
user.failed_login_count = 1
|
user.failed_login_count = 1
|
||||||
|
|||||||
@@ -313,7 +313,21 @@ def test_send_email_verification_returns_404_for_bad_input_data(client, notify_d
|
|||||||
assert mocked.call_count == 0
|
assert mocked.call_count == 0
|
||||||
|
|
||||||
|
|
||||||
def test_user_verify_user_code_valid_code_does_not_reset_failed_login_count(client, sample_sms_code):
|
def test_user_verify_user_code_returns_404_when_code_is_right_but_user_account_is_locked(client, sample_sms_code):
|
||||||
|
sample_sms_code.user.failed_login_count = 10
|
||||||
|
data = json.dumps({
|
||||||
|
'code_type': sample_sms_code.code_type,
|
||||||
|
'code': sample_sms_code.txt_code})
|
||||||
|
resp = client.post(
|
||||||
|
url_for('user.verify_user_code', user_id=sample_sms_code.user.id),
|
||||||
|
data=data,
|
||||||
|
headers=[('Content-Type', 'application/json'), create_authorization_header()])
|
||||||
|
assert resp.status_code == 404
|
||||||
|
assert sample_sms_code.user.failed_login_count == 10
|
||||||
|
assert not sample_sms_code.code_used
|
||||||
|
|
||||||
|
|
||||||
|
def test_user_verify_user_code_valid_code_resets_failed_login_count(client, sample_sms_code):
|
||||||
sample_sms_code.user.failed_login_count = 1
|
sample_sms_code.user.failed_login_count = 1
|
||||||
data = json.dumps({
|
data = json.dumps({
|
||||||
'code_type': sample_sms_code.code_type,
|
'code_type': sample_sms_code.code_type,
|
||||||
@@ -323,5 +337,21 @@ def test_user_verify_user_code_valid_code_does_not_reset_failed_login_count(clie
|
|||||||
data=data,
|
data=data,
|
||||||
headers=[('Content-Type', 'application/json'), create_authorization_header()])
|
headers=[('Content-Type', 'application/json'), create_authorization_header()])
|
||||||
assert resp.status_code == 204
|
assert resp.status_code == 204
|
||||||
assert sample_sms_code.user.failed_login_count == 1
|
assert sample_sms_code.user.failed_login_count == 0
|
||||||
assert sample_sms_code.code_used
|
assert sample_sms_code.code_used
|
||||||
|
|
||||||
|
|
||||||
|
def test_user_reset_failed_login_count_returns_200(client, sample_user):
|
||||||
|
sample_user.failed_login_count = 1
|
||||||
|
resp = client.post(url_for("user.user_reset_failed_login_count", user_id=sample_user.id),
|
||||||
|
data={},
|
||||||
|
headers=[('Content-Type', 'application/json'), create_authorization_header()])
|
||||||
|
assert resp.status_code == 200
|
||||||
|
assert sample_user.failed_login_count == 0
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_failed_login_count_returns_404_when_user_does_not_exist(client):
|
||||||
|
resp = client.post(url_for("user.user_reset_failed_login_count", user_id=uuid.uuid4()),
|
||||||
|
data={},
|
||||||
|
headers=[('Content-Type', 'application/json'), create_authorization_header()])
|
||||||
|
assert resp.status_code == 404
|
||||||
|
|||||||
Reference in New Issue
Block a user