Reputation: 1
Registration always goes in successful but then after submitting otp for verification, first error response "error":"authentication failed"
and when I try again "error": "error": "OTP or email not found in session."
.
class UserRegistrationView(APIView):
def post(self, request, format=None):
serializer = UserRegistrationSerializer(data=request.data)
if serializer.is_valid():
user = serializer.save()
# Generate and store OTP
otp = generate_otp()
request.session['otp'] = otp
request.session['email'] = user.email
request.session['otp_timestamp'] = timezone.now(
).isoformat() # Save as ISO format string
# Send OTP to user via email
email_subject = 'Your OTP Code'
email_message = f'Your OTP code is {
otp}. It will expire in 5 minutes.'
try:
send_mail(email_subject, email_message,
settings.EMAIL_HOST_USER, [user.email])
return Response({"message": "Registration successful. Please check your email for the OTP."}, status=status.HTTP_201_CREATED)
except Exception as e:
return Response({"error": f"Failed to send OTP. Please try again. Error: {str(e)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class UserRegistrationSerializer(serializers.ModelSerializer):
university = serializers.CharField(write_only=True)
gender = serializers.CharField(write_only=True)
class Meta:
model = User
fields = (
"id",
"username",
"email",
"password",
"university",
"gender",
)
extra_kwargs = {"password": {"write_only": True}}
def validate_email(self, value):
university = self.initial_data.get('university')
if university in UNIVERSITY_EMAIL_PATTERNS:
pattern = UNIVERSITY_EMAIL_PATTERNS[university]
if not re.match(pattern, value):
raise serializers.ValidationError(f"""Invalid email address for {
university}. Please use a valid student email.""")
if User.objects.filter(email=value).exists():
raise serializers.ValidationError(
'A user with this email already exists!')
return value
def create(self, validated_data):
university = validated_data.pop('university')
gender = validated_data.pop('gender')
try:
user = User.objects.create_user(
username=validated_data['username'],
email=validated_data['email'],
password=validated_data['password'],
is_active=False
)
UserProfile.objects.create(
user=user,
university=university,
gender=gender,
)
except Exception as e:
raise serializers.ValidationError(
f"Failed to create user: {str(e)}")
return user
class VerifyEmailView(APIView):
def post(self, request):
otp = request.data.get("otp")
email = request.session.get("email")
if not otp or not email:
return Response({"error": "OTP or email not found in session."}, status=status.HTTP_400_BAD_REQUEST)
saved_otp = request.session.get("otp")
if otp != saved_otp:
return Response({"error": "Invalid OTP."}, status=status.HTTP_400_BAD_REQUEST)
otp_timestamp_str = request.session.get("otp_timestamp")
if not otp_timestamp_str:
return Response({"error": "OTP timestamp not found."}, status=status.HTTP_400_BAD_REQUEST)
try:
otp_timestamp = dateutil.parser.isoparse(otp_timestamp_str)
except ValueError:
return Response({"error": "Invalid OTP timestamp format."}, status=status.HTTP_400_BAD_REQUEST)
if timezone.now() - otp_timestamp > timezone.timedelta(minutes=5):
return Response({"error": "OTP has expired. Please request a new one."}, status=status.HTTP_400_BAD_REQUEST)
try:
user = User.objects.get(email=email)
except ObjectDoesNotExist:
return Response({"error": "User not found."}, status=status.HTTP_404_NOT_FOUND)
user.is_active = True
user.save()
del request.session['otp']
del request.session['otp_timestamp']
del request.session['email']
user = authenticate(request, email=email, password=user.password)
if user is not None:
login(request, user)
serializer = UserProfileSerializer(user.userprofile)
return Response(serializer.data, status=status.HTTP_200_OK)
else:
return Response({"error": "Authentication failed."}, status=status.HTTP_400_BAD_REQUEST)
Please is there anything I am doing wrong?
At first I tried to generate the otp in the serializer but there were problems with the gmail server and remove from there to the registration views. Now the error messages are authentication failed and otp or email not found in session. I don't know whether this question is going to be flagged as duplicate because mine is verifying the otp, seems there's something wrong with my session or otp, I am not getting it.
Upvotes: 0
Views: 101