register.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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 RegisterUserSerializer(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. password = serializers.CharField(
  20. max_length=255,
  21. trim_whitespace=False,
  22. )
  23. def validate_username(self, data):
  24. ban = get_username_ban(data, registration_only=True)
  25. if ban:
  26. if ban.user_message:
  27. raise ValidationError(ban.user_message)
  28. else:
  29. raise ValidationError(_("This usernane is not allowed."))
  30. return data
  31. def validate_email(self, data):
  32. ban = get_email_ban(data, registration_only=True)
  33. if ban:
  34. if ban.user_message:
  35. raise ValidationError(ban.user_message)
  36. else:
  37. raise ValidationError(_("This e-mail address is not allowed."))
  38. return data
  39. def validate(self, data):
  40. request = self.context['request']
  41. self._added_errors = {}
  42. try:
  43. self.full_clean_password(data)
  44. except ValidationError as e:
  45. self.add_error('password', e)
  46. validators.validate_new_registration(request, data, self.add_error)
  47. if self._added_errors:
  48. # fail registration with additional errors
  49. raise serializers.ValidationError(self._added_errors)
  50. # run test for captcha
  51. try:
  52. captcha.test_request(self.context['request'])
  53. except ValidationError as e:
  54. raise serializers.ValidationError({'captcha': e.message})
  55. return data
  56. def full_clean_password(self, data):
  57. if data.get('password'):
  58. validate_password(
  59. data['password'],
  60. user=UserModel(
  61. username=data.get('username'),
  62. email=data.get('email'),
  63. ),
  64. )
  65. def add_error(self, field, error):
  66. """
  67. custom implementation for quasi add_error feature for custom validators
  68. we are doing some hacky introspection here to deconstruct ValidationError
  69. """
  70. self._added_errors.setdefault(field, [])
  71. if isinstance(error, ValidationError):
  72. self._added_errors[field].extend(list(error))
  73. elif isinstance(error, serializers.ValidationError):
  74. details = [e['message'] for e in error.get_full_details()]
  75. self._added_errors[field].extend(details)
  76. else:
  77. self._added_errors[field].append(six.text_type(error))