annotate gpp/accounts/forms.py @ 467:b910cc1460c8

Add the ability to conditionally add model instances to the search index on update. This is not perfect, as some instances should be deleted from the index if they are updated such that they should not be in the index anymore. Will think about and address that later.
author Brian Neal <bgneal@gmail.com>
date Sun, 24 Jul 2011 18:12:20 +0000
parents 69d0306a6fe7
children 7c3816d76c6c
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
gremmie@1 16
gremmie@1 17
gremmie@1 18 class RegisterForm(forms.Form):
bgneal@74 19 """Form used to register with the website"""
bgneal@346 20 username = forms.RegexField(max_length=30, regex=r'^\w+$',
bgneal@155 21 error_messages={
bgneal@347 22 'invalid': 'Your username must be 30 characters or less and '
bgneal@155 23 'contain only letters, numbers and underscores.'})
bgneal@74 24 email = forms.EmailField()
bgneal@346 25 password1 = forms.CharField(label="Password", widget=forms.PasswordInput)
bgneal@346 26 password2 = forms.CharField(label="Password confirmation", widget=forms.PasswordInput)
bgneal@316 27 agree_age = forms.BooleanField(required=True,
bgneal@155 28 label='I certify that I am over the age of 13',
bgneal@155 29 error_messages={
bgneal@347 30 'required': 'Sorry, but you must be over the age of 13 to '
bgneal@155 31 'register at our site.',
bgneal@155 32 })
bgneal@316 33 agree_tos = forms.BooleanField(required=True,
bgneal@155 34 label='I agree to the Terms of Service',
bgneal@155 35 error_messages={
bgneal@155 36 'required': 'You have not agreed to our Terms of Service.',
bgneal@155 37 })
bgneal@155 38 agree_privacy = forms.BooleanField(required=True,
bgneal@155 39 label='I agree to the Privacy Policy',
bgneal@155 40 error_messages={
bgneal@155 41 'required': 'You have not agreed to our Privacy Policy.',
bgneal@155 42 })
bgneal@346 43 question1 = forms.CharField(label="What number appears in the site name?")
bgneal@347 44 question2 = forms.CharField(label='', required=False,
bgneal@347 45 widget=forms.TextInput(attrs={'style': 'display: none;'}))
gremmie@1 46
bgneal@74 47 def __init__(self, *args, **kwargs):
bgneal@74 48 self.ip = kwargs.pop('ip', '?')
bgneal@74 49 super(RegisterForm, self).__init__(*args, **kwargs)
bgneal@74 50
bgneal@74 51 def clean_username(self):
bgneal@74 52 username = self.cleaned_data['username']
bgneal@74 53 try:
bgneal@74 54 User.objects.get(username = username)
bgneal@74 55 except User.DoesNotExist:
gremmie@1 56 try:
bgneal@74 57 PendingUser.objects.get(username = username)
bgneal@74 58 except PendingUser.DoesNotExist:
bgneal@74 59 try:
bgneal@74 60 IllegalUsername.objects.get(username = username)
bgneal@74 61 except IllegalUsername.DoesNotExist:
bgneal@74 62 return username
bgneal@74 63 self._validation_error("That username is not allowed.", username)
bgneal@74 64 self._validation_error("A pending user with that username already exists.", username)
bgneal@74 65 self._validation_error("A user with that username already exists.", username)
gremmie@1 66
bgneal@74 67 def clean_email(self):
bgneal@74 68 email = self.cleaned_data['email']
bgneal@74 69 try:
bgneal@74 70 User.objects.get(email = email)
bgneal@74 71 except User.DoesNotExist:
gremmie@1 72 try:
bgneal@74 73 PendingUser.objects.get(email = email)
bgneal@74 74 except PendingUser.DoesNotExist:
bgneal@74 75 try:
bgneal@74 76 IllegalEmail.objects.get(email = email)
bgneal@74 77 except IllegalEmail.DoesNotExist:
bgneal@74 78 return email
bgneal@74 79 self._validation_error("That email address is not allowed.", email)
bgneal@74 80 self._validation_error("A pending user with that email address already exists.", email)
bgneal@74 81 self._validation_error("A user with that email address already exists.", email)
gremmie@1 82
bgneal@74 83 def clean_password2(self):
bgneal@74 84 password1 = self.cleaned_data.get("password1", "")
bgneal@74 85 password2 = self.cleaned_data["password2"]
bgneal@74 86 if password1 != password2:
bgneal@74 87 self._validation_error("The two password fields didn't match.")
bgneal@155 88 if len(password1) < 6:
bgneal@155 89 self._validation_error("Please choose a password of 6 characters or more.")
bgneal@74 90 return password2
gremmie@1 91
bgneal@346 92 def clean_question1(self):
bgneal@346 93 answer = self.cleaned_data.get('question1')
bgneal@346 94 success = False
bgneal@346 95 if answer:
bgneal@346 96 try:
bgneal@346 97 val = int(answer)
bgneal@346 98 except ValueError:
bgneal@346 99 pass
bgneal@346 100 else:
bgneal@346 101 success = val == 101
bgneal@346 102 if not success:
bgneal@346 103 self._validation_error("Incorrect answer to our anti-spam question.", answer)
bgneal@346 104 return answer
bgneal@346 105
bgneal@347 106 def clean_question2(self):
bgneal@347 107 """
bgneal@347 108 Honeypot field should be empty.
bgneal@347 109 """
bgneal@347 110 answer = self.cleaned_data.get('question2')
bgneal@347 111 if answer:
bgneal@347 112 self._validation_error('Wrong answer #2: %s' % answer)
bgneal@347 113 return answer
bgneal@347 114
bgneal@74 115 def save(self):
bgneal@74 116 pending_user = PendingUser.objects.create_pending_user(self.cleaned_data['username'],
bgneal@74 117 self.cleaned_data['email'],
bgneal@74 118 self.cleaned_data['password1'])
gremmie@1 119
bgneal@74 120 # Send the confirmation email
gremmie@1 121
bgneal@74 122 site = Site.objects.get_current()
bgneal@74 123 admin_email = settings.ADMINS[0][1]
gremmie@1 124
bgneal@316 125 activation_link = 'http://%s%s' % (site.domain, reverse('accounts.views.register_confirm',
bgneal@74 126 kwargs = {'username' : pending_user.username, 'key' : pending_user.key}))
gremmie@1 127
bgneal@74 128 msg = render_to_string('accounts/registration_email.txt',
bgneal@74 129 {
bgneal@74 130 'site_name' : site.name,
bgneal@74 131 'site_domain' : site.domain,
bgneal@74 132 'user_email' : pending_user.email,
bgneal@74 133 'activation_link' : activation_link,
bgneal@74 134 'username' : pending_user.username,
bgneal@74 135 'admin_email' : admin_email,
bgneal@74 136 })
gremmie@1 137
bgneal@74 138 subject = 'Registration Confirmation for ' + site.name
bgneal@252 139 send_mail(subject, msg, admin_email, [self.cleaned_data['email']],
bgneal@252 140 expedite=True)
bgneal@316 141 logging.info('Accounts/registration conf. email sent to %s for user %s; IP = %s',
bgneal@316 142 self.cleaned_data['email'], pending_user.username, self.ip)
gremmie@1 143
bgneal@74 144 return pending_user
gremmie@1 145
bgneal@74 146 def _validation_error(self, msg, param=None):
bgneal@316 147 logging.error('Accounts/registration [%s]: %s (%s)', self.ip, msg, param)
bgneal@74 148 raise forms.ValidationError(msg)