participants.py 3.2 KB

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