gault-millau/apps/account/views/common.py
2019-08-30 17:56:35 +03:00

119 lines
4.3 KiB
Python

"""Common account views"""
from fcm_django.models import FCMDevice
from rest_framework import generics, status
from rest_framework import permissions
from rest_framework.response import Response
from django.utils.encoding import force_text
from django.utils.http import urlsafe_base64_decode
from utils.models import GMTokenGenerator
from utils import exceptions as utils_exceptions
from account import models
from account.serializers import common as serializers
from utils.views import JWTGenericViewMixin
# User views
class UserView(generics.RetrieveUpdateAPIView):
"""### User update view."""
serializer_class = serializers.UserSerializer
queryset = models.User.objects.active()
def get_object(self):
return self.request.user
# Firebase Cloud Messaging
class FCMDeviceViewSet(generics.GenericAPIView):
"""FCMDevice registration view.
* Pair of fields **registration_id** and **type** should be unique.
* In case of requested device existance, existing device will be returned
instead of creating new one.
"""
serializer_class = serializers.FCMDeviceSerializer
lookup_fields = ('registration_id', 'type',)
queryset = FCMDevice.objects.all()
permission_classes = (permissions.AllowAny,)
def post(self, request, *args, **kwargs):
"""Override post method."""
instance = self.get_object_or_none()
serializer = self.get_serializer(instance, data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(
serializer.data, status=status.HTTP_200_OK if instance else status.HTTP_201_CREATED)
def get_object_or_none(self):
"""Object as resylt and the view is displaying or None."""
queryset = self.get_queryset() # get the base queryset
queryset = self.filter_queryset(queryset) # apply any filter backends
# generate filter
filter = {f: self.request.data.get(f) for f in self.lookup_fields
if self.request.data.get(f)}
# get object and check permissions or return None
obj = queryset.filter(**filter).first()
obj and self.check_object_permissions(self.request, obj)
return obj
# Refresh access_token
class RefreshTokenView(JWTGenericViewMixin):
"""Refresh access_token"""
permission_classes = (permissions.IsAuthenticated,)
serializer_class = serializers.RefreshTokenSerializer
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
response = Response(serializer.data, status=status.HTTP_201_CREATED)
access_token = serializer.data.get('access_token')
refresh_token = serializer.data.get('refresh_token')
return self._put_cookies_in_response(
cookies=self._put_data_in_cookies(access_token=access_token,
refresh_token=refresh_token),
response=response)
# Change user email
class ChangeEmailView(JWTGenericViewMixin):
"""Change user email view"""
serializer_class = serializers.ChangeEmailSerializer
queryset = models.User.objects.all()
def patch(self, request, *args, **kwargs):
"""Implement POST-method"""
# Get user instance
instance = self.request.user
serializer = self.get_serializer(data=request.data, instance=instance)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(status=status.HTTP_200_OK)
class ChangeEmailConfirmView(JWTGenericViewMixin):
"""View for confirm changing email"""
permission_classes = (permissions.AllowAny, )
def get(self, request, *args, **kwargs):
"""Implement GET-method"""
uidb64 = kwargs.get('uidb64')
token = kwargs.get('token')
uid = force_text(urlsafe_base64_decode(uidb64))
user_qs = models.User.objects.filter(pk=uid)
if user_qs.exists():
user = user_qs.first()
if not GMTokenGenerator(GMTokenGenerator.CHANGE_EMAIL).check_token(
user, token):
raise utils_exceptions.NotValidTokenError()
# Approve email status
user.confirm_email()
return Response(status=status.HTTP_200_OK)
else:
raise utils_exceptions.UserNotFoundError()