1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-09 03:36:48 +00:00

fix(accounts): a signed-in user is sent on from the login page

The login page showed its sign-in card to a user who was already signed
in, with the navbar squeezed beside it. Both login views, with and
without OTP, now send that user to the page in next, or to the default
page when next is missing or points elsewhere. Every permission check
answers 403 instead of redirecting to the login, so this cannot loop.
The page test renders the login page signed out.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
catborise 2026-10-21 20:24:20 +03:00
parent 676bcfeb09
commit 961b43a42e
5 changed files with 22 additions and 0 deletions

View file

@ -141,3 +141,9 @@ class OTPLoginHTTPTestCase(TestCase):
device = TOTPDevice.objects.create(user=self.user, confirmed=True)
response = self._post(otp_token=wrong_token(device))
self.assertEqual(response.status_code, 200)
def test_a_signed_in_user_is_sent_on_from_the_login_page(self):
from django.urls import reverse
self.client.force_login(self.user)
response = self.client.get(f"{reverse('accounts:login')}?next={reverse('computes')}")
self.assertRedirects(response, reverse("computes"), fetch_redirect_response=False)

View file

@ -79,6 +79,14 @@ class AccountsTestCase(TestCase):
response = client.post(reverse("accounts:logout"))
self.assertRedirects(response, reverse("accounts:login"))
def test_a_signed_in_user_is_sent_on_from_the_login_page(self):
self.client.force_login(self.test_user)
login = reverse("accounts:login")
response = self.client.get(f"{login}?next={reverse('computes')}")
self.assertRedirects(response, reverse("computes"), fetch_redirect_response=False)
response = self.client.get(f"{login}?next=https://example.com/")
self.assertRedirects(response, settings.LOGIN_REDIRECT_URL, fetch_redirect_response=False)
def test_change_password(self):
self.client.force_login(self.test_user)

View file

@ -45,6 +45,7 @@ if settings.OTP_ENABLED:
LoginView.as_view(
template_name="accounts/otp_login.html",
authentication_form=SingleDeviceOTPForm,
redirect_authenticated_user=True,
),
name="login",
),

View file

@ -29,6 +29,8 @@ from django.contrib.auth.views import LoginView
from logs.views import addlogmsg
class CustomLoginView(LoginView):
redirect_authenticated_user = True
def form_valid(self, form):
username = form.cleaned_data['username']
addlogmsg(username, "-", "-", "Logged In")

View file

@ -55,6 +55,11 @@ class PageTests(TestCase):
self.assertEqual(response.status_code, 200)
checked.append("network")
yield "network", html.fromstring(response.content)
# a signed-in user is sent on from the login page
response = self.client_class().get(reverse("accounts:login"))
self.assertEqual(response.status_code, 200)
checked.append("accounts:login")
yield "accounts:login", html.fromstring(response.content)
self.assertTrue({"index", "overview", "instances:instance", "nwfilter"} <= set(checked), checked)
self.assertIn("instances:create_instance", checked)