File: //home/arjun/projects/unlimited-leads/Unlimited-Leads-Be/authorization/serializers.py
import uuid
import stripe
from rest_framework import serializers
from django.conf import settings
from django.contrib.auth.tokens import default_token_generator
from utils.validators import (
validate_password_strength,
validate_phone_number,
validate_otp,
)
from .models import (
UnlimitedLeadUser,
VerificationMailRequest,
ForgetPassowordRequest,
LoginUserDevice,
)
from services.stripe.stripe import StripeUtils
stripe.api_key = settings.STRIPE_SECRET_KEY
class UserSignupSerializer(serializers.ModelSerializer):
password = serializers.CharField(validators=[validate_password_strength])
confirm_password = serializers.CharField()
class Meta:
model = UnlimitedLeadUser
fields = [
"first_name",
"last_name",
"email",
"phone_number",
"password",
"confirm_password",
]
extra_kwargs = {
"first_name": {"required": True},
"last_name": {"required": True},
"phone_number": {"validators": [validate_phone_number]},
"password": {"required": True, "write_only": True},
"confirm_password": {"required": True, "write_only": True},
}
def validate_email(self, value):
if UnlimitedLeadUser.objects.filter(email=value, is_deleted=False).exists():
raise serializers.ValidationError("Email ID already exists.")
return value
def validate(self, attrs):
if attrs["password"] != attrs["confirm_password"]:
raise serializers.ValidationError(
{"confirm_password": "Passwords and Confirm Password do not match."}
)
return attrs
def create(self, validated_data):
validated_data.pop("confirm_password")
user = UnlimitedLeadUser(
first_name=validated_data["first_name"],
last_name=validated_data["last_name"],
username=str(uuid.uuid4()),
email=validated_data["email"],
phone_number=validated_data["phone_number"],
)
user.set_password(validated_data["password"])
user.save()
try:
customer_id = StripeUtils.create_customer(
name=f"{user.first_name} {user.last_name}",
email=user.email,
)
user.stripe_id = customer_id
user.save()
except Exception as e:
raise serializers.ValidationError({"stripe_error": str(e)})
return user
class LoginSerializer(serializers.Serializer):
email = serializers.EmailField()
password = serializers.CharField(validators=[validate_password_strength])
device_type = serializers.ChoiceField(choices=LoginUserDevice.DEVICE_CHOICES)
is_remember = serializers.BooleanField(default=False)
class Meta:
fields = ("email", "password")
extra_kwargs = {"password": {"write_only": True}}
def validate_email(self, value):
if not UnlimitedLeadUser.objects.filter(email=value, is_deleted=False).exists():
raise serializers.ValidationError("Email ID not exists. Consider signup.")
return value
class VerifyAccountSerializer(serializers.Serializer):
otp = serializers.CharField(validators=[validate_otp])
email = serializers.EmailField()
device_type = serializers.ChoiceField(choices=LoginUserDevice.DEVICE_CHOICES)
is_remember = serializers.BooleanField(default=False)
def validate_email(self, value):
try:
user = UnlimitedLeadUser.objects.get(email=value, is_deleted=False)
except UnlimitedLeadUser.DoesNotExist:
raise serializers.ValidationError("Email ID not exists. Consider signup.")
return user
def validate(self, attrs):
otp = attrs["otp"]
user = attrs["email"]
try:
verification = VerificationMailRequest.objects.get(
user=user, otp__isnull=False
)
except VerificationMailRequest.DoesNotExist:
raise serializers.ValidationError("You haven't requested verification")
if verification.is_expired():
raise serializers.ValidationError("OTP Expired")
if not verification.verify_otp(otp):
raise serializers.ValidationError("Invalid OTP")
return super().validate(attrs)
class ForgetPasswordRequestSerializer(serializers.Serializer):
email = serializers.EmailField()
def validate_email(self, value):
try:
user = UnlimitedLeadUser.objects.get(email=value, is_deleted=False)
except UnlimitedLeadUser.DoesNotExist:
raise serializers.ValidationError("Email ID not exists. Consider signup.")
return user
class ForgetPasswordSerializer(serializers.Serializer):
email = serializers.EmailField()
token = serializers.CharField()
password = serializers.CharField(
write_only=True, validators=[validate_password_strength]
)
def validate_email(self, value):
try:
user = UnlimitedLeadUser.objects.get(email=value, is_deleted=False)
except UnlimitedLeadUser.DoesNotExist:
raise serializers.ValidationError("Email ID not exists. Consider signup.")
return user
def validate(self, attrs):
user = attrs["email"]
token = attrs["token"]
password = attrs["password"]
if not default_token_generator.check_token(user, token):
raise serializers.ValidationError("The link has been expired.")
try:
reset_request = ForgetPassowordRequest.objects.get(user=user, token=token)
except ForgetPassowordRequest.DoesNotExist:
raise serializers.ValidationError("You haven't requested forget password")
if reset_request.is_expired():
raise serializers.ValidationError("This link has expired")
if user.check_password(password):
raise serializers.ValidationError(
"New password cannot be the same as the old password."
)
return attrs