From a6f86e9506dd43da042e8f335a761ec336536ac8 Mon Sep 17 00:00:00 2001 From: Dave Dash Date: Thu, 19 Aug 2010 10:42:01 -0700 Subject: [PATCH] bug 558507, adds recaptcha --- apps/users/forms.py | 42 ++++++++++++++++-------- apps/users/models.py | 6 ++-- apps/users/templates/users/register.html | 7 ++++ apps/users/tests/test_forms.py | 9 +++-- apps/users/views.py | 6 ++-- requirements/prod.txt | 4 +++ settings.py | 5 ++- 7 files changed, 57 insertions(+), 22 deletions(-) diff --git a/apps/users/forms.py b/apps/users/forms.py index 2f064df9c5..db193a191e 100644 --- a/apps/users/forms.py +++ b/apps/users/forms.py @@ -4,7 +4,9 @@ from django import forms from django.contrib.auth import forms as auth_forms from django.forms.util import ErrorList +import captcha.fields import commonware.log +import happyforms from tower import ugettext as _ from .models import UserProfile, BlacklistedUsername @@ -66,14 +68,19 @@ class UserDeleteForm(forms.Form): super(UserDeleteForm, self).save(**kw) -class UserRegisterForm(forms.ModelForm): - """For registering users. We're not building off +class UserRegisterForm(happyforms.ModelForm): + """ + For registering users. We're not building off d.contrib.auth.forms.UserCreationForm because it doesn't do a lot of the - details here, so we'd have to rewrite most of it anyway.""" - password = forms.CharField(max_length=255, required=False, - widget=forms.PasswordInput(render_value=False)) - password2 = forms.CharField(max_length=255, required=False, - widget=forms.PasswordInput(render_value=False)) + details here, so we'd have to rewrite most of it anyway. + """ + + password = forms.CharField(max_length=255, + widget=forms.PasswordInput(render_value=False)) + + password2 = forms.CharField(max_length=255, + widget=forms.PasswordInput(render_value=False)) + recaptcha = captcha.fields.ReCaptchaField() class Meta: model = UserProfile @@ -81,7 +88,7 @@ class UserRegisterForm(forms.ModelForm): def clean_username(self): name = self.cleaned_data['username'] if BlacklistedUsername.blocked(name): - raise forms.ValidationError("This username is invalid.") + raise forms.ValidationError(_('This username is invalid.')) return name def clean(self): @@ -90,13 +97,14 @@ class UserRegisterForm(forms.ModelForm): data = self.cleaned_data # Passwords - p1 = data.get("password") - p2 = data.get("password2") + p1 = data.get('password') + p2 = data.get('password2') if p1 != p2: - msg = _("The passwords did not match.") - self._errors["password2"] = ErrorList([msg]) - del data["password2"] + msg = _('The passwords did not match.') + self._errors['password2'] = ErrorList([msg]) + if p2: + del data['password2'] return data @@ -104,11 +112,19 @@ class UserRegisterForm(forms.ModelForm): class UserEditForm(UserRegisterForm): oldpassword = forms.CharField(max_length=255, required=False, widget=forms.PasswordInput(render_value=False)) + password = forms.CharField(max_length=255, required=False, + widget=forms.PasswordInput(render_value=False)) + + password2 = forms.CharField(max_length=255, required=False, + widget=forms.PasswordInput(render_value=False)) def __init__(self, *args, **kwargs): self.request = kwargs.pop('request', None) super(UserEditForm, self).__init__(*args, **kwargs) + # TODO: We should inherit from a base form not UserRegisterForm + del self.fields['recaptcha'] + class Meta: model = UserProfile exclude = ['password'] diff --git a/apps/users/models.py b/apps/users/models.py index bb96821789..3d933791ae 100644 --- a/apps/users/models.py +++ b/apps/users/models.py @@ -49,10 +49,8 @@ class UserProfile(amo.models.ModelBase): nickname = models.CharField(max_length=255, default='', null=True, blank=True) - firstname = models.CharField(max_length=255, default='', null=True, - blank=True) - lastname = models.CharField(max_length=255, default='', null=True, - blank=True) + firstname = models.CharField(max_length=255, default='', blank=True) + lastname = models.CharField(max_length=255, default='', blank=True) username = models.CharField(max_length=255, default='', unique=True) display_name = models.CharField(max_length=255, default='', null=True, diff --git a/apps/users/templates/users/register.html b/apps/users/templates/users/register.html index 33d691d00e..9cbcc55cee 100644 --- a/apps/users/templates/users/register.html +++ b/apps/users/templates/users/register.html @@ -58,6 +58,13 @@ {{ form.password2|safe }} {{ form.password2.errors|safe }} +
  • + + {{ form.recaptcha|safe }} + {{ form.recaptcha.errors|safe }} +
  • diff --git a/apps/users/tests/test_forms.py b/apps/users/tests/test_forms.py index d6e0587036..939487a405 100644 --- a/apps/users/tests/test_forms.py +++ b/apps/users/tests/test_forms.py @@ -5,6 +5,7 @@ from django.utils.http import int_to_base36 import test_utils from manage import settings +from mock import patch from nose.tools import eq_ import amo.test_utils @@ -266,13 +267,17 @@ class TestUserRegisterForm(UserFormBase): self.assertContains(r, "You are already logged in") self.assertNotContains(r, '') - def test_success(self): + @patch('captcha.fields.ReCaptchaField.clean') + def test_success(self, clean): + clean = lambda: '' + data = {'email': 'john.connor@sky.net', 'password': 'carebears', 'password2': 'carebears', 'username': 'BigJC', 'homepage': ''} - r = self.client.post('/en-US/firefox/users/register', data) + r = self.client.post('/en-US/firefox/users/register', data, + follow=True) self.assertContains(r, "Congratulations!") u = User.objects.get(email='john.connor@sky.net').get_profile() diff --git a/apps/users/views.py b/apps/users/views.py index 17d691e2d5..3a402b365f 100644 --- a/apps/users/views.py +++ b/apps/users/views.py @@ -1,4 +1,3 @@ -import json import random import string from django import http @@ -27,11 +26,12 @@ from .utils import EmailResetCode log = commonware.log.getLogger('z.users') + @login_required(redirect=False) @json_view def ajax(request): """Query for a user matching a given email.""" - email = request.GET.get('q','').strip() + email = request.GET.get('q', '').strip() u = get_object_or_404(UserProfile, email=email) return dict(id=u.id, name=u.display_name) @@ -306,7 +306,9 @@ def register(request): messages.info(request, _("You are already logged in to an account.")) form = None elif request.method == 'POST': + form = forms.UserRegisterForm(request.POST) + if form.is_valid(): data = request.POST u = UserProfile() diff --git a/requirements/prod.txt b/requirements/prod.txt index 9c6ff6ad7c..5cb23bbe58 100644 --- a/requirements/prod.txt +++ b/requirements/prod.txt @@ -31,3 +31,7 @@ importlib==1.0.2 # Better Forms -e git://github.com/mozilla/happyforms.git#egg=happyforms + +# Recaptcha +-e git://github.com/mozilla/django-recaptcha.git#egg=django-recaptcha + diff --git a/settings.py b/settings.py index 8ce08a982e..40fbdcc380 100644 --- a/settings.py +++ b/settings.py @@ -534,8 +534,11 @@ def read_only_mode(env): # Uploaded file limits MAX_ICON_UPLOAD_SIZE = 4 * 1024 * 1024 - ## Feature switches # Use this to keep collections compatible with remora before we're ready to # switch to zamboni/bandwagon3. NEW_COLLECTIONS = True + +# RECAPTCHA +RECAPTCHA_PUBLIC_KEY = '' +RECAPTCHA_PRIVATE_KEY = ''