auth.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. from django.core.exceptions import ValidationError
  2. from django.contrib.auth import authenticate, get_user_model
  3. from django.contrib.auth.forms import (AuthenticationForm as
  4. BaseAuthenticationForm)
  5. from django.utils.translation import ugettext_lazy as _
  6. from django.core.validators import validate_email
  7. from misago.core import forms
  8. from misago.users.bans import get_user_ban
  9. from misago.users.validators import validate_password
  10. class MisagoAuthMixin(object):
  11. error_messages = {
  12. 'empty_data': _("Fill out both fields."),
  13. 'invalid_login': _("Login or password is incorrect."),
  14. 'inactive_user': _("You have to activate your account before "
  15. "you will be able to sign in."),
  16. 'inactive_admin': _("Your account has to be activated by "
  17. "Administrator before you will be able "
  18. "to sign in."),
  19. }
  20. def confirm_user_active(self, user):
  21. if user.requires_activation_by_admin:
  22. raise ValidationError(
  23. self.error_messages['inactive_admin'],
  24. code='inactive_admin',
  25. )
  26. if user.requires_activation_by_user:
  27. raise ValidationError(
  28. self.error_messages['inactive_user'],
  29. code='inactive_user',
  30. )
  31. def confirm_user_not_banned(self, user):
  32. self.user_ban = get_user_ban(user)
  33. if self.user_ban:
  34. raise ValidationError('', code='banned')
  35. def get_errors_dict(self):
  36. error = self.errors.as_data()['__all__'][0]
  37. if error.code == 'banned':
  38. error.message = self.user_ban.ban.get_serialized_message()
  39. else:
  40. error.message = error.messages[0]
  41. return {
  42. 'detail': error.message,
  43. 'code': error.code
  44. }
  45. class AuthenticationForm(MisagoAuthMixin, forms.Form, BaseAuthenticationForm):
  46. """
  47. Base class for authenticating users, Floppy-forms and
  48. Misago login field comliant
  49. """
  50. username = forms.CharField(label=_("Username or e-mail"),
  51. required=False,
  52. max_length=254)
  53. password = forms.CharField(label=_("Password"), required=False,
  54. widget=forms.PasswordInput)
  55. def clean(self):
  56. username = self.cleaned_data.get('username')
  57. password = self.cleaned_data.get('password')
  58. if username and password:
  59. self.user_cache = authenticate(username=username,
  60. password=password)
  61. if self.user_cache is None or not self.user_cache.is_active:
  62. raise ValidationError(
  63. self.error_messages['invalid_login'],
  64. code='invalid_login',
  65. )
  66. else:
  67. self.confirm_login_allowed(self.user_cache)
  68. else:
  69. raise ValidationError(
  70. self.error_messages['empty_data'],
  71. code='empty_data',
  72. )
  73. return self.cleaned_data
  74. def confirm_login_allowed(self, user):
  75. self.confirm_user_active(user)
  76. self.confirm_user_not_banned(user)
  77. class AdminAuthenticationForm(AuthenticationForm):
  78. required_css_class = 'required'
  79. def __init__(self, *args, **kwargs):
  80. self.error_messages.update({
  81. 'not_staff': _("Your account does not have admin privileges.")
  82. })
  83. super(AdminAuthenticationForm, self).__init__(*args, **kwargs)
  84. def confirm_login_allowed(self, user):
  85. if not user.is_staff:
  86. raise forms.ValidationError(
  87. self.error_messages['not_staff'],
  88. code='not_staff',
  89. )
  90. class GetUserForm(MisagoAuthMixin, forms.Form):
  91. email = forms.CharField()
  92. def clean(self):
  93. data = super(GetUserForm, self).clean()
  94. email = data.get('email')
  95. if not email or len(email) > 250:
  96. raise forms.ValidationError(
  97. _("Enter e-mail address."),
  98. code='empty_email')
  99. try:
  100. validate_email(email)
  101. except forms.ValidationError:
  102. raise forms.ValidationError(
  103. _("Entered e-mail is invalid."),
  104. code='invalid_email')
  105. try:
  106. User = get_user_model()
  107. user = User.objects.get_by_email(data['email'])
  108. self.user_cache = user
  109. except User.DoesNotExist:
  110. raise forms.ValidationError(
  111. _("No user with this e-mail exists."),
  112. code='not_found')
  113. self.confirm_allowed(user)
  114. return data
  115. def confirm_allowed(self, user):
  116. """override this method to include additional checks"""
  117. class ResendActivationForm(GetUserForm):
  118. def confirm_allowed(self, user):
  119. username_format = {'user': user.username}
  120. if not user.requires_activation:
  121. message = _("%(user)s, your account is already active.")
  122. raise forms.ValidationError(message % username_format,
  123. code='already_active')
  124. if user.requires_activation_by_admin:
  125. message = _("%(user)s, only administrator may activate "
  126. "your account.")
  127. raise forms.ValidationError(message % username_format,
  128. code='inactive_admin')
  129. class ResetPasswordForm(GetUserForm):
  130. def confirm_allowed(self, user):
  131. self.confirm_user_active(user)