password validation, deactivated user's middleware

This commit is contained in:
jain
2023-08-18 15:45:57 +05:30
parent ef4c459229
commit 51d3b77ff7
6 changed files with 94 additions and 39 deletions

View File

@ -7,7 +7,9 @@ from rest_framework.renderers import JSONRenderer
from account.utils import custom_error_response from account.utils import custom_error_response
from account.models import UserDeviceDetails from account.models import UserDeviceDetails
from base.messages import ERROR_CODE, SUCCESS_CODE from base.messages import ERROR_CODE, SUCCESS_CODE
from base.constants import NUMBER
from junior.models import Junior
from guardian.models import Guardian
# Custom middleware # Custom middleware
# when user login with # when user login with
# multiple device simultaneously # multiple device simultaneously
@ -15,6 +17,16 @@ from base.messages import ERROR_CODE, SUCCESS_CODE
# multiple devices only # multiple devices only
# user can login in single # user can login in single
# device at a time""" # device at a time"""
def custom_response(custom_error):
"""custom response"""
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
class CustomMiddleware(object): class CustomMiddleware(object):
"""Custom middleware""" """Custom middleware"""
def __init__(self, get_response): def __init__(self, get_response):
@ -26,15 +38,21 @@ class CustomMiddleware(object):
response = self.get_response(request) response = self.get_response(request)
# Code to be executed after the view is called # Code to be executed after the view is called
device_id = request.META.get('HTTP_DEVICE_ID') device_id = request.META.get('HTTP_DEVICE_ID')
user_type = request.META.get('HTTP_USER_TYPE')
if request.user.is_authenticated: if request.user.is_authenticated:
"""device details""" """device details"""
device_details = UserDeviceDetails.objects.filter(user=request.user, device_id=device_id).last() device_details = UserDeviceDetails.objects.filter(user=request.user, device_id=device_id).last()
if user_type and str(user_type) == str(NUMBER['one']):
junior = Junior.objects.filter(auth=request.user, is_active=False).last()
if junior:
custom_error = custom_error_response(ERROR_CODE['2075'], response_status=status.HTTP_404_NOT_FOUND)
response = custom_response(custom_error)
elif user_type and str(user_type) == str(NUMBER['two']):
guardian = Guardian.objects.filter(user=request.user, is_active=False).last()
if guardian:
custom_error = custom_error_response(ERROR_CODE['2075'], response_status=status.HTTP_404_NOT_FOUND)
response = custom_response(custom_error)
if device_id and not device_details: if device_id and not device_details:
custom_error = custom_error_response(ERROR_CODE['2037'], response_status=status.HTTP_404_NOT_FOUND) 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) response = custom_response(custom_error)
# 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 return response

View File

@ -287,7 +287,7 @@ class UserLogin(viewsets.ViewSet):
def login(self, request): def login(self, request):
username = request.data.get('username') username = request.data.get('username')
password = request.data.get('password') password = request.data.get('password')
user_type = request.data.get('user_type') user_type = request.META.get('HTTP_USER_TYPE')
device_id = request.META.get('HTTP_DEVICE_ID') device_id = request.META.get('HTTP_DEVICE_ID')
user = authenticate(request, username=username, password=password) user = authenticate(request, username=username, password=password)

View File

