134 lines
4.8 KiB
Python
134 lines
4.8 KiB
Python
"""Common account views"""
|
|
from django.conf import settings
|
|
from django.utils.encoding import force_text
|
|
from django.utils.http import urlsafe_base64_decode
|
|
from fcm_django.models import FCMDevice
|
|
from rest_framework import generics
|
|
from rest_framework import permissions
|
|
from rest_framework import status
|
|
from rest_framework.response import Response
|
|
|
|
from account import models
|
|
from account.serializers import common as serializers
|
|
from authorization.tasks import send_confirm_email
|
|
from utils import exceptions as utils_exceptions
|
|
from utils.models import GMTokenGenerator
|
|
from utils.views import JWTGenericViewMixin
|
|
|
|
|
|
# User views
|
|
class UserRetrieveUpdateView(generics.RetrieveUpdateDestroyAPIView):
|
|
"""User update view."""
|
|
serializer_class = serializers.UserSerializer
|
|
queryset = models.User.objects.active()
|
|
|
|
def get_object(self):
|
|
return self.request.user
|
|
|
|
def delete(self, request, *args, **kwargs):
|
|
"""Overridden behavior of DELETE method."""
|
|
return Response(status=status.HTTP_204_NO_CONTENT)
|
|
|
|
|
|
class ChangePasswordView(generics.GenericAPIView):
|
|
"""Change password view"""
|
|
serializer_class = serializers.ChangePasswordSerializer
|
|
queryset = models.User.objects.active()
|
|
|
|
def patch(self, request, *args, **kwargs):
|
|
"""Implement PUT method"""
|
|
serializer = self.get_serializer(instance=self.request.user,
|
|
data=request.data)
|
|
serializer.is_valid(raise_exception=True)
|
|
serializer.save()
|
|
return Response(status=status.HTTP_200_OK)
|
|
|
|
|
|
class SendConfirmationEmailView(generics.GenericAPIView):
|
|
"""Confirm email view."""
|
|
|
|
def post(self, request, *args, **kwargs):
|
|
"""Override create method"""
|
|
user = self.request.user
|
|
country_code = self.request.country_code
|
|
|
|
if user.email_confirmed:
|
|
raise utils_exceptions.EmailConfirmedError()
|
|
|
|
# Send verification link on user email for change email address
|
|
if settings.USE_CELERY:
|
|
send_confirm_email.delay(
|
|
user_id=user.id,
|
|
country_code=country_code)
|
|
else:
|
|
send_confirm_email(
|
|
user_id=user.id,
|
|
country_code=country_code)
|
|
return Response(status=status.HTTP_200_OK)
|
|
|
|
|
|
class ConfirmEmailView(JWTGenericViewMixin, generics.GenericAPIView):
|
|
"""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.CONFIRM_EMAIL).check_token(
|
|
user, token):
|
|
raise utils_exceptions.NotValidTokenError()
|
|
# Approve email status
|
|
user.confirm_email()
|
|
# Create tokens
|
|
tokens = user.create_jwt_tokens()
|
|
return self._put_cookies_in_response(
|
|
cookies=self._put_data_in_cookies(
|
|
access_token=tokens.get('access_token'),
|
|
refresh_token=tokens.get('refresh_token')),
|
|
response=Response(status=status.HTTP_200_OK))
|
|
else:
|
|
raise utils_exceptions.UserNotFoundError()
|
|
|
|
|
|
# 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
|