PageRenderTime 47ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/django/contrib/auth/forms.py

https://github.com/seblach/django
Python | 227 lines | 218 code | 6 blank | 3 comment | 4 complexity | 0fc27a6034ed8eed199048d0d6278dfd MD5 | raw file
  1. from django import forms
  2. from django.template import Context, loader
  3. from django.utils.http import int_to_base36
  4. from django.utils.itercompat import any
  5. from django.utils.translation import ugettext_lazy as _
  6. from django.contrib.auth.models import User, UNUSABLE_PASSWORD
  7. from django.contrib.auth import authenticate
  8. from django.contrib.auth.tokens import default_token_generator
  9. from django.contrib.sites.models import get_current_site
  10. class UserCreationForm(forms.ModelForm):
  11. """
  12. A form that creates a user, with no privileges, from the given username and password.
  13. """
  14. username = forms.RegexField(label=_("Username"), max_length=30, regex=r'^[\w.@+-]+$',
  15. help_text = _("Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only."),
  16. error_messages = {'invalid': _("This value may contain only letters, numbers and @/./+/-/_ characters.")})
  17. password1 = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
  18. password2 = forms.CharField(label=_("Password confirmation"), widget=forms.PasswordInput,
  19. help_text = _("Enter the same password as above, for verification."))
  20. class Meta:
  21. model = User
  22. fields = ("username",)
  23. def clean_username(self):
  24. username = self.cleaned_data["username"]
  25. try:
  26. User.objects.get(username=username)
  27. except User.DoesNotExist:
  28. return username
  29. raise forms.ValidationError(_("A user with that username already exists."))
  30. def clean_password2(self):
  31. password1 = self.cleaned_data.get("password1", "")
  32. password2 = self.cleaned_data["password2"]
  33. if password1 != password2:
  34. raise forms.ValidationError(_("The two password fields didn't match."))
  35. return password2
  36. def save(self, commit=True):
  37. user = super(UserCreationForm, self).save(commit=False)
  38. user.set_password(self.cleaned_data["password1"])
  39. if commit:
  40. user.save()
  41. return user
  42. class UserChangeForm(forms.ModelForm):
  43. username = forms.RegexField(label=_("Username"), max_length=30, regex=r'^[\w.@+-]+$',
  44. help_text = _("Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only."),
  45. error_messages = {'invalid': _("This value may contain only letters, numbers and @/./+/-/_ characters.")})
  46. class Meta:
  47. model = User
  48. def __init__(self, *args, **kwargs):
  49. super(UserChangeForm, self).__init__(*args, **kwargs)
  50. f = self.fields.get('user_permissions', None)
  51. if f is not None:
  52. f.queryset = f.queryset.select_related('content_type')
  53. class AuthenticationForm(forms.Form):
  54. """
  55. Base class for authenticating users. Extend this to get a form that accepts
  56. username/password logins.
  57. """
  58. username = forms.CharField(label=_("Username"), max_length=30)
  59. password = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
  60. def __init__(self, request=None, *args, **kwargs):
  61. """
  62. If request is passed in, the form will validate that cookies are
  63. enabled. Note that the request (a HttpRequest object) must have set a
  64. cookie with the key TEST_COOKIE_NAME and value TEST_COOKIE_VALUE before
  65. running this validation.
  66. """
  67. self.request = request
  68. self.user_cache = None
  69. super(AuthenticationForm, self).__init__(*args, **kwargs)
  70. def clean(self):
  71. username = self.cleaned_data.get('username')
  72. password = self.cleaned_data.get('password')
  73. if username and password:
  74. self.user_cache = authenticate(username=username, password=password)
  75. if self.user_cache is None:
  76. raise forms.ValidationError(_("Please enter a correct username and password. Note that both fields are case-sensitive."))
  77. elif not self.user_cache.is_active:
  78. raise forms.ValidationError(_("This account is inactive."))
  79. self.check_for_test_cookie()
  80. return self.cleaned_data
  81. def check_for_test_cookie(self):
  82. if self.request and not self.request.session.test_cookie_worked():
  83. raise forms.ValidationError(
  84. _("Your Web browser doesn't appear to have cookies enabled. "
  85. "Cookies are required for logging in."))
  86. def get_user_id(self):
  87. if self.user_cache:
  88. return self.user_cache.id
  89. return None
  90. def get_user(self):
  91. return self.user_cache
  92. class PasswordResetForm(forms.Form):
  93. email = forms.EmailField(label=_("E-mail"), max_length=75)
  94. def clean_email(self):
  95. """
  96. Validates that an active user exists with the given email address.
  97. """
  98. email = self.cleaned_data["email"]
  99. self.users_cache = User.objects.filter(
  100. email__iexact=email,
  101. is_active=True)
  102. if not len(self.users_cache):
  103. raise forms.ValidationError(_("That e-mail address doesn't have an associated user account. Are you sure you've registered?"))
  104. if any((user.password == UNUSABLE_PASSWORD) for user in self.users_cache):
  105. raise forms.ValidationError(_("The user account associated with this e-mail address cannot reset the password."))
  106. return email
  107. def save(self, domain_override=None,
  108. subject_template_name='registration/password_reset_subject.txt',
  109. email_template_name='registration/password_reset_email.html',
  110. use_https=False, token_generator=default_token_generator,
  111. from_email=None, request=None):
  112. """
  113. Generates a one-use only link for resetting password and sends to the user
  114. """
  115. from django.core.mail import send_mail
  116. for user in self.users_cache:
  117. if not domain_override:
  118. current_site = get_current_site(request)
  119. site_name = current_site.name
  120. domain = current_site.domain
  121. else:
  122. site_name = domain = domain_override
  123. c = {
  124. 'email': user.email,
  125. 'domain': domain,
  126. 'site_name': site_name,
  127. 'uid': int_to_base36(user.id),
  128. 'user': user,
  129. 'token': token_generator.make_token(user),
  130. 'protocol': use_https and 'https' or 'http',
  131. }
  132. subject = loader.render_to_string(subject_template_name, c)
  133. # Email subject *must not* contain newlines
  134. subject = ''.join(subject.splitlines())
  135. email = loader.render_to_string(email_template_name, c)
  136. send_mail(subject, email, from_email, [user.email])
  137. class SetPasswordForm(forms.Form):
  138. """
  139. A form that lets a user change set his/her password without
  140. entering the old password
  141. """
  142. new_password1 = forms.CharField(label=_("New password"), widget=forms.PasswordInput)
  143. new_password2 = forms.CharField(label=_("New password confirmation"), widget=forms.PasswordInput)
  144. def __init__(self, user, *args, **kwargs):
  145. self.user = user
  146. super(SetPasswordForm, self).__init__(*args, **kwargs)
  147. def clean_new_password2(self):
  148. password1 = self.cleaned_data.get('new_password1')
  149. password2 = self.cleaned_data.get('new_password2')
  150. if password1 and password2:
  151. if password1 != password2:
  152. raise forms.ValidationError(_("The two password fields didn't match."))
  153. return password2
  154. def save(self, commit=True):
  155. self.user.set_password(self.cleaned_data['new_password1'])
  156. if commit:
  157. self.user.save()
  158. return self.user
  159. class PasswordChangeForm(SetPasswordForm):
  160. """
  161. A form that lets a user change his/her password by entering
  162. their old password.
  163. """
  164. old_password = forms.CharField(label=_("Old password"), widget=forms.PasswordInput)
  165. def clean_old_password(self):
  166. """
  167. Validates that the old_password field is correct.
  168. """
  169. old_password = self.cleaned_data["old_password"]
  170. if not self.user.check_password(old_password):
  171. raise forms.ValidationError(_("Your old password was entered incorrectly. Please enter it again."))
  172. return old_password
  173. PasswordChangeForm.base_fields.keyOrder = ['old_password', 'new_password1', 'new_password2']
  174. class AdminPasswordChangeForm(forms.Form):
  175. """
  176. A form used to change the password of a user in the admin interface.
  177. """
  178. password1 = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
  179. password2 = forms.CharField(label=_("Password (again)"), widget=forms.PasswordInput)
  180. def __init__(self, user, *args, **kwargs):
  181. self.user = user
  182. super(AdminPasswordChangeForm, self).__init__(*args, **kwargs)
  183. def clean_password2(self):
  184. password1 = self.cleaned_data.get('password1')
  185. password2 = self.cleaned_data.get('password2')
  186. if password1 and password2:
  187. if password1 != password2:
  188. raise forms.ValidationError(_("The two password fields didn't match."))
  189. return password2
  190. def save(self, commit=True):
  191. """
  192. Saves the new password.
  193. """
  194. self.user.set_password(self.cleaned_data["password1"])
  195. if commit:
  196. self.user.save()
  197. return self.user