auth.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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.template.defaultfilters import date as format_date
  6. from django.utils.translation import ugettext_lazy as _
  7. from misago.core import forms
  8. from misago.users.bans import get_user_ban
  9. class MisagoAuthMixin(object):
  10. def confirm_user_active(self, user):
  11. if user.requires_activation_by_admin:
  12. raise ValidationError(
  13. self.error_messages['inactive_admin'],
  14. code='inactive_admin',
  15. )
  16. if user.requires_activation_by_user:
  17. raise ValidationError(
  18. self.error_messages['inactive_user'],
  19. code='inactive_user',
  20. )
  21. def confirm_user_not_banned(self, user):
  22. self.user_ban = get_user_ban(user)
  23. if self.user_ban:
  24. if self.user_ban.valid_until:
  25. if self.user_ban.user_message:
  26. message = _("%(username)s, your account is "
  27. "banned until %(date)s for:")
  28. else:
  29. message = _("%(username)s, your account "
  30. "is banned until %(date)s.")
  31. date_format = {'date': format_date(self.user_ban.valid_until)}
  32. message = message % date_format
  33. else:
  34. if self.user_ban.user_message:
  35. message = _("%(username)s, your account is banned for:")
  36. else:
  37. message = _("%(username)s, your account is banned.")
  38. raise ValidationError(
  39. message % {'username': self.user_cache.username},
  40. code='banned',
  41. )
  42. class AuthenticationForm(MisagoAuthMixin, forms.Form, BaseAuthenticationForm):
  43. """
  44. Base class for authenticating users, Floppy-forms and
  45. Misago login field comliant
  46. """
  47. username = forms.CharField(label=_("Username or e-mail"),
  48. required=False,
  49. max_length=254)
  50. password = forms.CharField(label=_("Password"), required=False,
  51. widget=forms.PasswordInput)
  52. error_messages = {
  53. 'empty_data': _("You have to fill out both fields."),
  54. 'invalid_login': _("Your login or password is incorrect."),
  55. 'inactive_user': _("You have to activate your account before "
  56. "you will be able to sign in."),
  57. 'inactive_admin': _("Administrator has to activate your account "
  58. "before you will be able to sign in."),
  59. }
  60. def clean(self):
  61. username = self.cleaned_data.get('username')
  62. password = self.cleaned_data.get('password')
  63. if username and password:
  64. self.user_cache = authenticate(username=username,
  65. password=password)
  66. if self.user_cache is None or not self.user_cache.is_active:
  67. raise ValidationError(
  68. self.error_messages['invalid_login'],
  69. code='invalid_login',
  70. )
  71. else:
  72. self.confirm_login_allowed(self.user_cache)
  73. else:
  74. raise ValidationError(
  75. self.error_messages['empty_data'],
  76. code='empty_data',
  77. )
  78. return self.cleaned_data
  79. def confirm_login_allowed(self, user):
  80. self.confirm_user_active(user)
  81. self.confirm_user_not_banned(user)
  82. class AdminAuthenticationForm(AuthenticationForm):
  83. required_css_class = 'required'
  84. def __init__(self, *args, **kwargs):
  85. self.error_messages.update({
  86. 'not_staff': _("Your account does not have admin privileges.")
  87. })
  88. super(AdminAuthenticationForm, self).__init__(*args, **kwargs)
  89. def confirm_login_allowed(self, user):
  90. if not user.is_staff:
  91. raise forms.ValidationError(
  92. self.error_messages['not_staff'],
  93. code='not_staff',
  94. )
  95. class GetUserForm(MisagoAuthMixin, forms.Form):
  96. username = forms.CharField(label=_("Username or e-mail"))
  97. def clean(self):
  98. data = super(GetUserForm, self).clean()
  99. credential = data.get('username')
  100. if not credential or len(credential) > 250:
  101. raise forms.ValidationError(_("You have to fill out form."))
  102. try:
  103. User = get_user_model()
  104. user = User.objects.get_by_username_or_email(data['username'])
  105. self.user_cache = user
  106. except User.DoesNotExist:
  107. raise forms.ValidationError(_("User could not be found."))
  108. self.confirm_allowed(user)
  109. return data
  110. def confirm_allowed(self, user):
  111. raise NotImplementedError("confirm_allowed method must be defined "
  112. "by inheriting classes")
  113. class ResendActivationForm(GetUserForm):
  114. def confirm_allowed(self, user):
  115. self.confirm_user_not_banned(user)
  116. username_format = {'username': user.username}
  117. if not user.requires_activation:
  118. message = _("%(username)s, your account is already active.")
  119. raise forms.ValidationError(message % username_format)
  120. if user.requires_activation_by_admin:
  121. message = _("%(username)s, only administrator may activate "
  122. "your account.")
  123. raise forms.ValidationError(message % username_format)