Notes![what is notes.io? What is notes.io?](/theme/images/whatisnotesio.png)
![]() ![]() Notes - notes.io |
import logging
from datetime import datetime, timedelta
from azure.storage.blob import BlobServiceClient, ContentSettings, BlobSasPermissions, generate_blob_sas
from django.contrib.auth import logout
from django.utils import timezone
from django.utils.crypto import get_random_string
from django.conf import settings
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.authtoken.models import Token
from .models import UserDetails, OTP, UploadedImage
from .sendemail import send_reset_password_otp_email
from .serializers import (RegistrationSerializer, TicketFieldSerializer, LoginSerializer,
ResetPasswordSerializer, ForgotPasswordSerializer, VerifyOTPSerializer,
ChangePasswordSerializer, UserProfileSerializer, UploadImageSerializer)
logger = logging.getLogger(__name__)
class RegistrationAPIView(APIView):
"""
This RegistrationAPIView validate and process the incoming registration data.
"""
def post(self, request):
"""
Handle a POST request for user registration. Validates and processes
the incoming registration data using the `RegistrationSerializer`.
If the data is valid, registers the user.
"""
try:
serializer = RegistrationSerializer(data=request.data, context={'request': request})
if serializer.is_valid():
response_data, response_status = serializer.save()
return Response(response_data, status=response_status)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
except Exception as e:
# Log the exception with relevant details
logger.error(f"Error during user registration: {str(e)}", exc_info=True)
return Response({"error": "Internal Server Error"},
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class LoginAPIView(APIView):
"""
This LoginAPIView handles the user login and on successful validation generates a token for
authentication.
"""
def post(self, request):
"""
Handles user login through a POST request, using a custom serializer
(`LoginSerializer`). Upon successful validation, it generates or retrieves
a token for authentication, and returns a response with a success message
and the authentication token.
"""
try:
serializer = LoginSerializer(data=request.data, context={'request': request})
if serializer.is_valid():
user = serializer.validated_data['user']
# Generate or retrieve the token
token, created = Token.objects.get_or_create(user=user)
return Response({'message': 'Login successful', 'token': token.key},
status=status.HTTP_200_OK)
return Response({'message': serializer.errors},
status=status.HTTP_401_UNAUTHORIZED)
except Exception as e:
# Log the exception with relevant details (adjust logging as needed)
logger.error(f"Error during user login: {str(e)}", exc_info=True)
return Response({'message': 'Internal Server Error'},
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class LogoutAPIView(APIView):
"""
This LogoutAPIView handles the user logout through token authentication
and deletes the token after logout.
"""
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
def post(self, request):
"""
Handles user logout through a POST request with Token authentication.
Deletes the user's authentication token and logs out the user
"""
try:
# Delete the user's token upon logout
request.auth.delete()
# Logout the user
logout(request)
return Response({'message': 'Successfully logged out.'}, status=status.HTTP_200_OK)
except Exception as e:
# Log the exception with relevant details (adjust logging as needed)
logger.error(f"Error during user logout: {str(e)}", exc_info=True)
return Response({'message': 'Internal Server Error'},
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class ForgotPasswordView(APIView):
"""
This ForgotPasswordView initiate the password reset process
by sending OTP to the registered user.
"""
def post(self, request):
"""
Initiates the password reset process by validating
the provided email, generating and storing an OTP, and sending it to the registered
user's email.
"""
serializer = ForgotPasswordSerializer(data=request.data)
if serializer.is_valid():
email = serializer.validated_data['email']
if UserDetails.objects.filter(email=email).exists():
# Generate OTP
otp = get_random_string(length=6, allowed_chars='1234567890')
user_obj = UserDetails.objects.get(email=email)
OTP.objects.update_or_create(user=user_obj, defaults={'otp': otp})
send_reset_password_otp_email(user_obj=user_obj, otp=otp)
return Response({'message': 'OTP sent successfully'}, status=status.HTTP_200_OK)
return Response({'message': 'Enter a valid email address'},
status=status.HTTP_401_UNAUTHORIZED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class VerifyOTPView(APIView):
"""
This VerifyOTPView validates the OTP entered by the user.
"""
def post(self, request):
"""
Validates the OTP entered by the user using the `VerifyOTPSerializer`.
If the OTP is valid, checks its expiration status and returns a response
with a success message. If the OTP is invalid, expired, or the provided
email is not associated with any user account, returns an unauthorized
status with an appropriate error message.
"""
serializer = VerifyOTPSerializer(data=request.data)
if serializer.is_valid():
email = serializer.validated_data['email']
otp_entered = serializer.validated_data['otp']
try:
user_obj = UserDetails.objects.get(email=email)
otp_obj = OTP.objects.get(user=user_obj, otp=otp_entered)
# You can also check if the OTP is expired or not, based on your application logic
expiration_time = timezone.now() - otp_obj.updated_at
expiration_limit = timezone.timedelta(minutes=5)
if expiration_time > expiration_limit:
return Response({'message': 'OTP has expired'},
status=status.HTTP_401_UNAUTHORIZED)
return Response({'message': 'OTP verification successful'},
status=status.HTTP_200_OK)
except OTP.DoesNotExist:
return Response({'message': 'Invalid OTP or email address'},
status=status.HTTP_401_UNAUTHORIZED)
except UserDetails.DoesNotExist:
return Response({'message': 'Invalid email address'},
status=status.HTTP_401_UNAUTHORIZED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class ResetPasswordView(APIView):
"""
This ResetPasswordView initiates the password reset process and resets the user's password.
"""
def post(self, request):
"""
Initiates the password reset process by validating the data using
the `ResetPasswordSerializer`. If the data is valid, resets the user's
password and returns a response with a success message.
"""
serializer = ResetPasswordSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
response = {'message': 'Password reset successfully!'}
return Response(response, status=status.HTTP_200_OK)
return Response({'message': serializer.errors},
status=status.HTTP_400_BAD_REQUEST)
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import UserDetails, UserType, ApprovedUser, TicketField, OTP, UploadedImage
class CustomUserAdmin(UserAdmin):
list_display = ('email', 'first_name', 'last_name', 'user_type', 'application_status', 'created_at', 'modified_at')
list_filter = ('application_status','user_type', 'is_staff', 'is_superuser')
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Personal Info', {'fields': ('first_name','last_name', 'phone_number', 'image', 'cpi_account', 'user_type','application_status')}),
('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}),
('Important dates', {'fields': ('last_login', 'date_joined')}),
)
search_fields = ('email', 'first_name', 'last_name')
ordering = ('email',)
# Remove references to the 'username' field
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2'),
}),
)
from .models import *
from django.contrib.auth import get_user_model
from django.contrib.auth.hashers import check_password
from django.conf import settings
from rest_framework import serializers
from rest_framework import status
class RegistrationSerializer(serializers.ModelSerializer):
confirm_password = serializers.CharField(write_only=True, required=True, style={'input_type': 'password'})
password = serializers.CharField(min_length=8, style={'input_type': 'password'})
class Meta:
model = UserDetails
fields = ('first_name','last_name', 'email', 'image', 'phone_number', 'cpi_account', 'user_type', 'password', 'confirm_password')
extra_kwargs = {
'password': {'write_only': True},
'email': {'required': True},
'name': {'required': True},
'phone_number': {'required': True}
}
def validate(self, data):
password = data.get('password')
confirm_password = data.get('confirm_password')
if password != confirm_password:
raise serializers.ValidationError("Both Passwords do not match.")
return data
def create(self, validated_data):
validated_data.pop('confirm_password', None)
email = validated_data.get('email').lower()
security_code = self.context['request'].headers.get('Security-Code')
# Validate the security code (you can replace this with your actual validation logic)
if security_code != settings.SECURITY_CODE:
raise serializers.ValidationError({'message':'Unauthorized SignUp Request!!'})
# Check if the email is present in the ApprovedUser model
try:
approved_user = ApprovedUser.objects.get(user_email=email)
validated_data['application_status'] = 'Pre-Approved'
response_message = "Registration successful"
status_code = status.HTTP_201_CREATED
except ApprovedUser.DoesNotExist:
# If email is not in ApprovedUser model, set is_approved to False
response_message = "Your application is under process"
status_code = status.HTTP_202_ACCEPTED
# Create the user
validated_data['email'] = email
user = UserDetails.objects.create_user(**validated_data)
# Customize the response
response_data = {'message': response_message}
return response_data, status_code
class LoginSerializer(serializers.Serializer):
email = serializers.EmailField(required=True)
password = serializers.CharField(required=True, style={'input_type': 'password'})
def validate(self, attrs):
email = attrs.get('email').lower()
password = attrs.get('password')
if email and password:
UserDetails = get_user_model()
try:
user = UserDetails.objects.get(email=email)
# Check if the provided password is correct
if not check_password(password, user.password):
raise serializers.ValidationError({'non_field_errors': ['Invalid email or password.']})
# Check if the user is pre-approved or approved
if user.application_status not in ['Pre-Approved', 'Approved']:
raise serializers.ValidationError({'non_field_errors': ['You are not authorized for login as your application is still under process.']})
# Attach the authenticated user to the validated data
attrs['user'] = user
return attrs
except UserDetails.DoesNotExist:
raise serializers.ValidationError({'non_field_errors': ['Invalid email or password.']})
class ForgotPasswordSerializer(serializers.Serializer):
email = serializers.EmailField(required=True)
class VerifyOTPSerializer(serializers.Serializer):
email = serializers.EmailField(required=True)
otp = serializers.CharField(max_length=6)
class ResetPasswordSerializer(serializers.Serializer):
email = serializers.EmailField(required=True)
password = serializers.CharField(min_length=8, write_only=True)
confirm_password = serializers.CharField(min_length=8, write_only=True)
def validate(self, data):
password = data.get('password')
confirm_password = data.get('confirm_password')
if password != confirm_password:
raise serializers.ValidationError("Confirm Password doesn't match")
return data
def create(self, validated_data):
email = validated_data['email']
password = validated_data['password']
try:
user_obj = UserDetails.objects.get(email=email)
user_obj.set_password(password)
user_obj.save()
return user_obj
except UserDetails.DoesNotExist:
raise serializers.ValidationError('Invalid email address')
class ChangePasswordSerializer(serializers.Serializer):
old_password = serializers.CharField(required=True)
new_password = serializers.CharField(min_length=8, required=True)
confirm_new_password = serializers.CharField(min_length=8, required=True)
def validate(self, data):
user = self.context['request'].user
old_password = data.get("old_password")
new_password = data.get('new_password')
confirm_password = data.get('confirm_new_password')
if not user.check_password(old_password):
raise serializers.ValidationError('Invalid old password')
if new_password == confirm_password == old_password:
raise serializers.ValidationError('New password cannot be the same as the old password')
if new_password != confirm_password:
raise serializers.ValidationError("Confirm password doesn't match")
return data
![]() |
Notes is a web-based application for online taking notes. You can take your notes and share with others people. If you like taking long notes, notes.io is designed for you. To date, over 8,000,000,000+ notes created and continuing...
With notes.io;
- * You can take a note from anywhere and any device with internet connection.
- * You can share the notes in social platforms (YouTube, Facebook, Twitter, instagram etc.).
- * You can quickly share your contents without website, blog and e-mail.
- * You don't need to create any Account to share a note. As you wish you can use quick, easy and best shortened notes with sms, websites, e-mail, or messaging services (WhatsApp, iMessage, Telegram, Signal).
- * Notes.io has fabulous infrastructure design for a short link and allows you to share the note as an easy and understandable link.
Fast: Notes.io is built for speed and performance. You can take a notes quickly and browse your archive.
Easy: Notes.io doesn’t require installation. Just write and share note!
Short: Notes.io’s url just 8 character. You’ll get shorten link of your note when you want to share. (Ex: notes.io/q )
Free: Notes.io works for 14 years and has been free since the day it was started.
You immediately create your first note and start sharing with the ones you wish. If you want to contact us, you can use the following communication channels;
Email: [email protected]
Twitter: http://twitter.com/notesio
Instagram: http://instagram.com/notes.io
Facebook: http://facebook.com/notesio
Regards;
Notes.io Team