4cc9874a710721b9a1e753ff047aeaf43f87f82f
[philo.git] / philo / contrib / waldo / forms.py
1 from datetime import date
2
3 from django import forms
4 from django.conf import settings
5 from django.contrib.auth import authenticate
6 from django.contrib.auth.forms import AuthenticationForm, UserCreationForm
7 from django.contrib.auth.models import User
8 from django.core.exceptions import ValidationError
9 from django.utils.translation import ugettext_lazy as _
10
11 from philo.contrib.waldo.tokens import REGISTRATION_TIMEOUT_DAYS
12
13
14 class EmailInput(forms.TextInput):
15         input_type = 'email'
16
17
18 class RegistrationForm(UserCreationForm):
19         email = forms.EmailField(widget=EmailInput)
20         try:
21                 from recaptcha_django import ReCaptchaField
22         except ImportError:
23                 pass
24         else:
25                 if 'recaptcha_django.middleware.ReCaptchaMiddleware' in settings.MIDDLEWARE_CLASSES:
26                         recaptcha = ReCaptchaField()
27         
28         def clean_username(self):
29                 username = self.cleaned_data['username']
30                 
31                 # Trivial case: if the username doesn't exist, go for it!
32                 try:
33                         user = User.objects.get(username=username)
34                 except User.DoesNotExist:
35                         return username
36                 
37                 if not user.is_active and (date.today() - user.date_joined.date()).days > REGISTRATION_TIMEOUT_DAYS and user.last_login == user.date_joined:
38                         # Then this is a user who has not confirmed their registration and whose time is up. Delete the old user and return the username.
39                         user.delete()
40                         return username
41                 
42                 raise ValidationError(_("A user with that username already exists."))
43         
44         def clean_email(self):
45                 if User.objects.filter(email__iexact=self.cleaned_data['email']):
46                         raise ValidationError(_('This email is already in use. Please supply a different email address'))
47                 return self.cleaned_data['email']
48         
49         def save(self):
50                 username = self.cleaned_data['username']
51                 email = self.cleaned_data['email']
52                 password = self.cleaned_data['password1']
53                 new_user = User.objects.create_user(username, email, password)
54                 new_user.is_active = False
55                 new_user.save()
56                 return new_user
57
58
59 class UserAccountForm(forms.ModelForm):
60         first_name = User._meta.get_field('first_name').formfield(required=True)
61         last_name = User._meta.get_field('last_name').formfield(required=True)
62         email = User._meta.get_field('email').formfield(required=True, widget=EmailInput)
63         
64         def __init__(self, user, *args, **kwargs):
65                 kwargs['instance'] = user
66                 super(UserAccountForm, self).__init__(*args, **kwargs)
67         
68         class Meta:
69                 model = User
70                 fields = ('first_name', 'last_name', 'email')
71
72
73 class WaldoAuthenticationForm(AuthenticationForm):
74         ERROR_MESSAGE = _("Please enter a correct username and password. Note that both fields are case-sensitive.")
75         
76         def clean(self):
77                 username = self.cleaned_data.get('username')
78                 password = self.cleaned_data.get('password')
79                 message = self.ERROR_MESSAGE
80                 
81                 if username and password:
82                         self.user_cache = authenticate(username=username, password=password)
83                         if self.user_cache is None:
84                                 if u'@' in username:
85                                         # Maybe they entered their email? Look it up, but still raise a ValidationError.
86                                         try:
87                                                 user = User.objects.get(email=username)
88                                         except (User.DoesNotExist, User.MultipleObjectsReturned):
89                                                 pass
90                                         else:
91                                                 if user.check_password(password):
92                                                         message = _("Your e-mail address is not your username. Try '%s' instead.") % user.username
93                                 raise ValidationError(message)
94                         elif not self.user_cache.is_active:
95                                 raise ValidationError(message)
96                 self.check_for_test_cookie()
97                 return self.cleaned_data
98         
99         def check_for_test_cookie(self):
100                 # This method duplicates the Django 1.3 AuthenticationForm method.
101                 if self.request and not self.request.session.test_cookie_worked():
102                         raise forms.ValidationError(
103                                 _("Your Web browser doesn't appear to have cookies enabled. "
104                                   "Cookies are required for logging in."))