from .models import User from rest_framework import status from rest_framework.response import Response from rest_framework.generics import CreateAPIView,UpdateAPIView from rest_framework.authtoken.models import Token from rest_framework.views import APIView from django.contrib.auth import authenticate from drf_yasg.utils import swagger_auto_schema from drf_yasg import openapi from django.utils.http import urlsafe_base64_decode from django.utils.encoding import force_str from .serializers import ForgotPasswordSerializer, ResetPasswordSerializer, UserRegistrationSerializer from django.contrib.auth.tokens import default_token_generator class UserRegistrationAPIView(CreateAPIView): serializer_class = UserRegistrationSerializer def post(self, request, format=None): serializer = UserRegistrationSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class LoginView(APIView): @swagger_auto_schema( request_body=openapi.Schema( type=openapi.TYPE_OBJECT, required=['email', 'password'], properties={ 'email': openapi.Schema(type=openapi.TYPE_STRING), 'password': openapi.Schema(type=openapi.TYPE_STRING), }, ), responses={ status.HTTP_200_OK: openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'token': openapi.Schema(type=openapi.TYPE_STRING), }, ), }, ) def post(self, request): email = request.data.get('email') password = request.data.get('password') if email is None or password is None: return Response({'error': 'Please provide both email and password'}, status=status.HTTP_400_BAD_REQUEST) user = authenticate(email=email, password=password) if not user: return Response({'error': 'Invalid credentials'}, status=status.HTTP_401_UNAUTHORIZED) token, _ = Token.objects.get_or_create(user=user) return Response({'token': token.key}) class ResetPasswordView(CreateAPIView): serializer_class = ForgotPasswordSerializer def post(self, request): serializer = self.serializer_class(data=request.data) if serializer.is_valid(): email = serializer.validated_data.get("email") if User.objects.filter(email=email).exists(): user = User.objects.get(email=email) scheme = "https" if request.is_secure() else "http" full_host = request.get_host() base_url = f"{scheme}://{full_host}" user.send_forgot_password_email(base_url, email) return Response({"message": "Password reset email sent"}) else: return Response({"error": "Email does not exist"}, status=status.HTTP_400_BAD_REQUEST) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) class ChangePasswordView(UpdateAPIView): serializer_class = ResetPasswordSerializer http_method_names = ['patch', 'head', 'options', 'trace'] def partial_update(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) uid = force_str(urlsafe_base64_decode(serializer.validated_data['uid'])) user = User.objects.get(pk=uid) if user is not None and default_token_generator.check_token(user, serializer.validated_data['token']): user.set_password(serializer.validated_data['new_password']) user.save() return Response({"message": "Password updated successfully"}, status=status.HTTP_200_OK) else: return Response({"error": "Invalid token or user does not exist"}, status=status.HTTP_400_BAD_REQUEST)