mirror of
https://github.com/CyberSecurityUP/NeuroSploit.git
synced 2026-06-30 16:45:29 +02:00
v3.3.0 GUI dashboard + reports + model expansion + root fix
Engine:
- Fix: inject IS_SANDBOX=1 so Claude Code's --dangerously-skip-permissions
works under root (real backend runs were exiting rc=1 immediately)
- models: expand to 40 models / 13 providers, tagged CLI vs API
(NVIDIA NIM, DeepSeek, Mistral, Qwen/DashScope, Groq, Together, OpenRouter,
Ollama, Gemini) — Qwen/DeepSeek/Llama usable via API
- backends: on_start callback surfaces the exact argv ("what runs behind it")
- orchestrator: require a Playwright screenshot per confirmed finding; collect
results/activity.json; auto-generate reports after a run
- report.py: HTML always + PDF via Typst engine (.typ source emitted too)
Web dashboard (webgui/, stdlib only — no npm/build):
- Sidebar dashboard (PentAGI-style): Run / Agents / Insights / Reports / Settings
- Multi-target runs; live execution console + per-task activity; finding cards
with screenshots; backend+provider+model pickers (CLI & API)
- Agents tab: browse 213 + add new .md agents from the UI
- Insights: interactive RL-weight + severity charts
- Reports: download/preview PDF + HTML
- Settings/API: execution mode, per-provider API keys, orchestrator, verbosity
- Endpoints: /api/agents (GET/POST), /api/rl, /api/config, /api/reports,
/reports/* + /shots/* static serving
Cleanup: retire replaced web stack (frontend React, FastAPI backend, core
orchestration, old test) to legacy/. Active engine + GUI are fully standalone.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Executable
+1
@@ -0,0 +1 @@
|
||||
# Services package
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
"""
|
||||
NeuroSploit v3 - Report Service
|
||||
|
||||
Handles automatic report generation on scan completion/stop.
|
||||
"""
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select
|
||||
|
||||
from backend.models import Scan, Report, Vulnerability
|
||||
from backend.core.report_engine.generator import ReportGenerator
|
||||
from backend.api.websocket import manager as ws_manager
|
||||
|
||||
|
||||
class ReportService:
|
||||
"""Service for automatic report generation"""
|
||||
|
||||
def __init__(self, db: AsyncSession):
|
||||
self.db = db
|
||||
self.generator = ReportGenerator()
|
||||
|
||||
async def auto_generate_report(
|
||||
self,
|
||||
scan_id: str,
|
||||
is_partial: bool = False,
|
||||
format: str = "html"
|
||||
) -> Report:
|
||||
"""
|
||||
Automatically generate a report for a scan.
|
||||
|
||||
Args:
|
||||
scan_id: The scan ID to generate report for
|
||||
is_partial: True if scan was stopped/incomplete
|
||||
format: Report format (html, pdf, json)
|
||||
|
||||
Returns:
|
||||
The generated Report model instance
|
||||
"""
|
||||
# Get scan
|
||||
scan_result = await self.db.execute(select(Scan).where(Scan.id == scan_id))
|
||||
scan = scan_result.scalar_one_or_none()
|
||||
|
||||
if not scan:
|
||||
raise ValueError(f"Scan {scan_id} not found")
|
||||
|
||||
# Get vulnerabilities
|
||||
vulns_result = await self.db.execute(
|
||||
select(Vulnerability).where(Vulnerability.scan_id == scan_id)
|
||||
)
|
||||
vulnerabilities = vulns_result.scalars().all()
|
||||
|
||||
# Generate title
|
||||
if is_partial:
|
||||
title = f"Partial Report - {scan.name or 'Unnamed Scan'}"
|
||||
else:
|
||||
title = f"Security Assessment Report - {scan.name or 'Unnamed Scan'}"
|
||||
|
||||
# Generate report
|
||||
try:
|
||||
report_path, executive_summary = await self.generator.generate(
|
||||
scan=scan,
|
||||
vulnerabilities=vulnerabilities,
|
||||
format=format,
|
||||
title=title,
|
||||
include_executive_summary=True,
|
||||
include_poc=True,
|
||||
include_remediation=True
|
||||
)
|
||||
|
||||
# Create report record
|
||||
report = Report(
|
||||
scan_id=scan_id,
|
||||
title=title,
|
||||
format=format,
|
||||
file_path=str(report_path) if report_path else None,
|
||||
executive_summary=executive_summary,
|
||||
auto_generated=True,
|
||||
is_partial=is_partial
|
||||
)
|
||||
self.db.add(report)
|
||||
await self.db.commit()
|
||||
await self.db.refresh(report)
|
||||
|
||||
# Broadcast report generated event
|
||||
await ws_manager.broadcast_report_generated(scan_id, report.to_dict())
|
||||
await ws_manager.broadcast_log(
|
||||
scan_id,
|
||||
"info",
|
||||
f"Report auto-generated: {title}"
|
||||
)
|
||||
|
||||
return report
|
||||
|
||||
except Exception as e:
|
||||
await ws_manager.broadcast_log(
|
||||
scan_id,
|
||||
"error",
|
||||
f"Failed to auto-generate report: {str(e)}"
|
||||
)
|
||||
raise
|
||||
|
||||
|
||||
async def auto_generate_report(db: AsyncSession, scan_id: str, is_partial: bool = False) -> Report:
|
||||
"""Helper function to auto-generate a report"""
|
||||
service = ReportService(db)
|
||||
return await service.auto_generate_report(scan_id, is_partial)
|
||||
+1105
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user