4 from django
import forms
5 from django
.core
.validators
import RegexValidator
6 from django
.core
.exceptions
import ValidationError
7 from django
.db
import IntegrityError
, transaction
8 from django
.http
import HttpResponseRedirect
9 from django
.views
.generic
.edit
import FormView
10 from django
.utils
.translation
import ugettext
as _
11 from django
.template
.loader
import render_to_string
12 from django
.core
.urlresolvers
import reverse
, reverse_lazy
13 from django
.views
.generic
import TemplateView
14 from django
.views
.generic
.base
import View
15 from django
.contrib
import messages
16 from django
.contrib
.auth
import get_user_model
17 from django
.contrib
.sites
.shortcuts
import get_current_site
19 from mygpo
.utils
import random_token
20 from mygpo
.users
.models
import UserProxy
23 USERNAME_MAXLEN
= get_user_model()._meta
.get_field('username').max_length
25 USERNAME_REGEX
= re
.compile(r
'^\w[\w.+-]*$')
28 class UsernameValidator(RegexValidator
):
29 """ Validates that a username uses only allowed characters """
30 regex
= USERNAME_REGEX
31 message
= 'Invalid Username'
32 code
='invalid-username'
35 class RegistrationForm(forms
.Form
):
36 """ Form that is used to register a new user """
37 username
= forms
.CharField(max_length
=USERNAME_MAXLEN
,
38 validators
=[UsernameValidator()],
40 email
= forms
.EmailField()
41 password1
= forms
.CharField(widget
=forms
.PasswordInput())
42 password2
= forms
.CharField(widget
=forms
.PasswordInput())
45 cleaned_data
= super(RegistrationForm
, self
).clean()
46 password1
= cleaned_data
.get('password1')
47 password2
= cleaned_data
.get('password2')
49 if not password1
or password1
!= password2
:
50 raise forms
.ValidationError('Passwords do not match')
53 class RegistrationView(FormView
):
54 """ View to register a new user """
55 template_name
= 'registration/registration_form.html'
56 form_class
= RegistrationForm
57 success_url
= reverse_lazy('registration-complete')
59 def form_valid(self
, form
):
60 """ called whene the form was POSTed and its contents were valid """
63 user
= self
.create_user(form
)
65 except ValidationError
as e
:
66 messages
.error(self
.request
, '; '.join(e
.messages
))
67 return HttpResponseRedirect(reverse('register'))
69 except IntegrityError
:
70 messages
.error(self
.request
,
71 _('Username or email address already in use'))
72 return HttpResponseRedirect(reverse('register'))
74 send_activation_email(user
, self
.request
)
75 return super(RegistrationView
, self
).form_valid(form
)
78 def create_user(self
, form
):
79 User
= get_user_model()
81 user
.username
= form
.cleaned_data
['username']
83 email_addr
= form
.cleaned_data
['email']
84 user
.email
= email_addr
86 user
.set_password(form
.cleaned_data
['password1'])
87 user
.is_active
= False
93 except IntegrityError
as e
:
94 if 'django_auth_unique_email' in str(e
):
95 # this was not caught by the form validation, but now validates
96 # the DB's unique constraint
97 raise ValidationError('The email address {0} is '
98 'already in use.'.format(email_addr
))
102 user
.profile
.uuid
== uuid
.uuid1()
103 user
.profile
.activation_key
= random_token()
109 class ActivationView(TemplateView
):
110 """ Activates an already registered user """
112 template_name
= 'registration/activation_failed.html'
114 def get(self
, request
, activation_key
):
115 User
= get_user_model()
118 user
= UserProxy
.objects
.get(
119 profile__activation_key
=activation_key
,
122 except UserProxy
.DoesNotExist
:
123 messages
.error(request
, _('The activation link is either not '
124 'valid or has already expired.'))
125 return super(ActivationView
, self
).get(request
, activation_key
)
128 messages
.success(request
, _('Your user has been activated. '
129 'You can log in now.'))
130 return HttpResponseRedirect(reverse('login'))
133 class ResendActivationForm(forms
.Form
):
134 """ Form for resending the activation email """
136 username
= forms
.CharField(max_length
=USERNAME_MAXLEN
, required
=False)
137 email
= forms
.EmailField(required
=False)
140 cleaned_data
= super(ResendActivationForm
, self
).clean()
141 username
= cleaned_data
.get('username')
142 email
= cleaned_data
.get('email')
144 if not username
and not email
:
145 raise forms
.ValidationError(_('Either username or email address '
149 class ResendActivationView(FormView
):
150 """ View to resend the activation email """
151 template_name
= 'registration/resend_activation.html'
152 form_class
= ResendActivationForm
153 success_url
= reverse_lazy('resent-activation')
155 def form_valid(self
, form
):
156 """ called whene the form was POSTed and its contents were valid """
159 user
= UserProxy
.objects
.all().by_username_or_email(
160 form
.cleaned_data
['username'],
161 form
.cleaned_data
['email'],
164 except UserProxy
.DoesNotExist
:
165 messages
.error(self
.request
, _('User does not exist.'))
166 return HttpResponseRedirect(reverse('resend-activation'))
168 if user
.profile
.activation_key
is None:
169 messages
.success(self
.request
, _('Your account already has been '
170 'activated. Go ahead and log in.'))
172 send_activation_email(user
, self
.request
)
173 return super(ResendActivationView
, self
).form_valid(form
)
176 class ResentActivationView(TemplateView
):
177 template_name
= 'registration/resent_activation.html'
180 def send_activation_email(user
, request
):
181 """ Sends the activation email for the given user """
183 subj
= render_to_string('registration/activation_email_subject.txt')
184 # remove trailing newline added by render_to_string
187 msg
= render_to_string('registration/activation_email.txt', {
188 'site': get_current_site(request
),
189 'activation_key': user
.profile
.activation_key
,
191 user
.email_user(subj
, msg
)