import json from django.db.models import Q from rest_framework import serializers from assets.constants import RESOLVED_STATUS from assets.models.assets import Asset, AssetListGroup, OperatingSystem, AssetManufacturer from console.models import Vulnerability from core.serializers import DateTimeLocalizedField, ModelLocalizedSerializer from incident.models import Incident from incident.serializers.incident import IncidentSerializer class OsSerializer(serializers.ModelSerializer): class Meta: model = OperatingSystem fields = '__all__' class OsNameSerializer(serializers.ModelSerializer): class Meta: model = OperatingSystem fields = ['name'] class AssetManufacturerSerializer(serializers.ModelSerializer): class Meta: model = AssetManufacturer fields = ['id', 'name', 'description'] class AssetGroupSerializer(serializers.ModelSerializer): class Meta: model = AssetListGroup fields = ['name', 'description', 'id', 'collapsed'] class AssetListSerializer(serializers.ModelSerializer): updated = DateTimeLocalizedField() count_incidents = serializers.IntegerField() class Meta: model = Asset fields = ['id', 'name', 'asset_type', 'status', 'ip', 'updated', 'count_incidents'] class AssetDetailSerializer(serializers.ModelSerializer): os = OsSerializer() group = AssetGroupSerializer() incidents = IncidentSerializer(many=True) ports = serializers.SerializerMethodField() updated = DateTimeLocalizedField() class Meta: model = Asset fields = '__all__' def get_ports(self, asset): try: ports = json.loads(asset.ports) return f'{ports}' or f'{[]}' except TypeError: return f'{[]}' class AssetCreateUpdateSerializer(serializers.ModelSerializer): class Meta: model = Asset fields = '__all__' def to_representation(self, instance): return AssetDetailSerializer(instance=instance).data class AssetAuthorizeSerializer(serializers.Serializer): selected_assets = serializers.ListField(child=serializers.IntegerField()) class AssetCsvExportSerializer(ModelLocalizedSerializer): """ Serializer for CSV export of Assets data The idea behind parsing almost every field is that if we dont do this, than fields that are used as links to the other models will be shown in table as the dictionary """ incidents = serializers.SerializerMethodField('get_incidents') os = serializers.ReadOnlyField(source='os.name', allow_null=True) group = serializers.ReadOnlyField(source='group.name', allow_null=True) asset_type = serializers.ReadOnlyField(source='get_asset_type_display', allow_null=True) status = serializers.ReadOnlyField(source='get_status_display', allow_null=True) manufacturer = serializers.ReadOnlyField(source='manufacturer_name', allow_null=True) def get_incidents(self, obj): amount_of_active_incs = Incident.objects.filter(~Q(status=RESOLVED_STATUS), asset=obj).count() return amount_of_active_incs class Meta: model = Asset fields = ['name', 'manufacturer', 'updated', 'model', 'ip', 'os', 'ports', 'incidents', 'group', 'asset_type', 'status'] class IncidentTitleSerializer(serializers.ModelSerializer): class Meta: model = Incident fields = ['pk', 'title', 'status'] class AssetInfoSerializer(serializers.ModelSerializer): incidents = IncidentTitleSerializer(many=True) os = OsNameSerializer() updated = DateTimeLocalizedField() class Meta: model = Asset fields = ['id', 'name', 'description', 'ip', 'os', 'ports', 'updated', 'incidents', 'status'] class AssetIncidentInfoSerializer(serializers.ModelSerializer): class Meta: model = Incident fields = ['pk', 'title', 'description', 'status'] class AssetVulnerabilitiesInfoSerializer(serializers.ModelSerializer): class Meta: model = Vulnerability fields = ['name', 'description'] class AssetActiveProblemsSerializer(serializers.ModelSerializer): incidents = AssetIncidentInfoSerializer(many=True) def get_incidents(self, obj): inc_queryset = Incident.objects.filter(~Q(status=RESOLVED_STATUS), asset=obj) serializer = AssetIncidentInfoSerializer(instance=inc_queryset, many=True, context=self.context) return serializer.data class Meta: model = Asset fields = ['incidents']