From af0e6af5c43c2370e37e3d9040f50eb2fbb06da7 Mon Sep 17 00:00:00 2001 From: Anatoly Date: Fri, 4 Oct 2019 13:48:48 +0300 Subject: [PATCH] refactored email reconfirm view --- apps/account/serializers/common.py | 32 ----------------------- apps/account/urls/common.py | 1 + apps/account/views/common.py | 29 ++++++++++++++------- apps/authorization/serializers/common.py | 33 ------------------------ apps/authorization/tasks.py | 7 ++--- apps/authorization/urls/common.py | 1 - apps/authorization/views/common.py | 11 -------- 7 files changed, 24 insertions(+), 90 deletions(-) diff --git a/apps/account/serializers/common.py b/apps/account/serializers/common.py index e6076117..b68aca7d 100644 --- a/apps/account/serializers/common.py +++ b/apps/account/serializers/common.py @@ -172,38 +172,6 @@ class ChangeEmailSerializer(serializers.ModelSerializer): return instance -class ConfirmEmailSerializer(serializers.ModelSerializer): - """Confirm user email serializer""" - x = serializers.CharField(default=None) - - class Meta: - """Meta class""" - model = models.User - fields = ( - 'email', - ) - - def validate(self, attrs): - """Override validate method""" - email_confirmed = self.instance.email_confirmed - if email_confirmed: - raise utils_exceptions.EmailConfirmedError() - - return attrs - - def update(self, instance, validated_data): - """ - Override update method - """ - - # Send verification link on user email for change email address - if settings.USE_CELERY: - tasks.confirm_new_email_address.delay(instance.id) - else: - tasks.confirm_new_email_address(instance.id) - return instance - - # Firebase Cloud Messaging serializers class FCMDeviceSerializer(serializers.ModelSerializer): """FCM Device model serializer""" diff --git a/apps/account/urls/common.py b/apps/account/urls/common.py index 34583010..4ea2af66 100644 --- a/apps/account/urls/common.py +++ b/apps/account/urls/common.py @@ -8,5 +8,6 @@ app_name = 'account' urlpatterns = [ path('user/', views.UserRetrieveUpdateView.as_view(), name='user-retrieve-update'), path('change-password/', views.ChangePasswordView.as_view(), name='change-password'), + path('email/confirm/', views.SendConfirmationEmailView.as_view(), name='send-confirm-email'), path('email/confirm///', views.ConfirmEmailView.as_view(), name='confirm-email'), ] diff --git a/apps/account/views/common.py b/apps/account/views/common.py index ab62343f..d29ce2bb 100644 --- a/apps/account/views/common.py +++ b/apps/account/views/common.py @@ -1,4 +1,5 @@ """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 @@ -9,6 +10,7 @@ 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 @@ -38,19 +40,26 @@ class ChangePasswordView(generics.GenericAPIView): return Response(status=status.HTTP_200_OK) -class SendConfirmationEmailView(JWTGenericViewMixin): +class SendConfirmationEmailView(generics.GenericAPIView): """Confirm email view.""" - serializer_class = serializers.ConfirmEmailSerializer - queryset = models.User.objects.all() - def patch(self, request, *args, **kwargs): - """Implement PATCH-method""" - # Get user instance - instance = self.request.user + def post(self, request, *args, **kwargs): + """Override create method""" + user = self.request.user + country_code = self.request.country_code - serializer = self.get_serializer(data=request.data, instance=instance) - serializer.is_valid(raise_exception=True) - serializer.save() + 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) diff --git a/apps/authorization/serializers/common.py b/apps/authorization/serializers/common.py index 3e7195a5..ed68ba9f 100644 --- a/apps/authorization/serializers/common.py +++ b/apps/authorization/serializers/common.py @@ -76,39 +76,6 @@ class SignupSerializer(serializers.ModelSerializer): return obj -class ReconfirmSerializer(serializers.ModelSerializer): - - class Meta: - model = account_models.User - fields = ('email',) - - def validate_email(self, value): - """Validate email""" - users = list(account_models.User.objects.filter(email=value.lower()).all()) - if not users: - raise serializers.ValidationError(detail='User with mentioned email does not exist.') - users = list(filter(lambda user: not user.email_confirmed, users)) - if not users: - raise serializers.ValidationError(detail='User with this email is confirmed.') - return value - - def create(self, validated_data): - """Override create method""" - queryset = account_models.User.objects.all() - email = validated_data.get('email').lower() - country_code = self.context.get('request').country_code - obj = get_object_or_404(queryset, email=email) - if settings.USE_CELERY: - tasks.send_confirm_email.delay( - user_id=obj.id, - country_code=country_code) - else: - tasks.send_confirm_email( - user_id=obj.id, - country_code=country_code) - return obj - - class LoginByUsernameOrEmailSerializer(SourceSerializerMixin, serializers.ModelSerializer): """Serializer for login user""" diff --git a/apps/authorization/tasks.py b/apps/authorization/tasks.py index 9947c2a3..c97fbbae 100644 --- a/apps/authorization/tasks.py +++ b/apps/authorization/tasks.py @@ -4,18 +4,19 @@ from django.utils.translation import gettext_lazy as _ from celery import shared_task from account import models as account_models +from smtplib import SMTPException logging.basicConfig(format='[%(levelname)s] %(message)s', level=logging.INFO) logger = logging.getLogger(__name__) @shared_task -def send_confirm_email(user_id, country_code): +def send_confirm_email(user_id: int, country_code: str): """Send verification email to user.""" try: obj = account_models.User.objects.get(id=user_id) obj.send_email(subject=_('Email confirmation'), message=obj.confirm_email_template(country_code)) - except: + except Exception as e: logger.error(f'METHOD_NAME: {send_confirm_email.__name__}\n' - f'DETAIL: Exception occurred for user: {user_id}') + f'DETAIL: user {user_id}, - {e}') diff --git a/apps/authorization/urls/common.py b/apps/authorization/urls/common.py index 814ce836..4e6e59e1 100644 --- a/apps/authorization/urls/common.py +++ b/apps/authorization/urls/common.py @@ -29,7 +29,6 @@ urlpatterns_oauth2 = [ urlpatterns_jwt = [ path('signup/', views.SignUpView.as_view(), name='signup'), - path('signup/reconfirm/', views.ReconfirmView.as_view(), name='signup-reconfirm'), path('signup/confirm///', views.ConfirmationEmailView.as_view(), name='signup-confirm'), path('login/', views.LoginByUsernameOrEmailView.as_view(), name='login'), diff --git a/apps/authorization/views/common.py b/apps/authorization/views/common.py index a2e3e8c9..0b1a58e0 100644 --- a/apps/authorization/views/common.py +++ b/apps/authorization/views/common.py @@ -147,17 +147,6 @@ class SignUpView(generics.GenericAPIView): return Response(status=status.HTTP_201_CREATED) -class ReconfirmView(generics.CreateAPIView): - """ Resends confirmation email whether user's still not confirmed """ - permission_classes = (permissions.AllowAny,) - serializer_class = serializers.ReconfirmSerializer - - def post(self, request, *args, **kwargs): - serializer = self.get_serializer(data=request.data) - serializer.is_valid(raise_exception=True) - return Response(status=status.HTTP_201_CREATED) - - class ConfirmationEmailView(JWTGenericViewMixin): """View for confirmation email"""