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 d33b267..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 @@ -44,7 +46,7 @@ from junior.models import JuniorPoints # referral code, # Define function for generating # alphanumeric code - +# otp expiry def delete_user_account_condition(user, user_type_data, user_type, user_tb, data, random_num): """delete user account""" if user_type == '1' and user_type_data == '1': @@ -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..7a26d9e 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 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 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): 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 f102972..dc8202f 100644 --- a/junior/serializers.py +++ b/junior/serializers.py @@ -146,8 +146,8 @@ class JuniorDetailSerializer(serializers.ModelSerializer): """Meta info""" model = Junior fields = ['id', 'email', 'first_name', 'last_name', 'country_code', 'phone', 'gender', 'dob', - 'guardian_code', 'image', 'is_invited', 'referral_code','is_active', 'is_complete_profile', 'created_at', - 'image', 'updated_at'] + 'guardian_code', 'image', 'is_invited', 'referral_code','is_active', 'is_complete_profile', + 'created_at', 'image', 'updated_at'] class JuniorDetailListSerializer(serializers.ModelSerializer): """junior serializer""" diff --git a/notifications/views.py b/notifications/views.py index 4644e62..c66d655 100644 --- a/notifications/views.py +++ b/notifications/views.py @@ -11,8 +11,10 @@ from rest_framework import viewsets, status, views from account.utils import custom_response, custom_error_response from base.messages import SUCCESS_CODE, ERROR_CODE from notifications.constants import TEST_NOTIFICATION +# Import serializer from notifications.serializers import RegisterDevice, NotificationListSerializer, ReadNotificationSerializer from notifications.utils import send_notification +# Import model from notifications.models import Notification diff --git a/web_admin/serializers/article_serializer.py b/web_admin/serializers/article_serializer.py index af07bd7..e125acf 100644 --- a/web_admin/serializers/article_serializer.py +++ b/web_admin/serializers/article_serializer.py @@ -224,7 +224,7 @@ class ArticleListSerializer(serializers.ModelSerializer): total_points = serializers.SerializerMethodField('get_total_points') is_completed = serializers.SerializerMethodField('get_is_completed') - class Meta: + class Meta(object): """ meta class """ @@ -279,7 +279,7 @@ class ArticleQuestionSerializer(serializers.ModelSerializer): return junior_article_obj.submitted_answer.id return None - class Meta: + class Meta(object): """ meta class """ @@ -300,7 +300,7 @@ class StartAssessmentSerializer(serializers.ModelSerializer): if data: return data.current_que_page return NUMBER['zero'] - class Meta: + class Meta(object): """ meta class """ @@ -326,7 +326,7 @@ class ArticleCardlistSerializer(serializers.ModelSerializer): return data.current_card_page return NUMBER['zero'] - class Meta: + class Meta(object): """ meta class """