From 379ae2831a6992a46543d33597d4e622bdc86e77 Mon Sep 17 00:00:00 2001 From: Anatoly Date: Wed, 14 Aug 2019 15:52:27 +0300 Subject: [PATCH] version 0.0.9: added single endpoint to login using username or email and password, remove separated login endpoints --- apps/authorization/serializers/common.py | 50 +++++++----------------- apps/authorization/urls/common.py | 6 +-- apps/authorization/views/common.py | 13 ++---- 3 files changed, 20 insertions(+), 49 deletions(-) diff --git a/apps/authorization/serializers/common.py b/apps/authorization/serializers/common.py index 43b6fe07..509e3abc 100644 --- a/apps/authorization/serializers/common.py +++ b/apps/authorization/serializers/common.py @@ -3,6 +3,7 @@ from django.contrib.auth import password_validation as password_validators from rest_framework import serializers from rest_framework import validators as rest_validators from django.contrib.auth import authenticate +from django.db.models import Q from django.conf import settings from account import models as account_models @@ -67,7 +68,9 @@ class SignupSerializer(JWTBaseMixin, serializers.ModelSerializer): write_only=True ) password = serializers.CharField(write_only=True) - email = serializers.EmailField(write_only=True) + email = serializers.EmailField( + validators=(rest_validators.UniqueValidator(queryset=account_models.User.objects.all()),), + write_only=True) newsletter = serializers.BooleanField(write_only=True) class Meta: @@ -97,54 +100,31 @@ class SignupSerializer(JWTBaseMixin, serializers.ModelSerializer): return obj -class LoginByUsernameSerializer(JWTBaseMixin, serializers.ModelSerializer): - """Serializer for login user by username and password""" - username = serializers.CharField(write_only=True) - password = serializers.CharField(write_only=True) - - class Meta: - """Meta-class""" - model = account_models.User - fields = ( - 'username', 'password', 'refresh_token', 'access_token' - ) - - def validate(self, attrs): - """Override validate method""" - username = attrs.pop('username') - password = attrs.pop('password') - user = authenticate(username=username, - password=password) - if not user: - raise utils_exceptions.UserNotFoundError() - self.instance = user - return attrs - - -class LoginByEmailSerializer(JWTBaseMixin, serializers.ModelSerializer): +class LoginByUsernameOrEmailSerializer(JWTBaseMixin, serializers.ModelSerializer): """Serializer for login user""" - email = serializers.EmailField(write_only=True) + username_or_email = serializers.CharField(write_only=True) password = serializers.CharField(write_only=True) class Meta: """Meta-class""" model = account_models.User fields = ( - 'email', 'password', 'refresh_token', 'access_token' + 'username_or_email', 'password', 'refresh_token', 'access_token' ) def validate(self, attrs): """Override validate method""" - email = attrs.pop('email') + username_or_email = attrs.pop('username_or_email') password = attrs.pop('password') - try: - user = account_models.User.objects.get(email=email) - except account_models.User.DoesNotExist: + user_qs = account_models.User.objects.filter(Q(username=username_or_email) | + Q(email=username_or_email)) + if not user_qs.exists(): raise utils_exceptions.UserNotFoundError() else: - user = authenticate(username=user.get_username(), - password=password) - if not user: + user = user_qs.first() + authentication = authenticate(username=user.get_username(), + password=password) + if not authentication: raise utils_exceptions.UserNotFoundError() self.instance = user return attrs diff --git a/apps/authorization/urls/common.py b/apps/authorization/urls/common.py index cf8469e7..941b7629 100644 --- a/apps/authorization/urls/common.py +++ b/apps/authorization/urls/common.py @@ -32,10 +32,8 @@ urlpatterns_jwt = [ path('signup/', views.SignUpView.as_view(), name='signup'), # sign in - path('login/username/', views.LoginByUsernameView.as_view(), - name='login-username'), - path('login/email/', views.LoginByEmailView.as_view(), - name='login-email'), + path('login/', views.LoginByUsernameOrEmailView.as_view(), + name='login'), # refresh token path('refresh-token/', views.RefreshTokenView.as_view(), name="refresh-token"), diff --git a/apps/authorization/views/common.py b/apps/authorization/views/common.py index d2d147d0..f6412b21 100644 --- a/apps/authorization/views/common.py +++ b/apps/authorization/views/common.py @@ -201,18 +201,11 @@ class SignUpView(JWTViewMixin): response=response) -# Login by username + password -class LoginByUsernameView(JWTViewMixin): - """Login by username""" - permission_classes = (permissions.AllowAny,) - serializer_class = serializers.LoginByUsernameSerializer - - -# Login by email + password -class LoginByEmailView(JWTViewMixin): +# Login by username|email + password +class LoginByUsernameOrEmailView(JWTViewMixin): """Login by email and password""" permission_classes = (permissions.AllowAny,) - serializer_class = serializers.LoginByEmailSerializer + serializer_class = serializers.LoginByUsernameOrEmailSerializer # Refresh access_token