validators.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. from django.core.exceptions import ValidationError
  2. from django.utils.module_loading import import_string
  3. from django.utils.translation import gettext as _
  4. from django.utils.translation import ngettext
  5. from .. import hooks
  6. from ..categories import THREADS_ROOT_NAME
  7. from ..categories.models import Category
  8. from ..categories.permissions import can_browse_category, can_see_category
  9. from ..conf import settings
  10. from ..core.validators import validate_sluggable
  11. from .threadtypes import trees_map
  12. def validate_category(user_acl, category_id, allow_root=False):
  13. try:
  14. threads_tree_id = trees_map.get_tree_id_for_root(THREADS_ROOT_NAME)
  15. category = Category.objects.get(tree_id=threads_tree_id, id=category_id)
  16. except Category.DoesNotExist:
  17. category = None
  18. # Skip ACL validation for root category?
  19. if allow_root and category and not category.level:
  20. return category
  21. if not category or not can_see_category(user_acl, category):
  22. raise ValidationError(_("Requested category could not be found."))
  23. if not can_browse_category(user_acl, category):
  24. raise ValidationError(_("You don't have permission to access this category."))
  25. return category
  26. def validate_thread_title(settings, title):
  27. validate_thread_title_length(settings, title)
  28. error_not_sluggable = _("Thread title should contain alpha-numeric characters.")
  29. error_slug_too_long = _("Thread title is too long.")
  30. validate_sluggable(error_not_sluggable, error_slug_too_long)(title)
  31. def validate_thread_title_length(settings, value):
  32. value_len = len(value)
  33. if not value_len:
  34. raise ValidationError(_("You have to enter an thread title."))
  35. if value_len < settings.thread_title_length_min:
  36. # pylint: disable=line-too-long
  37. message = ngettext(
  38. "Thread title should be at least %(limit_value)s character long (it has %(show_value)s).",
  39. "Thread title should be at least %(limit_value)s characters long (it has %(show_value)s).",
  40. settings.thread_title_length_min,
  41. )
  42. raise ValidationError(
  43. message
  44. % {"limit_value": settings.thread_title_length_min, "show_value": value_len}
  45. )
  46. if value_len > settings.thread_title_length_max:
  47. # pylint: disable=line-too-long
  48. message = ngettext(
  49. "Thread title cannot be longer than %(limit_value)s character (it has %(show_value)s).",
  50. "Thread title cannot be longer than %(limit_value)s characters (it has %(show_value)s).",
  51. settings.thread_title_length_max,
  52. )
  53. raise ValidationError(
  54. message
  55. % {"limit_value": settings.thread_title_length_max, "show_value": value_len}
  56. )
  57. def validate_post_length(settings, value):
  58. value_len = len(value)
  59. if not value_len:
  60. raise ValidationError(_("You have to enter a message."))
  61. if value_len < settings.post_length_min:
  62. # pylint: disable=line-too-long
  63. message = ngettext(
  64. "Posted message should be at least %(limit_value)s character long (it has %(show_value)s).",
  65. "Posted message should be at least %(limit_value)s characters long (it has %(show_value)s).",
  66. settings.post_length_min,
  67. )
  68. raise ValidationError(
  69. message % {"limit_value": settings.post_length_min, "show_value": value_len}
  70. )
  71. if settings.post_length_max and value_len > settings.post_length_max:
  72. # pylint: disable=line-too-long
  73. message = ngettext(
  74. "Posted message cannot be longer than %(limit_value)s character (it has %(show_value)s).",
  75. "Posted message cannot be longer than %(limit_value)s characters (it has %(show_value)s).",
  76. settings.post_length_max,
  77. )
  78. raise ValidationError(
  79. message % {"limit_value": settings.post_length_max, "show_value": value_len}
  80. )
  81. # Post validation framework
  82. validators_list = settings.MISAGO_POST_VALIDATORS
  83. POST_VALIDATORS = list(map(import_string, validators_list))
  84. def validate_post(context, data, validators=None):
  85. validators = validators or POST_VALIDATORS
  86. for validator in validators:
  87. data = validator(context, data) or data
  88. for validator in hooks.post_validators:
  89. data = validator(context, data) or data
  90. return data