annotate accounts/forms.py @ 645:99f7917702ca

Fix 081a88b3bfc8, javascript resize of forum images. Commit 081a88b3bfc8 broke those pages that loaded forums.js but did not load the imagesLoaded jQuery extension. Now we have arranged it so that only the forums topic view loads imagesLoaded and put the resizing javascript inline.
author Brian Neal <bgneal@gmail.com>
date Mon, 11 Mar 2013 15:30:25 -0500
parents ee87ea74d46b
children 8e6b8ffe5f34
rev   line source
gremmie@1 1 """forms for the accounts application"""
gremmie@1 2
bgneal@74 3 import logging
bgneal@74 4
gremmie@1 5 from django import forms
gremmie@1 6 from django.contrib.auth.models import User
gremmie@1 7 from django.core.urlresolvers import reverse
gremmie@1 8 from django.template.loader import render_to_string
gremmie@1 9 from django.contrib.sites.models import Site
bgneal@6 10 from django.conf import settings
gremmie@1 11
gremmie@1 12 from core.functions import send_mail
gremmie@1 13 from accounts.models import PendingUser
gremmie@1 14 from accounts.models import IllegalUsername
gremmie@1 15 from accounts.models import IllegalEmail
bgneal@472 16 from antispam.rate_limit import block_ip
gremmie@1 17
gremmie@1 18
gremmie@1 19 class RegisterForm(forms.Form):
bgneal@74 20 """Form used to register with the website"""
bgneal@498 21 username = forms.RegexField(
bgneal@498 22 max_length=30,
bgneal@498 23 regex=r'^\w+$',
bgneal@498 24 error_messages={'invalid': ('Your username must be 30 characters or'
bgneal@498 25 ' less and contain only letters, numbers and underscores.')},
bgneal@498 26 widget=forms.TextInput(attrs={'class': 'text'}),
bgneal@498 27 )
bgneal@498 28 email = forms.EmailField(widget=forms.TextInput(attrs={'class': 'text'}))
bgneal@498 29 password1 = forms.CharField(label="Password",
bgneal@498 30 widget=forms.PasswordInput(attrs={'class': 'text'}))
bgneal@498 31 password2 = forms.CharField(label="Password confirmation",
bgneal@498 32 widget=forms.PasswordInput(attrs={'class': 'text'}))
bgneal@316 33 agree_age = forms.BooleanField(required=True,
bgneal@155 34 label='I certify that I am over the age of 13',
bgneal@155 35 error_messages={
bgneal@347 36 'required': 'Sorry, but you must be over the age of 13 to '
bgneal@155 37 'register at our site.',
bgneal@155 38 })
bgneal@316 39 agree_tos = forms.BooleanField(required=True,
bgneal@155 40 label='I agree to the Terms of Service',
bgneal@155 41 error_messages={
bgneal@155 42 'required': 'You have not agreed to our Terms of Service.',
bgneal@155 43 })
bgneal@155 44 agree_privacy = forms.BooleanField(required=True,
bgneal@155 45 label='I agree to the Privacy Policy',
bgneal@155 46 error_messages={
bgneal@155 47 'required': 'You have not agreed to our Privacy Policy.',
bgneal@155 48 })
bgneal@498 49 question1 = forms.CharField(label="What number appears in the site name?",
bgneal@498 50 widget=forms.TextInput(attrs={'class': 'text'}))
bgneal@347 51 question2 = forms.CharField(label='', required=False,
bgneal@347 52 widget=forms.TextInput(attrs={'style': 'display: none;'}))
gremmie@1 53
bgneal@74 54 def __init__(self, *args, **kwargs):
bgneal@74 55 self.ip = kwargs.pop('ip', '?')
bgneal@74 56 super(RegisterForm, self).__init__(*args, **kwargs)
bgneal@74 57
bgneal@74 58 def clean_username(self):
bgneal@74 59 username = self.cleaned_data['username']
bgneal@74 60 try:
bgneal@565 61 User.objects.get(username=username)
bgneal@74 62 except User.DoesNotExist:
gremmie@1 63 try:
bgneal@565 64 PendingUser.objects.get(username=username)
bgneal@74 65 except PendingUser.DoesNotExist:
bgneal@74 66 try:
bgneal@565 67 IllegalUsername.objects.get(username=username)
bgneal@74 68 except IllegalUsername.DoesNotExist:
bgneal@74 69 return username
bgneal@74 70 self._validation_error("That username is not allowed.", username)
bgneal@74 71 self._validation_error("A pending user with that username already exists.", username)
bgneal@74 72 self._validation_error("A user with that username already exists.", username)
gremmie@1 73
bgneal@74 74 def clean_email(self):
bgneal@74 75 email = self.cleaned_data['email']
bgneal@565 76
bgneal@565 77 if User.objects.filter(email=email).count():
bgneal@565 78 self._validation_error("A user with that email address already exists.", email)
bgneal@565 79 elif PendingUser.objects.filter(email=email).count():
bgneal@74 80 self._validation_error("A pending user with that email address already exists.", email)
bgneal@565 81 elif IllegalEmail.objects.filter(email=email).count():
bgneal@565 82 self._validation_error("That email address is not allowed.", email)
bgneal@565 83
bgneal@565 84 # email is ok
bgneal@565 85 return email
gremmie@1 86
bgneal@74 87 def clean_password2(self):
bgneal@74 88 password1 = self.cleaned_data.get("password1", "")
bgneal@74 89 password2 = self.cleaned_data["password2"]
bgneal@74 90 if password1 != password2:
bgneal@74 91 self._validation_error("The two password fields didn't match.")
bgneal@155 92 if len(password1) < 6:
bgneal@155 93 self._validation_error("Please choose a password of 6 characters or more.")
bgneal@74 94 return password2
gremmie@1 95
bgneal@346 96 def clean_question1(self):
bgneal@346 97 answer = self.cleaned_data.get('question1')
bgneal@346 98 success = False
bgneal@346 99 if answer:
bgneal@346 100 try:
bgneal@346 101 val = int(answer)
bgneal@346 102 except ValueError:
bgneal@346 103 pass
bgneal@346 104 else:
bgneal@346 105 success = val == 101
bgneal@346 106 if not success:
bgneal@346 107 self._validation_error("Incorrect answer to our anti-spam question.", answer)
bgneal@346 108 return answer
bgneal@346 109
bgneal@347 110 def clean_question2(self):
bgneal@347 111 """
bgneal@347 112 Honeypot field should be empty.
bgneal@347 113 """
bgneal@347 114 answer = self.cleaned_data.get('question2')
bgneal@347 115 if answer:
bgneal@472 116 block_ip(self.ip)
bgneal@347 117 self._validation_error('Wrong answer #2: %s' % answer)
bgneal@347 118 return answer
bgneal@347 119
bgneal@74 120 def save(self):
bgneal@74 121 pending_user = PendingUser.objects.create_pending_user(self.cleaned_data['username'],
bgneal@74 122 self.cleaned_data['email'],
bgneal@74 123 self.cleaned_data['password1'])
gremmie@1 124
bgneal@74 125 # Send the confirmation email
gremmie@1 126
bgneal@74 127 site = Site.objects.get_current()
bgneal@74 128 admin_email = settings.ADMINS[0][1]
gremmie@1 129
bgneal@316 130 activation_link = 'http://%s%s' % (site.domain, reverse('accounts.views.register_confirm',
bgneal@74 131 kwargs = {'username' : pending_user.username, 'key' : pending_user.key}))
gremmie@1 132
bgneal@74 133 msg = render_to_string('accounts/registration_email.txt',
bgneal@74 134 {
bgneal@74 135 'site_name' : site.name,
bgneal@74 136 'site_domain' : site.domain,
bgneal@74 137 'user_email' : pending_user.email,
bgneal@74 138 'activation_link' : activation_link,
bgneal@74 139 'username' : pending_user.username,
bgneal@74 140 'admin_email' : admin_email,
bgneal@74 141 })
gremmie@1 142
bgneal@74 143 subject = 'Registration Confirmation for ' + site.name
bgneal@513 144 send_mail(subject, msg, admin_email, [self.cleaned_data['email']])
bgneal@316 145 logging.info('Accounts/registration conf. email sent to %s for user %s; IP = %s',
bgneal@316 146 self.cleaned_data['email'], pending_user.username, self.ip)
gremmie@1 147
bgneal@74 148 return pending_user
gremmie@1 149
bgneal@74 150 def _validation_error(self, msg, param=None):
bgneal@316 151 logging.error('Accounts/registration [%s]: %s (%s)', self.ip, msg, param)
bgneal@74 152 raise forms.ValidationError(msg)