Skip to content

Commit e77c5c7

Browse files
author
githubnull
committed
feat: 添加扫描配置管理功能和引导式参数编辑器
- 后端: 新增扫描配置预设API、模型和服务(ScanPreset, ScanPresetDatabase, scanPresetService) - 前端: 新增扫描配置管理页面(默认配置、常用配置、历史配置) - 前端: 新增引导式参数编辑器组件(GuidedParamEditor, GuidedParamEditorDialog) - 前端: 新增HTTP报文格式解析器和参数定义工具 - BurpSuite: 引导式编辑弹窗增加配置名称和描述显示 - BurpSuite: 优化编辑弹窗尺寸和描述文本样式 - 双击已选参数可编辑功能 - 无描述时显示占位文本(无描述)
1 parent 5356a96 commit e77c5c7

33 files changed

Lines changed: 7012 additions & 15 deletions
Lines changed: 324 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,324 @@
1+
"""
2+
扫描配置预设API
3+
提供Web端扫描配置预设的管理接口
4+
"""
5+
import logging
6+
from typing import Optional
7+
8+
from fastapi import APIRouter, HTTPException, Query, Request, Depends
9+
from fastapi import status as http_status
10+
11+
from model.BaseResponseMsg import BaseResponseMsg
12+
from model.ScanPreset import (
13+
ScanPreset, ScanPresetCreate, ScanPresetUpdate, PresetType
14+
)
15+
from service.scanPresetService import scanPresetService
16+
from utils.auth import get_current_user
17+
18+
logger = logging.getLogger(__name__)
19+
20+
router = APIRouter(prefix="/scan-preset")
21+
22+
23+
@router.get("/list", summary="获取所有预设配置列表")
24+
async def get_all_presets(
25+
include_inactive: bool = Query(False, description="是否包含未激活的配置"),
26+
current_user: dict = Depends(get_current_user)
27+
):
28+
"""获取所有预设配置,包括默认配置、常用配置和历史配置"""
29+
try:
30+
result = scanPresetService.get_all_presets(include_inactive)
31+
return BaseResponseMsg(
32+
success=True,
33+
code=http_status.HTTP_200_OK,
34+
msg="获取成功",
35+
data={
36+
"presets": [p.model_dump() for p in result.presets],
37+
"total": result.total,
38+
"default_preset": result.default_preset.model_dump() if result.default_preset else None
39+
}
40+
)
41+
except Exception as e:
42+
logger.error(f"Failed to get presets: {e}")
43+
raise HTTPException(status_code=500, detail=str(e))
44+
45+
46+
@router.get("/config-options", summary="获取配置选项(用于下拉菜单)")
47+
async def get_config_options(
48+
current_user: dict = Depends(get_current_user)
49+
):
50+
"""
51+
获取所有可选配置,用于下拉菜单
52+
返回:默认配置、常用配置列表、历史配置列表
53+
"""
54+
try:
55+
result = scanPresetService.get_all_config_options()
56+
return BaseResponseMsg(
57+
success=True,
58+
code=http_status.HTTP_200_OK,
59+
msg="获取成功",
60+
data={
61+
"default": result["default"].model_dump() if result["default"] else None,
62+
"presets": [p.model_dump() for p in result["presets"]],
63+
"history": [p.model_dump() for p in result["history"]]
64+
}
65+
)
66+
except Exception as e:
67+
logger.error(f"Failed to get config options: {e}")
68+
raise HTTPException(status_code=500, detail=str(e))
69+
70+
71+
@router.get("/default", summary="获取默认配置")
72+
async def get_default_preset(
73+
current_user: dict = Depends(get_current_user)
74+
):
75+
"""获取默认扫描配置"""
76+
try:
77+
preset = scanPresetService.get_default_preset()
78+
if not preset:
79+
return BaseResponseMsg(
80+
success=False,
81+
code=http_status.HTTP_404_NOT_FOUND,
82+
msg="默认配置不存在",
83+
data=None
84+
)
85+
return BaseResponseMsg(
86+
success=True,
87+
code=http_status.HTTP_200_OK,
88+
msg="获取成功",
89+
data=preset.model_dump()
90+
)
91+
except Exception as e:
92+
logger.error(f"Failed to get default preset: {e}")
93+
raise HTTPException(status_code=500, detail=str(e))
94+
95+
96+
@router.put("/default", summary="更新默认配置")
97+
async def update_default_preset(
98+
options: dict,
99+
current_user: dict = Depends(get_current_user)
100+
):
101+
"""更新默认扫描配置的选项"""
102+
try:
103+
preset = scanPresetService.update_default_preset(options)
104+
if not preset:
105+
return BaseResponseMsg(
106+
success=False,
107+
code=http_status.HTTP_404_NOT_FOUND,
108+
msg="更新失败",
109+
data=None
110+
)
111+
return BaseResponseMsg(
112+
success=True,
113+
code=http_status.HTTP_200_OK,
114+
msg="更新成功",
115+
data=preset.model_dump()
116+
)
117+
except Exception as e:
118+
logger.error(f"Failed to update default preset: {e}")
119+
raise HTTPException(status_code=500, detail=str(e))
120+
121+
122+
@router.get("/presets", summary="获取常用配置列表")
123+
async def get_preset_configs(
124+
current_user: dict = Depends(get_current_user)
125+
):
126+
"""获取常用配置列表"""
127+
try:
128+
presets = scanPresetService.get_preset_configs()
129+
return BaseResponseMsg(
130+
success=True,
131+
code=http_status.HTTP_200_OK,
132+
msg="获取成功",
133+
data={
134+
"presets": [p.model_dump() for p in presets],
135+
"total": len(presets)
136+
}
137+
)
138+
except Exception as e:
139+
logger.error(f"Failed to get preset configs: {e}")
140+
raise HTTPException(status_code=500, detail=str(e))
141+
142+
143+
@router.get("/history", summary="获取历史配置列表")
144+
async def get_history_configs(
145+
limit: int = Query(20, ge=1, le=100, description="返回数量限制"),
146+
current_user: dict = Depends(get_current_user)
147+
):
148+
"""获取历史配置列表"""
149+
try:
150+
presets = scanPresetService.get_history_configs(limit)
151+
return BaseResponseMsg(
152+
success=True,
153+
code=http_status.HTTP_200_OK,
154+
msg="获取成功",
155+
data={
156+
"presets": [p.model_dump() for p in presets],
157+
"total": len(presets)
158+
}
159+
)
160+
except Exception as e:
161+
logger.error(f"Failed to get history configs: {e}")
162+
raise HTTPException(status_code=500, detail=str(e))
163+
164+
165+
@router.get("/{preset_id}", summary="获取指定预设配置")
166+
async def get_preset_by_id(
167+
preset_id: int,
168+
current_user: dict = Depends(get_current_user)
169+
):
170+
"""根据ID获取预设配置"""
171+
try:
172+
preset = scanPresetService.get_preset_by_id(preset_id)
173+
if not preset:
174+
return BaseResponseMsg(
175+
success=False,
176+
code=http_status.HTTP_404_NOT_FOUND,
177+
msg="配置不存在",
178+
data=None
179+
)
180+
return BaseResponseMsg(
181+
success=True,
182+
code=http_status.HTTP_200_OK,
183+
msg="获取成功",
184+
data=preset.model_dump()
185+
)
186+
except Exception as e:
187+
logger.error(f"Failed to get preset by id: {e}")
188+
raise HTTPException(status_code=500, detail=str(e))
189+
190+
191+
@router.post("", summary="创建新的预设配置")
192+
async def create_preset(
193+
data: ScanPresetCreate,
194+
current_user: dict = Depends(get_current_user)
195+
):
196+
"""创建新的预设配置"""
197+
try:
198+
preset = scanPresetService.create_preset(data)
199+
if not preset:
200+
return BaseResponseMsg(
201+
success=False,
202+
code=http_status.HTTP_400_BAD_REQUEST,
203+
msg="创建失败,配置名称可能已存在",
204+
data=None
205+
)
206+
return BaseResponseMsg(
207+
success=True,
208+
code=http_status.HTTP_201_CREATED,
209+
msg="创建成功",
210+
data=preset.model_dump()
211+
)
212+
except Exception as e:
213+
logger.error(f"Failed to create preset: {e}")
214+
raise HTTPException(status_code=500, detail=str(e))
215+
216+
217+
@router.put("/{preset_id}", summary="更新预设配置")
218+
async def update_preset(
219+
preset_id: int,
220+
data: ScanPresetUpdate,
221+
current_user: dict = Depends(get_current_user)
222+
):
223+
"""更新指定的预设配置"""
224+
try:
225+
preset = scanPresetService.update_preset(preset_id, data)
226+
if not preset:
227+
return BaseResponseMsg(
228+
success=False,
229+
code=http_status.HTTP_404_NOT_FOUND,
230+
msg="更新失败,配置不存在或名称冲突",
231+
data=None
232+
)
233+
return BaseResponseMsg(
234+
success=True,
235+
code=http_status.HTTP_200_OK,
236+
msg="更新成功",
237+
data=preset.model_dump()
238+
)
239+
except Exception as e:
240+
logger.error(f"Failed to update preset: {e}")
241+
raise HTTPException(status_code=500, detail=str(e))
242+
243+
244+
@router.delete("/{preset_id}", summary="删除预设配置")
245+
async def delete_preset(
246+
preset_id: int,
247+
current_user: dict = Depends(get_current_user)
248+
):
249+
"""删除指定的预设配置"""
250+
try:
251+
success = scanPresetService.delete_preset(preset_id)
252+
if not success:
253+
return BaseResponseMsg(
254+
success=False,
255+
code=http_status.HTTP_400_BAD_REQUEST,
256+
msg="删除失败,配置不存在或为默认配置",
257+
data=None
258+
)
259+
return BaseResponseMsg(
260+
success=True,
261+
code=http_status.HTTP_200_OK,
262+
msg="删除成功",
263+
data=None
264+
)
265+
except Exception as e:
266+
logger.error(f"Failed to delete preset: {e}")
267+
raise HTTPException(status_code=500, detail=str(e))
268+
269+
270+
@router.post("/history", summary="添加到历史记录")
271+
async def add_to_history(
272+
request: Request,
273+
name: str = Query(..., description="配置名称"),
274+
current_user: dict = Depends(get_current_user)
275+
):
276+
"""将配置添加到历史记录"""
277+
try:
278+
body = await request.json()
279+
options = body.get("options", {})
280+
281+
preset = scanPresetService.add_to_history(name, options)
282+
if not preset:
283+
return BaseResponseMsg(
284+
success=False,
285+
code=http_status.HTTP_400_BAD_REQUEST,
286+
msg="添加失败",
287+
data=None
288+
)
289+
return BaseResponseMsg(
290+
success=True,
291+
code=http_status.HTTP_201_CREATED,
292+
msg="添加成功",
293+
data=preset.model_dump()
294+
)
295+
except Exception as e:
296+
logger.error(f"Failed to add to history: {e}")
297+
raise HTTPException(status_code=500, detail=str(e))
298+
299+
300+
@router.post("/{preset_id}/apply", summary="应用预设配置")
301+
async def apply_preset(
302+
preset_id: int,
303+
request: Request,
304+
current_user: dict = Depends(get_current_user)
305+
):
306+
"""应用预设配置到选项,返回合并后的选项"""
307+
try:
308+
body = await request.json()
309+
base_options = body.get("base_options", {})
310+
311+
result = scanPresetService.apply_preset_to_options(preset_id, base_options)
312+
313+
# 记录使用
314+
scanPresetService.record_preset_usage(preset_id)
315+
316+
return BaseResponseMsg(
317+
success=True,
318+
code=http_status.HTTP_200_OK,
319+
msg="应用成功",
320+
data={"options": result}
321+
)
322+
except Exception as e:
323+
logger.error(f"Failed to apply preset: {e}")
324+
raise HTTPException(status_code=500, detail=str(e))

0 commit comments

Comments
 (0)