diff --git a/app/user/rest.py b/app/user/rest.py index dc8f24d1c..b4ab3726b 100644 --- a/app/user/rest.py +++ b/app/user/rest.py @@ -84,6 +84,13 @@ def update_user_attribute(user_id): return jsonify(data=user_schema.dump(user_to_update).data), 200 +@user.route('//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('//verify/password', methods=['POST']) def verify_user_password(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) 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: increment_failed_login_count(user_to_verify) raise InvalidRequest("Code not found", status_code=404) @@ -135,6 +144,7 @@ def verify_user_code(user_id): if code_type == 'sms': user_to_verify.current_session_id = str(uuid.uuid4()) user_to_verify.logged_in_at = datetime.utcnow() + user_to_verify.failed_login_count = 0 save_model_user(user_to_verify) 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) if errors: raise InvalidRequest(errors, status_code=400) - print("reset login count") - reset_failed_login_count(user) update_user_password(user, pwd) return jsonify(data=user_schema.dump(user).data), 200 diff --git a/tests/app/user/test_rest.py b/tests/app/user/test_rest.py index a1070fcff..e476b2ebb 100644 --- a/tests/app/user/test_rest.py +++ b/tests/app/user/test_rest.py @@ -505,20 +505,6 @@ def test_update_user_password_saves_correctly(client, sample_service): 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): user = sample_service.users[0] user.failed_login_count = 1 diff --git a/tests/app/user/test_rest_verify.py b/tests/app/user/test_rest_verify.py index a82b05990..1e08115a9 100644 --- a/tests/app/user/test_rest_verify.py +++ b/tests/app/user/test_rest_verify.py @@ -313,7 +313,21 @@ def test_send_email_verification_returns_404_for_bad_input_data(client, notify_d 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 data = json.dumps({ '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, headers=[('Content-Type', 'application/json'), create_authorization_header()]) 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 + + +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