blob: 8b13728cc887a77e3cb807d04e2d34cca3b441e6 [file] [log] [blame]
Mitja Nikolaus1280ef42018-08-21 16:20:07 +02001"""REST API for accessing log files."""
2from django.core.exceptions import ObjectDoesNotExist
3from django.utils.decorators import method_decorator
4from drf_yasg import openapi
5from drf_yasg.utils import swagger_auto_schema
Dirk Vogt7160b5e2016-10-12 17:04:40 +02006
Mitja Nikolaus1280ef42018-08-21 16:20:07 +02007from rest_framework import generics, status
8from rest_framework.decorators import (
9 api_view,
10 parser_classes,
11 permission_classes,
12)
13from rest_framework.exceptions import (
14 PermissionDenied,
15 NotFound,
16 ValidationError,
17)
Dirk Vogt7160b5e2016-10-12 17:04:40 +020018from rest_framework.parsers import FileUploadParser
19from rest_framework.permissions import IsAuthenticated
Dirk Vogt7160b5e2016-10-12 17:04:40 +020020from rest_framework.response import Response
Dirk Vogt83107df2017-05-02 12:04:19 +020021
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020022from crashreports.response_descriptions import default_desc
Dirk Vogt83107df2017-05-02 12:04:19 +020023from crashreports.serializers import LogFileSerializer
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020024from crashreports.models import Crashreport, LogFile
25from crashreports.permissions import (
26 HasRightsOrIsDeviceOwnerDeviceCreation,
27 user_owns_uuid,
28 user_is_hiccup_staff,
Mitja Nikolaus4d759da2018-08-28 15:31:29 +020029 SWAGGER_SECURITY_REQUIREMENTS_ALL,
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020030)
Dirk Vogt83107df2017-05-02 12:04:19 +020031
32
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020033@method_decorator(
34 name="get",
Mitja Nikolaus4d759da2018-08-28 15:31:29 +020035 decorator=swagger_auto_schema(
36 operation_description="List log files",
37 security=SWAGGER_SECURITY_REQUIREMENTS_ALL,
38 ),
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020039)
Mitja Nikolaus0343baf2018-09-03 11:56:31 +020040class ListView(generics.ListAPIView):
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020041 """Endpoint for listing log files."""
42
Dirk Vogt83107df2017-05-02 12:04:19 +020043 queryset = LogFile.objects.all()
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020044 permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation,)
Dirk Vogt83107df2017-05-02 12:04:19 +020045 serializer_class = LogFileSerializer
46
47
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020048@method_decorator(
49 name="get",
50 decorator=swagger_auto_schema(
51 operation_description="Get a log file",
Mitja Nikolaus4d759da2018-08-28 15:31:29 +020052 security=SWAGGER_SECURITY_REQUIREMENTS_ALL,
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020053 responses=dict([default_desc(NotFound)]),
54 ),
55)
56@method_decorator(
57 name="put",
58 decorator=swagger_auto_schema(
59 operation_description="Update a log file",
Mitja Nikolaus4d759da2018-08-28 15:31:29 +020060 security=SWAGGER_SECURITY_REQUIREMENTS_ALL,
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020061 responses=dict([default_desc(NotFound), default_desc(ValidationError)]),
62 ),
63)
64@method_decorator(
65 name="patch",
66 decorator=swagger_auto_schema(
67 operation_description="Partially update a log file",
Mitja Nikolaus4d759da2018-08-28 15:31:29 +020068 security=SWAGGER_SECURITY_REQUIREMENTS_ALL,
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020069 responses=dict([default_desc(NotFound), default_desc(ValidationError)]),
70 ),
71)
72@method_decorator(
73 name="delete",
74 decorator=swagger_auto_schema(
75 operation_description="Delete a log file",
Mitja Nikolaus4d759da2018-08-28 15:31:29 +020076 security=SWAGGER_SECURITY_REQUIREMENTS_ALL,
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020077 responses=dict([default_desc(NotFound)]),
78 ),
79)
Dirk Vogt83107df2017-05-02 12:04:19 +020080class RetrieveUpdateDestroyView(generics.RetrieveUpdateDestroyAPIView):
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020081 """Endpoint for retrieving, updating and deleting log files."""
82
83 # pylint: disable=too-many-ancestors
84
Dirk Vogt83107df2017-05-02 12:04:19 +020085 queryset = LogFile.objects.all()
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020086 permission_classes = (HasRightsOrIsDeviceOwnerDeviceCreation,)
Dirk Vogt83107df2017-05-02 12:04:19 +020087 serializer_class = LogFileSerializer
Dirk Vogt7160b5e2016-10-12 17:04:40 +020088
89
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020090@swagger_auto_schema(
91 method="post",
Mitja Nikolaus4d759da2018-08-28 15:31:29 +020092 security=SWAGGER_SECURITY_REQUIREMENTS_ALL,
Mitja Nikolaus1280ef42018-08-21 16:20:07 +020093 request_body=LogFileSerializer,
94 responses=dict(
95 [
96 default_desc(ValidationError),
97 (
98 status.HTTP_404_NOT_FOUND,
99 openapi.Response("Crashreport does not exist."),
100 ),
101 (status.HTTP_201_CREATED, openapi.Response("Created")),
102 ]
103 ),
104)
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +0200105@api_view(http_method_names=["POST"])
106@parser_classes([FileUploadParser])
107@permission_classes([IsAuthenticated])
Dirk Vogt36635692016-10-17 12:19:10 +0200108def logfile_put(request, uuid, device_local_id, filename):
Mitja Nikolaus1280ef42018-08-21 16:20:07 +0200109 """Upload a log file for a crash report."""
Dirk Vogt7160b5e2016-10-12 17:04:40 +0200110 try:
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +0200111 crashreport = Crashreport.objects.get(
112 device__uuid=uuid, device_local_id=device_local_id
113 )
Mitja Nikolaus1280ef42018-08-21 16:20:07 +0200114 except ObjectDoesNotExist:
Dirk Vogt36635692016-10-17 12:19:10 +0200115 raise NotFound(detail="Crashreport does not exist.")
116
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +0200117 if not (
118 user_owns_uuid(request.user, crashreport.device.uuid)
119 or user_is_hiccup_staff(request.user)
120 ):
Dirk Vogt7160b5e2016-10-12 17:04:40 +0200121 raise PermissionDenied(detail="Not allowed.")
Mitja Nikolaus1280ef42018-08-21 16:20:07 +0200122 file = request.data["file"]
123 logfile = LogFile(crashreport=crashreport, logfile=file)
Dirk Vogt7160b5e2016-10-12 17:04:40 +0200124 logfile.save()
Dirk Vogt36635692016-10-17 12:19:10 +0200125 return Response(status=201)