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 dcfb4a2..1780a5d 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..c17f853 100644 --- a/account/views.py +++ b/account/views.py @@ -1,11 +1,12 @@ """Account view """ +import threading + from notifications.utils import remove_fcm_token # django imports from datetime import datetime, timedelta from rest_framework import viewsets, status, views from rest_framework.decorators import action -import random import logging from django.utils import timezone import jwt @@ -35,10 +36,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 +281,48 @@ 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 str(user_type) == USER_TYPE_FLAG["TWO"]: + 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 + else: + return custom_error_response( + ERROR_CODE["2070"], + response_status=status.HTTP_401_UNAUTHORIZED + ) + elif str(user_type) == USER_TYPE_FLAG["FIRST"]: + 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["2071"], + response_status=status.HTTP_401_UNAUTHORIZED + ) + 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 +332,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 +346,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): @@ -371,12 +401,13 @@ class AdminLoginViewSet(viewsets.GenericViewSet): class UserEmailVerification(viewsets.ModelViewSet): """User Email verification""" serializer_class = EmailVerificationSerializer + http_method_names = ('post',) - def list(self, request, *args, **kwargs): + def create(self, request, *args, **kwargs): try: - user_obj = User.objects.filter(username=self.request.GET.get('email')).last() - email_data = UserEmailOtp.objects.filter(email=self.request.GET.get('email'), - otp=self.request.GET.get('otp')).last() + user_obj = User.objects.filter(username=self.request.data.get('email')).last() + email_data = UserEmailOtp.objects.filter(email=self.request.data.get('email'), + otp=self.request.data.get('otp')).last() if email_data: input_datetime_str = str(email_data.expired_at) input_format = "%Y-%m-%d %H:%M:%S.%f%z" @@ -390,12 +421,12 @@ class UserEmailVerification(viewsets.ModelViewSet): email_data.is_verified = True email_data.save() if email_data.user_type == '1': - junior_data = Junior.objects.filter(auth__email=self.request.GET.get('email')).last() + junior_data = Junior.objects.filter(auth__email=self.request.data.get('email')).last() if junior_data: junior_data.is_verified = True junior_data.save() else: - guardian_data = Guardian.objects.filter(user__email=self.request.GET.get('email')).last() + guardian_data = Guardian.objects.filter(user__email=self.request.data.get('email')).last() if guardian_data: guardian_data.is_verified = True guardian_data.save() @@ -505,7 +536,7 @@ class UserNotificationAPIViewSet(viewsets.ModelViewSet): permission_classes = [IsAuthenticated] def list(self, request, *args, **kwargs): """profile view""" - queryset = self.queryset.filter(user=request.user) + queryset = UserNotification.objects.filter(user=request.user) serializer = UserNotificationSerializer(queryset, many=True) return custom_response(None, serializer.data, response_status=status.HTTP_200_OK) 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..10fbfaa 100644 --- a/base/messages.py +++ b/base/messages.py @@ -94,7 +94,10 @@ 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", + "2070": "You did not find as a guardian", + "2071": "You did not find as a junior" } """Success message code""" diff --git a/junior/serializers.py b/junior/serializers.py index dc8202f..c3e2d72 100644 --- a/junior/serializers.py +++ b/junior/serializers.py @@ -320,7 +320,7 @@ class RemoveJuniorSerializer(serializers.ModelSerializer): if instance: instance.is_invited = False instance.guardian_code = '{}' - instance.guardian_code_status = str(NUMBER['1']) + instance.guardian_code_status = str(NUMBER['one']) instance.save() return instance