diff --git a/.gitignore b/.gitignore index 4d3ab557..a9701f21 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,11 @@ env/ *.db *cache* + +# vim +[._]*.s[a-w][a-z] +[._]s[a-w][a-z] +*.un~ +Session.vim +.netrwhist +*~ diff --git a/docs/configuration.rst b/docs/configuration.rst index 018d4ae9..b6b994f6 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -159,7 +159,8 @@ Feature Flags option. Defaults to ``False``. ``SECURITY_TRACKABLE`` Specifies if Flask-Security should track basic user login statistics. If set to ``True``, ensure your - models have the required fields/attribues. Defaults to + models have the required fields/attribues. Be sure to + use `ProxyFix ` if you are using a proxy. Defaults to ``False`` ``SECURITY_PASSWORDLESS`` Specifies if Flask-Security should enable the passwordless login feature. If set to ``True``, users diff --git a/flask_security/utils.py b/flask_security/utils.py index 86bb24a6..0419ba04 100644 --- a/flask_security/utils.py +++ b/flask_security/utils.py @@ -62,10 +62,10 @@ def login_user(user, remember=None): return False if _security.trackable: - if 'X-Forwarded-For' not in request.headers: - remote_addr = request.remote_addr or 'untrackable' + if 'X-Forwarded-For' in request.headers: + remote_addr = request.headers.getlist("X-Forwarded-For")[0].rpartition(' ')[-1] else: - remote_addr = request.headers.getlist("X-Forwarded-For")[0] + remote_addr = request.remote_addr or 'untrackable' old_current_login, new_current_login = user.current_login_at, datetime.utcnow() old_current_ip, new_current_ip = user.current_login_ip, remote_addr diff --git a/tests/test_trackable.py b/tests/test_trackable.py index 1e08662d..70177542 100644 --- a/tests/test_trackable.py +++ b/tests/test_trackable.py @@ -26,3 +26,19 @@ def test_trackable_flag(app, client): assert user.last_login_ip == 'untrackable' assert user.current_login_ip == '127.0.0.1' assert user.login_count == 2 + + +def test_trackable_with_multiple_ips_in_headers(app, client): + e = 'matt@lp.com' + authenticate(client, email=e) + logout(client) + authenticate(client, email=e, headers={ + 'X-Forwarded-For': '99.99.99.99, 88.88.88.88'}) + + with app.app_context(): + user = app.security.datastore.find_user(email=e) + assert user.last_login_at is not None + assert user.current_login_at is not None + assert user.last_login_ip == 'untrackable' + assert user.current_login_ip == '88.88.88.88' + assert user.login_count == 2