mirror of
https://github.com/yyhuni/xingrin.git
synced 2026-01-31 11:46:16 +08:00
292 lines
8.0 KiB
Python
292 lines
8.0 KiB
Python
|
|
from rest_framework import serializers
|
|||
|
|
from .models import Subdomain, WebSite, Directory, HostPortMapping, Endpoint, Vulnerability
|
|||
|
|
from .models.snapshot_models import (
|
|||
|
|
SubdomainSnapshot,
|
|||
|
|
WebsiteSnapshot,
|
|||
|
|
DirectorySnapshot,
|
|||
|
|
EndpointSnapshot,
|
|||
|
|
VulnerabilitySnapshot,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
|
|||
|
|
# 注意:IPAddress 和 Port 模型已被重构为 HostPortMapping
|
|||
|
|
# 以下是基于新架构的序列化器实现
|
|||
|
|
|
|||
|
|
# class PortSerializer(serializers.ModelSerializer):
|
|||
|
|
# """端口序列化器"""
|
|||
|
|
#
|
|||
|
|
# class Meta:
|
|||
|
|
# model = Port
|
|||
|
|
# fields = ['number', 'service_name', 'description', 'is_uncommon']
|
|||
|
|
|
|||
|
|
|
|||
|
|
class SubdomainSerializer(serializers.ModelSerializer):
|
|||
|
|
"""子域名序列化器"""
|
|||
|
|
|
|||
|
|
class Meta:
|
|||
|
|
model = Subdomain
|
|||
|
|
fields = [
|
|||
|
|
'id', 'name', 'discovered_at', 'target'
|
|||
|
|
]
|
|||
|
|
read_only_fields = ['id', 'discovered_at']
|
|||
|
|
|
|||
|
|
|
|||
|
|
class SubdomainListSerializer(serializers.ModelSerializer):
|
|||
|
|
"""子域名列表序列化器(用于扫描详情)"""
|
|||
|
|
|
|||
|
|
# 注意:Subdomain 模型已简化,只保留核心字段
|
|||
|
|
# cname, is_cdn, cdn_name 等字段已移至 SubdomainSnapshot
|
|||
|
|
# ports 和 ip_addresses 关系已被重构为 HostPortMapping
|
|||
|
|
|
|||
|
|
class Meta:
|
|||
|
|
model = Subdomain
|
|||
|
|
fields = [
|
|||
|
|
'id', 'name', 'discovered_at'
|
|||
|
|
]
|
|||
|
|
read_only_fields = ['id', 'discovered_at']
|
|||
|
|
|
|||
|
|
|
|||
|
|
# class IPAddressListSerializer(serializers.ModelSerializer):
|
|||
|
|
# """IP 地址列表序列化器"""
|
|||
|
|
#
|
|||
|
|
# subdomain = serializers.CharField(source='subdomain.name', allow_blank=True, default='')
|
|||
|
|
# created_at = serializers.DateTimeField(read_only=True)
|
|||
|
|
# ports = PortSerializer(many=True, read_only=True)
|
|||
|
|
#
|
|||
|
|
# class Meta:
|
|||
|
|
# model = IPAddress
|
|||
|
|
# fields = [
|
|||
|
|
# 'id',
|
|||
|
|
# 'ip',
|
|||
|
|
# 'subdomain',
|
|||
|
|
# 'reverse_pointer',
|
|||
|
|
# 'created_at',
|
|||
|
|
# 'ports',
|
|||
|
|
# ]
|
|||
|
|
# read_only_fields = fields
|
|||
|
|
|
|||
|
|
|
|||
|
|
class WebSiteSerializer(serializers.ModelSerializer):
|
|||
|
|
"""站点序列化器"""
|
|||
|
|
|
|||
|
|
subdomain = serializers.CharField(source='subdomain.name', allow_blank=True, default='')
|
|||
|
|
|
|||
|
|
class Meta:
|
|||
|
|
model = WebSite
|
|||
|
|
fields = [
|
|||
|
|
'id',
|
|||
|
|
'url',
|
|||
|
|
'location',
|
|||
|
|
'title',
|
|||
|
|
'webserver',
|
|||
|
|
'content_type',
|
|||
|
|
'status_code',
|
|||
|
|
'content_length',
|
|||
|
|
'body_preview',
|
|||
|
|
'tech',
|
|||
|
|
'vhost',
|
|||
|
|
'subdomain',
|
|||
|
|
'discovered_at',
|
|||
|
|
]
|
|||
|
|
read_only_fields = fields
|
|||
|
|
|
|||
|
|
|
|||
|
|
class VulnerabilitySerializer(serializers.ModelSerializer):
|
|||
|
|
"""漏洞资产序列化器(按目标查看漏洞资产)。"""
|
|||
|
|
|
|||
|
|
class Meta:
|
|||
|
|
model = Vulnerability
|
|||
|
|
fields = [
|
|||
|
|
'id',
|
|||
|
|
'target',
|
|||
|
|
'url',
|
|||
|
|
'vuln_type',
|
|||
|
|
'severity',
|
|||
|
|
'source',
|
|||
|
|
'cvss_score',
|
|||
|
|
'description',
|
|||
|
|
'raw_output',
|
|||
|
|
'discovered_at',
|
|||
|
|
]
|
|||
|
|
read_only_fields = fields
|
|||
|
|
|
|||
|
|
|
|||
|
|
class VulnerabilitySnapshotSerializer(serializers.ModelSerializer):
|
|||
|
|
"""漏洞快照序列化器(用于扫描历史漏洞列表)。"""
|
|||
|
|
|
|||
|
|
class Meta:
|
|||
|
|
model = VulnerabilitySnapshot
|
|||
|
|
fields = [
|
|||
|
|
'id',
|
|||
|
|
'url',
|
|||
|
|
'vuln_type',
|
|||
|
|
'severity',
|
|||
|
|
'source',
|
|||
|
|
'cvss_score',
|
|||
|
|
'description',
|
|||
|
|
'raw_output',
|
|||
|
|
'discovered_at',
|
|||
|
|
]
|
|||
|
|
read_only_fields = fields
|
|||
|
|
|
|||
|
|
|
|||
|
|
class EndpointListSerializer(serializers.ModelSerializer):
|
|||
|
|
"""端点列表序列化器(用于目标端点列表页)"""
|
|||
|
|
|
|||
|
|
# 将 GF 匹配模式映射为前端使用的 tags 字段
|
|||
|
|
tags = serializers.ListField(
|
|||
|
|
child=serializers.CharField(),
|
|||
|
|
source='matched_gf_patterns',
|
|||
|
|
read_only=True,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
class Meta:
|
|||
|
|
model = Endpoint
|
|||
|
|
fields = [
|
|||
|
|
'id',
|
|||
|
|
'url',
|
|||
|
|
'location',
|
|||
|
|
'status_code',
|
|||
|
|
'title',
|
|||
|
|
'content_length',
|
|||
|
|
'content_type',
|
|||
|
|
'webserver',
|
|||
|
|
'body_preview',
|
|||
|
|
'tech',
|
|||
|
|
'vhost',
|
|||
|
|
'tags',
|
|||
|
|
'discovered_at',
|
|||
|
|
]
|
|||
|
|
read_only_fields = fields
|
|||
|
|
|
|||
|
|
|
|||
|
|
class DirectorySerializer(serializers.ModelSerializer):
|
|||
|
|
"""目录序列化器"""
|
|||
|
|
|
|||
|
|
website_url = serializers.CharField(source='website.url', read_only=True)
|
|||
|
|
discovered_at = serializers.DateTimeField(read_only=True)
|
|||
|
|
|
|||
|
|
class Meta:
|
|||
|
|
model = Directory
|
|||
|
|
fields = [
|
|||
|
|
'id',
|
|||
|
|
'url',
|
|||
|
|
'status',
|
|||
|
|
'content_length',
|
|||
|
|
'words',
|
|||
|
|
'lines',
|
|||
|
|
'content_type',
|
|||
|
|
'duration',
|
|||
|
|
'website_url',
|
|||
|
|
'discovered_at',
|
|||
|
|
]
|
|||
|
|
read_only_fields = fields
|
|||
|
|
|
|||
|
|
|
|||
|
|
class IPAddressAggregatedSerializer(serializers.Serializer):
|
|||
|
|
"""
|
|||
|
|
IP 地址聚合序列化器
|
|||
|
|
|
|||
|
|
基于 HostPortMapping 模型,按 IP 聚合显示:
|
|||
|
|
- ip: IP 地址
|
|||
|
|
- hosts: 该 IP 关联的所有主机名列表
|
|||
|
|
- ports: 该 IP 关联的所有端口列表
|
|||
|
|
- discovered_at: 首次发现时间
|
|||
|
|
"""
|
|||
|
|
ip = serializers.IPAddressField(read_only=True)
|
|||
|
|
hosts = serializers.ListField(child=serializers.CharField(), read_only=True)
|
|||
|
|
ports = serializers.ListField(child=serializers.IntegerField(), read_only=True)
|
|||
|
|
discovered_at = serializers.DateTimeField(read_only=True)
|
|||
|
|
|
|||
|
|
|
|||
|
|
# ==================== 快照序列化器 ====================
|
|||
|
|
|
|||
|
|
class SubdomainSnapshotSerializer(serializers.ModelSerializer):
|
|||
|
|
"""子域名快照序列化器(用于扫描历史)"""
|
|||
|
|
|
|||
|
|
class Meta:
|
|||
|
|
model = SubdomainSnapshot
|
|||
|
|
fields = ['id', 'name', 'discovered_at']
|
|||
|
|
read_only_fields = fields
|
|||
|
|
|
|||
|
|
|
|||
|
|
class WebsiteSnapshotSerializer(serializers.ModelSerializer):
|
|||
|
|
"""网站快照序列化器(用于扫描历史)"""
|
|||
|
|
|
|||
|
|
subdomain_name = serializers.CharField(source='subdomain.name', read_only=True)
|
|||
|
|
webserver = serializers.CharField(source='web_server', read_only=True) # 映射字段名
|
|||
|
|
status_code = serializers.IntegerField(source='status', read_only=True) # 映射字段名
|
|||
|
|
|
|||
|
|
class Meta:
|
|||
|
|
model = WebsiteSnapshot
|
|||
|
|
fields = [
|
|||
|
|
'id',
|
|||
|
|
'url',
|
|||
|
|
'location',
|
|||
|
|
'title',
|
|||
|
|
'webserver', # 使用映射后的字段名
|
|||
|
|
'content_type',
|
|||
|
|
'status_code', # 使用映射后的字段名
|
|||
|
|
'content_length',
|
|||
|
|
'body_preview',
|
|||
|
|
'tech',
|
|||
|
|
'vhost',
|
|||
|
|
'subdomain_name',
|
|||
|
|
'discovered_at',
|
|||
|
|
]
|
|||
|
|
read_only_fields = fields
|
|||
|
|
|
|||
|
|
|
|||
|
|
class DirectorySnapshotSerializer(serializers.ModelSerializer):
|
|||
|
|
"""目录快照序列化器(用于扫描历史)"""
|
|||
|
|
|
|||
|
|
# DirectorySnapshot 当前不再关联 Website,这里暂时将 website_url 映射为自身的 url,保证字段兼容
|
|||
|
|
website_url = serializers.CharField(source='url', read_only=True)
|
|||
|
|
|
|||
|
|
class Meta:
|
|||
|
|
model = DirectorySnapshot
|
|||
|
|
fields = [
|
|||
|
|
'id',
|
|||
|
|
'url',
|
|||
|
|
'status',
|
|||
|
|
'content_length',
|
|||
|
|
'words',
|
|||
|
|
'lines',
|
|||
|
|
'content_type',
|
|||
|
|
'duration',
|
|||
|
|
'website_url',
|
|||
|
|
'discovered_at',
|
|||
|
|
]
|
|||
|
|
read_only_fields = fields
|
|||
|
|
|
|||
|
|
|
|||
|
|
class EndpointSnapshotSerializer(serializers.ModelSerializer):
|
|||
|
|
"""端点快照序列化器(用于扫描历史)"""
|
|||
|
|
|
|||
|
|
# 将 GF 匹配模式映射为前端使用的 tags 字段
|
|||
|
|
tags = serializers.ListField(
|
|||
|
|
child=serializers.CharField(),
|
|||
|
|
source='matched_gf_patterns',
|
|||
|
|
read_only=True,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
class Meta:
|
|||
|
|
model = EndpointSnapshot
|
|||
|
|
fields = [
|
|||
|
|
'id',
|
|||
|
|
'url',
|
|||
|
|
'host',
|
|||
|
|
'location',
|
|||
|
|
'title',
|
|||
|
|
'webserver',
|
|||
|
|
'content_type',
|
|||
|
|
'status_code',
|
|||
|
|
'content_length',
|
|||
|
|
'body_preview',
|
|||
|
|
'tech',
|
|||
|
|
'vhost',
|
|||
|
|
'tags',
|
|||
|
|
'discovered_at',
|
|||
|
|
]
|
|||
|
|
read_only_fields = fields
|