[fix] auth

This commit is contained in:
Data-Name-ID
2024-04-01 17:31:33 +03:00
parent c8b070368b
commit 851017847c
9 changed files with 135 additions and 447 deletions
+13 -117
View File
@@ -1,131 +1,27 @@
from datetime import timedelta
import bcrypt
import jwt
from django.conf import settings
from django.utils import timezone
from rest_framework import status
from rest_framework.exceptions import (
NotAuthenticated,
PermissionDenied,
ValidationError,
)
from rest_framework.generics import CreateAPIView, UpdateAPIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from api.users.models import User
from api.users.serializers import (
PasswordChangeSerializer,
UpdateProfileSerializer,
UserLoginSerializer,
UserProfileSerializer,
UserRegistrationSerializer,
ChangePasswordSerializer,
UserSerializer,
)
class SignupUserApiView(APIView):
def post(self, request):
serializer = UserRegistrationSerializer(data=request.data)
if serializer.is_valid():
password = serializer.validated_data["password"]
password_hash = bcrypt.hashpw(
password.encode("utf-8"), bcrypt.gensalt()
).decode("utf-8")
serializer.validated_data["password"] = password_hash
serializer.save()
return Response("ok", status=status.HTTP_201_CREATED)
raise ValidationError(serializer.errors)
class SignupUserApiView(CreateAPIView):
http_method_names = ("post",)
serializer_class = UserSerializer
class SigninUserApiView(APIView):
def post(self, request):
serializer = UserLoginSerializer(data=request.data)
if not serializer.is_valid():
raise ValidationError(serializer.errors)
username = serializer.validated_data.get("username")
password = serializer.validated_data.get("password")
user = User.objects.filter(username=username).first()
if user is not None:
if not bcrypt.checkpw(
password.encode("utf-8"), user.password.encode("utf-8")
):
raise NotAuthenticated(
{"error": "Invalid credentials"},
)
else:
raise NotAuthenticated(
{"error": "Invalid credentials"},
)
token = jwt.encode(
{
"id": user.id,
"password": password,
"exp": timezone.now() + timedelta(hours=24),
},
settings.SECRET_KEY,
algorithm="HS256",
)
return Response({"token": token})
class ProfileMeApiView(APIView):
class ProfileMeApiView(UpdateAPIView):
permission_classes = [IsAuthenticated]
def get(self, request):
serializer = UserProfileSerializer(request.user)
return Response(serializer.data)
def patch(self, request):
user = request.user
serializer = UpdateProfileSerializer(
user, data=request.data, partial=True
)
if serializer.is_valid():
errors = User.check_unique(user.id, serializer.validated_data)
if errors:
return Response(
{"reason:": str(errors)}, status=status.HTTP_409_CONFLICT
)
serializer.save()
return Response(self._get_profile_data(user))
raise ValidationError(serializer.errors)
def get_object(self):
return self.request.user
class PasswordChangeApiView(APIView):
class PasswordChangeApiView(UpdateAPIView):
permission_classes = [IsAuthenticated]
serializer_class = ChangePasswordSerializer
def post(self, request):
serializer = PasswordChangeSerializer(data=request.data)
if serializer.is_valid():
old_password = serializer.validated_data.get("oldPassword")
new_password = serializer.validated_data.get("newPassword")
if bcrypt.checkpw(
old_password.encode("utf-8"),
request.user.password.encode("utf-8"),
):
password_hash = bcrypt.hashpw(
new_password.encode("utf-8"), bcrypt.gensalt()
).decode("utf-8")
request.user.password = password_hash
request.user.save()
return Response({"status": "ok"}, status=status.HTTP_200_OK)
raise PermissionDenied({"error": "Invalid old password"})
raise ValidationError(serializer.errors)
def get_object(self):
return self.request.user