From c9f0451dd42cc2c84342c02d4af297c4c23c0b13 Mon Sep 17 00:00:00 2001 From: Jumana Bahrainwala Date: Thu, 28 Sep 2023 16:57:13 -0400 Subject: [PATCH] Add line to log failed login attempt --- app/config.py | 1 + app/user/rest.py | 10 +++++++++- tests/app/user/test_rest.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/app/config.py b/app/config.py index 0d48aa7c73..cdf9c6b398 100644 --- a/app/config.py +++ b/app/config.py @@ -290,6 +290,7 @@ class Config(object): ONE_OFF_MESSAGE_FILENAME = "Report" MAX_VERIFY_CODE_COUNT = 10 JOBS_MAX_SCHEDULE_HOURS_AHEAD = 96 + FAILED_LOGIN_LIMIT = os.getenv("FAILED_LOGIN_LIMIT", 10) # 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 diff --git a/app/user/rest.py b/app/user/rest.py index edfb0481fc..4f3150600c 100644 --- a/app/user/rest.py +++ b/app/user/rest.py @@ -230,7 +230,15 @@ def verify_user_password(user_id): return jsonify({}), 204 else: increment_failed_login_count(user_to_verify) - message = "Incorrect password" + # We want to get the user again to check the failed login count + user_to_verify = get_user_by_id(user_id=user_id) + import pdb; pdb.set_trace() + if user_to_verify.failed_login_count >= current_app.config["FAILED_LOGIN_LIMIT"]: + message = "Failed login: Incorrect password for user_id {user_id} failed_login {failed_login_count} times".format( + user_id=user_id, failed_login_count=user_to_verify.failed_login_count + ) + else: + message = "Incorrect password" errors = {"password": [message]} raise InvalidRequest(errors, status_code=400) diff --git a/tests/app/user/test_rest.py b/tests/app/user/test_rest.py index d02fc5be40..8695483b8b 100644 --- a/tests/app/user/test_rest.py +++ b/tests/app/user/test_rest.py @@ -1544,3 +1544,31 @@ def test_update_user_blocked(admin_request, sample_user, account_change_template assert resp["data"]["id"] == str(sample_user.id) assert resp["data"]["blocked"] + + +class TestFailedLoginAttempts: + + def test_update_user_password_saves_correctly(client, sample_service): + sample_user = sample_service.users[0] + new_password = "tQETOgIO8yzDMyCsDjLZIEVZHAvkFArYfmSI1KTsJnlnPohI2tfIa8kfng7bxCm" + data = {"_password": new_password} + auth_header = create_authorization_header() + headers = [("Content-Type", "application/json"), auth_header] + resp = client.post( + url_for("user.update_password", user_id=sample_user.id), + data=json.dumps(data), + headers=headers, + ) + assert resp.status_code == 200 + + json_resp = json.loads(resp.get_data(as_text=True)) + assert json_resp["data"]["password_changed_at"] is not None + data = {"password": new_password} + auth_header = create_authorization_header() + headers = [("Content-Type", "application/json"), auth_header] + resp = client.post( + url_for("user.t_user_password", user_id=str(sample_user.id)), + data=json.dumps(data), + headers=headers, + ) + assert resp.status_code == 204 \ No newline at end of file