Files
rengine/shared/models/scan_engine.py
T
Yogesh Ojha 1498812593 feat: enhance engine management UI and backend
- Updated the engine management UI in `+page.svelte` to improve user experience with new controls for filtering stages, toggling side panels, and managing YAML configurations.
- Introduced new components such as `EngineSummaryBar` and `Resizable` for better layout handling.
- Added clipboard functionality for copying YAML configurations and formatting options.
- Enhanced the backend models in `scan_engine.py` to include a new `PreviewResolved` class for better handling of scan context and parameters.
- Updated presets in `presets.py` to clarify descriptions and improve user understanding of stage settings.
2026-09-02 18:03:52 +05:30

163 lines
4.9 KiB
Python

import uuid
from datetime import datetime
from pydantic import BaseModel
from pydantic import Field as PydanticField
from sqlalchemy import Column
from sqlalchemy.types import JSON, Text
from sqlmodel import Field, SQLModel
from shared.models.scan_context import ScanContextCreate
from shared.utils.datetime import utc_now
class ScanEngine(SQLModel, table=True):
__tablename__ = "scan_engines"
id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True, index=True)
project_id: uuid.UUID = Field(foreign_key="projects.id", index=True)
created_by: uuid.UUID = Field(foreign_key="users.id")
name: str = Field(max_length=200)
description: str | None = Field(default=None, max_length=1000)
intensity: str = Field(default="normal")
global_threads: int = Field(default=30)
global_http_crawl: bool = Field(default=True)
global_headers: list = Field(
default_factory=list, sa_column=Column(JSON, nullable=False)
)
stages: dict = Field(default_factory=dict, sa_column=Column(JSON, nullable=False))
yaml_source: str | None = Field(default=None, sa_column=Column(Text, nullable=True))
tool_options: dict = Field(
default_factory=dict, sa_column=Column(JSON, nullable=False)
)
created_at: datetime = Field(default_factory=utc_now)
updated_at: datetime = Field(default_factory=utc_now)
last_used_at: datetime | None = Field(default=None)
class ScanEngineCreate(BaseModel):
name: str
description: str | None = None
intensity: str = "normal"
global_threads: int = 30
global_http_crawl: bool = True
global_headers: list[str] = PydanticField(default_factory=list)
stages: dict[str, dict] = PydanticField(default_factory=dict)
yaml_source: str | None = None
tool_options: dict[str, str] = PydanticField(default_factory=dict)
class ScanEngineUpdate(BaseModel):
name: str | None = None
description: str | None = None
intensity: str | None = None
global_threads: int | None = None
global_http_crawl: bool | None = None
global_headers: list[str] | None = None
stages: dict[str, dict] | None = None
yaml_source: str | None = None
tool_options: dict[str, str] | None = None
class EngineUsage(BaseModel):
schedules: int = 0
scans: int = 0
class ScanEngineRead(BaseModel):
id: uuid.UUID
project_id: uuid.UUID
created_by: uuid.UUID
name: str
description: str | None
intensity: str
global_threads: int
global_http_crawl: bool
global_headers: list[str]
stages: dict[str, dict]
yaml_source: str | None
tool_options: dict[str, str] = PydanticField(default_factory=dict)
usage: EngineUsage = PydanticField(default_factory=EngineUsage)
created_at: datetime
updated_at: datetime
last_used_at: datetime | None
class StageField(BaseModel):
name: str
title: str
description: str | None = None
type: str
default: object = None
options: list[str] | None = None
minimum: int | None = None
maximum: int | None = None
scale: str | None = None
class StageCatalogEntry(BaseModel):
name: str
title: str
description: str
phase: str
level: int
applies_to: list[str]
tools: list[str]
api_keys: list[str]
requires_api_keys: bool = False
touches_target: bool = True
defaults: dict
fields: list[StageField] = PydanticField(default_factory=list)
class ToolOption(BaseModel):
name: str
label: str
phase: str
example: str
class EnginePreset(BaseModel):
name: str
title: str
description: str
stages: dict[str, dict]
class EngineCatalog(BaseModel):
phases: list[str]
stages: list[StageCatalogEntry]
rate_tools: list[str]
tool_options: list[ToolOption]
presets: list[EnginePreset]
target_types: list[str]
class PreviewResolved(BaseModel):
header_names: list[str] = PydanticField(default_factory=list)
global_threads: int = 30
global_rate_limit_ceiling: int | None = None
per_tool_rate_limits: dict[str, int] = PydanticField(default_factory=dict)
excluded_subdomains: list[str] = PydanticField(default_factory=list)
excluded_paths: list[str] = PydanticField(default_factory=list)
excluded_ips: list[str] = PydanticField(default_factory=list)
included_subdomains: list[str] = PydanticField(default_factory=list)
follow_redirects: bool | None = None
http_protocol: str = "both"
class EnginePreviewResult(BaseModel):
phases: list = PydanticField(default_factory=list)
resolved_stages: dict[str, dict] = PydanticField(default_factory=dict)
resolved: PreviewResolved = PydanticField(default_factory=PreviewResolved)
warnings: list[str] = PydanticField(default_factory=list)
class EnginePreviewRequest(BaseModel):
target_type: str
context_id: uuid.UUID | None = None
context: ScanContextCreate | None = None
intensity: str = "normal"
global_threads: int = 30
stages: dict[str, dict] = PydanticField(default_factory=dict)