from drf_spectacular.utils import OpenApiResponse, extend_schema from rest_framework.permissions import AllowAny from rest_framework.decorators import action from django_core.mixins.base import BaseViewSetMixin from rest_framework.viewsets import GenericViewSet from core.services import UserService, SmsService from ..serializers import LoginSerializer, ConfirmSerializer from django.utils.translation import gettext_lazy as _ from rest_framework.response import Response from rest_framework import status from django.contrib.auth import get_user_model from rest_framework.exceptions import PermissionDenied from django_core import exceptions User = get_user_model() @extend_schema(tags=["Login"]) class LoginView(BaseViewSetMixin, GenericViewSet, UserService): permission_classes = [AllowAny] def get_serializer_class(self): match self.action: case "send_code": return LoginSerializer case "confirm": return ConfirmSerializer case _: return LoginSerializer @extend_schema( summary="Tasdiqlash ko'dini olish", responses={ 200: OpenApiResponse( response={ "type": "object", "properties": {"detail": {"type": "string"}}, } ) }, ) @action(detail=False, methods=["post"], url_path="send-code") def send_code(self, request): ser = self.get_serializer(data=request.data) ser.is_valid(raise_exception=True) data = ser.validated_data phone = data.get("phone") self.send_confirmation(phone) return Response( {"detail": _("Sms %(phone)s raqamiga yuborildi") % {"phone": phone}}, status=status.HTTP_202_ACCEPTED, ) @extend_schema( summary="Tasdiqlash ko'dini kiritish", responses={ 200: OpenApiResponse( response={ "type": "object", "properties": { "token": {"type": "string"}, "ask_name": {"type": "boolean"}, }, } ) }, ) @action(detail=False, methods=["post"], url_path="confirm") def confirm(self, request): ser = self.get_serializer(data=request.data) ser.is_valid(raise_exception=True) data = ser.validated_data phone = data.get("phone") code = data.get("code") try: if SmsService.check_confirm(phone, code=code): user = User.objects.filter(phone=phone).first() if user is None: user = User.objects.create_user(phone) token = self.get_token(user) return Response( data={ "token": token, "ask_name": True if user.first_name is None or user.first_name == "" else False, }, status=status.HTTP_202_ACCEPTED, ) except exceptions.SmsException as e: raise PermissionDenied(e) except Exception as e: raise PermissionDenied(e)