File: test_trackable.py

package info (click to toggle)
flask-security 5.6.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 3,420 kB
  • sloc: python: 23,164; javascript: 204; makefile: 138
file content (107 lines) | stat: -rw-r--r-- 3,269 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
"""
test_trackable
~~~~~~~~~~~~~~

Trackable tests
"""

import datetime
import pytest
from flask import after_this_request, redirect
from werkzeug.middleware.proxy_fix import ProxyFix

from flask_security import login_user

from tests.test_utils import authenticate, logout

pytestmark = pytest.mark.trackable()


def _client_ip(client):
    """Compatibility layer for Flask<0.12."""
    return getattr(client, "environ_base", {}).get("REMOTE_ADDR")


def test_trackable_flag(app, client):
    app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1)
    e = "matt@lp.com"
    authenticate(client, email=e)
    logout(client)
    authenticate(client, email=e, headers={"X-Forwarded-For": "127.0.0.1"})

    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 == _client_ip(client)
        assert user.current_login_ip == "127.0.0.1"
        assert user.login_count == 2


def test_trackable_with_multiple_ips_in_headers(app, client):
    app.wsgi_app = ProxyFix(app.wsgi_app, x_for=2)

    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, 77.77.77.77"},
    )

    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 == _client_ip(client)
        assert user.current_login_ip == "88.88.88.88"
        assert user.login_count == 2


def test_trackable_using_login_user(app, client):
    """
    This tests is only to serve as an example of how one needs to call
    datastore.commit() after logging a user in to make sure the trackable
    fields are saved to the datastore.
    """
    app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1)

    @app.route("/login_custom", methods=["POST"])
    def login_custom():
        user = app.security.datastore.find_user(email=e)
        login_user(user)

        @after_this_request
        def save_user(response):
            app.security.datastore.commit()
            return response

        return redirect("/")

    e = "matt@lp.com"
    authenticate(client, email=e)
    logout(client)

    data = dict(email=e, password="password", remember="y")
    client.post("/login_custom", data=data, headers={"X-Forwarded-For": "127.0.0.1"})

    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 == _client_ip(client)
        assert user.current_login_ip == "127.0.0.1"
        assert user.login_count == 2


@pytest.mark.settings(datetime_factory=lambda: datetime.datetime(2024, 3, 24))
def test_trackable_datetime(app, client):
    app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1)
    e = "matt@lp.com"
    authenticate(client, email=e)

    with app.app_context():
        user = app.security.datastore.find_user(email=e)
        assert user.current_login_at == datetime.datetime(2024, 3, 24)
        assert user.login_count == 1