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 .models import Archive, Ticket
from .models import Archive
class ArchiveUploadSerializer(serializers.ModelSerializer):
class PublicArchiveUploadSerializer(serializers.ModelSerializer):
ticket = serializers.ReadOnlyField(source='ticket.token')
class Meta:
model = Archive
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'
router = routers.DefaultRouter()
router.register(r'archives', views.ArchiveUploadViewSet)
router.register(r'tickets/create', views.TicketCreateViewSet)
router.register(r'archives', views.PublicArchiveUploadViewSet)
urlpatterns = [

View File

@ -1,4 +1,5 @@
import json
from django.core.exceptions import ValidationError
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import FileResponse, JsonResponse
from django.views import generic
@ -7,6 +8,7 @@ from django.urls import reverse_lazy
from django.db.models import Q
from rest_framework import status
from rest_framework.response import Response
from rest_framework.parsers import FormParser, MultiPartParser
from rest_framework import mixins
@ -16,7 +18,7 @@ from .models import Archive, Ticket
from .forms import TicketForm
from .utils import PageTitleViewMixin, is_ajax
from .serializers import ArchiveUploadSerializer, TicketSerializer
from .serializers import PublicArchiveUploadSerializer
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')
serializer_class = ArchiveUploadSerializer
serializer_class = PublicArchiveUploadSerializer
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):
serializer.save(user=self.request.user)
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)
serializer.save(ticket=self.request.data['ticket'])