From 806b3f6851da1475f6eccde196f6e17cb35f8782 Mon Sep 17 00:00:00 2001 From: Adam Shimali Date: Thu, 28 Jan 2016 11:32:46 +0000 Subject: [PATCH] If failed login count > 0 and user subsequently logs in sucessfully, then failed logins set to 0. --- app/dao/users_dao.py | 7 ++++++ app/user/rest.py | 12 +++++++-- tests/app/dao/test_users_dao.py | 12 ++++++++- tests/app/user/test_rest_verify.py | 39 ++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 3 deletions(-) diff --git a/app/dao/users_dao.py b/app/dao/users_dao.py index a3e87f275..10d6f301e 100644 --- a/app/dao/users_dao.py +++ b/app/dao/users_dao.py @@ -68,3 +68,10 @@ def increment_failed_login_count(user): user.failed_login_count += 1 db.session.add(user) db.session.commit() + + +def reset_failed_login_count(user): + if user.failed_login_count > 0: + user.failed_login_count = 0 + db.session.add(user) + db.session.commit() diff --git a/app/user/rest.py b/app/user/rest.py index 79321099a..2af6cbc53 100644 --- a/app/user/rest.py +++ b/app/user/rest.py @@ -4,8 +4,15 @@ from sqlalchemy.exc import DataError from sqlalchemy.orm.exc import NoResultFound from app.dao.services_dao import get_model_services from app.dao.users_dao import ( - get_model_users, save_model_user, delete_model_user, - create_user_code, get_user_code, use_user_code, increment_failed_login_count) + get_model_users, + save_model_user, + delete_model_user, + create_user_code, + get_user_code, + use_user_code, + increment_failed_login_count, + reset_failed_login_count +) from app.schemas import ( user_schema, users_schema, service_schema, services_schema, verify_code_schema, user_schema_load_json) @@ -72,6 +79,7 @@ def verify_user_password(user_id): result="error", message={'password': ['Required field missing data']}), 400 if user.check_password(txt_pwd): + reset_failed_login_count(user) return jsonify({}), 204 else: increment_failed_login_count(user) diff --git a/tests/app/dao/test_users_dao.py b/tests/app/dao/test_users_dao.py index 6d17a9b3b..7456a30c4 100644 --- a/tests/app/dao/test_users_dao.py +++ b/tests/app/dao/test_users_dao.py @@ -2,11 +2,13 @@ from sqlalchemy.exc import DataError from sqlalchemy.orm.exc import NoResultFound import pytest + from app.dao.users_dao import ( save_model_user, get_model_users, delete_model_user, - increment_failed_login_count + increment_failed_login_count, + reset_failed_login_count ) from tests.app.conftest import sample_user as create_sample_user @@ -74,3 +76,11 @@ def test_increment_failed_login_should_increment_failed_logins(notify_api, notif assert sample_user.failed_login_count == 0 increment_failed_login_count(sample_user) assert sample_user.failed_login_count == 1 + + +def test_reset_failed_login_should_set_failed_logins_to_0(notify_api, notify_db, notify_db_session, sample_user): + assert User.query.count() == 1 + increment_failed_login_count(sample_user) + assert sample_user.failed_login_count == 1 + reset_failed_login_count(sample_user) + assert sample_user.failed_login_count == 0 diff --git a/tests/app/user/test_rest_verify.py b/tests/app/user/test_rest_verify.py index 21710b5e9..ab4f2a66c 100644 --- a/tests/app/user/test_rest_verify.py +++ b/tests/app/user/test_rest_verify.py @@ -182,6 +182,45 @@ def test_user_verify_password_invalid_password(notify_api, assert sample_user.failed_login_count == 1 +def test_user_verify_password_valid_password_resets_failed_logins(notify_api, + notify_db, + notify_db_session, + sample_user): + + with notify_api.test_request_context(): + with notify_api.test_client() as client: + data = json.dumps({'password': 'bad password'}) + auth_header = create_authorization_header( + path=url_for('user.verify_user_password', user_id=sample_user.id), + method='POST', + request_body=data) + + assert sample_user.failed_login_count == 0 + + resp = client.post( + url_for('user.verify_user_password', user_id=sample_user.id), + data=data, + headers=[('Content-Type', 'application/json'), auth_header]) + assert resp.status_code == 400 + json_resp = json.loads(resp.get_data(as_text=True)) + assert 'Incorrect password' in json_resp['message']['password'] + + assert sample_user.failed_login_count == 1 + + data = json.dumps({'password': 'password'}) + auth_header = create_authorization_header( + path=url_for('user.verify_user_password', user_id=sample_user.id), + method='POST', + request_body=data) + resp = client.post( + url_for('user.verify_user_password', user_id=sample_user.id), + data=data, + headers=[('Content-Type', 'application/json'), auth_header]) + + assert resp.status_code == 204 + assert sample_user.failed_login_count == 0 + + def test_user_verify_password_missing_password(notify_api, notify_db, notify_db_session,