chess_rpg_backend/game/api/v1/views.py

150 lines
5.0 KiB
Python
Raw Normal View History

2022-06-04 19:30:54 +03:00
from rest_framework import status
2022-06-04 19:30:54 +03:00
from rest_framework.generics import GenericAPIView, UpdateAPIView
2022-06-06 20:15:45 +03:00
from rest_framework.mixins import (
CreateModelMixin,
RetrieveModelMixin,
ListModelMixin,
DestroyModelMixin,
UpdateModelMixin,
)
2022-06-04 19:30:54 +03:00
from rest_framework.response import Response
2022-06-05 13:09:27 +03:00
from game.authentication import PlayerAuthentication
2022-06-07 23:54:26 +03:00
from game.models import Hero, Deck
2022-06-06 20:15:45 +03:00
from game.api.v1.serializers import (
CreateHeroSerializer,
GetHeroSerializer,
CreatePlayerSerializer,
ListHeroSerializer,
2022-06-07 23:54:26 +03:00
CreateDeckSerializer,
2022-06-06 20:15:45 +03:00
GetDeckSerializer,
)
2022-06-05 13:09:27 +03:00
from game.services.jwt import sign_jwt
2022-06-04 19:30:54 +03:00
2022-06-06 20:15:45 +03:00
class ListCreateHeroView(GenericAPIView, CreateModelMixin, ListModelMixin):
2022-06-05 13:09:27 +03:00
authentication_classes = (PlayerAuthentication,)
2022-06-04 19:30:54 +03:00
def perform_create(self, serializer):
return serializer.save()
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
instance = self.perform_create(serializer)
return Response({"uuid": instance.uuid}, status=status.HTTP_201_CREATED)
2022-06-05 13:09:27 +03:00
def get(self, request, *args, **kwargs):
return self.list(request, *args, **kwargs)
def get_serializer_class(self):
if self.request.method == "GET":
2022-06-06 20:15:45 +03:00
return ListHeroSerializer
2022-06-05 13:09:27 +03:00
else:
return CreateHeroSerializer
def get_queryset(self):
return Hero.objects.filter(player_id=self.request.user.id)
2022-06-04 19:30:54 +03:00
class RetrieveHeroView(RetrieveModelMixin, UpdateAPIView, GenericAPIView):
serializer_class = GetHeroSerializer
2022-06-05 13:09:27 +03:00
authentication_classes = (PlayerAuthentication,)
2022-06-04 19:30:54 +03:00
lookup_field = "uuid"
queryset = Hero.objects.all()
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs)
2022-06-05 13:09:27 +03:00
class PlayerCreateView(GenericAPIView, CreateModelMixin):
2022-06-06 20:15:45 +03:00
serializer_class = CreatePlayerSerializer
2022-06-05 13:09:27 +03:00
def perform_create(self, serializer):
return serializer.save()
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
instance = self.perform_create(serializer)
# TODO: add JTI to refresh token
access_jwt = sign_jwt({"id": instance.id, "type": "access"}, t_life=3600)
refresh_jwt = sign_jwt({"id": instance.id, "type": "refresh"})
2022-06-06 20:15:45 +03:00
return Response(
2022-06-08 19:03:38 +03:00
{
"access_token": access_jwt,
"refresh_token": refresh_jwt,
"deck_id": instance.get_last_deck().id,
},
2022-06-06 20:15:45 +03:00
status=status.HTTP_201_CREATED,
)
class DeckCreateView(GenericAPIView, CreateModelMixin):
2022-06-07 23:54:26 +03:00
serializer_class = CreateDeckSerializer
2022-06-06 20:15:45 +03:00
authentication_classes = (PlayerAuthentication,)
def perform_create(self, serializer):
return serializer.save(player=self.request.user)
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
instance = self.perform_create(serializer)
heroes_list = ListHeroSerializer(instance.get_heroes(), many=True)
2022-06-08 19:03:38 +03:00
heroes_list.data["deck_id"] = instance.id
2022-06-06 20:15:45 +03:00
return Response(heroes_list.data, status=status.HTTP_201_CREATED)
class RetireUpdateDeleteDeckView(
RetrieveHeroView, DestroyModelMixin, UpdateModelMixin, GenericAPIView
):
2022-06-07 23:54:26 +03:00
lookup_field = "id"
queryset = Deck.objects.all()
2022-06-06 20:15:45 +03:00
def get_serializer_class(self):
if self.request.method == "GET":
return GetDeckSerializer
2022-06-07 23:54:26 +03:00
else:
return CreateDeckSerializer
2022-06-06 20:15:45 +03:00
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
2022-06-07 23:54:26 +03:00
def put(self, request, *args, **kwargs):
2022-06-08 19:03:38 +03:00
if not self._check_user_identity(request.user.id, kwargs["id"]):
return Response(
"Attempt to change another user's deck",
status=status.HTTP_403_FORBIDDEN,
)
2022-06-07 23:54:26 +03:00
return self.update(request, *args, **kwargs)
def patch(self, request, *args, **kwargs):
2022-06-08 19:03:38 +03:00
if not self._check_user_identity(request.user.id, kwargs["id"]):
return Response(
"Attempt to change another user's deck",
status=status.HTTP_403_FORBIDDEN,
)
2022-06-07 23:54:26 +03:00
return self.partial_update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
2022-06-08 19:03:38 +03:00
if not self._check_user_identity(request.user.id, kwargs["id"]):
return Response(
"Attempt to delete another user's deck",
status=status.HTTP_403_FORBIDDEN,
)
2022-06-07 23:54:26 +03:00
return self.destroy(request, *args, **kwargs)
2022-06-08 19:03:38 +03:00
def _check_user_identity(self, user_id, deck_id) -> bool:
return deck_id in list(
Deck.objects.filter(player_id=user_id).values_list("id", flat=True)
)