mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 19:26:48 +00:00
EMAIL_TIMEOUT was not set, and Django's SMTP connection then waits for a server without end: one that accepts the connection and stops answering held the request's thread for good, also on the login page's Email OTP form, which anyone may post. The settings template sets 10 seconds. An administrator whose mail fails is told why on the account page instead of getting an error page.
104 lines
5 KiB
Python
104 lines
5 KiB
Python
"""Changes to a user's own account, VM ownership, OTP mails and SSH keys write rows on the Logs page."""
|
|
|
|
from django.contrib.auth import get_user_model
|
|
from django.test import TestCase
|
|
from django.urls import reverse
|
|
|
|
from accounts.models import UserAttributes
|
|
from logs.models import Logs
|
|
|
|
|
|
def rows():
|
|
return list(Logs.objects.order_by("id").values_list("message", "success"))
|
|
|
|
|
|
class OwnAccountRowTests(TestCase):
|
|
def setUp(self):
|
|
self.bob = get_user_model().objects.create_user("bob", password="Bob-pass-2026")
|
|
self.client.force_login(self.bob)
|
|
Logs.objects.all().delete() # the login's row
|
|
|
|
def test_own_profile_and_password(self):
|
|
self.client.post(reverse("accounts:profile"), {"username": "bob", "email": "bob@example.com"})
|
|
self.client.post(reverse("accounts:change_password"), {
|
|
"old_password": "Bob-pass-2026", "new_password1": "Bob-new-pass-1", "new_password2": "Bob-new-pass-1"})
|
|
self.assertEqual(rows(), [("User bob: change email", True), ("User bob: change password", True)])
|
|
self.assertFalse(Logs.objects.filter(message__contains="pass-").exists())
|
|
|
|
def test_the_first_login_password_change(self):
|
|
self.bob.user_permissions.clear()
|
|
UserAttributes.objects.update_or_create(user=self.bob, defaults={"must_change_password": True})
|
|
self.client.post(reverse("accounts:change_password"), {
|
|
"old_password": "Bob-pass-2026", "new_password1": "Bob-new-pass-1", "new_password2": "Bob-new-pass-1"})
|
|
self.assertEqual(rows(), [("User bob: change password", True)])
|
|
|
|
|
|
SSH_KEY = ("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC6OOdbfv27QVnSC6sKxGaHb6YFc+3gxCkyVR3cTSXE/n5BEGf8aOgBpepULWa1RZfx"
|
|
"YHY14PlKULDygdXSdrrR2kNSwoKz/Oo4d+3EE92L7ocl1+djZbptzgWgtw1OseLwbFik+iKlIdqPsH+IUQvX7yV545ZQtAP8Qj1R+uCqkw=="
|
|
" test@test")
|
|
|
|
|
|
class AdminAccountRowTests(TestCase):
|
|
def setUp(self):
|
|
from computes.models import Compute
|
|
from instances.models import Instance
|
|
|
|
self.admin = get_user_model().objects.create_superuser("audit-admin", "audit@example.com", "pw")
|
|
self.bob = get_user_model().objects.create_user("bob", password="Bob-pass-2026")
|
|
compute = Compute.objects.create(name="c1", hostname="127.0.0.1", login="", password="", type=4)
|
|
self.vm = Instance.objects.create(compute=compute, name="vm", uuid="66666666-6666-6666-6666-666666666666")
|
|
self.client.force_login(self.admin)
|
|
Logs.objects.all().delete() # the login's row
|
|
|
|
def test_ownership_from_the_accounts_pages(self):
|
|
from accounts.models import UserInstance
|
|
|
|
self.client.post(reverse("accounts:user_instance_create", args=[self.bob.pk]),
|
|
{"user": self.bob.pk, "instance": self.vm.pk})
|
|
ui = UserInstance.objects.get(user=self.bob, instance=self.vm)
|
|
url = reverse("accounts:user_instance_update", args=[ui.pk])
|
|
self.client.post(url, {"is_vnc": "on"})
|
|
self.client.post(url, {"is_vnc": "on"}) # no change
|
|
self.client.post(reverse("accounts:user_instance_delete", args=[ui.pk]))
|
|
self.assertEqual(rows(), [
|
|
("VM vm: add owner bob", True),
|
|
("VM vm: change owner bob: is_vnc", True),
|
|
("VM vm: remove owner bob", True),
|
|
])
|
|
self.assertEqual(set(Logs.objects.values_list("user", "host", "instance", "instance_uuid")),
|
|
{("audit-admin", "c1", "vm", self.vm.uuid)})
|
|
|
|
def test_otp_mail_without_an_email(self):
|
|
from smtplib import SMTPException
|
|
from unittest.mock import patch
|
|
|
|
from django_otp.plugins.otp_totp.models import TOTPDevice
|
|
|
|
url = reverse("accounts:admin_email_otp", args=[self.bob.pk])
|
|
with patch("accounts.views.send_email_with_otp") as send:
|
|
self.client.post(url)
|
|
send.assert_not_called()
|
|
self.assertFalse(TOTPDevice.objects.filter(user=self.bob).exists())
|
|
|
|
self.bob.email = "bob@example.com"
|
|
self.bob.save()
|
|
with patch("accounts.views.send_email_with_otp") as send:
|
|
self.client.post(url)
|
|
send.assert_called_once()
|
|
with patch("accounts.views.send_email_with_otp", side_effect=SMTPException("refused")):
|
|
response = self.client.post(url, follow=True)
|
|
self.assertContains(response, "The OTP QR code could not be mailed to bob: refused")
|
|
self.assertEqual(rows(), [
|
|
("User bob: mail OTP QR code: no email address", False),
|
|
("User bob: mail OTP QR code", True),
|
|
("User bob: mail OTP QR code: SMTPException", False),
|
|
])
|
|
|
|
def test_ssh_keys(self):
|
|
from accounts.models import UserSSHKey
|
|
|
|
self.client.post(reverse("accounts:ssh_key_create"), {"keyname": "laptop", "keypublic": SSH_KEY})
|
|
key = UserSSHKey.objects.get(keyname="laptop")
|
|
self.client.post(reverse("accounts:ssh_key_delete", args=[key.pk]))
|
|
self.assertEqual(rows(), [("SSH key laptop: add", True), ("SSH key laptop: delete", True)])
|
|
self.assertFalse(Logs.objects.filter(message__contains="AAAA").exists())
|