login in only single device at a time

This commit is contained in:
jain
2023-07-14 19:38:58 +05:30
parent 485dc83911
commit 5bd865a685
8 changed files with 126 additions and 23 deletions

View File

@ -2,7 +2,7 @@
from django.contrib import admin
"""Import django app"""
from .models import UserEmailOtp, DefaultTaskImages, UserNotification, UserDelete
from .models import UserEmailOtp, DefaultTaskImages, UserNotification, UserDelete, UserDeviceDetails
# Register your models here.
@admin.register(UserDelete)
@ -37,3 +37,10 @@ class UserEmailOtpAdmin(admin.ModelAdmin):
"""Return object in email and otp format"""
return self.email + '-' + self.otp
@admin.register(UserDeviceDetails)
class UserDeviceDetailsAdmin(admin.ModelAdmin):
"""User profile admin"""
list_display = ['user', 'device_id']
def __str__(self):
return self.user.email

View File

@ -0,0 +1,36 @@
"""middleware file"""
"""Django import"""
from rest_framework import status
from rest_framework.response import Response
from rest_framework.renderers import JSONRenderer
"""App django"""
from account.utils import custom_error_response
from account.models import UserDeviceDetails
from base.messages import ERROR_CODE, SUCCESS_CODE
"""Custom middleware
when user login with
multiple device simultaneously"""
class CustomMiddleware:
"""Custom middleware"""
def __init__(self, get_response):
"""response"""
self.get_response = get_response
def __call__(self, request):
# Code to be executed before the view is called
response = self.get_response(request)
# Code to be executed after the view is called
device_id = request.META['HTTP_DEVICE_ID']
if request.user.is_authenticated:
"""device details"""
device_details = UserDeviceDetails.objects.filter(user=request.user, device_id=device_id).last()
if not device_details:
custom_error = custom_error_response(ERROR_CODE['2037'], response_status=status.HTTP_404_NOT_FOUND)
response = Response(custom_error.data, status=status.HTTP_404_NOT_FOUND)
# Set content type header to "application/json"
response['Content-Type'] = 'application/json'
# Render the response as JSON
renderer = JSONRenderer()
response.content = renderer.render(response.data)
return response

View File

@ -0,0 +1,31 @@
# Generated by Django 4.2.2 on 2023-07-14 11:08
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('account', '0007_alter_defaulttaskimages_options_and_more'),
]
operations = [
migrations.CreateModel(
name='UserDeviceDetails',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('device_id', models.CharField(max_length=500)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='user_device_details', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'User Device Details',
'verbose_name_plural': 'User Device Details',
'db_table': 'user_device_details',
},
),
]

View File

@ -145,3 +145,23 @@ class UserNotification(models.Model):
def __str__(self):
return self.user.email
class UserDeviceDetails(models.Model):
"""
User notification details
"""
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='user_device_details')
"""Device ID"""
device_id = models.CharField(max_length=500)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta(object):
""" Meta information """
db_table = 'user_device_details'
verbose_name = 'User Device Details'
verbose_name_plural = 'User Device Details'
def __str__(self):
return self.user.email

View File

