auth.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. from rest_framework import serializers
  2. from django.contrib.auth import get_user_model
  3. from django.contrib.auth.password_validation import validate_password
  4. from django.core.exceptions import ValidationError
  5. from django.urls import reverse
  6. from django.utils.translation import ugettext_lazy, ugettext as _
  7. from misago.acl import serialize_acl
  8. from misago.users.authmixin import AuthMixin
  9. from misago.users.tokens import is_password_change_token_valid
  10. from .user import UserSerializer
  11. UserModel = get_user_model()
  12. class AuthenticatedUserSerializer(UserSerializer):
  13. email = serializers.SerializerMethodField()
  14. class Meta:
  15. model = UserModel
  16. fields = UserSerializer.Meta.fields + [
  17. 'has_usable_password',
  18. 'is_hiding_presence',
  19. 'limits_private_thread_invites_to',
  20. 'unread_private_threads',
  21. 'subscribe_to_started_threads',
  22. 'subscribe_to_replied_threads',
  23. ]
  24. def get_email(self, obj):
  25. return obj.email
  26. AuthenticatedUserSerializer = AuthenticatedUserSerializer.exclude_fields(
  27. 'is_avatar_locked',
  28. 'is_blocked',
  29. 'is_followed',
  30. 'is_signature_locked',
  31. 'meta',
  32. 'signature',
  33. 'status',
  34. )
  35. class AnonymousUserSerializer(serializers.Serializer):
  36. id = serializers.ReadOnlyField()
  37. class LoginSerializer(serializers.Serializer, AuthMixin):
  38. username = serializers.CharField(max_length=255)
  39. password = serializers.CharField(max_length=255, trim_whitespace=False)
  40. def validate(self, data):
  41. user = self.authenticate(data.get('username'), data.get('password'))
  42. self.confirm_login_allowed(user)
  43. return {'user': user}
  44. class GetUserSerializer(serializers.Serializer, AuthMixin):
  45. email = serializers.EmailField(max_length=255)
  46. def validate(self, data):
  47. user = self.get_user_by_email(data.get('email'))
  48. self.confirm_allowed(user)
  49. return {'user': user}
  50. def confirm_allowed(self, user):
  51. """override this method to include additional checks"""
  52. pass
  53. class ResendActivationSerializer(GetUserSerializer):
  54. def confirm_allowed(self, user):
  55. username_format = {'user': user.username}
  56. if not user.requires_activation:
  57. message = _("%(user)s, your account is already active.")
  58. raise ValidationError(message % username_format)
  59. if user.requires_activation_by_admin:
  60. message = _("%(user)s, only administrator may activate your account.")
  61. raise ValidationError(message % username_format)
  62. class SendPasswordFormSerializer(GetUserSerializer):
  63. auth_messages = {
  64. 'inactive_user': ugettext_lazy(
  65. "You have to activate your account before "
  66. "you will be able to request new password."
  67. ),
  68. 'inactive_admin': ugettext_lazy(
  69. "Administrator has to activate your account before "
  70. "you will be able to request new password."
  71. ),
  72. }
  73. def confirm_allowed(self, user):
  74. self.confirm_user_active(user)
  75. class ChangeForgottenPasswordSerializer(serializers.Serializer, AuthMixin):
  76. password = serializers.CharField(
  77. max_length=255,
  78. trim_whitespace=False,
  79. )
  80. token = serializers.CharField(max_length=255)
  81. auth_messages = {
  82. 'inactive_user': ugettext_lazy(
  83. "You have to activate your account before "
  84. "you will be able to change your password."
  85. ),
  86. 'inactive_admin': ugettext_lazy(
  87. "Administrator has to activate your account before "
  88. "you will be able to change your password."
  89. ),
  90. }
  91. def confirm_allowed(self):
  92. self.confirm_user_active(self.instance)
  93. self.confirm_user_not_banned(self.instance)
  94. def validate_password(self, value):
  95. validate_password(value, user=self.instance)
  96. return value
  97. def validate_token(self, value):
  98. if not is_password_change_token_valid(self.instance, value):
  99. raise ValidationError(_("Form link is invalid or expired. Please try again."))
  100. return value
  101. def validate(self, data):
  102. self.confirm_allowed()
  103. return data
  104. def save(self):
  105. self.instance.set_password(self.validated_data['password'])
  106. self.instance.save()