register.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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.utils import six
  6. from django.utils.translation import ugettext as _
  7. from misago.users import captcha, validators
  8. from misago.users.bans import get_email_ban, get_username_ban
  9. UserModel = get_user_model()
  10. class BaseRegisterUserSerializer(serializers.Serializer):
  11. username = serializers.CharField(
  12. max_length=255,
  13. validators=[validators.validate_username],
  14. )
  15. email = serializers.CharField(
  16. max_length=255,
  17. validators=[validators.validate_email],
  18. )
  19. def validate_username(self, data):
  20. ban = get_username_ban(data, registration_only=True)
  21. if ban:
  22. if ban.user_message:
  23. raise ValidationError(ban.user_message)
  24. else:
  25. raise ValidationError(_("This usernane is not allowed."))
  26. return data
  27. def validate_email(self, data):
  28. ban = get_email_ban(data, registration_only=True)
  29. if ban:
  30. if ban.user_message:
  31. raise ValidationError(ban.user_message)
  32. else:
  33. raise ValidationError(_("This e-mail address is not allowed."))
  34. return data
  35. def validate_added_errors(self):
  36. if self._added_errors:
  37. # fail registration with additional errors
  38. raise serializers.ValidationError(self._added_errors)
  39. def validate(self, data):
  40. self._added_errors = {}
  41. return data
  42. def add_error(self, field, error):
  43. """
  44. custom implementation for quasi add_error feature for custom validators
  45. we are doing some hacky introspection here to deconstruct ValidationError
  46. """
  47. self._added_errors.setdefault(field, [])
  48. if isinstance(error, ValidationError):
  49. self._added_errors[field].extend(list(error))
  50. elif isinstance(error, serializers.ValidationError):
  51. details = [e['message'] for e in error.get_full_details()]
  52. self._added_errors[field].extend(details)
  53. else:
  54. self._added_errors[field].append(six.text_type(error))
  55. class SocialRegisterUserSerializer(BaseRegisterUserSerializer):
  56. def validate(self, data):
  57. data = super(SocialRegisterUserSerializer, self).validate(data)
  58. request = self.context['request']
  59. validators.validate_new_registration(request, data, self.add_error)
  60. self.validate_added_errors()
  61. return data
  62. class RegisterUserSerializer(BaseRegisterUserSerializer):
  63. password = serializers.CharField(
  64. max_length=255,
  65. trim_whitespace=False,
  66. )
  67. def validate(self, data):
  68. data = super(RegisterUserSerializer, self).validate(data)
  69. request = self.context['request']
  70. try:
  71. self.full_clean_password(data)
  72. except ValidationError as e:
  73. self.add_error('password', e)
  74. validators.validate_new_registration(request, data, self.add_error)
  75. self.validate_added_errors()
  76. # run test for captcha
  77. try:
  78. captcha.test_request(self.context['request'])
  79. except ValidationError as e:
  80. raise serializers.ValidationError({'captcha': e.message})
  81. return data
  82. def full_clean_password(self, data):
  83. if data.get('password'):
  84. validate_password(
  85. data['password'],
  86. user=UserModel(
  87. username=data.get('username'),
  88. email=data.get('email'),
  89. ),
  90. )