feat(rt-import): import Red Team engagement results as validated tests

Backend — POST /tests/import-rt (red_lead + admin):
  Accepts engagement JSON with name/date/description/operator and
  a list of techniques each with mitre_id, result, attack_success,
  platform, notes. Creates one Test per technique directly in
  'validated' state (red + blue validation = approved) bypassing
  the normal workflow. Recalculates technique.status_global for
  all affected techniques. Returns created/skipped summary.

Frontend — /tests/import-rt (new dedicated page):
  - Format reference panel (collapsible) with field descriptions
  - Download template JSON button (generates a filled example)
  - Paste JSON textarea + file upload (.json)
  - Live validation + preview table showing what will be imported
  - Import button with spinner
  - Success / warning / error result display
  Accessible to admin and red_lead only.
  Added to sidebar under Tests > Import RT Results.
This commit is contained in:
kitos
2026-05-29 16:15:35 +02:00
parent 98e0f27172
commit 6021f0801c
5 changed files with 542 additions and 2 deletions
+9
View File
@@ -20,6 +20,7 @@ const TestDetailPage = React.lazy(() => import("./pages/TestDetailPage"));
const TestCatalogPage = React.lazy(() => import("./pages/TestCatalogPage"));
const ValidatedTestsPage = React.lazy(() => import("./pages/ValidatedTestsPage"));
const ReviewQueuePage = React.lazy(() => import("./pages/ReviewQueuePage"));
const ImportRTPage = React.lazy(() => import("./pages/ImportRTPage"));
const ReportsPage = React.lazy(() => import("./pages/ReportsPage"));
const SystemPage = React.lazy(() => import("./pages/SystemPage"));
const UsersPage = React.lazy(() => import("./pages/UsersPage"));
@@ -76,6 +77,14 @@ export default function App() {
<Route path="/tests" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><TestsPage /></Suspense>} />
<Route path="/tests/new" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><TestCreatePage /></Suspense>} />
<Route path="/tests/validated" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><ValidatedTestsPage /></Suspense>} />
<Route
path="/tests/import-rt"
element={
<ProtectedRoute roles={["admin", "red_lead"]}>
<Suspense fallback={<LoadingSpinner text="Loading…" />}><ImportRTPage /></Suspense>
</ProtectedRoute>
}
/>
<Route path="/tests/:testId" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><TestDetailPage /></Suspense>} />
<Route path="/test-catalog" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><TestCatalogPage /></Suspense>} />
<Route path="/test-catalog/:templateId/use" element={<Suspense fallback={<LoadingSpinner text="Loading…" />}><TestCatalogPage /></Suspense>} />