2022-11-01 11:25:21 +00:00
|
|
|
import datetime
|
2024-04-09 08:04:26 +00:00
|
|
|
import logging
|
2022-12-21 20:52:01 +00:00
|
|
|
from unittest import mock
|
|
|
|
|
2023-08-13 20:08:28 +00:00
|
|
|
from flask import g
|
2020-10-22 15:37:01 +00:00
|
|
|
|
2024-03-15 18:58:06 +00:00
|
|
|
from canaille.app import models
|
|
|
|
|
2020-10-22 15:37:01 +00:00
|
|
|
|
2022-12-04 11:57:59 +00:00
|
|
|
def test_index(testclient, user):
|
|
|
|
res = testclient.get("/", status=302)
|
|
|
|
assert res.location == "/login"
|
|
|
|
|
2023-08-13 20:08:28 +00:00
|
|
|
g.user = user
|
2022-12-04 11:57:59 +00:00
|
|
|
res = testclient.get("/", status=302)
|
|
|
|
assert res.location == "/profile/user"
|
|
|
|
|
2023-12-18 17:06:03 +00:00
|
|
|
testclient.app.config["CANAILLE"]["ACL"]["DEFAULT"]["PERMISSIONS"] = []
|
2023-08-13 20:08:28 +00:00
|
|
|
g.user.reload()
|
2022-12-04 11:57:59 +00:00
|
|
|
res = testclient.get("/", status=302)
|
|
|
|
assert res.location == "/about"
|
|
|
|
|
|
|
|
|
2024-04-09 08:04:26 +00:00
|
|
|
def test_signin_and_out(testclient, user, caplog):
|
2020-08-20 08:31:36 +00:00
|
|
|
with testclient.session_transaction() as session:
|
2022-12-29 00:10:07 +00:00
|
|
|
assert not session.get("user_id")
|
2020-08-20 08:31:36 +00:00
|
|
|
|
2020-10-30 18:19:34 +00:00
|
|
|
res = testclient.get("/login", status=200)
|
2020-08-20 08:31:36 +00:00
|
|
|
|
2023-05-11 13:33:34 +00:00
|
|
|
res.form["login"] = "user"
|
2021-01-23 21:30:43 +00:00
|
|
|
res = res.form.submit(status=302)
|
|
|
|
res = res.follow(status=200)
|
|
|
|
|
|
|
|
with testclient.session_transaction() as session:
|
2023-05-11 13:33:34 +00:00
|
|
|
assert "user" == session.get("attempt_login")
|
2021-01-23 21:30:43 +00:00
|
|
|
|
2020-08-20 08:31:36 +00:00
|
|
|
res.form["password"] = "correct horse battery staple"
|
|
|
|
res = res.form.submit()
|
2023-05-17 14:20:37 +00:00
|
|
|
|
|
|
|
assert (
|
|
|
|
"success",
|
|
|
|
"Connection successful. Welcome John (johnny) Doe",
|
|
|
|
) in res.flashes
|
2024-04-09 08:04:26 +00:00
|
|
|
assert (
|
|
|
|
"canaille",
|
|
|
|
logging.INFO,
|
|
|
|
"Succeed login attempt for user from unknown IP",
|
|
|
|
) in caplog.record_tuples
|
2020-10-30 22:41:02 +00:00
|
|
|
res = res.follow(status=302)
|
|
|
|
res = res.follow(status=200)
|
2020-08-20 08:31:36 +00:00
|
|
|
|
|
|
|
with testclient.session_transaction() as session:
|
2023-02-05 18:08:25 +00:00
|
|
|
assert [user.id] == session.get("user_id")
|
2021-01-23 21:30:43 +00:00
|
|
|
assert "attempt_login" not in session
|
2020-08-20 08:31:36 +00:00
|
|
|
|
2021-12-06 22:17:08 +00:00
|
|
|
res = testclient.get("/login", status=302)
|
|
|
|
|
2020-08-20 08:31:36 +00:00
|
|
|
res = testclient.get("/logout")
|
2023-03-16 15:25:14 +00:00
|
|
|
assert (
|
|
|
|
"success",
|
|
|
|
"You have been disconnected. See you next time John (johnny) Doe",
|
|
|
|
) in res.flashes
|
2024-04-09 08:04:26 +00:00
|
|
|
assert (
|
|
|
|
"canaille",
|
|
|
|
logging.INFO,
|
|
|
|
"Logout user from unknown IP",
|
|
|
|
) in caplog.record_tuples
|
2020-10-30 22:41:02 +00:00
|
|
|
res = res.follow(status=302)
|
|
|
|
res = res.follow(status=200)
|
2022-12-24 01:40:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_visitor_logout(testclient, user):
|
|
|
|
with testclient.session_transaction() as session:
|
2022-12-29 00:10:07 +00:00
|
|
|
assert not session.get("user_id")
|
2022-12-24 01:40:50 +00:00
|
|
|
|
|
|
|
res = testclient.get("/logout")
|
|
|
|
res = res.follow(status=302)
|
|
|
|
res = res.follow(status=200)
|
2023-03-16 15:25:14 +00:00
|
|
|
assert (
|
|
|
|
"success",
|
|
|
|
"You have been disconnected. See you next time user",
|
|
|
|
) not in res.flashes
|
2020-08-20 08:31:36 +00:00
|
|
|
|
|
|
|
with testclient.session_transaction() as session:
|
2022-12-29 00:10:07 +00:00
|
|
|
assert not session.get("user_id")
|
2020-08-20 08:31:36 +00:00
|
|
|
|
|
|
|
|
2024-04-09 08:04:26 +00:00
|
|
|
def test_signin_wrong_password(testclient, user, caplog):
|
2020-08-20 08:31:36 +00:00
|
|
|
with testclient.session_transaction() as session:
|
2022-12-29 00:10:07 +00:00
|
|
|
assert not session.get("user_id")
|
2020-08-20 08:31:36 +00:00
|
|
|
|
2020-10-30 18:19:34 +00:00
|
|
|
res = testclient.get("/login", status=200)
|
2020-08-20 08:31:36 +00:00
|
|
|
|
2023-05-11 13:33:34 +00:00
|
|
|
res.form["login"] = "user"
|
2021-01-23 21:30:43 +00:00
|
|
|
res = res.form.submit(status=302)
|
|
|
|
res = res.follow(status=200)
|
2020-08-20 08:31:36 +00:00
|
|
|
res.form["password"] = "incorrect horse"
|
2020-10-30 22:41:02 +00:00
|
|
|
res = res.form.submit(status=200)
|
2023-01-28 18:02:00 +00:00
|
|
|
assert ("error", "Login failed, please check your information") in res.flashes
|
2024-04-09 08:04:26 +00:00
|
|
|
assert (
|
|
|
|
"canaille",
|
|
|
|
logging.INFO,
|
|
|
|
"Failed login attempt for user from unknown IP",
|
|
|
|
) in caplog.record_tuples
|
2020-08-20 08:31:36 +00:00
|
|
|
|
|
|
|
|
2023-11-28 17:10:12 +00:00
|
|
|
def test_signin_password_substring(testclient, user):
|
|
|
|
with testclient.session_transaction() as session:
|
|
|
|
assert not session.get("user_id")
|
|
|
|
|
|
|
|
res = testclient.get("/login", status=200)
|
|
|
|
|
|
|
|
res.form["login"] = "user"
|
|
|
|
res = res.form.submit(status=302)
|
|
|
|
res = res.follow(status=200)
|
|
|
|
res.form["password"] = "c"
|
|
|
|
res = res.form.submit(status=200)
|
|
|
|
assert ("error", "Login failed, please check your information") in res.flashes
|
|
|
|
|
|
|
|
|
2022-11-01 11:25:21 +00:00
|
|
|
def test_signin_bad_csrf(testclient, user):
|
|
|
|
with testclient.session_transaction() as session:
|
|
|
|
assert not session.get("user_id")
|
|
|
|
|
|
|
|
res = testclient.get("/login", status=200)
|
|
|
|
|
|
|
|
res.form["login"] = "John (johnny) Doe"
|
|
|
|
res = res.form.submit(status=302)
|
|
|
|
res = res.follow(status=200)
|
|
|
|
|
|
|
|
res.form["password"] = ""
|
|
|
|
res = res.form.submit(status=200)
|
|
|
|
assert ("error", "Login failed, please check your information") in res.flashes
|
|
|
|
|
|
|
|
|
2022-05-19 10:36:39 +00:00
|
|
|
def test_signin_with_alternate_attribute(testclient, user):
|
2020-10-30 18:19:34 +00:00
|
|
|
res = testclient.get("/login", status=200)
|
2020-08-20 08:45:33 +00:00
|
|
|
|
|
|
|
res.form["login"] = "user"
|
2021-01-23 21:30:43 +00:00
|
|
|
res = res.form.submit(status=302)
|
|
|
|
res = res.follow(status=200)
|
|
|
|
|
2020-08-20 08:45:33 +00:00
|
|
|
res.form["password"] = "correct horse battery staple"
|
|
|
|
res = res.form.submit()
|
2020-10-30 22:41:02 +00:00
|
|
|
res = res.follow(status=302)
|
|
|
|
res = res.follow(status=200)
|
2020-08-20 08:45:33 +00:00
|
|
|
|
|
|
|
with testclient.session_transaction() as session:
|
2023-02-05 18:08:25 +00:00
|
|
|
assert [user.id] == session.get("user_id")
|
2020-10-22 15:37:01 +00:00
|
|
|
|
|
|
|
|
2022-12-20 21:50:02 +00:00
|
|
|
def test_password_page_without_signin_in_redirects_to_login_page(testclient, user):
|
|
|
|
res = testclient.get("/password", status=302)
|
|
|
|
assert res.location == "/login"
|
2024-04-09 07:20:38 +00:00
|
|
|
assert res.flashes == [
|
|
|
|
("warning", "Cannot remember the login you attempted to sign in with")
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def test_password_page_already_logged_in(testclient, logged_user):
|
|
|
|
res = testclient.get("/password", status=302)
|
|
|
|
assert res.location == "/profile/user"
|
2022-12-20 21:50:02 +00:00
|
|
|
|
|
|
|
|
2023-05-20 15:17:46 +00:00
|
|
|
def test_user_without_password_first_login(testclient, backend, smtpd):
|
2022-12-21 20:52:01 +00:00
|
|
|
assert len(smtpd.messages) == 0
|
2023-04-09 09:37:04 +00:00
|
|
|
u = models.User(
|
2023-02-05 17:57:18 +00:00
|
|
|
formatted_name="Temp User",
|
|
|
|
family_name="Temp",
|
|
|
|
user_name="temp",
|
2023-06-29 15:47:01 +00:00
|
|
|
emails=["john@doe.com", "johhny@doe.com"],
|
2020-11-16 14:39:58 +00:00
|
|
|
)
|
2022-05-08 14:31:17 +00:00
|
|
|
u.save()
|
2020-11-16 14:39:58 +00:00
|
|
|
|
|
|
|
res = testclient.get("/login", status=200)
|
2023-05-11 13:33:34 +00:00
|
|
|
res.form["login"] = "temp"
|
2022-12-21 20:52:01 +00:00
|
|
|
res = res.form.submit(status=302)
|
2020-11-16 14:39:58 +00:00
|
|
|
|
2022-12-21 20:52:01 +00:00
|
|
|
assert res.location == "/firstlogin/temp"
|
|
|
|
res = res.follow(status=200)
|
2023-03-16 15:25:14 +00:00
|
|
|
res.mustcontain("First login")
|
2020-11-16 14:39:58 +00:00
|
|
|
|
2022-12-21 20:52:01 +00:00
|
|
|
res = res.form.submit(name="action", value="sendmail")
|
|
|
|
assert (
|
2023-03-16 15:25:14 +00:00
|
|
|
"success",
|
2022-12-21 20:52:01 +00:00
|
|
|
"A password initialization link has been sent at your email address. "
|
2023-03-16 15:25:14 +00:00
|
|
|
"You should receive it within a few minutes.",
|
|
|
|
) in res.flashes
|
2023-06-29 15:47:01 +00:00
|
|
|
assert len(smtpd.messages) == 2
|
2023-11-28 16:59:50 +00:00
|
|
|
assert [message["X-RcptTo"] for message in smtpd.messages] == u.emails
|
2022-12-21 20:52:01 +00:00
|
|
|
assert "Password initialization" in smtpd.messages[0].get("Subject")
|
|
|
|
u.delete()
|
|
|
|
|
|
|
|
|
|
|
|
@mock.patch("smtplib.SMTP")
|
|
|
|
def test_first_login_account_initialization_mail_sending_failed(
|
2023-05-20 15:17:46 +00:00
|
|
|
SMTP, testclient, backend, smtpd
|
2022-12-21 20:52:01 +00:00
|
|
|
):
|
|
|
|
SMTP.side_effect = mock.Mock(side_effect=OSError("unit test mail error"))
|
|
|
|
assert len(smtpd.messages) == 0
|
|
|
|
|
2023-04-09 09:37:04 +00:00
|
|
|
u = models.User(
|
2023-02-05 17:57:18 +00:00
|
|
|
formatted_name="Temp User",
|
|
|
|
family_name="Temp",
|
|
|
|
user_name="temp",
|
2023-10-02 19:58:46 +00:00
|
|
|
emails=["john@doe.com"],
|
2022-12-21 20:52:01 +00:00
|
|
|
)
|
|
|
|
u.save()
|
|
|
|
|
|
|
|
res = testclient.get("/firstlogin/temp")
|
|
|
|
res = res.form.submit(name="action", value="sendmail", expect_errors=True)
|
|
|
|
assert (
|
2023-03-16 15:25:14 +00:00
|
|
|
"success",
|
2022-12-21 20:52:01 +00:00
|
|
|
"A password initialization link has been sent at your email address. "
|
2023-03-16 15:25:14 +00:00
|
|
|
"You should receive it within a few minutes.",
|
|
|
|
) not in res.flashes
|
|
|
|
assert ("error", "Could not send the password initialization email") in res.flashes
|
2022-12-21 20:52:01 +00:00
|
|
|
assert len(smtpd.messages) == 0
|
2022-05-08 14:31:17 +00:00
|
|
|
u.delete()
|
2022-05-18 09:31:26 +00:00
|
|
|
|
2020-11-16 14:39:58 +00:00
|
|
|
|
2023-05-20 15:17:46 +00:00
|
|
|
def test_first_login_form_error(testclient, backend, smtpd):
|
2022-12-21 20:56:31 +00:00
|
|
|
assert len(smtpd.messages) == 0
|
2023-04-09 09:37:04 +00:00
|
|
|
u = models.User(
|
2023-02-05 17:57:18 +00:00
|
|
|
formatted_name="Temp User",
|
|
|
|
family_name="Temp",
|
|
|
|
user_name="temp",
|
2023-10-02 19:58:46 +00:00
|
|
|
emails=["john@doe.com"],
|
2022-12-21 20:56:31 +00:00
|
|
|
)
|
|
|
|
u.save()
|
|
|
|
|
|
|
|
res = testclient.get("/firstlogin/temp", status=200)
|
|
|
|
res.form["csrf_token"] = "invalid"
|
2024-03-15 18:55:12 +00:00
|
|
|
res = res.form.submit(
|
|
|
|
name="action", value="sendmail", status=400, expect_errors=True
|
|
|
|
)
|
2022-12-21 20:56:31 +00:00
|
|
|
assert len(smtpd.messages) == 0
|
|
|
|
u.delete()
|
|
|
|
|
|
|
|
|
2022-12-20 23:24:17 +00:00
|
|
|
def test_first_login_page_unavailable_for_users_with_password(
|
2023-05-20 15:17:46 +00:00
|
|
|
testclient, backend, user
|
2022-12-20 23:24:17 +00:00
|
|
|
):
|
|
|
|
testclient.get("/firstlogin/user", status=404)
|
|
|
|
|
|
|
|
|
2023-05-20 15:17:46 +00:00
|
|
|
def test_user_password_deleted_during_login(testclient, backend):
|
2023-04-09 09:37:04 +00:00
|
|
|
u = models.User(
|
2023-02-05 17:57:18 +00:00
|
|
|
formatted_name="Temp User",
|
|
|
|
family_name="Temp",
|
|
|
|
user_name="temp",
|
2023-10-02 19:58:46 +00:00
|
|
|
emails=["john@doe.com"],
|
2023-04-10 19:42:14 +00:00
|
|
|
password="correct horse battery staple",
|
2022-12-20 21:59:23 +00:00
|
|
|
)
|
|
|
|
u.save()
|
|
|
|
|
|
|
|
res = testclient.get("/login")
|
2023-05-11 13:33:34 +00:00
|
|
|
res.form["login"] = "temp"
|
2022-12-20 21:59:23 +00:00
|
|
|
res = res.form.submit().follow()
|
|
|
|
res.form["password"] = "correct horse battery staple"
|
|
|
|
|
2023-11-21 13:57:28 +00:00
|
|
|
u.password = None
|
2022-12-20 21:59:23 +00:00
|
|
|
u.save()
|
|
|
|
|
|
|
|
res = res.form.submit(status=302)
|
|
|
|
assert res.location == "/firstlogin/temp"
|
|
|
|
|
|
|
|
u.delete()
|
|
|
|
|
|
|
|
|
2023-05-20 15:17:46 +00:00
|
|
|
def test_user_deleted_in_session(testclient, backend):
|
2023-04-09 09:37:04 +00:00
|
|
|
u = models.User(
|
2023-02-05 17:57:18 +00:00
|
|
|
formatted_name="Jake Doe",
|
|
|
|
family_name="Jake",
|
|
|
|
user_name="jake",
|
2023-10-02 19:58:46 +00:00
|
|
|
emails=["jake@doe.com"],
|
2023-04-10 19:42:14 +00:00
|
|
|
password="correct horse battery staple",
|
2020-11-25 16:41:03 +00:00
|
|
|
)
|
2022-05-08 14:31:17 +00:00
|
|
|
u.save()
|
2020-12-11 10:52:37 +00:00
|
|
|
testclient.get("/profile/jake", status=403)
|
|
|
|
|
|
|
|
with testclient.session_transaction() as session:
|
2023-02-05 18:08:25 +00:00
|
|
|
session["user_id"] = [u.id]
|
2020-11-25 16:41:03 +00:00
|
|
|
|
2022-05-08 14:31:17 +00:00
|
|
|
u.delete()
|
2020-11-25 16:41:03 +00:00
|
|
|
|
2023-06-28 15:56:49 +00:00
|
|
|
testclient.get("/profile/jake", status=404)
|
2020-12-11 10:52:37 +00:00
|
|
|
with testclient.session_transaction() as session:
|
2022-12-29 00:10:07 +00:00
|
|
|
assert not session.get("user_id")
|
2020-12-11 10:52:37 +00:00
|
|
|
|
|
|
|
|
2022-05-19 10:36:39 +00:00
|
|
|
def test_impersonate(testclient, logged_admin, user):
|
2023-06-30 16:10:16 +00:00
|
|
|
res = testclient.get("/", status=302).follow(status=200).click("Account settings")
|
2023-02-05 17:57:18 +00:00
|
|
|
assert "admin" == res.form["user_name"].value
|
2020-12-11 10:52:37 +00:00
|
|
|
|
|
|
|
res = (
|
|
|
|
testclient.get("/impersonate/user", status=302)
|
|
|
|
.follow(status=302)
|
|
|
|
.follow(status=200)
|
2023-06-30 16:10:16 +00:00
|
|
|
.click("Account settings")
|
2020-12-11 10:52:37 +00:00
|
|
|
)
|
2023-02-05 17:57:18 +00:00
|
|
|
assert "user" == res.form["user_name"].value
|
2020-12-11 10:52:37 +00:00
|
|
|
|
|
|
|
testclient.get("/logout", status=302).follow(status=302).follow(status=200)
|
|
|
|
|
2023-06-30 16:10:16 +00:00
|
|
|
res = testclient.get("/", status=302).follow(status=200).click("Account settings")
|
2023-02-05 17:57:18 +00:00
|
|
|
assert "admin" == res.form["user_name"].value
|
2020-12-31 18:55:30 +00:00
|
|
|
|
|
|
|
|
2022-05-19 10:36:39 +00:00
|
|
|
def test_wrong_login(testclient, user):
|
2023-12-18 17:06:03 +00:00
|
|
|
testclient.app.config["CANAILLE"]["HIDE_INVALID_LOGINS"] = True
|
2020-12-31 18:55:30 +00:00
|
|
|
|
|
|
|
res = testclient.get("/login", status=200)
|
|
|
|
res.form["login"] = "invalid"
|
2021-01-23 21:30:43 +00:00
|
|
|
res = res.form.submit(status=302)
|
|
|
|
res = res.follow(status=200)
|
|
|
|
|
2020-12-31 18:55:30 +00:00
|
|
|
res.form["password"] = "incorrect horse"
|
|
|
|
res = res.form.submit(status=200)
|
2023-03-16 15:25:14 +00:00
|
|
|
res.mustcontain(no="The login 'invalid' does not exist")
|
2020-12-31 18:55:30 +00:00
|
|
|
|
2023-12-18 17:06:03 +00:00
|
|
|
testclient.app.config["CANAILLE"]["HIDE_INVALID_LOGINS"] = False
|
2020-12-31 18:55:30 +00:00
|
|
|
|
|
|
|
res = testclient.get("/login", status=200)
|
|
|
|
res.form["login"] = "invalid"
|
|
|
|
res = res.form.submit(status=200)
|
2023-03-16 15:25:14 +00:00
|
|
|
res.mustcontain("The login 'invalid' does not exist")
|
2021-01-01 15:42:13 +00:00
|
|
|
|
|
|
|
|
2023-05-20 15:17:46 +00:00
|
|
|
def test_admin_self_deletion(testclient, backend):
|
2023-04-09 09:37:04 +00:00
|
|
|
admin = models.User(
|
2023-02-05 17:57:18 +00:00
|
|
|
formatted_name="Temp admin",
|
|
|
|
family_name="admin",
|
|
|
|
user_name="temp",
|
2023-10-02 19:58:46 +00:00
|
|
|
emails=["temp@temp.com"],
|
2023-04-10 19:42:14 +00:00
|
|
|
password="admin",
|
2021-01-01 15:42:13 +00:00
|
|
|
)
|
2022-05-08 14:31:17 +00:00
|
|
|
admin.save()
|
2021-01-01 15:42:13 +00:00
|
|
|
with testclient.session_transaction() as sess:
|
2023-02-05 18:08:25 +00:00
|
|
|
sess["user_id"] = [admin.id]
|
2021-01-01 15:42:13 +00:00
|
|
|
|
2023-03-16 17:39:28 +00:00
|
|
|
res = testclient.get("/profile/temp/settings")
|
2023-07-06 16:43:37 +00:00
|
|
|
res = res.form.submit(name="action", value="confirm-delete")
|
2021-01-01 15:42:13 +00:00
|
|
|
res = (
|
|
|
|
res.form.submit(name="action", value="delete", status=302)
|
|
|
|
.follow(status=302)
|
|
|
|
.follow(status=200)
|
|
|
|
)
|
|
|
|
|
2024-04-07 16:46:08 +00:00
|
|
|
assert models.User.get(user_name="temp") is None
|
2021-01-01 15:42:13 +00:00
|
|
|
|
|
|
|
with testclient.session_transaction() as sess:
|
2022-12-29 00:10:07 +00:00
|
|
|
assert not sess.get("user_id")
|
2021-01-01 15:42:13 +00:00
|
|
|
|
|
|
|
|
2023-05-20 15:17:46 +00:00
|
|
|
def test_user_self_deletion(testclient, backend):
|
2023-04-09 09:37:04 +00:00
|
|
|
user = models.User(
|
2023-02-05 17:57:18 +00:00
|
|
|
formatted_name="Temp user",
|
|
|
|
family_name="user",
|
|
|
|
user_name="temp",
|
2023-10-02 19:58:46 +00:00
|
|
|
emails=["temp@temp.com"],
|
2023-04-10 19:42:14 +00:00
|
|
|
password="correct horse battery staple",
|
2021-01-01 15:42:13 +00:00
|
|
|
)
|
2022-05-08 14:31:17 +00:00
|
|
|
user.save()
|
2021-01-01 15:42:13 +00:00
|
|
|
with testclient.session_transaction() as sess:
|
2023-02-05 18:08:25 +00:00
|
|
|
sess["user_id"] = [user.id]
|
2021-01-01 15:42:13 +00:00
|
|
|
|
2023-12-18 17:06:03 +00:00
|
|
|
testclient.app.config["CANAILLE"]["ACL"]["DEFAULT"]["PERMISSIONS"] = ["edit_self"]
|
2023-03-16 17:39:28 +00:00
|
|
|
res = testclient.get("/profile/temp/settings")
|
2023-03-16 15:25:14 +00:00
|
|
|
res.mustcontain(no="Delete my account")
|
2021-01-01 15:42:13 +00:00
|
|
|
|
2023-12-18 17:06:03 +00:00
|
|
|
testclient.app.config["CANAILLE"]["ACL"]["DEFAULT"]["PERMISSIONS"] = [
|
2022-04-05 15:16:09 +00:00
|
|
|
"edit_self",
|
|
|
|
"delete_account",
|
|
|
|
]
|
2023-11-24 11:10:17 +00:00
|
|
|
# Simulate an app restart
|
|
|
|
user.reload()
|
|
|
|
|
2023-03-16 17:39:28 +00:00
|
|
|
res = testclient.get("/profile/temp/settings")
|
2023-03-16 15:25:14 +00:00
|
|
|
res.mustcontain("Delete my account")
|
2023-07-06 16:43:37 +00:00
|
|
|
res = res.form.submit(name="action", value="confirm-delete")
|
2021-01-01 15:42:13 +00:00
|
|
|
res = (
|
|
|
|
res.form.submit(name="action", value="delete", status=302)
|
|
|
|
.follow(status=302)
|
|
|
|
.follow(status=200)
|
|
|
|
)
|
|
|
|
|
2024-04-07 16:46:08 +00:00
|
|
|
assert models.User.get(user_name="temp") is None
|
2021-01-01 15:42:13 +00:00
|
|
|
|
|
|
|
with testclient.session_transaction() as sess:
|
2022-12-29 00:10:07 +00:00
|
|
|
assert not sess.get("user_id")
|
2021-01-01 15:42:13 +00:00
|
|
|
|
2023-12-18 17:06:03 +00:00
|
|
|
testclient.app.config["CANAILLE"]["ACL"]["DEFAULT"]["PERMISSIONS"] = []
|
2022-11-01 11:25:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_account_locking(user, backend):
|
|
|
|
assert not user.locked
|
|
|
|
assert not user.lock_date
|
2024-04-07 18:12:13 +00:00
|
|
|
assert backend.check_user_password(user, "correct horse battery staple") == (
|
|
|
|
True,
|
|
|
|
None,
|
|
|
|
)
|
2022-11-01 11:25:21 +00:00
|
|
|
|
2023-05-26 15:44:15 +00:00
|
|
|
user.lock_date = datetime.datetime.now(datetime.timezone.utc)
|
2023-11-24 11:10:17 +00:00
|
|
|
assert user.locked
|
2022-11-01 11:25:21 +00:00
|
|
|
user.save()
|
|
|
|
assert user.locked
|
|
|
|
assert models.User.get(id=user.id).locked
|
2024-04-07 18:12:13 +00:00
|
|
|
assert backend.check_user_password(user, "correct horse battery staple") == (
|
2022-11-01 11:25:21 +00:00
|
|
|
False,
|
|
|
|
"Your account has been locked.",
|
|
|
|
)
|
|
|
|
|
2023-11-21 13:57:28 +00:00
|
|
|
user.lock_date = None
|
2022-11-01 11:25:21 +00:00
|
|
|
user.save()
|
|
|
|
assert not user.locked
|
|
|
|
assert not models.User.get(id=user.id).locked
|
2024-04-07 18:12:13 +00:00
|
|
|
assert backend.check_user_password(user, "correct horse battery staple") == (
|
|
|
|
True,
|
|
|
|
None,
|
|
|
|
)
|
2022-11-01 11:25:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_account_locking_past_date(user, backend):
|
|
|
|
assert not user.locked
|
|
|
|
assert not user.lock_date
|
2024-04-07 18:12:13 +00:00
|
|
|
assert backend.check_user_password(user, "correct horse battery staple") == (
|
|
|
|
True,
|
|
|
|
None,
|
|
|
|
)
|
2022-11-01 11:25:21 +00:00
|
|
|
|
2023-05-26 15:44:15 +00:00
|
|
|
user.lock_date = datetime.datetime.now(datetime.timezone.utc).replace(
|
2022-11-01 11:25:21 +00:00
|
|
|
microsecond=0
|
|
|
|
) - datetime.timedelta(days=30)
|
|
|
|
user.save()
|
|
|
|
assert user.locked
|
|
|
|
assert models.User.get(id=user.id).locked
|
2024-04-07 18:12:13 +00:00
|
|
|
assert backend.check_user_password(user, "correct horse battery staple") == (
|
2022-11-01 11:25:21 +00:00
|
|
|
False,
|
|
|
|
"Your account has been locked.",
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def test_account_locking_future_date(user, backend):
|
|
|
|
assert not user.locked
|
|
|
|
assert not user.lock_date
|
2024-04-07 18:12:13 +00:00
|
|
|
assert backend.check_user_password(user, "correct horse battery staple") == (
|
|
|
|
True,
|
|
|
|
None,
|
|
|
|
)
|
2022-11-01 11:25:21 +00:00
|
|
|
|
2023-05-26 15:44:15 +00:00
|
|
|
user.lock_date = datetime.datetime.now(datetime.timezone.utc).replace(
|
2022-11-01 11:25:21 +00:00
|
|
|
microsecond=0
|
|
|
|
) + datetime.timedelta(days=365 * 4)
|
|
|
|
user.save()
|
|
|
|
assert not user.locked
|
|
|
|
assert not models.User.get(id=user.id).locked
|
2024-04-07 18:12:13 +00:00
|
|
|
assert backend.check_user_password(user, "correct horse battery staple") == (
|
|
|
|
True,
|
|
|
|
None,
|
|
|
|
)
|
2022-11-01 11:25:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_signin_locked_account(testclient, user):
|
|
|
|
with testclient.session_transaction() as session:
|
|
|
|
assert not session.get("user_id")
|
|
|
|
|
2023-05-26 15:44:15 +00:00
|
|
|
user.lock_date = datetime.datetime.now(datetime.timezone.utc)
|
2022-11-01 11:25:21 +00:00
|
|
|
user.save()
|
|
|
|
|
|
|
|
res = testclient.get("/login", status=200)
|
|
|
|
res.form["login"] = "user"
|
|
|
|
|
|
|
|
res = res.form.submit(status=302).follow(status=200)
|
|
|
|
res.form["password"] = "correct horse battery staple"
|
|
|
|
|
|
|
|
res = res.form.submit()
|
|
|
|
res.mustcontain("Your account has been locked.")
|
|
|
|
|
2023-11-21 13:57:28 +00:00
|
|
|
user.lock_date = None
|
2022-11-01 11:25:21 +00:00
|
|
|
user.save()
|
|
|
|
|
|
|
|
|
|
|
|
def test_account_locked_during_session(testclient, logged_user):
|
2023-05-26 15:44:15 +00:00
|
|
|
logged_user.lock_date = datetime.datetime.now(datetime.timezone.utc)
|
2022-11-01 11:25:21 +00:00
|
|
|
logged_user.save()
|
|
|
|
testclient.get("/profile/user/settings", status=403)
|