Files
Iliyan Angelov 6b247e5b9f Updates
2025-09-19 11:58:53 +03:00

355 lines
14 KiB
Python

"""
Serializers for Collaboration & War Rooms models
"""
from rest_framework import serializers
from django.contrib.auth import get_user_model
from ..models import (
WarRoom, ConferenceBridge, IncidentCommandRole,
TimelineEvent, WarRoomMessage, IncidentDecision,
MessageReaction, ChatFile, ChatCommand, ChatBot
)
from incident_intelligence.serializers.incident import IncidentSerializer
from security.serializers.security import UserSerializer
User = get_user_model()
class WarRoomSerializer(serializers.ModelSerializer):
"""Serializer for WarRoom model"""
incident = IncidentSerializer(read_only=True)
incident_id = serializers.UUIDField(write_only=True)
allowed_users = UserSerializer(many=True, read_only=True)
allowed_user_ids = serializers.ListField(
child=serializers.UUIDField(),
write_only=True,
required=False
)
created_by = UserSerializer(read_only=True)
created_by_id = serializers.UUIDField(write_only=True, required=False)
class Meta:
model = WarRoom
fields = [
'id', 'name', 'description', 'incident', 'incident_id',
'status', 'privacy_level', 'slack_channel_id', 'teams_channel_id',
'discord_channel_id', 'allowed_users', 'allowed_user_ids',
'required_clearance_level', 'message_count', 'last_activity',
'active_participants', 'created_by', 'created_by_id',
'created_at', 'updated_at', 'archived_at'
]
read_only_fields = ['id', 'created_at', 'updated_at', 'message_count', 'last_activity', 'active_participants']
def create(self, validated_data):
"""Create war room with allowed users"""
allowed_user_ids = validated_data.pop('allowed_user_ids', [])
war_room = WarRoom.objects.create(**validated_data)
# Add allowed users
if allowed_user_ids:
users = User.objects.filter(id__in=allowed_user_ids)
war_room.allowed_users.set(users)
return war_room
def update(self, instance, validated_data):
"""Update war room with allowed users"""
allowed_user_ids = validated_data.pop('allowed_user_ids', None)
# Update war room fields
for attr, value in validated_data.items():
setattr(instance, attr, value)
instance.save()
# Update allowed users if provided
if allowed_user_ids is not None:
users = User.objects.filter(id__in=allowed_user_ids)
instance.allowed_users.set(users)
return instance
class ConferenceBridgeSerializer(serializers.ModelSerializer):
"""Serializer for ConferenceBridge model"""
incident = IncidentSerializer(read_only=True)
incident_id = serializers.UUIDField(write_only=True)
war_room = WarRoomSerializer(read_only=True)
war_room_id = serializers.UUIDField(write_only=True, required=False)
invited_participants = UserSerializer(many=True, read_only=True)
invited_participant_ids = serializers.ListField(
child=serializers.UUIDField(),
write_only=True,
required=False
)
active_participants = UserSerializer(many=True, read_only=True)
created_by = UserSerializer(read_only=True)
created_by_id = serializers.UUIDField(write_only=True, required=False)
class Meta:
model = ConferenceBridge
fields = [
'id', 'name', 'description', 'incident', 'incident_id',
'war_room', 'war_room_id', 'bridge_type', 'status',
'meeting_id', 'meeting_url', 'dial_in_number', 'access_code',
'scheduled_start', 'scheduled_end', 'actual_start', 'actual_end',
'invited_participants', 'invited_participant_ids',
'active_participants', 'max_participants',
'recording_enabled', 'recording_url', 'transcription_enabled',
'transcription_url', 'integration_config',
'created_by', 'created_by_id', 'created_at', 'updated_at'
]
read_only_fields = ['id', 'created_at', 'updated_at', 'actual_start', 'actual_end', 'active_participants']
def create(self, validated_data):
"""Create conference bridge with invited participants"""
invited_participant_ids = validated_data.pop('invited_participant_ids', [])
conference = ConferenceBridge.objects.create(**validated_data)
# Add invited participants
if invited_participant_ids:
users = User.objects.filter(id__in=invited_participant_ids)
conference.invited_participants.set(users)
return conference
def update(self, instance, validated_data):
"""Update conference bridge with invited participants"""
invited_participant_ids = validated_data.pop('invited_participant_ids', None)
# Update conference fields
for attr, value in validated_data.items():
setattr(instance, attr, value)
instance.save()
# Update invited participants if provided
if invited_participant_ids is not None:
users = User.objects.filter(id__in=invited_participant_ids)
instance.invited_participants.set(users)
return instance
class IncidentCommandRoleSerializer(serializers.ModelSerializer):
"""Serializer for IncidentCommandRole model"""
incident = IncidentSerializer(read_only=True)
incident_id = serializers.UUIDField(write_only=True)
war_room = WarRoomSerializer(read_only=True)
war_room_id = serializers.UUIDField(write_only=True, required=False)
assigned_user = UserSerializer(read_only=True)
assigned_user_id = serializers.UUIDField(write_only=True, required=False)
reassigned_by = UserSerializer(read_only=True)
created_by = UserSerializer(read_only=True)
created_by_id = serializers.UUIDField(write_only=True, required=False)
class Meta:
model = IncidentCommandRole
fields = [
'id', 'incident', 'incident_id', 'war_room', 'war_room_id',
'role_type', 'assigned_user', 'assigned_user_id', 'status',
'responsibilities', 'decision_authority', 'assigned_at',
'reassigned_at', 'reassigned_by', 'assignment_notes',
'decisions_made', 'communications_sent', 'last_activity',
'created_by', 'created_by_id', 'created_at', 'updated_at'
]
read_only_fields = [
'id', 'assigned_at', 'reassigned_at', 'reassigned_by',
'decisions_made', 'communications_sent', 'last_activity',
'created_at', 'updated_at'
]
class TimelineEventSerializer(serializers.ModelSerializer):
"""Serializer for TimelineEvent model"""
incident = IncidentSerializer(read_only=True)
incident_id = serializers.UUIDField(write_only=True)
related_user = UserSerializer(read_only=True)
related_user_id = serializers.UUIDField(write_only=True, required=False)
created_by = UserSerializer(read_only=True)
created_by_id = serializers.UUIDField(write_only=True, required=False)
class Meta:
model = TimelineEvent
fields = [
'id', 'incident', 'incident_id', 'event_type', 'title',
'description', 'source_type', 'event_time', 'created_at',
'related_user', 'related_user_id', 'event_data', 'tags',
'is_critical_event', 'postmortem_notes',
'created_by', 'created_by_id'
]
read_only_fields = ['id', 'created_at']
class MessageReactionSerializer(serializers.ModelSerializer):
"""Serializer for MessageReaction model"""
user = UserSerializer(read_only=True)
class Meta:
model = MessageReaction
fields = ['id', 'user', 'emoji', 'created_at']
read_only_fields = ['id', 'created_at']
class ChatFileSerializer(serializers.ModelSerializer):
"""Serializer for ChatFile model"""
uploaded_by = UserSerializer(read_only=True)
class Meta:
model = ChatFile
fields = [
'id', 'message', 'filename', 'original_filename', 'file_type',
'file_size', 'mime_type', 'file_path', 'file_url',
'data_classification', 'is_encrypted', 'file_hash',
'uploaded_by', 'uploaded_at', 'access_log'
]
read_only_fields = ['id', 'uploaded_at', 'access_log']
class ChatCommandSerializer(serializers.ModelSerializer):
"""Serializer for ChatCommand model"""
executed_by = UserSerializer(read_only=True)
class Meta:
model = ChatCommand
fields = [
'id', 'message', 'command_type', 'command_text', 'parameters',
'executed_by', 'executed_at', 'execution_status',
'execution_result', 'error_message', 'automation_execution'
]
read_only_fields = ['id', 'executed_at']
class ChatBotSerializer(serializers.ModelSerializer):
"""Serializer for ChatBot model"""
class Meta:
model = ChatBot
fields = [
'id', 'name', 'bot_type', 'description', 'is_active',
'auto_respond', 'response_triggers', 'knowledge_base',
'created_at', 'updated_at'
]
read_only_fields = ['id', 'created_at', 'updated_at']
class WarRoomMessageSerializer(serializers.ModelSerializer):
"""Serializer for WarRoomMessage model"""
war_room = WarRoomSerializer(read_only=True)
war_room_id = serializers.UUIDField(write_only=True)
sender = UserSerializer(read_only=True)
sender_id = serializers.UUIDField(write_only=True, required=False)
reply_to = serializers.PrimaryKeyRelatedField(
queryset=WarRoomMessage.objects.all(),
required=False
)
pinned_by = UserSerializer(read_only=True)
mentioned_users = UserSerializer(many=True, read_only=True)
mentioned_user_ids = serializers.ListField(
child=serializers.UUIDField(),
write_only=True,
required=False
)
reactions = MessageReactionSerializer(many=True, read_only=True)
chat_files = ChatFileSerializer(many=True, read_only=True)
chat_commands = ChatCommandSerializer(many=True, read_only=True)
reactions_summary = serializers.SerializerMethodField()
class Meta:
model = WarRoomMessage
fields = [
'id', 'war_room', 'war_room_id', 'message_type', 'content',
'sender', 'sender_id', 'sender_name', 'is_edited', 'edited_at',
'is_pinned', 'pinned_at', 'pinned_by', 'reply_to',
'attachments', 'mentioned_users', 'mentioned_user_ids',
'notification_sent', 'external_message_id', 'external_data',
'is_encrypted', 'encryption_key_id', 'reactions', 'reactions_summary',
'chat_files', 'chat_commands', 'created_at', 'updated_at'
]
read_only_fields = [
'id', 'is_edited', 'edited_at', 'pinned_at', 'pinned_by',
'notification_sent', 'created_at', 'updated_at'
]
def get_reactions_summary(self, obj):
"""Get reactions summary for the message"""
return obj.get_reactions_summary()
def create(self, validated_data):
"""Create message with mentioned users"""
mentioned_user_ids = validated_data.pop('mentioned_user_ids', [])
message = WarRoomMessage.objects.create(**validated_data)
# Add mentioned users
if mentioned_user_ids:
users = User.objects.filter(id__in=mentioned_user_ids)
message.mentioned_users.set(users)
return message
class IncidentDecisionSerializer(serializers.ModelSerializer):
"""Serializer for IncidentDecision model"""
incident = IncidentSerializer(read_only=True)
incident_id = serializers.UUIDField(write_only=True)
command_role = IncidentCommandRoleSerializer(read_only=True)
command_role_id = serializers.UUIDField(write_only=True)
approved_by = UserSerializer(read_only=True)
implemented_by = UserSerializer(read_only=True)
class Meta:
model = IncidentDecision
fields = [
'id', 'incident', 'incident_id', 'command_role', 'command_role_id',
'decision_type', 'title', 'description', 'rationale', 'status',
'requires_approval', 'approved_by', 'approved_at',
'implementation_notes', 'implemented_at', 'implemented_by',
'impact_assessment', 'success_metrics', 'created_at', 'updated_at'
]
read_only_fields = [
'id', 'approved_by', 'approved_at', 'implemented_at',
'implemented_by', 'created_at', 'updated_at'
]
class WarRoomSummarySerializer(serializers.ModelSerializer):
"""Simplified serializer for WarRoom list views"""
incident_title = serializers.CharField(source='incident.title', read_only=True)
incident_severity = serializers.CharField(source='incident.severity', read_only=True)
participant_count = serializers.SerializerMethodField()
class Meta:
model = WarRoom
fields = [
'id', 'name', 'incident_title', 'incident_severity',
'status', 'privacy_level', 'message_count', 'last_activity',
'participant_count', 'created_at'
]
def get_participant_count(self, obj):
"""Get count of allowed users"""
return obj.allowed_users.count()
class TimelineEventSummarySerializer(serializers.ModelSerializer):
"""Simplified serializer for TimelineEvent list views"""
incident_title = serializers.CharField(source='incident.title', read_only=True)
related_user_name = serializers.CharField(source='related_user.username', read_only=True)
class Meta:
model = TimelineEvent
fields = [
'id', 'incident_title', 'event_type', 'title', 'description',
'source_type', 'event_time', 'related_user_name',
'is_critical_event', 'created_at'
]