gremmie@1: """forms for the accounts application"""
gremmie@1: 
bgneal@74: import logging
bgneal@74: 
gremmie@1: from django import forms
gremmie@1: from django.contrib.auth.models import User
gremmie@1: from django.core.urlresolvers import reverse
gremmie@1: from django.template.loader import render_to_string
gremmie@1: from django.contrib.sites.models import Site
bgneal@6: from django.conf import settings
gremmie@1: 
gremmie@1: from core.functions import send_mail
gremmie@1: from accounts.models import PendingUser
gremmie@1: from accounts.models import IllegalUsername
gremmie@1: from accounts.models import IllegalEmail
gremmie@1: 
gremmie@1: 
gremmie@1: class RegisterForm(forms.Form):
bgneal@74:     """Form used to register with the website"""
bgneal@74:     username = forms.RegexField(max_length = 30, regex = r'^\w+$',
bgneal@74:         error_messages = {'invalid' : 'Your username must be 30 characters or less and contain only letters, numbers and underscores.'})
bgneal@74:     email = forms.EmailField()
bgneal@74:     password1 = forms.CharField(label = "Password", widget = forms.PasswordInput)
bgneal@74:     password2 = forms.CharField(label = "Password confirmation", widget = forms.PasswordInput)
bgneal@74:     agree_tos = forms.BooleanField(required = True, label = 'I agree to the Terms of Service',
bgneal@74:         error_messages = {'required' : 'You have not agreed to our Terms of Service'})
bgneal@74:     agree_privacy = forms.BooleanField(required = True, label = 'I agree to the Privacy Policy',
bgneal@74:         error_messages = {'required' : 'You have not agreed to our Privacy Policy'})
gremmie@1: 
bgneal@74:     def __init__(self, *args, **kwargs):
bgneal@74:         self.ip = kwargs.pop('ip', '?')
bgneal@74:         super(RegisterForm, self).__init__(*args, **kwargs)
bgneal@74: 
bgneal@74:     def clean_username(self):
bgneal@74:         username = self.cleaned_data['username']
bgneal@74:         try:
bgneal@74:             User.objects.get(username = username)
bgneal@74:         except User.DoesNotExist:
gremmie@1:             try:
bgneal@74:                 PendingUser.objects.get(username = username)
bgneal@74:             except PendingUser.DoesNotExist:
bgneal@74:                 try:
bgneal@74:                     IllegalUsername.objects.get(username = username)
bgneal@74:                 except IllegalUsername.DoesNotExist:
bgneal@74:                     return username
bgneal@74:                 self._validation_error("That username is not allowed.", username)
bgneal@74:             self._validation_error("A pending user with that username already exists.", username)
bgneal@74:         self._validation_error("A user with that username already exists.", username)
gremmie@1: 
bgneal@74:     def clean_email(self):
bgneal@74:         email = self.cleaned_data['email']
bgneal@74:         try:
bgneal@74:             User.objects.get(email = email)
bgneal@74:         except User.DoesNotExist:
gremmie@1:             try:
bgneal@74:                 PendingUser.objects.get(email = email)
bgneal@74:             except PendingUser.DoesNotExist:
bgneal@74:                 try:
bgneal@74:                     IllegalEmail.objects.get(email = email)
bgneal@74:                 except IllegalEmail.DoesNotExist:
bgneal@74:                     return email
bgneal@74:                 self._validation_error("That email address is not allowed.", email)
bgneal@74:             self._validation_error("A pending user with that email address already exists.", email)
bgneal@74:         self._validation_error("A user with that email address already exists.", email)
gremmie@1: 
bgneal@74:     def clean_password2(self):
bgneal@74:         password1 = self.cleaned_data.get("password1", "")
bgneal@74:         password2 = self.cleaned_data["password2"]
bgneal@74:         if password1 != password2:
bgneal@74:             self._validation_error("The two password fields didn't match.")
bgneal@74:         return password2
gremmie@1: 
bgneal@74:     def save(self):
bgneal@74:         pending_user = PendingUser.objects.create_pending_user(self.cleaned_data['username'],
bgneal@74:                 self.cleaned_data['email'],
bgneal@74:                 self.cleaned_data['password1'])
gremmie@1: 
bgneal@74:         # Send the confirmation email
gremmie@1: 
bgneal@74:         site = Site.objects.get_current()
bgneal@74:         admin_email = settings.ADMINS[0][1]
gremmie@1: 
bgneal@74:         activation_link = 'http://%s%s' % (site.domain, reverse('accounts.views.register_confirm', 
bgneal@74:                 kwargs = {'username' : pending_user.username, 'key' : pending_user.key}))
gremmie@1: 
bgneal@74:         msg = render_to_string('accounts/registration_email.txt',
bgneal@74:                 {
bgneal@74:                     'site_name' : site.name,
bgneal@74:                     'site_domain' : site.domain,
bgneal@74:                     'user_email' : pending_user.email,
bgneal@74:                     'activation_link' : activation_link,
bgneal@74:                     'username' : pending_user.username,
bgneal@74:                     'admin_email' : admin_email,
bgneal@74:                 })
gremmie@1: 
bgneal@74:         subject = 'Registration Confirmation for ' + site.name
bgneal@74:         send_mail(subject, msg, admin_email, [self.cleaned_data['email']])
bgneal@74:         logging.info('Accounts/registration conf. email sent to %s for user %s; IP = %s' % \
bgneal@74:                 (self.cleaned_data['email'], pending_user.username, self.ip))
gremmie@1: 
bgneal@74:         return pending_user
gremmie@1: 
bgneal@74:     def _validation_error(self, msg, param=None):
bgneal@74:         logging.error('Accounts/registration [%s]: %s (%s)' % (self.ip, msg, param))
bgneal@74:         raise forms.ValidationError(msg)