blob: 1125f6223b268089a363006c8533c8834f696cc2 [file] [log] [blame]
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +02001"""Serializers for Crashreport-related models."""
Borjan Tchakaloff340b6f32018-03-01 15:23:43 +04002from django.utils import timezone
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +02003from django.core.exceptions import ObjectDoesNotExist
Dirk Vogtd1345212016-09-14 14:31:45 +02004from rest_framework import serializers
Dirk Vogtf2a33422016-10-11 17:17:26 +02005from rest_framework.exceptions import NotFound
Dirk Vogtd1345212016-09-14 14:31:45 +02006from rest_framework import permissions
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +02007
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +02008from crashreports.models import Crashreport, Device, HeartBeat, LogFile
Dirk Vogt67eb1482016-10-13 12:42:56 +02009from crashreports.permissions import user_is_hiccup_staff
10
11
12class PrivateField(serializers.ReadOnlyField):
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +020013 """Class for making a field private.
14
15 The private attribute can then only be read by Hiccup staff members
16 """
Dirk Vogt67eb1482016-10-13 12:42:56 +020017
18 def get_attribute(self, instance):
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +020019 """Get the private attribute.
20
Dirk Vogt67eb1482016-10-13 12:42:56 +020021 Given the *outgoing* object instance, return the primitive value
22 that should be used for this field.
23 """
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020024 if user_is_hiccup_staff(self.context["request"].user):
Dirk Vogt67eb1482016-10-13 12:42:56 +020025 return super(PrivateField, self).get_attribute(instance)
26 return -1
Dirk Vogtd1345212016-09-14 14:31:45 +020027
Mitja Nikolaus2189b5e2018-08-31 10:50:55 +020028 def to_internal_value(self, data):
29 """Transform the *incoming* primitive data into a native value.
30
31 Since PrivateField is read only, there will never be any incoming data,
32 thus we raise NotImplementedError.
33 """
34 raise NotImplementedError()
35
Dirk Vogtf2a33422016-10-11 17:17:26 +020036
Dirk Vogtd1345212016-09-14 14:31:45 +020037class CrashReportSerializer(serializers.ModelSerializer):
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +020038 """Serializer for CrashReport instances."""
39
Dirk Vogtf2a33422016-10-11 17:17:26 +020040 permission_classes = (permissions.AllowAny,)
Dirk Vogt83107df2017-05-02 12:04:19 +020041 logfiles = serializers.HyperlinkedRelatedField(
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020042 read_only=True, many=True, view_name="api_v1_logfiles_by_id"
43 )
Dirk Vogtf2a33422016-10-11 17:17:26 +020044 uuid = serializers.CharField(max_length=64)
Dirk Vogt67eb1482016-10-13 12:42:56 +020045 id = PrivateField()
46 device_local_id = serializers.IntegerField(required=False)
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +020047 date = serializers.DateTimeField(default_timezone=timezone.utc)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020048
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +020049 class Meta: # noqa: D106
Dirk Vogtd1345212016-09-14 14:31:45 +020050 model = Crashreport
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020051 exclude = ("device",)
Dirk Vogtf2a33422016-10-11 17:17:26 +020052
53 def create(self, validated_data):
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +020054 """Create a crashreport.
55
56 Args:
57 validated_data: Data of the crashreport, excluding the device
58
59 Returns: The created report
60
61 """
Dirk Vogtf2a33422016-10-11 17:17:26 +020062 try:
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020063 device = Device.objects.get(uuid=validated_data["uuid"])
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +020064 except ObjectDoesNotExist:
Dirk Vogtf2a33422016-10-11 17:17:26 +020065 raise NotFound(detail="uuid does not exist")
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020066 validated_data.pop("uuid", None)
Dirk Vogtf2a33422016-10-11 17:17:26 +020067 report = Crashreport(**validated_data)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020068 report.device = device
Dirk Vogtf2a33422016-10-11 17:17:26 +020069 report.save()
70 return report
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020071
72
73class HeartBeatSerializer(serializers.ModelSerializer):
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +020074 """Serializer for HeartBeat instances."""
75
Dirk Vogt36635692016-10-17 12:19:10 +020076 permission_classes = (permissions.IsAuthenticated,)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020077 uuid = serializers.CharField(max_length=64)
Dirk Vogt67eb1482016-10-13 12:42:56 +020078 id = PrivateField()
79 device_local_id = serializers.IntegerField(required=False)
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +020080 date = serializers.DateTimeField(default_timezone=timezone.utc)
Dirk Vogte1784882016-10-13 16:09:38 +020081
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +020082 class Meta: # noqa: D106
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020083 model = HeartBeat
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020084 exclude = ("device",)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020085
86 def create(self, validated_data):
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +020087 """Create a heartbeat report.
88
89 Args:
90 validated_data: Data of the heartbeat, excluding the device
91
92 Returns: The created heartbeat
93
94 """
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020095 try:
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020096 device = Device.objects.get(uuid=validated_data["uuid"])
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +020097 except ObjectDoesNotExist:
Dirk Vogtc9e10ab2016-10-12 13:58:15 +020098 raise NotFound(detail="uuid does not exist")
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +020099 validated_data.pop("uuid", None)
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200100 heartbeat = HeartBeat(**validated_data)
101 heartbeat.device = device
102 heartbeat.save()
103 return heartbeat
104
Dirk Vogtf2a33422016-10-11 17:17:26 +0200105
Dirk Vogt83107df2017-05-02 12:04:19 +0200106class LogFileSerializer(serializers.ModelSerializer):
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +0200107 """Serializer for LogFile instances."""
108
Dirk Vogt83107df2017-05-02 12:04:19 +0200109 permission_classes = (permissions.IsAdminUser,)
110
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +0200111 class Meta: # noqa: D106
Dirk Vogt83107df2017-05-02 12:04:19 +0200112 model = LogFile
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +0200113 fields = "__all__"
Dirk Vogt83107df2017-05-02 12:04:19 +0200114
115
Dirk Vogtf2a33422016-10-11 17:17:26 +0200116class DeviceSerializer(serializers.ModelSerializer):
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +0200117 """Serializer for Device instances."""
Dirk Vogtc9e10ab2016-10-12 13:58:15 +0200118
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +0200119 permission_classes = (permissions.IsAdminUser,)
120 board_date = serializers.DateTimeField(default_timezone=timezone.utc)
121 last_heartbeat = serializers.DateTimeField(default_timezone=timezone.utc)
122
123 class Meta: # noqa: D106
Dirk Vogtf2a33422016-10-11 17:17:26 +0200124 model = Device
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +0200125 fields = "__all__"
Franz-Xaver Geigerd9943352018-02-27 14:26:41 +0100126
127
128class DeviceCreateSerializer(DeviceSerializer):
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +0200129 """Serializer for creating Device instances."""
Franz-Xaver Geigerd9943352018-02-27 14:26:41 +0100130
Mitja Nikolaus5c3e0572018-07-30 13:36:14 +0200131 class Meta: # noqa: D106
Franz-Xaver Geigerd9943352018-02-27 14:26:41 +0100132 model = Device
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +0200133 fields = ("board_date", "chipset")
Franz-Xaver Geigerd9943352018-02-27 14:26:41 +0100134 extra_kwargs = {
Mitja Nikolauscb50f2c2018-08-24 13:54:48 +0200135 "board_date": {"required": True},
136 "chipset": {"required": True},
Franz-Xaver Geigerd9943352018-02-27 14:26:41 +0100137 }