users.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. from django.contrib.auth import get_user_model
  2. from django.core.exceptions import PermissionDenied
  3. from django.shortcuts import get_object_or_404
  4. from django.utils.translation import ugettext as _
  5. from rest_framework import mixins, status, viewsets
  6. from rest_framework.decorators import detail_route, list_route
  7. from rest_framework.pagination import PageNumberPagination
  8. from rest_framework.parsers import JSONParser, MultiPartParser
  9. from rest_framework.response import Response
  10. from misago.acl import add_acl
  11. from misago.users.forms.options import ForumOptionsForm
  12. from misago.users.permissions.profiles import (allow_browse_users_list,
  13. allow_see_users_online_list)
  14. from misago.users.rest_permissions import (BasePermission,
  15. IsAuthenticatedOrReadOnly, UnbannedAnonOnly)
  16. from misago.users.serializers import UserSerializer, UserProfileSerializer
  17. from misago.users.api.userendpoints.list import list_endpoint
  18. from misago.users.api.userendpoints.avatar import avatar_endpoint
  19. from misago.users.api.userendpoints.create import create_endpoint
  20. from misago.users.api.userendpoints.signature import signature_endpoint
  21. from misago.users.api.userendpoints.username import username_endpoint
  22. from misago.users.api.userendpoints.changeemail import change_email_endpoint
  23. from misago.users.api.userendpoints.changepassword import change_password_endpoint
  24. class UserViewSetPermission(BasePermission):
  25. def has_permission(self, request, view):
  26. if view.action == 'create':
  27. policy = UnbannedAnonOnly()
  28. else:
  29. policy = IsAuthenticatedOrReadOnly()
  30. return policy.has_permission(request, view)
  31. def allow_self_only(user, pk, message):
  32. if user.is_anonymous():
  33. raise PermissionDenied(
  34. _("You have to sign in to perform this action."))
  35. if user.pk != int(pk):
  36. raise PermissionDenied(message)
  37. class UsersPagination(PageNumberPagination):
  38. page_size = 16
  39. class UserViewSet(viewsets.GenericViewSet):
  40. permission_classes = (UserViewSetPermission,)
  41. parser_classes=(JSONParser, MultiPartParser)
  42. serializer_class = UserSerializer
  43. queryset = get_user_model().objects
  44. pagination_class = UsersPagination
  45. def get_queryset(self):
  46. relations = ('rank', 'online_tracker', 'ban_cache')
  47. return self.queryset.select_related(*relations)
  48. def list(self, request):
  49. allow_browse_users_list(request.user)
  50. users_list = list_endpoint(request, self.get_queryset())
  51. if not users_list:
  52. return Response([])
  53. if 'data' in users_list:
  54. return Response(users_list['data'])
  55. if users_list.get('paginate'):
  56. page = self.paginate_queryset(users_list['queryset'])
  57. users_list['queryset'] = page
  58. if users_list.get('serializer'):
  59. serializer_class = users_list.get('serializer')
  60. else:
  61. serializer_class = self.serializer_class
  62. serializer = serializer_class(
  63. users_list['queryset'], many=True, context={'user': request.user})
  64. if users_list.get('paginate'):
  65. return self.get_paginated_response(serializer.data)
  66. else:
  67. return Response(serializer.data)
  68. def create(self, request):
  69. return create_endpoint(request)
  70. def retrieve(self, request, pk=None):
  71. qs = self.get_queryset()
  72. profile = get_object_or_404(self.get_queryset(), id=pk)
  73. add_acl(request.user, profile)
  74. serializer = UserProfileSerializer(
  75. profile, context={'user': request.user})
  76. return Response(serializer.data)
  77. @detail_route(methods=['get', 'post'])
  78. def avatar(self, request, pk=None):
  79. allow_self_only(
  80. request.user, pk, _("You can't change other users avatars."))
  81. return avatar_endpoint(request)
  82. @detail_route(methods=['post'])
  83. def forum_options(self, request, pk=None):
  84. allow_self_only(
  85. request.user, pk, _("You can't change other users options."))
  86. form = ForumOptionsForm(request.data, instance=request.user)
  87. if form.is_valid():
  88. form.save()
  89. return Response({
  90. 'detail': _("Your forum options have been changed.")
  91. })
  92. else:
  93. return Response(form.errors, status=status.HTTP_400_BAD_REQUEST)
  94. @detail_route(methods=['get', 'post'])
  95. def username(self, request, pk=None):
  96. allow_self_only(
  97. request.user, pk, _("You can't change other users names."))
  98. return username_endpoint(request)
  99. @detail_route(methods=['get', 'post'])
  100. def signature(self, request, pk=None):
  101. allow_self_only(
  102. request.user, pk, _("You can't change other users signatures."))
  103. return signature_endpoint(request)
  104. @detail_route(methods=['post'])
  105. def change_password(self, request, pk=None):
  106. allow_self_only(
  107. request.user, pk, _("You can't change other users passwords."))
  108. return change_password_endpoint(request)
  109. @detail_route(methods=['post'])
  110. def change_email(self, request, pk=None):
  111. allow_self_only(request.user, pk,
  112. _("You can't change other users e-mail addresses."))
  113. return change_email_endpoint(request)