@ -5,17 +5,23 @@ from rest_framework import viewsets, status, views
from rest_framework.decorators import action
import random
import logging
from PIL import Image
from django.views.decorators.csrf import csrf_exempt
from django.utils import timezone
import jwt
from django.contrib.auth import logout
"""App Import"""
from guardian.utils import upload_image_to_alibaba
from django.contrib.auth import authenticate, login
from rest_framework.permissions import IsAuthenticated
from templated_email import send_templated_mail
import google.oauth2.credentials
import google.auth.transport.requests
from rest_framework import status
import requests
from rest_framework.response import Response
from django.conf import settings
"""App Import"""
from guardian.models import Guardian
from junior.models import Junior
from account.models import UserProfile, UserPhoneOtp, UserEmailOtp, DefaultTaskImages, UserNotification
from guardian.utils import upload_image_to_alibaba
from account.models import UserDeviceDetails, UserPhoneOtp, UserEmailOtp, DefaultTaskImages, UserNotification
from django.contrib.auth.models import User
"""Account serializer"""
from .serializers import (SuperUserSerializer, GuardianSerializer, JuniorSerializer, EmailVerificationSerializer,
@ -29,15 +35,6 @@ from base.constants import NUMBER, ZOD, JUN, GRD
from guardian.tasks import generate_otp
from account.utils import (send_otp_email, send_support_email, custom_response, custom_error_response,
generate_code)
from rest_framework.permissions import IsAuthenticated
from templated_email import send_templated_mail
import google.oauth2.credentials
import google.auth.transport.requests
from rest_framework import status
import requests
from rest_framework.response import Response
from django.conf import settings
from rest_framework_simplejwt.tokens import RefreshToken
from junior.serializers import JuniorProfileSerializer
from guardian.serializers import GuardianProfileSerializer
@ -229,7 +226,6 @@ class ForgotPasswordAPIView(views.APIView):
'verification_code': verification_code
}
)
expiry = timezone.now() + timezone.timedelta(days=1)
user_data, created = UserEmailOtp.objects.get_or_create(email=email)
if created:
@ -285,6 +281,7 @@ class UserLogin(viewsets.ViewSet):
def login(self, request):
username = request.data.get('username')
password = request.data.get('password')
device_id = request.META.get('HTTP_DEVICE_ID')
user = authenticate(request, username=username, password=password)
try:
@ -296,6 +293,10 @@ class UserLogin(viewsets.ViewSet):
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()
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)
@ -347,7 +348,6 @@ class UserEmailVerification(viewsets.ModelViewSet):
"""User Email verification"""
serializer_class = EmailVerificationSerializer
queryset = UserEmailOtp.objects.all()
permission_classes = [IsAuthenticated]
def list(self, request, *args, **kwargs):
try:
@ -379,7 +379,8 @@ class UserEmailVerification(viewsets.ModelViewSet):
refresh = RefreshToken.for_user(user_obj)
access_token = str(refresh.access_token)
refresh_token = str(refresh)
return custom_response(SUCCESS_CODE['3011'], {"auth_token":access_token, "refresh_token":refresh_token},
return custom_response(SUCCESS_CODE['3011'], {"auth_token":access_token,
"refresh_token":refresh_token},
response_status=status.HTTP_200_OK)
else:
return custom_error_response(ERROR_CODE["2008"], response_status=status.HTTP_400_BAD_REQUEST)
@ -429,8 +430,6 @@ class ProfileAPIViewSet(viewsets.ModelViewSet):
serializer = GuardianProfileSerializer(guardian_data)
return custom_response(None, serializer.data, response_status=status.HTTP_200_OK)
class UploadImageAPIViewSet(viewsets.ModelViewSet):
"""Profile viewset"""
queryset = DefaultTaskImages.objects.all()
@ -527,7 +526,6 @@ class SendSupportEmail(views.APIView):
else:
return custom_error_response(ERROR_CODE['2033'], response_status=status.HTTP_400_BAD_REQUEST)
class LogoutAPIView(views.APIView):
"""Log out API"""
permission_classes = (IsAuthenticated,)
@ -550,3 +548,4 @@ class AccessTokenAPIView(views.APIView):
access_token = str(refresh.access_token)
data = {"auth_token": access_token}
return custom_response(None, data, response_status=status.HTTP_200_OK)

View File

@ -59,7 +59,8 @@ ERROR_CODE = {
"2033": "Missing required fields",
"2034": "Junior is not associated",
"2035": "Image should not be 0 kb",
"2036": "Choose valid user"
"2036": "Choose valid user",
"2037": "You are already log in another device"
}
"""Success message code"""
SUCCESS_CODE = {

View File

@ -9,7 +9,15 @@ from rest_framework import routers
"""Define Router"""
router = routers.SimpleRouter()
"""API End points with router"""
"""API End points with router
in this file
we define various api end point
that is covered in this guardian
section API:- like
sign-up, create guardian profile,
create-task,
all task list, top junior,
filter-task"""
"""Sign up API"""
router.register('sign-up', SignupViewset, basename='sign-up')
"""Create guardian profile API"""

View File

@ -67,6 +67,7 @@ MIDDLEWARE = [
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'account.custom_middleware.CustomMiddleware'
]
ROOT_URLCONF = 'zod_bank.urls'