category.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. from django.core.exceptions import PermissionDenied
  2. from django.utils.translation import gettext as _
  3. from django.utils.translation import gettext_lazy
  4. from rest_framework import serializers
  5. from misago.acl.objectacl import add_acl_to_obj
  6. from misago.categories import THREADS_ROOT_NAME
  7. from misago.categories.models import Category
  8. from misago.categories.permissions import can_browse_category, can_see_category
  9. from misago.threads.permissions import allow_start_thread
  10. from misago.threads.threadtypes import trees_map
  11. from . import PostingEndpoint, PostingMiddleware
  12. class CategoryMiddleware(PostingMiddleware):
  13. """middleware that validates category id and sets category on thread and post instances"""
  14. def use_this_middleware(self):
  15. if self.mode == PostingEndpoint.START:
  16. return self.tree_name == THREADS_ROOT_NAME
  17. return False
  18. def get_serializer(self):
  19. return CategorySerializer(self.user_acl, data=self.request.data)
  20. def pre_save(self, serializer):
  21. category = serializer.category_cache
  22. add_acl_to_obj(self.user_acl, category)
  23. # set flags for savechanges middleware
  24. category.update_all = False
  25. category.update_fields = []
  26. # assign category to thread and post
  27. self.thread.category = category
  28. self.post.category = category
  29. class CategorySerializer(serializers.Serializer):
  30. category = serializers.IntegerField(
  31. error_messages={
  32. "required": gettext_lazy("You have to select category to post thread in."),
  33. "invalid": gettext_lazy("Selected category is invalid."),
  34. }
  35. )
  36. def __init__(self, user_acl, *args, **kwargs):
  37. self.user_acl = user_acl
  38. self.category_cache = None
  39. super().__init__(*args, **kwargs)
  40. def validate_category(self, value):
  41. try:
  42. self.category_cache = Category.objects.get(
  43. pk=value, tree_id=trees_map.get_tree_id_for_root(THREADS_ROOT_NAME)
  44. )
  45. can_see = can_see_category(self.user_acl, self.category_cache)
  46. can_browse = can_browse_category(self.user_acl, self.category_cache)
  47. if not (self.category_cache.level and can_see and can_browse):
  48. raise PermissionDenied(_("Selected category is invalid."))
  49. allow_start_thread(self.user_acl, self.category_cache)
  50. except Category.DoesNotExist:
  51. raise serializers.ValidationError(
  52. _(
  53. "Selected category doesn't exist or you don't have permission to browse it."
  54. )
  55. )
  56. except PermissionDenied as e:
  57. raise serializers.ValidationError(e.args[0])