@ -96,12 +96,12 @@ ERROR_CODE = {
"2067": "Action not allowed. User type missing.", "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", "2069": "Invalid user type",
"2070": "You did not find as a guardian", "2070": "You do not find as a guardian",
"2071": "You did not find as a junior", "2071": "You do not find as a junior",
"2072": "You can not approve or reject this task because junior does not exist in the system", "2072": "You can not approve or reject this task because junior does not exist in the system",
"2073": "You can not approve or reject this junior because junior does not exist in the system", "2073": "You can not approve or reject this junior because junior does not exist in the system",
"2074": "You can not complete this task because you does not exist in the system" "2074": "You can not complete this task because you does not exist in the system",
"2075": "Your account is deactivated. Please contact with admin"
} }
"""Success message code""" """Success message code"""
SUCCESS_CODE = { SUCCESS_CODE = {

Binary file not shown.

View File

@ -1,6 +1,7 @@
"""Serializer of Guardian""" """Serializer of Guardian"""
# third party imports # third party imports
import logging import logging
from django.contrib.auth import password_validation
from rest_framework import serializers from rest_framework import serializers
# Import Refresh token of jwt # Import Refresh token of jwt
from rest_framework_simplejwt.tokens import RefreshToken from rest_framework_simplejwt.tokens import RefreshToken
@ -30,7 +31,8 @@ from .utils import real_time, convert_timedelta_into_datetime, update_referral_p
from notifications.constants import TASK_POINTS, TASK_REJECTED from notifications.constants import TASK_POINTS, TASK_REJECTED
# send notification function # send notification function
from notifications.utils import send_notification, send_notification_to_junior from notifications.utils import send_notification, send_notification_to_junior
from django.core.exceptions import ValidationError
from django.utils.translation import gettext as _
# In this serializer file # In this serializer file
# define user serializer, # define user serializer,
@ -42,10 +44,45 @@ from notifications.utils import send_notification, send_notification_to_junior
# guardian profile serializer, # guardian profile serializer,
# approve junior serializer, # approve junior serializer,
# approve task serializer, # approve task serializer,
from rest_framework import serializers
class PasswordValidator:
def __init__(self, min_length=8, max_length=None, require_uppercase=True, require_numbers=True):
self.min_length = min_length
self.max_length = max_length
self.require_uppercase = require_uppercase
self.require_numbers = require_numbers
def __call__(self, value):
self.enforce_password_policy(value)
def enforce_password_policy(self, password):
special_characters = "!@#$%^&*()_-+=<>?/[]{}|"
if len(password) < self.min_length:
raise serializers.ValidationError(
_("Password must be at least %(min_length)d characters long.") % {'min_length': self.min_length}
)
if self.max_length is not None and len(password) > self.max_length:
raise serializers.ValidationError(
_("Password must be at most %(max_length)d characters long.") % {'max_length': self.max_length}
)
if self.require_uppercase and not any(char.isupper() for char in password):
raise serializers.ValidationError(_("Password must contain at least one uppercase letter."))
if self.require_numbers and not any(char.isdigit() for char in password):
raise serializers.ValidationError(_("Password must contain at least one digit."))
if self.require_numbers and not any(char in special_characters for char in password):
raise serializers.ValidationError(_("Password must contain at least one special character."))
class UserSerializer(serializers.ModelSerializer): class UserSerializer(serializers.ModelSerializer):
"""User serializer""" """User serializer"""
auth_token = serializers.SerializerMethodField('get_auth_token') auth_token = serializers.SerializerMethodField('get_auth_token')
password = serializers.CharField(write_only=True, validators=[PasswordValidator()])
class Meta(object): class Meta(object):
"""Meta info""" """Meta info"""

View File

@ -180,32 +180,32 @@ AUTH_PASSWORD_VALIDATORS = [
# database query logs settings # database query logs settings
# Allows us to check db hits # Allows us to check db hits
# useful to optimize db query and hit # useful to optimize db query and hit
# LOGGING = { LOGGING = {
# "version": 1, "version": 1,
# "filters": { "filters": {
# "require_debug_true": { "require_debug_true": {
# "()": "django.utils.log.RequireDebugTrue" "()": "django.utils.log.RequireDebugTrue"
# } }
# }, },
# "handlers": { "handlers": {
# "console": { "console": {
# "level": "DEBUG", "level": "DEBUG",
# "filters": [ "filters": [
# "require_debug_true" "require_debug_true"
# ], ],
# "class": "logging.StreamHandler" "class": "logging.StreamHandler"
# } }
# }, },
# # database logger # database logger
# "loggers": { "loggers": {
# "django.db.backends": { "django.db.backends": {
# "level": "DEBUG", "level": "DEBUG",
# "handlers": [ "handlers": [
# "console" "console"
# ] ]
# } }
# } }
# } }
# Internationalization # Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/ # https://docs.djangoproject.com/en/3.0/topics/i18n/