mirror of
https://github.com/HamzaSha1/zod-backend.git
synced 2025-08-26 06:09:41 +00:00
password validation, deactivated user's middleware
This commit is contained in:
@ -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
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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.
@ -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"""
|
||||||
|
@ -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/
|
||||||
|
Reference in New Issue
Block a user