PageRenderTime 46ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/apps/users/forms.py

https://github.com/chengwang/kitsune
Python | 195 lines | 170 code | 15 blank | 10 comment | 3 complexity | 47d775738aa86b3a03c118d874d516e5 MD5 | raw file
  1. import re
  2. from django import forms
  3. from django.conf import settings
  4. from django.contrib.auth import authenticate, forms as auth_forms
  5. from django.contrib.auth.models import User
  6. from tower import ugettext as _, ugettext_lazy as _lazy
  7. from sumo.widgets import ImageWidget
  8. from upload.forms import clean_image_extension
  9. from upload.utils import check_file_size, FileTooLargeError
  10. from users.models import Profile
  11. from users.widgets import FacebookURLWidget, TwitterURLWidget
  12. USERNAME_INVALID = _lazy(u'Username may contain only letters, '
  13. 'numbers and @/./+/-/_ characters.')
  14. USERNAME_REQUIRED = _lazy(u'Username is required.')
  15. USERNAME_SHORT = _lazy(u'Username is too short (%(show_value)s characters). '
  16. 'It must be at least %(limit_value)s characters.')
  17. USERNAME_LONG = _lazy(u'Username is too long (%(show_value)s characters). '
  18. 'It must be %(limit_value)s characters or less.')
  19. EMAIL_REQUIRED = _lazy(u'Email address is required.')
  20. EMAIL_SHORT = _lazy(u'Email address is too short (%(show_value)s characters). '
  21. 'It must be at least %(limit_value)s characters.')
  22. EMAIL_LONG = _lazy(u'Email address is too long (%(show_value)s characters). '
  23. 'It must be %(limit_value)s characters or less.')
  24. PASSWD_REQUIRED = _lazy(u'Password is required.')
  25. PASSWD2_REQUIRED = _lazy(u'Please enter your password twice.')
  26. class RegisterForm(forms.ModelForm):
  27. """A user registration form that requires unique email addresses.
  28. The default Django user creation form does not require an email address,
  29. let alone that it be unique. This form does, and sets a minimum length
  30. for usernames.
  31. """
  32. username = forms.RegexField(
  33. label=_lazy(u'Username:'), max_length=30, min_length=4,
  34. regex=r'^[\w.@+-]+$',
  35. help_text=_lazy(u'Required. 30 characters or fewer. Letters, digits '
  36. 'and @/./+/-/_ only.'),
  37. error_messages={'invalid': USERNAME_INVALID,
  38. 'required': USERNAME_REQUIRED,
  39. 'min_length': USERNAME_SHORT,
  40. 'max_length': USERNAME_LONG})
  41. email = forms.EmailField(label=_lazy(u'Email address:'),
  42. error_messages={'required': EMAIL_REQUIRED,
  43. 'min_length': EMAIL_SHORT,
  44. 'max_length': EMAIL_LONG})
  45. password = forms.CharField(label=_lazy(u'Password:'),
  46. widget=forms.PasswordInput(
  47. render_value=False),
  48. error_messages={'required': PASSWD_REQUIRED})
  49. password2 = forms.CharField(label=_lazy(u'Repeat password:'),
  50. widget=forms.PasswordInput(
  51. render_value=False),
  52. error_messages={'required': PASSWD2_REQUIRED},
  53. help_text=_lazy(u'Enter the same password as '
  54. 'above, for verification.'))
  55. class Meta(object):
  56. model = User
  57. fields = ('username', 'password', 'password2', 'email')
  58. def clean(self):
  59. super(RegisterForm, self).clean()
  60. password = self.cleaned_data.get('password')
  61. password2 = self.cleaned_data.get('password2')
  62. if not password == password2:
  63. raise forms.ValidationError(_('Passwords must match.'))
  64. return self.cleaned_data
  65. def clean_email(self):
  66. email = self.cleaned_data['email']
  67. if User.objects.filter(email=email).exists():
  68. raise forms.ValidationError(_('A user with that email address '
  69. 'already exists.'))
  70. return email
  71. def __init__(self, request=None, *args, **kwargs):
  72. super(RegisterForm, self).__init__(request, auto_id='id_for_%s',
  73. *args, **kwargs)
  74. class AuthenticationForm(auth_forms.AuthenticationForm):
  75. """Overrides the default django form.
  76. * Doesn't prefill password on validation error.
  77. * Allows logging in inactive users (initialize with `only_active=False`).
  78. """
  79. password = forms.CharField(label=_lazy(u"Password"),
  80. widget=forms.PasswordInput(render_value=False))
  81. def __init__(self, request=None, only_active=True, *args, **kwargs):
  82. self.only_active = only_active
  83. super(AuthenticationForm, self).__init__(request, *args, **kwargs)
  84. def clean(self):
  85. username = self.cleaned_data.get('username')
  86. password = self.cleaned_data.get('password')
  87. if username and password:
  88. self.user_cache = authenticate(username=username,
  89. password=password)
  90. if self.user_cache is None:
  91. raise forms.ValidationError(
  92. _('Please enter a correct username and password. Note '
  93. 'that both fields are case-sensitive.'))
  94. elif self.only_active and not self.user_cache.is_active:
  95. raise forms.ValidationError(_('This account is inactive.'))
  96. if self.request:
  97. if not self.request.session.test_cookie_worked():
  98. raise forms.ValidationError(
  99. _("Your Web browser doesn't appear to have cookies "
  100. "enabled. Cookies are required for logging in."))
  101. return self.cleaned_data
  102. class ProfileForm(forms.ModelForm):
  103. """The form for editing the user's profile."""
  104. class Meta(object):
  105. model = Profile
  106. exclude = ('user', 'livechat_id', 'avatar')
  107. widgets = {
  108. 'twitter': TwitterURLWidget,
  109. 'facebook': FacebookURLWidget,
  110. }
  111. def clean_twitter(self):
  112. twitter = self.cleaned_data['twitter']
  113. if twitter and not re.match(TwitterURLWidget.pattern, twitter):
  114. raise forms.ValidationError(_(u'Please enter a twitter.com URL.'))
  115. return twitter
  116. def clean_facebook(self):
  117. facebook = self.cleaned_data['facebook']
  118. if facebook and not re.match(FacebookURLWidget.pattern, facebook):
  119. raise forms.ValidationError(_(u'Please enter a facebook.com URL.'))
  120. return facebook
  121. class AvatarForm(forms.ModelForm):
  122. """The form for editing the user's avatar."""
  123. avatar = forms.ImageField(required=True, widget=ImageWidget)
  124. def __init__(self, *args, **kwargs):
  125. super(AvatarForm, self).__init__(*args, **kwargs)
  126. self.fields['avatar'].help_text = (
  127. u'Your avatar will be resized to {size}x{size}'.format(
  128. size=settings.AVATAR_SIZE))
  129. class Meta(object):
  130. model = Profile
  131. fields = ('avatar',)
  132. def clean_avatar(self):
  133. if not ('avatar' in self.cleaned_data and self.cleaned_data['avatar']):
  134. return self.cleaned_data['avatar']
  135. try:
  136. check_file_size(self.cleaned_data['avatar'],
  137. settings.MAX_AVATAR_FILE_SIZE)
  138. except FileTooLargeError as e:
  139. raise forms.ValidationError(e.args[0])
  140. clean_image_extension(self.cleaned_data.get('avatar'))
  141. return self.cleaned_data['avatar']
  142. class EmailConfirmationForm(forms.Form):
  143. """A simple form that requires an email address."""
  144. email = forms.EmailField(label=_lazy(u'Email address:'))
  145. class EmailChangeForm(forms.Form):
  146. """A simple form that requires an email address and validates that it is
  147. not the current user's email."""
  148. email = forms.EmailField(label=_lazy(u'Email address:'))
  149. def __init__(self, user, *args, **kwargs):
  150. super(EmailChangeForm, self).__init__(*args, **kwargs)
  151. self.user = user
  152. def clean_email(self):
  153. if self.user.email == self.cleaned_data['email']:
  154. raise forms.ValidationError(_('This is your current email.'))
  155. return self.cleaned_data['email']