mirror of
https://github.com/yyhuni/xingrin.git
synced 2026-02-06 14:43:11 +08:00
- Consolidate common migrations into dedicated common app module - Remove asset search materialized view migration (0002) and simplify migration structure - Reorganize target detail page with new overview and settings sub-routes - Add target overview component displaying key asset information - Add target settings component for configuration management - Enhance scan history UI with improved data table and column definitions - Update scheduled scan dialog with better form handling - Refactor target service with improved API integration - Update scan hooks (use-scans, use-scheduled-scans) with better state management - Add internationalization strings for new target management features - Update Docker initialization and startup scripts for new app structure - Bump Django to 5.2.7 and update dependencies in requirements.txt - Add WeChat group contact information to README - Improve UI tabs component with better accessibility and styling
214 lines
14 KiB
Python
214 lines
14 KiB
Python
# Generated by Django 5.2.7 on 2026-01-06 00:55
|
||
|
||
from django.db import migrations, models
|
||
|
||
|
||
class Migration(migrations.Migration):
|
||
|
||
initial = True
|
||
|
||
dependencies = [
|
||
]
|
||
|
||
operations = [
|
||
migrations.CreateModel(
|
||
name='NucleiTemplateRepo',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('name', models.CharField(help_text='仓库名称,用于前端展示和配置引用', max_length=200, unique=True)),
|
||
('repo_url', models.CharField(help_text='Git 仓库地址', max_length=500)),
|
||
('local_path', models.CharField(blank=True, default='', help_text='本地工作目录绝对路径', max_length=500)),
|
||
('commit_hash', models.CharField(blank=True, default='', help_text='最后同步的 Git commit hash,用于 Worker 版本校验', max_length=40)),
|
||
('last_synced_at', models.DateTimeField(blank=True, help_text='最后一次成功同步时间', null=True)),
|
||
('created_at', models.DateTimeField(auto_now_add=True, help_text='创建时间')),
|
||
('updated_at', models.DateTimeField(auto_now=True, help_text='更新时间')),
|
||
],
|
||
options={
|
||
'verbose_name': 'Nuclei 模板仓库',
|
||
'verbose_name_plural': 'Nuclei 模板仓库',
|
||
'db_table': 'nuclei_template_repo',
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name='ARLFingerprint',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('name', models.CharField(help_text='指纹名称', max_length=300, unique=True)),
|
||
('rule', models.TextField(help_text='匹配规则表达式')),
|
||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||
],
|
||
options={
|
||
'verbose_name': 'ARL 指纹',
|
||
'verbose_name_plural': 'ARL 指纹',
|
||
'db_table': 'arl_fingerprint',
|
||
'ordering': ['-created_at'],
|
||
'indexes': [models.Index(fields=['name'], name='arl_fingerp_name_c3a305_idx'), models.Index(fields=['-created_at'], name='arl_fingerp_created_ed1060_idx')],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name='EholeFingerprint',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('cms', models.CharField(help_text='产品/CMS名称', max_length=200)),
|
||
('method', models.CharField(default='keyword', help_text='匹配方式', max_length=200)),
|
||
('location', models.CharField(default='body', help_text='匹配位置', max_length=200)),
|
||
('keyword', models.JSONField(default=list, help_text='关键词列表')),
|
||
('is_important', models.BooleanField(default=False, help_text='是否重点资产')),
|
||
('type', models.CharField(blank=True, default='-', help_text='分类', max_length=100)),
|
||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||
],
|
||
options={
|
||
'verbose_name': 'EHole 指纹',
|
||
'verbose_name_plural': 'EHole 指纹',
|
||
'db_table': 'ehole_fingerprint',
|
||
'ordering': ['-created_at'],
|
||
'indexes': [models.Index(fields=['cms'], name='ehole_finge_cms_72ca2c_idx'), models.Index(fields=['method'], name='ehole_finge_method_17f0db_idx'), models.Index(fields=['location'], name='ehole_finge_locatio_7bb82b_idx'), models.Index(fields=['type'], name='ehole_finge_type_ca2bce_idx'), models.Index(fields=['is_important'], name='ehole_finge_is_impo_d56e64_idx'), models.Index(fields=['-created_at'], name='ehole_finge_created_d862b0_idx')],
|
||
'constraints': [models.UniqueConstraint(fields=('cms', 'method', 'location'), name='unique_ehole_fingerprint')],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name='FingerPrintHubFingerprint',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('fp_id', models.CharField(help_text='指纹ID', max_length=200, unique=True)),
|
||
('name', models.CharField(help_text='指纹名称', max_length=300)),
|
||
('author', models.CharField(blank=True, default='', help_text='作者', max_length=200)),
|
||
('tags', models.CharField(blank=True, default='', help_text='标签', max_length=500)),
|
||
('severity', models.CharField(blank=True, default='info', help_text='严重程度', max_length=50)),
|
||
('metadata', models.JSONField(blank=True, default=dict, help_text='元数据')),
|
||
('http', models.JSONField(default=list, help_text='HTTP 匹配规则')),
|
||
('source_file', models.CharField(blank=True, default='', help_text='来源文件', max_length=500)),
|
||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||
],
|
||
options={
|
||
'verbose_name': 'FingerPrintHub 指纹',
|
||
'verbose_name_plural': 'FingerPrintHub 指纹',
|
||
'db_table': 'fingerprinthub_fingerprint',
|
||
'ordering': ['-created_at'],
|
||
'indexes': [models.Index(fields=['fp_id'], name='fingerprint_fp_id_df467f_idx'), models.Index(fields=['name'], name='fingerprint_name_95b6fb_idx'), models.Index(fields=['author'], name='fingerprint_author_80f54b_idx'), models.Index(fields=['severity'], name='fingerprint_severit_f70422_idx'), models.Index(fields=['-created_at'], name='fingerprint_created_bec16c_idx')],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name='FingersFingerprint',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('name', models.CharField(help_text='指纹名称', max_length=300, unique=True)),
|
||
('link', models.URLField(blank=True, default='', help_text='相关链接', max_length=500)),
|
||
('rule', models.JSONField(default=list, help_text='匹配规则数组')),
|
||
('tag', models.JSONField(default=list, help_text='标签数组')),
|
||
('focus', models.BooleanField(default=False, help_text='是否重点关注')),
|
||
('default_port', models.JSONField(blank=True, default=list, help_text='默认端口数组')),
|
||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||
],
|
||
options={
|
||
'verbose_name': 'Fingers 指纹',
|
||
'verbose_name_plural': 'Fingers 指纹',
|
||
'db_table': 'fingers_fingerprint',
|
||
'ordering': ['-created_at'],
|
||
'indexes': [models.Index(fields=['name'], name='fingers_fin_name_952de0_idx'), models.Index(fields=['link'], name='fingers_fin_link_4c6b7f_idx'), models.Index(fields=['focus'], name='fingers_fin_focus_568c7f_idx'), models.Index(fields=['-created_at'], name='fingers_fin_created_46fc91_idx')],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name='GobyFingerprint',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('name', models.CharField(help_text='产品名称', max_length=300, unique=True)),
|
||
('logic', models.CharField(help_text='逻辑表达式', max_length=500)),
|
||
('rule', models.JSONField(default=list, help_text='规则数组')),
|
||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||
],
|
||
options={
|
||
'verbose_name': 'Goby 指纹',
|
||
'verbose_name_plural': 'Goby 指纹',
|
||
'db_table': 'goby_fingerprint',
|
||
'ordering': ['-created_at'],
|
||
'indexes': [models.Index(fields=['name'], name='goby_finger_name_82084c_idx'), models.Index(fields=['logic'], name='goby_finger_logic_a63226_idx'), models.Index(fields=['-created_at'], name='goby_finger_created_50e000_idx')],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name='ScanEngine',
|
||
fields=[
|
||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||
('name', models.CharField(help_text='引擎名称', max_length=200, unique=True)),
|
||
('configuration', models.CharField(blank=True, default='', help_text='引擎配置,yaml 格式', max_length=10000)),
|
||
('created_at', models.DateTimeField(auto_now_add=True, help_text='创建时间')),
|
||
('updated_at', models.DateTimeField(auto_now=True, help_text='更新时间')),
|
||
],
|
||
options={
|
||
'verbose_name': '扫描引擎',
|
||
'verbose_name_plural': '扫描引擎',
|
||
'db_table': 'scan_engine',
|
||
'ordering': ['-created_at'],
|
||
'indexes': [models.Index(fields=['-created_at'], name='scan_engine_created_da4870_idx')],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name='WappalyzerFingerprint',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('name', models.CharField(help_text='应用名称', max_length=300, unique=True)),
|
||
('cats', models.JSONField(default=list, help_text='分类 ID 数组')),
|
||
('cookies', models.JSONField(blank=True, default=dict, help_text='Cookie 检测规则')),
|
||
('headers', models.JSONField(blank=True, default=dict, help_text='HTTP Header 检测规则')),
|
||
('script_src', models.JSONField(blank=True, default=list, help_text='脚本 URL 正则数组')),
|
||
('js', models.JSONField(blank=True, default=list, help_text='JavaScript 变量检测规则')),
|
||
('implies', models.JSONField(blank=True, default=list, help_text='依赖关系数组')),
|
||
('meta', models.JSONField(blank=True, default=dict, help_text='HTML meta 标签检测规则')),
|
||
('html', models.JSONField(blank=True, default=list, help_text='HTML 内容正则数组')),
|
||
('description', models.TextField(blank=True, default='', help_text='应用描述')),
|
||
('website', models.URLField(blank=True, default='', help_text='官网链接', max_length=500)),
|
||
('cpe', models.CharField(blank=True, default='', help_text='CPE 标识符', max_length=300)),
|
||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||
],
|
||
options={
|
||
'verbose_name': 'Wappalyzer 指纹',
|
||
'verbose_name_plural': 'Wappalyzer 指纹',
|
||
'db_table': 'wappalyzer_fingerprint',
|
||
'ordering': ['-created_at'],
|
||
'indexes': [models.Index(fields=['name'], name='wappalyzer__name_63c669_idx'), models.Index(fields=['website'], name='wappalyzer__website_88de1c_idx'), models.Index(fields=['cpe'], name='wappalyzer__cpe_30c761_idx'), models.Index(fields=['-created_at'], name='wappalyzer__created_8e6c21_idx')],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name='Wordlist',
|
||
fields=[
|
||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||
('name', models.CharField(help_text='字典名称,唯一', max_length=200, unique=True)),
|
||
('description', models.CharField(blank=True, default='', help_text='字典描述', max_length=200)),
|
||
('file_path', models.CharField(help_text='后端保存的字典文件绝对路径', max_length=500)),
|
||
('file_size', models.BigIntegerField(default=0, help_text='文件大小(字节)')),
|
||
('line_count', models.IntegerField(default=0, help_text='字典行数')),
|
||
('file_hash', models.CharField(blank=True, default='', help_text='文件 SHA-256 哈希,用于缓存校验', max_length=64)),
|
||
('created_at', models.DateTimeField(auto_now_add=True, help_text='创建时间')),
|
||
('updated_at', models.DateTimeField(auto_now=True, help_text='更新时间')),
|
||
],
|
||
options={
|
||
'verbose_name': '字典文件',
|
||
'verbose_name_plural': '字典文件',
|
||
'db_table': 'wordlist',
|
||
'ordering': ['-created_at'],
|
||
'indexes': [models.Index(fields=['-created_at'], name='wordlist_created_4afb02_idx')],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name='WorkerNode',
|
||
fields=[
|
||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||
('name', models.CharField(help_text='节点名称', max_length=100)),
|
||
('ip_address', models.GenericIPAddressField(help_text='IP 地址(本地节点为 127.0.0.1)')),
|
||
('ssh_port', models.IntegerField(default=22, help_text='SSH 端口')),
|
||
('username', models.CharField(default='root', help_text='SSH 用户名', max_length=50)),
|
||
('password', models.CharField(blank=True, default='', help_text='SSH 密码', max_length=200)),
|
||
('is_local', models.BooleanField(default=False, help_text='是否为本地节点(Docker 容器内)')),
|
||
('status', models.CharField(choices=[('pending', '待部署'), ('deploying', '部署中'), ('online', '在线'), ('offline', '离线'), ('updating', '更新中'), ('outdated', '版本过低')], default='pending', help_text='状态: pending/deploying/online/offline', max_length=20)),
|
||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||
('updated_at', models.DateTimeField(auto_now=True)),
|
||
],
|
||
options={
|
||
'verbose_name': 'Worker 节点',
|
||
'db_table': 'worker_node',
|
||
'ordering': ['-created_at'],
|
||
'constraints': [models.UniqueConstraint(condition=models.Q(('is_local', False)), fields=('ip_address',), name='unique_remote_worker_ip'), models.UniqueConstraint(fields=('name',), name='unique_worker_name')],
|
||
},
|
||
),
|
||
]
|