participants.py 3.5 KB

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