from django.contrib import admin from django.shortcuts import get_object_or_404 from django.utils import timezone from oauth2_provider.contrib.rest_framework import TokenHasScope from rest_framework import generics, permissions, serializers from rest_framework.permissions import BasePermission from rest_framework.response import Response from rest_framework.views import APIView from aleksis.apps.kort.models import Card, CardPrinter, CardPrintJob admin.autodiscover() class CorrectPrinterPermission(BasePermission): """Check whether the OAuth2 application belongs to the printer.""" def has_object_permission(self, request, view, obj) -> bool: token = request.auth if token.application == obj.oauth2_application: return True return False class CorrectJobPrinterPermission(BasePermission): """Check whether the OAuth2 application belongs to the job's printer.""" def has_object_permission(self, request, view, obj) -> bool: token = request.auth if token.application == obj.printer.oauth2_application: return True return False class CardPrinterSerializer(serializers.ModelSerializer): class Meta: model = CardPrinter fields = ( "id", "name", "description", "location", "status", "status_label", "status_color", "status_icon", "status_text", "last_seen_at", "cups_printer", "generate_number_on_server", ) class CardPrinterStatusSerializer(serializers.ModelSerializer): class Meta: model = CardPrinter fields = ("status", "status_text") class CardSerializer(serializers.ModelSerializer): class Meta: model = Card fields = ("id", "chip_number", "valid_until", "deactivated", "person", "pdf_file") class CardPrintJobSerializer(serializers.ModelSerializer): card = CardSerializer() class Meta: model = CardPrintJob fields = ("id", "printer", "card", "status", "status_text") class CardPrintJobStatusSerializer(serializers.ModelSerializer): class Meta: model = CardPrintJob fields = ("id", "status", "status_text") class CardPrinterDetails(generics.RetrieveAPIView): """Show details about the card printer.""" permission_classes = [permissions.IsAuthenticated, TokenHasScope, CorrectPrinterPermission] required_scopes = ["card_printer"] serializer_class = CardPrinterSerializer queryset = CardPrinter.objects.all() def get_object(self): token = self.request.auth return token.application.card_printers.all().first() class CardPrinterUpdateStatus(generics.UpdateAPIView): """Update the status of the card printer.""" permission_classes = [permissions.IsAuthenticated, TokenHasScope, CorrectPrinterPermission] required_scopes = ["card_printer"] serializer_class = CardPrinterStatusSerializer queryset = CardPrinter.objects.all() def update(self, request, *args, **kwargs): r = super().update(request, *args, **kwargs) instance = self.get_object() instance.last_seen_at = timezone.now() instance.save() return r class GetNextPrintJob(APIView): """Get the next print job.""" permission_classes = [permissions.IsAuthenticated, TokenHasScope, CorrectPrinterPermission] required_scopes = ["card_printer"] serializer_class = CardPrinterSerializer queryset = CardPrinter.objects.all() def get_object(self, pk): return get_object_or_404(CardPrinter, pk=pk) def get(self, request, pk, *args, **kwargs): printer = self.get_object(pk) job = printer.get_next_print_job() if not job: return Response({"status": "no_job"}) serializer = CardPrintJobSerializer(job) return Response(serializer.data) class CardPrintJobUpdateStatusView(generics.UpdateAPIView): """Update the status of the card printer.""" permission_classes = [permissions.IsAuthenticated, TokenHasScope, CorrectJobPrinterPermission] required_scopes = ["card_printer"] serializer_class = CardPrintJobStatusSerializer queryset = CardPrintJob.objects.all()