1
0

views.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. from django.contrib.auth import get_user_model, update_session_auth_hash
  2. from django.contrib.auth.tokens import default_token_generator
  3. from django.utils.timezone import now
  4. from rest_framework import generics, status, views, viewsets
  5. from rest_framework.decorators import action
  6. from rest_framework.exceptions import NotFound
  7. from rest_framework.response import Response
  8. from djoser import signals, utils
  9. from djoser.compat import get_user_email
  10. from djoser.conf import settings
  11. User = get_user_model()
  12. class TokenCreateView(utils.ActionViewMixin, generics.GenericAPIView):
  13. """
  14. Use this endpoint to obtain user authentication token.
  15. """
  16. serializer_class = settings.SERIALIZERS.token_create
  17. permission_classes = settings.PERMISSIONS.token_create
  18. def _action(self, serializer):
  19. token = utils.login_user(self.request, serializer.user)
  20. token_serializer_class = settings.SERIALIZERS.token
  21. return Response(
  22. data=token_serializer_class(token).data, status=status.HTTP_200_OK
  23. )
  24. class TokenDestroyView(views.APIView):
  25. """
  26. Use this endpoint to logout user (remove user authentication token).
  27. """
  28. permission_classes = settings.PERMISSIONS.token_destroy
  29. def post(self, request):
  30. utils.logout_user(request)
  31. return Response(status=status.HTTP_204_NO_CONTENT)
  32. class UserViewSet(viewsets.ModelViewSet):
  33. serializer_class = settings.SERIALIZERS.user
  34. queryset = User.objects.all()
  35. permission_classes = settings.PERMISSIONS.user
  36. token_generator = default_token_generator
  37. lookup_field = settings.USER_ID_FIELD
  38. def permission_denied(self, request, **kwargs):
  39. if (
  40. settings.HIDE_USERS
  41. and request.user.is_authenticated
  42. and self.action in ["update", "partial_update", "list", "retrieve"]
  43. ):
  44. raise NotFound()
  45. super().permission_denied(request, **kwargs)
  46. def get_queryset(self):
  47. user = self.request.user
  48. queryset = super().get_queryset()
  49. if settings.HIDE_USERS and self.action == "list" and not user.is_staff:
  50. queryset = queryset.filter(pk=user.pk)
  51. return queryset
  52. def get_permissions(self):
  53. if self.action == "create":
  54. self.permission_classes = settings.PERMISSIONS.user_create
  55. elif self.action == "activation":
  56. self.permission_classes = settings.PERMISSIONS.activation
  57. elif self.action == "resend_activation":
  58. self.permission_classes = settings.PERMISSIONS.password_reset
  59. elif self.action == "list":
  60. self.permission_classes = settings.PERMISSIONS.user_list
  61. elif self.action == "reset_password":
  62. self.permission_classes = settings.PERMISSIONS.password_reset
  63. elif self.action == "reset_password_confirm":
  64. self.permission_classes = settings.PERMISSIONS.password_reset_confirm
  65. elif self.action == "set_password":
  66. self.permission_classes = settings.PERMISSIONS.set_password
  67. elif self.action == "set_username":
  68. self.permission_classes = settings.PERMISSIONS.set_username
  69. elif self.action == "reset_username":
  70. self.permission_classes = settings.PERMISSIONS.username_reset
  71. elif self.action == "reset_username_confirm":
  72. self.permission_classes = settings.PERMISSIONS.username_reset_confirm
  73. elif self.action == "destroy" or (
  74. self.action == "me" and self.request and self.request.method == "DELETE"
  75. ):
  76. self.permission_classes = settings.PERMISSIONS.user_delete
  77. return super().get_permissions()
  78. def get_serializer_class(self):
  79. if self.action == "create":
  80. if settings.USER_CREATE_PASSWORD_RETYPE:
  81. return settings.SERIALIZERS.user_create_password_retype
  82. return settings.SERIALIZERS.user_create
  83. elif self.action == "destroy" or (
  84. self.action == "me" and self.request and self.request.method == "DELETE"
  85. ):
  86. return settings.SERIALIZERS.user_delete
  87. elif self.action == "activation":
  88. return settings.SERIALIZERS.activation
  89. elif self.action == "resend_activation":
  90. return settings.SERIALIZERS.password_reset
  91. elif self.action == "reset_password":
  92. return settings.SERIALIZERS.password_reset
  93. elif self.action == "reset_password_confirm":
  94. if settings.PASSWORD_RESET_CONFIRM_RETYPE:
  95. return settings.SERIALIZERS.password_reset_confirm_retype
  96. return settings.SERIALIZERS.password_reset_confirm
  97. elif self.action == "set_password":
  98. if settings.SET_PASSWORD_RETYPE:
  99. return settings.SERIALIZERS.set_password_retype
  100. return settings.SERIALIZERS.set_password
  101. elif self.action == "set_username":
  102. if settings.SET_USERNAME_RETYPE:
  103. return settings.SERIALIZERS.set_username_retype
  104. return settings.SERIALIZERS.set_username
  105. elif self.action == "reset_username":
  106. return settings.SERIALIZERS.username_reset
  107. elif self.action == "reset_username_confirm":
  108. if settings.USERNAME_RESET_CONFIRM_RETYPE:
  109. return settings.SERIALIZERS.username_reset_confirm_retype
  110. return settings.SERIALIZERS.username_reset_confirm
  111. elif self.action == "me":
  112. return settings.SERIALIZERS.current_user
  113. return self.serializer_class
  114. def get_instance(self):
  115. return self.request.user
  116. def perform_create(self, serializer):
  117. user = serializer.save()
  118. signals.user_registered.send(
  119. sender=self.__class__, user=user, request=self.request
  120. )
  121. context = {"user": user}
  122. to = [get_user_email(user)]
  123. if settings.SEND_ACTIVATION_EMAIL:
  124. settings.EMAIL.activation(self.request, context).send(to)
  125. elif settings.SEND_CONFIRMATION_EMAIL:
  126. settings.EMAIL.confirmation(self.request, context).send(to)
  127. def perform_update(self, serializer):
  128. super().perform_update(serializer)
  129. user = serializer.instance
  130. # should we send activation email after update?
  131. if settings.SEND_ACTIVATION_EMAIL:
  132. context = {"user": user}
  133. to = [get_user_email(user)]
  134. settings.EMAIL.activation(self.request, context).send(to)
  135. def destroy(self, request, *args, **kwargs):
  136. instance = self.get_object()
  137. serializer = self.get_serializer(instance, data=request.data)
  138. serializer.is_valid(raise_exception=True)
  139. if instance == request.user:
  140. utils.logout_user(self.request)
  141. self.perform_destroy(instance)
  142. return Response(status=status.HTTP_204_NO_CONTENT)
  143. @action(["get", "put", "patch", "delete"], detail=False)
  144. def me(self, request, *args, **kwargs):
  145. self.get_object = self.get_instance
  146. if request.method == "GET":
  147. return self.retrieve(request, *args, **kwargs)
  148. elif request.method == "PUT":
  149. return self.update(request, *args, **kwargs)
  150. elif request.method == "PATCH":
  151. return self.partial_update(request, *args, **kwargs)
  152. elif request.method == "DELETE":
  153. return self.destroy(request, *args, **kwargs)
  154. @action(["post"], detail=False)
  155. def activation(self, request, *args, **kwargs):
  156. serializer = self.get_serializer(data=request.data)
  157. serializer.is_valid(raise_exception=True)
  158. user = serializer.user
  159. user.is_active = True
  160. user.save()
  161. signals.user_activated.send(
  162. sender=self.__class__, user=user, request=self.request
  163. )
  164. if settings.SEND_CONFIRMATION_EMAIL:
  165. context = {"user": user}
  166. to = [get_user_email(user)]
  167. settings.EMAIL.confirmation(self.request, context).send(to)
  168. return Response(status=status.HTTP_204_NO_CONTENT)
  169. @action(["post"], detail=False)
  170. def resend_activation(self, request, *args, **kwargs):
  171. serializer = self.get_serializer(data=request.data)
  172. serializer.is_valid(raise_exception=True)
  173. user = serializer.get_user(is_active=False)
  174. if not settings.SEND_ACTIVATION_EMAIL or not user:
  175. return Response(status=status.HTTP_400_BAD_REQUEST)
  176. context = {"user": user}
  177. to = [get_user_email(user)]
  178. settings.EMAIL.activation(self.request, context).send(to)
  179. return Response(status=status.HTTP_204_NO_CONTENT)
  180. @action(["post"], detail=False)
  181. def set_password(self, request, *args, **kwargs):
  182. serializer = self.get_serializer(data=request.data)
  183. serializer.is_valid(raise_exception=True)
  184. self.request.user.set_password(serializer.data["new_password"])
  185. self.request.user.save()
  186. if settings.PASSWORD_CHANGED_EMAIL_CONFIRMATION:
  187. context = {"user": self.request.user}
  188. to = [get_user_email(self.request.user)]
  189. settings.EMAIL.password_changed_confirmation(self.request, context).send(to)
  190. if settings.LOGOUT_ON_PASSWORD_CHANGE:
  191. utils.logout_user(self.request)
  192. elif settings.CREATE_SESSION_ON_LOGIN:
  193. update_session_auth_hash(self.request, self.request.user)
  194. return Response(status=status.HTTP_204_NO_CONTENT)
  195. @action(["post"], detail=False)
  196. def reset_password(self, request, *args, **kwargs):
  197. serializer = self.get_serializer(data=request.data)
  198. serializer.is_valid(raise_exception=True)
  199. user = serializer.get_user()
  200. if user:
  201. context = {"user": user}
  202. to = [get_user_email(user)]
  203. settings.EMAIL.password_reset(self.request, context).send(to)
  204. return Response(status=status.HTTP_204_NO_CONTENT)
  205. @action(["post"], detail=False)
  206. def reset_password_confirm(self, request, *args, **kwargs):
  207. serializer = self.get_serializer(data=request.data)
  208. serializer.is_valid(raise_exception=True)
  209. serializer.user.set_password(serializer.data["new_password"])
  210. if hasattr(serializer.user, "last_login"):
  211. serializer.user.last_login = now()
  212. serializer.user.save()
  213. if settings.PASSWORD_CHANGED_EMAIL_CONFIRMATION:
  214. context = {"user": serializer.user}
  215. to = [get_user_email(serializer.user)]
  216. settings.EMAIL.password_changed_confirmation(self.request, context).send(to)
  217. return Response(status=status.HTTP_204_NO_CONTENT)
  218. @action(["post"], detail=False, url_path="set_{}".format(User.USERNAME_FIELD))
  219. def set_username(self, request, *args, **kwargs):
  220. serializer = self.get_serializer(data=request.data)
  221. serializer.is_valid(raise_exception=True)
  222. user = self.request.user
  223. new_username = serializer.data["new_" + User.USERNAME_FIELD]
  224. setattr(user, User.USERNAME_FIELD, new_username)
  225. user.save()
  226. if settings.USERNAME_CHANGED_EMAIL_CONFIRMATION:
  227. context = {"user": user}
  228. to = [get_user_email(user)]
  229. settings.EMAIL.username_changed_confirmation(self.request, context).send(to)
  230. return Response(status=status.HTTP_204_NO_CONTENT)
  231. @action(["post"], detail=False, url_path="reset_{}".format(User.USERNAME_FIELD))
  232. def reset_username(self, request, *args, **kwargs):
  233. serializer = self.get_serializer(data=request.data)
  234. serializer.is_valid(raise_exception=True)
  235. user = serializer.get_user()
  236. if user:
  237. context = {"user": user}
  238. to = [get_user_email(user)]
  239. settings.EMAIL.username_reset(self.request, context).send(to)
  240. return Response(status=status.HTTP_204_NO_CONTENT)
  241. @action(
  242. ["post"], detail=False, url_path="reset_{}_confirm".format(User.USERNAME_FIELD)
  243. )
  244. def reset_username_confirm(self, request, *args, **kwargs):
  245. serializer = self.get_serializer(data=request.data)
  246. serializer.is_valid(raise_exception=True)
  247. new_username = serializer.data["new_" + User.USERNAME_FIELD]
  248. setattr(serializer.user, User.USERNAME_FIELD, new_username)
  249. if hasattr(serializer.user, "last_login"):
  250. serializer.user.last_login = now()
  251. serializer.user.save()
  252. if settings.USERNAME_CHANGED_EMAIL_CONFIRMATION:
  253. context = {"user": serializer.user}
  254. to = [get_user_email(serializer.user)]
  255. settings.EMAIL.username_changed_confirmation(self.request, context).send(to)
  256. return Response(status=status.HTTP_204_NO_CONTENT)