From 3aa20fdaa16c3d0388f7ac2d3b45cff2ff4fa8bb Mon Sep 17 00:00:00 2001 From: A'zamov Samandar Date: Sat, 6 Dec 2025 15:09:54 +0500 Subject: [PATCH] fix(login) --- core/apps/accounts/serializers/auth.py | 6 ---- core/apps/accounts/urls.py | 4 +-- core/apps/accounts/views/login.py | 50 ++++++++++++++++++++------ pyproject.toml | 1 + 4 files changed, 43 insertions(+), 18 deletions(-) diff --git a/core/apps/accounts/serializers/auth.py b/core/apps/accounts/serializers/auth.py index b777163..d0e6350 100644 --- a/core/apps/accounts/serializers/auth.py +++ b/core/apps/accounts/serializers/auth.py @@ -9,12 +9,6 @@ OTP_SIZE = env.int("OTP_SIZE", 4) class LoginSerializer(serializers.Serializer): phone = serializers.CharField(max_length=255) - def validate_phone(self, value): - user = get_user_model().objects.filter(phone=value, validated_at__isnull=False).exists() - if not user: - raise exceptions.ValidationError(_("Phone Not Found")) - return value - class RegisterSerializer(serializers.ModelSerializer): phone = serializers.CharField(max_length=255) diff --git a/core/apps/accounts/urls.py b/core/apps/accounts/urls.py index 7cc506c..359d068 100644 --- a/core/apps/accounts/urls.py +++ b/core/apps/accounts/urls.py @@ -8,11 +8,11 @@ from .views import RegisterView, ResetPasswordView, MeView, ChangePasswordView, from rest_framework.routers import DefaultRouter router = DefaultRouter() -router.register("auth", RegisterView, basename="auth") +# router.register("auth", RegisterView, basename="auth") router.register("auth", ResetPasswordView, basename="reset-password") router.register("auth", MeView, basename="me") router.register("auth", ChangePasswordView, basename="change-password") -router.register("login", LoginView, basename="login") +router.register("auth/login", LoginView, basename="login") urlpatterns = [ path("", include(router.urls)), diff --git a/core/apps/accounts/views/login.py b/core/apps/accounts/views/login.py index 380b4a1..09b6702 100644 --- a/core/apps/accounts/views/login.py +++ b/core/apps/accounts/views/login.py @@ -1,4 +1,4 @@ -from drf_spectacular.utils import extend_schema +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 @@ -12,6 +12,8 @@ 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): @@ -21,25 +23,50 @@ class LoginView(BaseViewSetMixin, GenericViewSet, UserService): match self.action: case "send_code": return LoginSerializer - case "send_confirm": + case "confirm": return ConfirmSerializer case _: return LoginSerializer - @action(detail=False, methods=["post"], url_path="send_code") + @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') + phone = data.get("phone") self.send_confirmation(phone) return Response( {"detail": _("Sms %(phone)s raqamiga yuborildi") % {"phone": phone}}, status=status.HTTP_202_ACCEPTED, ) - @action(detail=False, methods=["post"], url_path="send_confirm") - def send_confirm(self, request): + @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 @@ -47,15 +74,18 @@ class LoginView(BaseViewSetMixin, GenericViewSet, UserService): code = data.get("code") try: if SmsService.check_confirm(phone, code=code): - token = self.get_token(get_user_model().objects.filter(phone=phone).first()) + 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={ - "detail": _("Tasdiqlash ko'di qabul qilindi"), "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) # Response exception for APIException + raise PermissionDenied(e) except Exception as e: - raise PermissionDenied(e) # Api exception for APIException + raise PermissionDenied(e) diff --git a/pyproject.toml b/pyproject.toml index 2b41186..e0ffbca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,3 +25,4 @@ typeCheckingMode = "basic" reportMissingImports = false reportMissingTypeStubs = false pythonVersion = "3.12" +enableReachabilityAnalysis = false