Skip to content

Commit

Permalink
signup robustness
Browse files Browse the repository at this point in the history
  • Loading branch information
zackmdavis committed Oct 26, 2014
1 parent 80ab4f8 commit 883b695
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 47 deletions.
22 changes: 17 additions & 5 deletions core/forms.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
from django import forms

from core.models import FinetoothUser

class CommentForm(forms.Form):
content = forms.CharField(
label="", widget=forms.Textarea(attrs={'rows': 6})
)

class SignupForm(forms.Form):
username = forms.CharField(label="username")
password = forms.CharField(widget=forms.PasswordInput())
confirm_password = forms.CharField(widget=forms.PasswordInput())
email = forms.CharField()
class SignupForm(forms.ModelForm):
class Meta:
model = FinetoothUser
fields = ('username', 'email')

password = forms.CharField(widget=forms.PasswordInput)
confirm_password = forms.CharField(widget=forms.PasswordInput)

def clean_confirm_password(self):
password = self.cleaned_data.get('password')
confirm_password = self.cleaned_data.get('confirm_password')
if password != confirm_password:
raise forms.ValidationError(
"Password confirmation didn't match."
)
return password
60 changes: 41 additions & 19 deletions core/tests/view_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,56 @@ class SignupTest(TestCase):
def test_can_sign_up(self):
response = self.client.post(
reverse('sign_up'),
{'username': "signup_testr", 'password': "moeDukr(,rpdCesLlrqr",
'confirm_password': "moeDukr(,rpdCesLlrqr", 'email': "[email protected]"}
)
# XX: The call to assertRedirects was printing an empty
# dictionary to standard out (if someone accidentally left a
# debugging print statement in Django core (?!), I couldn't
# find it)
with open(os.devnull, 'w') as dev_null:
original_stdout = sys.stdout
sys.stdout = dev_null
self.assertRedirects(response, '/')
sys.stdout = original_stdout
self.assertTrue(
FinetoothUser.objects.filter(username="signup_testr").exists()
)

@skip("an apparently spurious TransactionManagementError due to the issue "
"described at http://stackoverflow.com/a/23326971") # TODO FIXME
{'username': "signup_testr",
'password': "moeDukr(,rpdCesLlrq",
'confirm_password': "moeDukr(,rpdCesLlrq",
'email': "[email protected]"}
)
self.assertRedirects(response, '/')
user_queryset = FinetoothUser.objects.filter(username="signup_testr")
self.assertTrue(user_queryset.exists())
self.assertTrue(user_queryset[0].check_password("moeDukr(,rpdCesLlrq"))

def test_cannnot_claim_extant_username(self):
f.FinetoothUserFactory.create(username="username_squatter")
response = self.client.post(
reverse('sign_up'),
{'username': "username_squatter", 'password': "oclxJums^whyysmtam",
{'username': "username_squatter",
'password': "oclxJums^whyysmtam",
'confirm_password': "oclxJums^whyysmtam",
'email': "[email protected]"},
follow=True
)
self.assertIn(b"Username already exists.", response.content)

def test_confirm_password_must_match(self):
prior_user_count = FinetoothUser.objects.count()
response = self.client.post(
reverse('sign_up'),
{'username': "pentest",
'password': "*sd6f3mjdrt3y42",
'confirm_password': "not_the_same_password_is_it",
'email': "[email protected]"},
follow=True
)
post_user_count = FinetoothUser.objects.count()
self.assertEqual(prior_user_count, post_user_count)
self.assertEqual(422, response.status_code)

def test_required_fields(self):
prior_user_count = FinetoothUser.objects.count()
response = self.client.post(
reverse('sign_up'),
{'username': '',
'password': "oclxJums^whyysmtam",
'confirm_password': "oclxJums^whyysmtam",
'email': ''},
follow=True
)
post_user_count = FinetoothUser.objects.count()
self.assertEqual(prior_user_count, post_user_count)
self.assertEqual(422, response.status_code)


class TaggingTest(TestCase):

Expand Down
38 changes: 17 additions & 21 deletions core/views/views.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import json
from datetime import datetime


from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.http import HttpResponseForbidden
from django.http import HttpResponseBadRequest
from django.http import HttpRequest

from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.debug import sensitive_post_parameters
from django.views.decorators.http import require_POST
Expand All @@ -32,30 +30,28 @@ def home(request, page_number):
context = scored_context(context['posts'], context)
return render(request, "home.html", context)

@sensitive_post_parameters('password')
@sensitive_post_parameters('password', 'confirm_password')
def sign_up(request):
if request.method == "POST":
signup_form = SignupForm(request.POST)
if signup_form.is_valid():
try:
username = signup_form.cleaned_data["username"]
email = signup_form.cleaned_data["email"]
password = signup_form.cleaned_data["password"]
confirm_password = signup_form.cleaned_data["confirm_password"]
if password != confirm_password:
messages.error(request, "Passwords do not match.")
return render(request, 'sign_up.html', {'form': signup_form})
FinetoothUser.objects.create_user(username, email, password)
messages.success(request, "Account creation successful!")
new_user = authenticate(username=username, password=password)
login(request, new_user)
return redirect("home")
except IntegrityError:
messages.error(request, "Username already exists.")
return redirect("sign_up")
username = signup_form.cleaned_data["username"]
email = signup_form.cleaned_data["email"]
password = signup_form.cleaned_data["password"]
confirm_password = signup_form.cleaned_data["confirm_password"]
FinetoothUser.objects.create_user(username, email, password)
messages.success(request, "Account creation successful!")
new_user = authenticate(username=username, password=password)
login(request, new_user)
return redirect("home")
else:
messages.warning(request, signup_form.errors)
return render(
request, 'sign_up.html', {'signup_form': signup_form}, status=422
)
else:
form = SignupForm()
return render(request, 'sign_up.html', locals())
signup_form = SignupForm()
return render(request, 'sign_up.html', {'signup_form': signup_form})

@require_POST
def logout_view(request):
Expand Down
3 changes: 1 addition & 2 deletions templates/sign_up.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
{% block content %}
<form action="{% url 'sign_up' %}" method="post">
{% csrf_token %}
{{form.as_p}}
{{ signup_form.as_p }}

<p><input type="submit" value="Submit"></p>
</form>
{% endblock %}

0 comments on commit 883b695

Please sign in to comment.