test_user.py 5.14 KB
Newer Older
1
2
3
4
5
import hashlib

from datetime import datetime, timedelta

import bcrypt
Kevin Morris's avatar
Kevin Morris committed
6
7
import pytest

8
import aurweb.auth
9
10
11
import aurweb.config

from aurweb.db import query
Kevin Morris's avatar
Kevin Morris committed
12
from aurweb.models.account_type import AccountType
13
14
from aurweb.models.ban import Ban
from aurweb.models.session import Session
Kevin Morris's avatar
Kevin Morris committed
15
from aurweb.models.ssh_pub_key import SSHPubKey
Kevin Morris's avatar
Kevin Morris committed
16
17
from aurweb.models.user import User
from aurweb.testing import setup_test_db
18
19
20
21
from aurweb.testing.models import make_session, make_user
from aurweb.testing.requests import Request

account_type, user = None, None
Kevin Morris's avatar
Kevin Morris committed
22
23
24
25


@pytest.fixture(autouse=True)
def setup():
26
    from aurweb.db import session
Kevin Morris's avatar
Kevin Morris committed
27

28
    global account_type, user
Kevin Morris's avatar
Kevin Morris committed
29

Kevin Morris's avatar
Kevin Morris committed
30
    setup_test_db("Users", "Sessions", "Bans", "SSHPubKeys")
Kevin Morris's avatar
Kevin Morris committed
31

Kevin Morris's avatar
Kevin Morris committed
32
33
    account_type = query(AccountType,
                         AccountType.AccountType == "User").first()
Kevin Morris's avatar
Kevin Morris committed
34

35
36
37
38
39
40
41
42
    user = make_user(Username="test", Email="test@example.org",
                     RealName="Test User", Passwd="testPassword",
                     AccountType=account_type)


def test_user_login_logout():
    """ Test creating a user and reading its columns. """
    from aurweb.db import session
Kevin Morris's avatar
Kevin Morris committed
43

44
    # Assert that make_user created a valid user.
Kevin Morris's avatar
Kevin Morris committed
45
46
    assert bool(user.ID)

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
    # Test authentication.
    assert user.valid_password("testPassword")
    assert not user.valid_password("badPassword")

    assert user in account_type.users

    # Make a raw request.
    request = Request()
    assert not user.login(request, "badPassword")
    assert not user.is_authenticated()

    sid = user.login(request, "testPassword")
    assert sid is not None
    assert user.is_authenticated()
    assert "AURSID" in request.cookies

    # Expect that User session relationships work right.
    user_session = session.query(Session).filter(
        Session.UsersID == user.ID).first()
    assert user_session == user.session
    assert user.session.SessionID == sid
    assert user.session.User == user

Kevin Morris's avatar
Kevin Morris committed
70
    # Search for the user via query API.
Kevin Morris's avatar
Kevin Morris committed
71
    result = query(User, User.ID == user.ID).first()
Kevin Morris's avatar
Kevin Morris committed
72
73

    # Compare the result and our original user.
74
    assert result == user
Kevin Morris's avatar
Kevin Morris committed
75
76
77
78
79
    assert result.ID == user.ID
    assert result.AccountType.ID == user.AccountType.ID
    assert result.Username == user.Username
    assert result.Email == user.Email

80
81
82
83
84
    # Test result authenticate methods to ensure they work the same.
    assert not result.valid_password("badPassword")
    assert result.valid_password("testPassword")
    assert result.is_authenticated()

Kevin Morris's avatar
Kevin Morris committed
85
86
87
88
89
90
91
92
    # Ensure we've got the correct account type.
    assert user.AccountType.ID == account_type.ID
    assert user.AccountType.AccountType == account_type.AccountType

    # Test out user string functions.
    assert repr(user) == f"<User(ID='{user.ID}', " + \
        "AccountType='User', Username='test')>"

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
    # Test logout.
    user.logout(request)
    assert "AURSID" not in request.cookies
    assert not user.is_authenticated()


def test_user_login_twice():
    request = Request()
    assert user.login(request, "testPassword")
    assert user.login(request, "testPassword")


def test_user_login_banned():
    from aurweb.db import session

    # Add ban for the next 30 seconds.
    banned_timestamp = datetime.utcnow() + timedelta(seconds=30)
    ban = Ban(IPAddress="127.0.0.1", BanTS=banned_timestamp)
    session.add(ban)
    session.commit()

    request = Request()
    request.client.host = "127.0.0.1"
    assert not user.login(request, "testPassword")


def test_user_login_suspended():
    from aurweb.db import session
    user.Suspended = True
    session.commit()
    assert not user.login(Request(), "testPassword")


def test_legacy_user_authentication():
    from aurweb.db import session

    user.Salt = bcrypt.gensalt().decode()
    user.Passwd = hashlib.md5(f"{user.Salt}testPassword".encode()).hexdigest()
    session.commit()

    assert not user.valid_password("badPassword")
    assert user.valid_password("testPassword")

    # Test by passing a password of None value in.
    assert not user.valid_password(None)


def test_user_login_with_outdated_sid():
    from aurweb.db import session

    # Make a session with a LastUpdateTS 5 seconds ago, causing
    # user.login to update it with a new sid.
    _session = make_session(UsersID=user.ID, SessionID="stub",
                            LastUpdateTS=datetime.utcnow().timestamp() - 5)
    sid = user.login(Request(), "testPassword")
    assert sid and user.is_authenticated()
    assert sid != "stub"

    session.delete(_session)
    session.commit()


def test_user_update_password():
    user.update_password("secondPassword")
    assert not user.valid_password("testPassword")
    assert user.valid_password("secondPassword")


def test_user_minimum_passwd_length():
    passwd_min_len = aurweb.config.getint("options", "passwd_min_len")
    assert User.minimum_passwd_length() == passwd_min_len
Kevin Morris's avatar
Kevin Morris committed
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180


def test_user_ssh_pub_key():
    from aurweb.db import session

    assert user.ssh_pub_key is None

    ssh_pub_key = SSHPubKey(UserID=user.ID,
                            Fingerprint="testFingerprint",
                            PubKey="testPubKey")
    session.add(ssh_pub_key)
    session.commit()

    assert user.ssh_pub_key == ssh_pub_key

    session.delete(ssh_pub_key)
    session.commit()