participants.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. from django.contrib.auth import get_user_model
  2. from django.core.exceptions import PermissionDenied
  3. from django.utils.translation import gettext as _
  4. from django.utils.translation import ngettext
  5. from rest_framework import serializers
  6. from . import PostingEndpoint, PostingMiddleware
  7. from ....acl import useracl
  8. from ....categories import PRIVATE_THREADS_ROOT_NAME
  9. from ...participants import add_participants, set_owner
  10. from ...permissions import allow_message_user
  11. User = get_user_model()
  12. class ParticipantsMiddleware(PostingMiddleware):
  13. def use_this_middleware(self):
  14. if self.mode == PostingEndpoint.START:
  15. return self.tree_name == PRIVATE_THREADS_ROOT_NAME
  16. return False
  17. def get_serializer(self):
  18. return ParticipantsSerializer(
  19. data=self.request.data,
  20. context={
  21. "request": self.request,
  22. "user": self.user,
  23. "user_acl": self.user_acl,
  24. },
  25. )
  26. def save(self, serializer):
  27. set_owner(self.thread, self.user)
  28. add_participants(self.request, self.thread, serializer.users_cache)
  29. class ParticipantsSerializer(serializers.Serializer):
  30. to = serializers.ListField(child=serializers.CharField(), required=True)
  31. def validate_to(self, usernames):
  32. clean_usernames = self.clean_usernames(usernames)
  33. self.users_cache = self.get_users(clean_usernames)
  34. def clean_usernames(self, usernames):
  35. clean_usernames = []
  36. for name in usernames:
  37. clean_name = name.strip().lower()
  38. if clean_name == self.context["user"].slug:
  39. raise serializers.ValidationError(
  40. _(
  41. "You can't include yourself on the list of users to invite to new thread."
  42. )
  43. )
  44. if clean_name and clean_name not in clean_usernames:
  45. clean_usernames.append(clean_name)
  46. if not clean_usernames:
  47. raise serializers.ValidationError(_("You have to enter user names."))
  48. max_participants = self.context["user_acl"]["max_private_thread_participants"]
  49. if max_participants and len(clean_usernames) > max_participants:
  50. message = ngettext(
  51. "You can't add more than %(users)s user to private thread (you've added %(added)s).",
  52. "You can't add more than %(users)s users to private thread (you've added %(added)s).",
  53. max_participants,
  54. )
  55. raise serializers.ValidationError(
  56. message % {"users": max_participants, "added": len(clean_usernames)}
  57. )
  58. return list(set(clean_usernames))
  59. def get_users(self, usernames):
  60. users = []
  61. for user in User.objects.filter(slug__in=usernames):
  62. try:
  63. user_acl = useracl.get_user_acl(
  64. user, self.context["request"].cache_versions
  65. )
  66. allow_message_user(self.context["user_acl"], user, user_acl)
  67. except PermissionDenied as e:
  68. raise serializers.ValidationError(str(e))
  69. users.append(user)
  70. if len(usernames) != len(users):
  71. invalid_usernames = set(usernames) - set([u.slug for u in users])
  72. sorted_usernames = sorted(invalid_usernames)
  73. message = _("One or more users could not be found: %(usernames)s")
  74. raise serializers.ValidationError(
  75. message % {"usernames": ", ".join(sorted_usernames)}
  76. )
  77. return users