diff --git a/account/serializers.py b/account/serializers.py index edf4de9..ebdc263 100644 --- a/account/serializers.py +++ b/account/serializers.py @@ -216,10 +216,17 @@ class GuardianSerializer(serializers.ModelSerializer): def get_user_type(self, obj): """user type""" - email_verified = UserEmailOtp.objects.filter(email=obj.user.username).last() - if email_verified and email_verified.user_type is not None: - return email_verified.user_type - return str(NUMBER['two']) + if self.context.get('user_type', ''): + return self.context.get('user_type') + # remove the below code once user_type can be passed + # from everywhere from where this serializer is being called + else: + email_verified = UserEmailOtp.objects.filter( + email=obj.user.username + ).last() + if email_verified and email_verified.user_type is not None: + return email_verified.user_type + return str(NUMBER['two']) def get_auth(self, obj): """user email address""" diff --git a/account/utils.py b/account/utils.py index fd2f40f..52c016a 100644 --- a/account/utils.py +++ b/account/utils.py @@ -1,4 +1,6 @@ """Account utils""" +from celery import shared_task + """Import django""" from django.conf import settings from rest_framework import viewsets, status @@ -20,7 +22,7 @@ from rest_framework import serializers # Import messages from base package""" from junior.models import Junior from guardian.models import Guardian -from account.models import UserDelete +from account.models import UserDelete, UserDeviceDetails from base.messages import ERROR_CODE from django.utils import timezone from base.constants import NUMBER @@ -109,6 +111,7 @@ def guardian_account_update(user_tb): for data in jun_data: data.guardian_code.remove(guardian_data.guardian_code) data.save() +@shared_task() def send_otp_email(recipient_email, otp): """Send otp on email with template""" from_email = settings.EMAIL_FROM_ADDRESS @@ -124,6 +127,20 @@ def send_otp_email(recipient_email, otp): ) return otp +@shared_task +def user_device_details(user, device_id): + """ + Used to store the device id of the user + user: user object + device_id: string + return + """ + device_details, created = UserDeviceDetails.objects.get_or_create(user=user) + if device_details: + device_details.device_id = device_id + device_details.save() + + def send_support_email(name, sender, subject, message): """Send otp on email with template""" to_email = [settings.EMAIL_FROM_ADDRESS] diff --git a/account/views.py b/account/views.py index 8c2932d..cb2ee56 100644 --- a/account/views.py +++ b/account/views.py @@ -1,4 +1,6 @@ """Account view """ +import threading + from notifications.utils import remove_fcm_token # django imports @@ -35,10 +37,10 @@ from .serializers import (SuperUserSerializer, GuardianSerializer, JuniorSeriali AdminLoginSerializer) from rest_framework_simplejwt.tokens import RefreshToken from base.messages import ERROR_CODE, SUCCESS_CODE -from base.constants import NUMBER, ZOD, JUN, GRD +from base.constants import NUMBER, ZOD, JUN, GRD, USER_TYPE_FLAG from guardian.tasks import generate_otp from account.utils import (send_otp_email, send_support_email, custom_response, custom_error_response, - generate_code, OTP_EXPIRY) + generate_code, OTP_EXPIRY, user_device_details) from junior.serializers import JuniorProfileSerializer from guardian.serializers import GuardianProfileSerializer @@ -280,29 +282,38 @@ class UserPhoneVerification(viewsets.ModelViewSet): return custom_error_response(ERROR_CODE["2008"], response_status=status.HTTP_400_BAD_REQUEST) - class UserLogin(viewsets.ViewSet): """User login""" @action(methods=['post'], detail=False) def login(self, request): username = request.data.get('username') password = request.data.get('password') + user_type = request.data.get('user_type') device_id = request.META.get('HTTP_DEVICE_ID') user = authenticate(request, username=username, password=password) try: if user is not None: login(request, user) - guardian_data = Guardian.objects.filter(user__username=username, is_verified=True).last() - if guardian_data: - serializer = GuardianSerializer(guardian_data).data - junior_data = Junior.objects.filter(auth__username=username, is_verified=True).last() - if junior_data: - serializer = JuniorSerializer(junior_data).data - device_details, created = UserDeviceDetails.objects.get_or_create(user=user) - if device_details: - device_details.device_id = device_id - device_details.save() + if user_type == USER_TYPE_FLAG["FIRST"]: + guardian_data = Guardian.objects.filter(user__username=username, is_verified=True).last() + if guardian_data: + serializer = GuardianSerializer( + guardian_data, context={'user_type': user_type} + ).data + elif user_type == USER_TYPE_FLAG["TWO"]: + junior_data = Junior.objects.filter(auth__username=username, is_verified=True).last() + if junior_data: + serializer = JuniorSerializer( + junior_data, context={'user_type': user_type} + ).data + else: + return custom_error_response( + ERROR_CODE["2069"], + response_status=status.HTTP_401_UNAUTHORIZED + ) + # storing device id in using thread so the time would be reduced + threading.Thread(target=user_device_details, args=(user, device_id)) return custom_response(SUCCESS_CODE['3003'], serializer, response_status=status.HTTP_200_OK) else: return custom_error_response(ERROR_CODE["2002"], response_status=status.HTTP_401_UNAUTHORIZED) @@ -312,9 +323,12 @@ class UserLogin(viewsets.ViewSet): refresh = RefreshToken.for_user(user) access_token = str(refresh.access_token) refresh_token = str(refresh) - data = {"auth_token":access_token, "refresh_token":refresh_token, "is_profile_complete": False, - "user_type": email_verified.user_type, - } + data = { + "auth_token":access_token, + "refresh_token":refresh_token, + "is_profile_complete": False, + "user_type": user_type, + } is_verified = False if email_verified: is_verified = email_verified.is_verified @@ -323,11 +337,18 @@ class UserLogin(viewsets.ViewSet): email_verified.otp = otp email_verified.save() data.update({"email_otp":otp}) - send_otp_email(username, otp) - return custom_response(ERROR_CODE['2024'], {"email_otp": otp, "is_email_verified": is_verified}, - response_status=status.HTTP_200_OK) + send_otp_email.delay(username, otp) + return custom_response( + ERROR_CODE['2024'], + {"email_otp": otp, "is_email_verified": is_verified}, + response_status=status.HTTP_200_OK + ) data.update({"is_email_verified": is_verified}) - return custom_response(SUCCESS_CODE['3003'], data, response_status=status.HTTP_200_OK) + return custom_response( + SUCCESS_CODE['3003'], + data, + response_status=status.HTTP_200_OK + ) @action(methods=['post'], detail=False) def admin_login(self, request): diff --git a/base/constants.py b/base/constants.py index 05fa8b8..9688c0f 100644 --- a/base/constants.py +++ b/base/constants.py @@ -50,6 +50,13 @@ USER_TYPE = ( ('2', 'guardian'), ('3', 'superuser') ) + +USER_TYPE_FLAG = { + "FIRST" : "1", + "TWO" : "2", + "THREE": "3" +} + """gender""" GENDERS = ( ('1', 'Male'), diff --git a/base/messages.py b/base/messages.py index 87f5e9a..c7863c8 100644 --- a/base/messages.py +++ b/base/messages.py @@ -94,7 +94,8 @@ ERROR_CODE = { "2065": "Passwords do not match. Please try again.", "2066": "Task does not exist or not in expired state", "2067": "Action not allowed. User type missing.", - "2068": "No guardian associated with this junior" + "2068": "No guardian associated with this junior", + "2069": "Invalid user type" } """Success message code"""