Browse Source

A work around for email servers that open our one-time login links.

pull/81/head
Pēteris Caune 8 years ago
parent
commit
2ea01a5ff8
3 changed files with 88 additions and 13 deletions
  1. +7
    -3
      hc/accounts/tests/test_check_token.py
  2. +19
    -10
      hc/accounts/views.py
  3. +62
    -0
      templates/accounts/check_token_submit.html

+ 7
- 3
hc/accounts/tests/test_check_token.py View File

@ -9,8 +9,12 @@ class CheckTokenTestCase(BaseTestCase):
self.profile.token = make_password("secret-token")
self.profile.save()
def test_it_redirects(self):
def test_it_shows_form(self):
r = self.client.get("/accounts/check_token/alice/secret-token/")
self.assertContains(r, "You are about to log in")
def test_it_redirects(self):
r = self.client.post("/accounts/check_token/alice/secret-token/")
self.assertRedirects(r, "/checks/")
# After login, token should be blank
@ -22,12 +26,12 @@ class CheckTokenTestCase(BaseTestCase):
self.client.login(username="[email protected]", password="password")
# Login again, when already authenticated
r = self.client.get("/accounts/check_token/alice/secret-token/")
r = self.client.post("/accounts/check_token/alice/secret-token/")
self.assertRedirects(r, "/checks/")
def test_it_redirects_bad_login(self):
# Login with a bad token
url = "/accounts/check_token/alice/invalid-token/"
r = self.client.get(url, follow=True)
r = self.client.post(url, follow=True)
self.assertRedirects(r, "/accounts/login/")
self.assertContains(r, "incorrect or expired")

+ 19
- 10
hc/accounts/views.py View File

@ -105,19 +105,28 @@ def check_token(request, username, token):
# User is already logged in
return redirect("hc-checks")
user = authenticate(username=username, token=token)
if user is not None and user.is_active:
# This should get rid of "welcome_code" in session
request.session.flush()
# Some email servers open links in emails to check for malicious content.
# To work around this, we sign user in if the method is POST.
#
# If the method is GET, we instead serve a HTML form and a piece
# of Javascript to automatically submit it.
user.profile.token = ""
user.profile.save()
auth_login(request, user)
if request.method == "POST":
user = authenticate(username=username, token=token)
if user is not None and user.is_active:
# This should get rid of "welcome_code" in session
request.session.flush()
return redirect("hc-checks")
user.profile.token = ""
user.profile.save()
auth_login(request, user)
return redirect("hc-checks")
request.session["bad_link"] = True
return redirect("hc-login")
request.session["bad_link"] = True
return redirect("hc-login")
return render(request, "accounts/check_token_submit.html")
@login_required


+ 62
- 0
templates/accounts/check_token_submit.html View File

@ -0,0 +1,62 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Continue to healthchecks.io</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<form id="form-auto" method="post">{% csrf_token %}</form>
<script>
document.getElementById("form-auto").submit();
</script>
<style>
body {
font-family: Arial;
text-align: center;
margin: 10em;
}
form {
text
}
input {
display: inline-block;
margin-bottom: 0;
font-weight: normal;
text-align: center;
vertical-align: middle;
touch-action: manipulation;
cursor: pointer;
background-image: none;
border: 1px solid transparent;
white-space: nowrap;
padding: 10px 16px;
font-size: 18px;
line-height: 1.3333333;
border-radius: 6px;
color: #ffffff;
background-color: #22bc66;
border-color: #1ea65a;
}
</style>
<noscript>
<p>You are about to log into healthchecks.io.</p>
<p>Please press the button below to continue:</p>
<br />
<form id="form" method="post">
{% csrf_token %}
<input
id="submit-btn"
type="submit"
class="btn btn-lg btn-primary"
value="Continue to healthchecks.io">
</form>
</noscript>
</body>
</html>

Loading…
Cancel
Save