mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 11:16:47 +00:00
fix(logs): a lost-OTP mail and a wrong old password leave a row
The "Lost OTP?" page writes a row when it mails a user their QR code link, or fails to, under the anonymous requester and their address. A password change refused for a wrong old password writes a failed row.
This commit is contained in:
parent
c5c6de6ba8
commit
56a3ca4c99
3 changed files with 21 additions and 1 deletions
|
|
@ -25,6 +25,16 @@ class OwnAccountRowTests(TestCase):
|
|||
self.assertEqual(rows(), [("User bob: change email", True), ("User bob: change password", True)])
|
||||
self.assertFalse(Logs.objects.filter(message__contains="pass-").exists())
|
||||
|
||||
def test_a_wrong_old_password_is_a_failed_row(self):
|
||||
# someone at an open session guessing the password
|
||||
self.client.post(reverse("accounts:change_password"), {
|
||||
"old_password": "guess-2026", "new_password1": "Bob-new-pass-1", "new_password2": "Bob-new-pass-1"})
|
||||
self.client.get(reverse("accounts:change_password"))
|
||||
self.client.post(reverse("accounts:change_password"), { # none given: not a guess
|
||||
"new_password1": "Bob-new-pass-1", "new_password2": "Bob-new-pass-1"})
|
||||
self.assertEqual(rows(), [("User bob: change password: wrong old password", False)])
|
||||
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})
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ from django.core.cache import cache
|
|||
from django.test import TestCase, override_settings
|
||||
from django.urls import reverse
|
||||
|
||||
from logs.models import Logs
|
||||
|
||||
URL = reverse("accounts:email_otp")
|
||||
|
||||
|
||||
|
|
@ -35,6 +37,9 @@ class EmailOTPTests(TestCase):
|
|||
self.enroll()
|
||||
self.post("OTP.User@Example.com") # addresses match case-insensitively
|
||||
self.assertEqual([m.to for m in mail.outbox], [["otp.user@example.com"]])
|
||||
# the requester is anonymous: the row does not make it the user
|
||||
self.assertEqual(list(Logs.objects.values_list("user", "message", "success", "ip")),
|
||||
[("", "User otp-user: mail OTP QR code (lost OTP)", True, "127.0.0.1")])
|
||||
|
||||
def test_an_unenrolled_user_gets_no_mail_and_no_device(self):
|
||||
self.post("otp.user@example.com")
|
||||
|
|
@ -63,6 +68,7 @@ class EmailOTPTests(TestCase):
|
|||
self.enroll()
|
||||
with self.assertLogs("accounts.views", level="ERROR"):
|
||||
self.post("otp.user@example.com")
|
||||
self.assertIs(Logs.objects.get(message__startswith="User otp-user: mail OTP QR code (lost OTP):").success, False)
|
||||
|
||||
|
||||
@override_settings(OTP_ENABLED=False)
|
||||
|
|
|
|||
|
|
@ -222,6 +222,8 @@ def change_password(request):
|
|||
logging.getLogger(__name__).warning("Could not remove the generated admin password file")
|
||||
messages.success(request, _("Password Changed"))
|
||||
return redirect("accounts:profile")
|
||||
if form.has_error("old_password", "password_incorrect"): # someone at an open session guessing it
|
||||
failed(request, None, f"User {request.user.username}", "change password", "wrong old password")
|
||||
|
||||
return render(request, "accounts/change_password_form.html", {"form": form, "must_change": must_change})
|
||||
|
||||
|
|
@ -329,7 +331,9 @@ def email_otp(request):
|
|||
device = get_existing_totp_device(user)
|
||||
if device is not None:
|
||||
try:
|
||||
send_email_with_otp(request, user)
|
||||
# the row's user is the requester: anonymous
|
||||
with audit(request, None, f"User {user.username}", "mail OTP QR code (lost OTP)"):
|
||||
send_email_with_otp(request, user)
|
||||
except Exception:
|
||||
logging.getLogger(__name__).exception("Could not mail the OTP QR code to user %s", user.pk)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue