forked from GithubBackups/healthchecks
login, set-password, and change-email tokens use different salts.
This commit is contained in:
parent
2393dad09e
commit
de7160a0e6
@ -1,4 +1,3 @@
|
|||||||
from django.contrib.auth.hashers import check_password
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from hc.accounts.models import Profile
|
from hc.accounts.models import Profile
|
||||||
|
|
||||||
@ -22,7 +21,7 @@ class ProfileBackend(BasicBackend):
|
|||||||
except Profile.DoesNotExist:
|
except Profile.DoesNotExist:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if not check_password(token, profile.token):
|
if not profile.check_token(token, "login"):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return profile.user
|
return profile.user
|
||||||
|
@ -4,7 +4,7 @@ import uuid
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.hashers import make_password
|
from django.contrib.auth.hashers import check_password, make_password
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.core import signing
|
from django.core import signing
|
||||||
from django.db import models
|
from django.db import models
|
||||||
@ -54,11 +54,17 @@ class Profile(models.Model):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.team_name or self.user.email
|
return self.team_name or self.user.email
|
||||||
|
|
||||||
def send_instant_login_link(self, inviting_profile=None):
|
def prepare_token(self, salt):
|
||||||
token = str(uuid.uuid4())
|
token = str(uuid.uuid4())
|
||||||
self.token = make_password(token)
|
self.token = make_password(token, salt)
|
||||||
self.save()
|
self.save()
|
||||||
|
return token
|
||||||
|
|
||||||
|
def check_token(self, token, salt):
|
||||||
|
return salt in self.token and check_password(token, self.token)
|
||||||
|
|
||||||
|
def send_instant_login_link(self, inviting_profile=None):
|
||||||
|
token = self.prepare_token("login")
|
||||||
path = reverse("hc-check-token", args=[self.user.username, token])
|
path = reverse("hc-check-token", args=[self.user.username, token])
|
||||||
ctx = {
|
ctx = {
|
||||||
"button_text": "Log In",
|
"button_text": "Log In",
|
||||||
@ -68,10 +74,7 @@ class Profile(models.Model):
|
|||||||
emails.login(self.user.email, ctx)
|
emails.login(self.user.email, ctx)
|
||||||
|
|
||||||
def send_set_password_link(self):
|
def send_set_password_link(self):
|
||||||
token = str(uuid.uuid4())
|
token = self.prepare_token("set-password")
|
||||||
self.token = make_password(token)
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
path = reverse("hc-set-password", args=[token])
|
path = reverse("hc-set-password", args=[token])
|
||||||
ctx = {
|
ctx = {
|
||||||
"button_text": "Set Password",
|
"button_text": "Set Password",
|
||||||
@ -80,10 +83,7 @@ class Profile(models.Model):
|
|||||||
emails.set_password(self.user.email, ctx)
|
emails.set_password(self.user.email, ctx)
|
||||||
|
|
||||||
def send_change_email_link(self):
|
def send_change_email_link(self):
|
||||||
token = str(uuid.uuid4())
|
token = self.prepare_token("change-email")
|
||||||
self.token = make_password(token)
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
path = reverse("hc-change-email", args=[token])
|
path = reverse("hc-change-email", args=[token])
|
||||||
ctx = {
|
ctx = {
|
||||||
"button_text": "Change Email",
|
"button_text": "Change Email",
|
||||||
|
@ -6,7 +6,7 @@ from hc.test import BaseTestCase
|
|||||||
class ChangeEmailTestCase(BaseTestCase):
|
class ChangeEmailTestCase(BaseTestCase):
|
||||||
|
|
||||||
def test_it_shows_form(self):
|
def test_it_shows_form(self):
|
||||||
self.profile.token = make_password("foo")
|
self.profile.token = make_password("foo", "change-email")
|
||||||
self.profile.save()
|
self.profile.save()
|
||||||
|
|
||||||
self.client.login(username="alice@example.org", password="password")
|
self.client.login(username="alice@example.org", password="password")
|
||||||
@ -15,7 +15,7 @@ class ChangeEmailTestCase(BaseTestCase):
|
|||||||
self.assertContains(r, "Change Account's Email Address")
|
self.assertContains(r, "Change Account's Email Address")
|
||||||
|
|
||||||
def test_it_changes_password(self):
|
def test_it_changes_password(self):
|
||||||
self.profile.token = make_password("foo")
|
self.profile.token = make_password("foo", "change-email")
|
||||||
self.profile.save()
|
self.profile.save()
|
||||||
|
|
||||||
self.client.login(username="alice@example.org", password="password")
|
self.client.login(username="alice@example.org", password="password")
|
||||||
@ -28,7 +28,7 @@ class ChangeEmailTestCase(BaseTestCase):
|
|||||||
self.assertFalse(self.alice.has_usable_password())
|
self.assertFalse(self.alice.has_usable_password())
|
||||||
|
|
||||||
def test_it_requires_unique_email(self):
|
def test_it_requires_unique_email(self):
|
||||||
self.profile.token = make_password("foo")
|
self.profile.token = make_password("foo", "change-email")
|
||||||
self.profile.save()
|
self.profile.save()
|
||||||
|
|
||||||
self.client.login(username="alice@example.org", password="password")
|
self.client.login(username="alice@example.org", password="password")
|
||||||
|
@ -6,7 +6,7 @@ class CheckTokenTestCase(BaseTestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(CheckTokenTestCase, self).setUp()
|
super(CheckTokenTestCase, self).setUp()
|
||||||
self.profile.token = make_password("secret-token")
|
self.profile.token = make_password("secret-token", "login")
|
||||||
self.profile.save()
|
self.profile.save()
|
||||||
|
|
||||||
def test_it_shows_form(self):
|
def test_it_shows_form(self):
|
||||||
|
@ -7,7 +7,6 @@ from django.contrib.auth import login as auth_login
|
|||||||
from django.contrib.auth import logout as auth_logout
|
from django.contrib.auth import logout as auth_logout
|
||||||
from django.contrib.auth import authenticate
|
from django.contrib.auth import authenticate
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth.hashers import check_password
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.core import signing
|
from django.core import signing
|
||||||
from django.http import HttpResponseForbidden, HttpResponseBadRequest
|
from django.http import HttpResponseForbidden, HttpResponseBadRequest
|
||||||
@ -288,7 +287,7 @@ def badges(request):
|
|||||||
@login_required
|
@login_required
|
||||||
def set_password(request, token):
|
def set_password(request, token):
|
||||||
profile = request.user.profile
|
profile = request.user.profile
|
||||||
if not check_password(token, profile.token):
|
if not profile.check_token(token, "set-password"):
|
||||||
return HttpResponseBadRequest()
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
@ -315,7 +314,7 @@ def set_password(request, token):
|
|||||||
@login_required
|
@login_required
|
||||||
def change_email(request, token):
|
def change_email(request, token):
|
||||||
profile = request.user.profile
|
profile = request.user.profile
|
||||||
if not check_password(token, profile.token):
|
if not profile.check_token(token, "change-email"):
|
||||||
return HttpResponseBadRequest()
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
|
Loading…
x
Reference in New Issue
Block a user