Add: public api view for upload ticket

This commit is contained in:
Stepan Zhukovsky 2023-08-09 20:24:16 +09:00
parent 02906554dd
commit 90d7e64db3
3 changed files with 51 additions and 26 deletions

View File

@ -1,17 +1,11 @@
from rest_framework import serializers from rest_framework import serializers
from .models import Archive, Ticket from .models import Archive
class ArchiveUploadSerializer(serializers.ModelSerializer): class PublicArchiveUploadSerializer(serializers.ModelSerializer):
ticket = serializers.ReadOnlyField(source='ticket.token')
class Meta: class Meta:
model = Archive model = Archive
fields = ['file', 'ticket'] fields = ['file', 'ticket']
class TicketSerializer(serializers.ModelSerializer):
class Meta:
model = Ticket
fields = ['number', 'platform', 'note']

View File

@ -7,9 +7,7 @@ from . import views
app_name = 'collector' app_name = 'collector'
router = routers.DefaultRouter() router = routers.DefaultRouter()
router.register(r'archives', views.ArchiveUploadViewSet) router.register(r'archives', views.PublicArchiveUploadViewSet)
router.register(r'tickets/create', views.TicketCreateViewSet)
urlpatterns = [ urlpatterns = [

View File

@ -1,4 +1,5 @@
import json import json
from django.core.exceptions import ValidationError
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import FileResponse, JsonResponse from django.http import FileResponse, JsonResponse
from django.views import generic from django.views import generic
@ -7,6 +8,7 @@ from django.urls import reverse_lazy
from django.db.models import Q from django.db.models import Q
from rest_framework import status from rest_framework import status
from rest_framework.response import Response
from rest_framework.parsers import FormParser, MultiPartParser from rest_framework.parsers import FormParser, MultiPartParser
from rest_framework import mixins from rest_framework import mixins
@ -16,7 +18,7 @@ from .models import Archive, Ticket
from .forms import TicketForm from .forms import TicketForm
from .utils import PageTitleViewMixin, is_ajax from .utils import PageTitleViewMixin, is_ajax
from .serializers import ArchiveUploadSerializer, TicketSerializer from .serializers import PublicArchiveUploadSerializer
class ArchiveHandlerView(LoginRequiredMixin, SingleObjectMixin, generic.View): class ArchiveHandlerView(LoginRequiredMixin, SingleObjectMixin, generic.View):
@ -172,20 +174,51 @@ class DeleteTicketHandler(SingleObjectMixin, generic.View):
) )
class ArchiveUploadViewSet(mixins.CreateModelMixin, GenericViewSet): class PublicArchiveUploadViewSet(mixins.CreateModelMixin, GenericViewSet):
queryset = Archive.objects.order_by('-time_create') queryset = Archive.objects.order_by('-time_create')
serializer_class = ArchiveUploadSerializer serializer_class = PublicArchiveUploadSerializer
parser_classes = (MultiPartParser, FormParser) parser_classes = (MultiPartParser, FormParser)
# permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def create(self, request, *args, **kwargs):
# ! upload-token protection:
upload_token = request.headers.get('upload-token', '')
if upload_token:
try:
bound_ticket = Ticket.objects.get(token=upload_token)
if bound_ticket.resolved:
return Response(
{'error': f'ticket {upload_token} already resolved'},
status=status.HTTP_423_LOCKED
)
if bound_ticket.attempts <= 0:
return Response(
{'error': f'token {upload_token} expired'},
status=status.HTTP_423_LOCKED
)
bound_ticket.attempts -= 1
bound_ticket.save()
# ? mixin bound ticket to request.data from user
request.data['ticket'] = bound_ticket
except ValidationError:
return Response(
{'error': f'token {upload_token} is not valid'},
status=status.HTTP_403_FORBIDDEN
)
else:
return Response(
{'error': 'Header Upload-Token is required'},
status=status.HTTP_401_UNAUTHORIZED
)
# ! default create method:
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(
serializer.data,
status=status.HTTP_201_CREATED,
headers=headers
)
def perform_create(self, serializer): def perform_create(self, serializer):
serializer.save(user=self.request.user) serializer.save(ticket=self.request.data['ticket'])
class TicketCreateViewSet(mixins.CreateModelMixin, GenericViewSet):
queryset = Ticket.objects.order_by('-time_create')
serializer_class = TicketSerializer
# permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def perform_create(self, serializer):
serializer.save(user=self.request.user)