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