register.py 3.4 KB

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