from django.contrib.auth import get_user_model from django.contrib.auth.tokens import default_token_generator from django.contrib.contenttypes.models import ContentType from django.db import models from django.utils.http import urlsafe_base64_decode from rest_framework import serializers, status from rest_framework.response import Response from rest_framework.views import APIView from djeveric.signals import user_confirmed, AlreadyConfirmed class ConfirmationSerializer(serializers.Serializer): uid = serializers.CharField() token = serializers.CharField() type_id = serializers.CharField() obj_id = serializers.CharField() class ConfirmationView(APIView): def post(self, request, format=None): serializer = ConfirmationSerializer(data=request.data) if serializer.is_valid(): user = self.get_user(serializer.validated_data["uid"]) token = serializer.validated_data["token"] if user is not None and default_token_generator.check_token(user, token): obj = self.get_obj(serializer.validated_data["type_id"], serializer.validated_data["obj_id"]) if obj is not None: try: user_confirmed.send(sender=self.__class__, user=user, instance=obj, key=None) except AlreadyConfirmed as e: return Response({"message": str(e)}, status=status.HTTP_400_BAD_REQUEST) return Response(serializer.data, status=status.HTTP_204_NO_CONTENT) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def get_obj(self, type_id, obj_id): try: # urlsafe_base64_decode() decodes to bytestring type_pk = urlsafe_base64_decode(type_id).decode() obj_pk = urlsafe_base64_decode(obj_id).decode() obj = ContentType.objects.get_for_id(type_pk).get_object_for_this_type(pk=obj_pk) except (TypeError, ValueError, OverflowError, models.Model.DoesNotExist): obj = None return obj def get_user(self, uid): try: # urlsafe_base64_decode() decodes to bytestring uid = urlsafe_base64_decode(uid).decode() user = get_user_model().objects.get(pk=uid) except (TypeError, ValueError, OverflowError, models.Model.DoesNotExist): user = None return user