Browse Source

Fix the login view to handle already authenticated users

If an already authenticated user visits /accounts/login/,
Healthchecks will now redirect them to their dashboard
instead of showing the login form.
pull/551/head
Pēteris Caune 3 years ago
parent
commit
af7e8fc949
No known key found for this signature in database GPG Key ID: E28D7679E9A9EDE2
2 changed files with 17 additions and 0 deletions
  1. +10
    -0
      hc/accounts/tests/test_login.py
  2. +7
    -0
      hc/accounts/views.py

+ 10
- 0
hc/accounts/tests/test_login.py View File

@ -11,6 +11,16 @@ class LoginTestCase(BaseTestCase):
super().setUp() super().setUp()
self.checks_url = f"/projects/{self.project.code}/checks/" self.checks_url = f"/projects/{self.project.code}/checks/"
def test_it_shows_form(self):
r = self.client.get("/accounts/login/")
self.assertContains(r, "Email Me a Link")
def test_it_redirects_authenticated_get(self):
self.client.login(username="[email protected]", password="password")
r = self.client.get("/accounts/login/")
self.assertRedirects(r, self.checks_url)
def test_it_sends_link(self): def test_it_sends_link(self):
form = {"identity": "[email protected]"} form = {"identity": "[email protected]"}


+ 7
- 0
hc/accounts/views.py View File

@ -164,6 +164,9 @@ def login(request):
response.set_cookie("auto-login", "1", max_age=300, httponly=True) response.set_cookie("auto-login", "1", max_age=300, httponly=True)
return response return response
if request.user.is_authenticated:
return _redirect_after_login(request)
bad_link = request.session.pop("bad_link", None) bad_link = request.session.pop("bad_link", None)
ctx = { ctx = {
"page": "login", "page": "login",
@ -868,11 +871,15 @@ def login_totp(request):
totp = pyotp.totp.TOTP(user.profile.totp) totp = pyotp.totp.TOTP(user.profile.totp)
if request.method == "POST": if request.method == "POST":
# To guard against brute-forcing TOTP codes, we allow
# 96 attempts per user per 24h.
if not TokenBucket.authorize_totp_attempt(user): if not TokenBucket.authorize_totp_attempt(user):
return render(request, "try_later.html") return render(request, "try_later.html")
form = forms.TotpForm(totp, request.POST) form = forms.TotpForm(totp, request.POST)
if form.is_valid(): if form.is_valid():
# We blacklist an used TOTP code for 90 seconds,
# so an attacker cannot reuse a stolen code.
if not TokenBucket.authorize_totp_code(user, form.cleaned_data["code"]): if not TokenBucket.authorize_totp_code(user, form.cleaned_data["code"]):
return render(request, "try_later.html") return render(request, "try_later.html")


Loading…
Cancel
Save