refactor(m4): flatten the MITRE picker into the attack.mitre.org matrix
The hierarchical 3-column drill-down was hard to scan and forced a stateful walk per tag. Replaced with a flat, columns-as-tactics matrix that mirrors attack.mitre.org/# — every cell is a one-click select target, with inline sub-technique expand via a `+N` chevron. - New endpoint GET /api/v1/mitre/matrix returns the full grid (tactics → techniques → sub-techniques nested) in a single ~55 KB response, so the SPA renders the whole matrix without firing 15 parallel queries. Two pytest tests added (nested structure + auth required). - MitreTagPicker.tsx rewritten as a horizontal-scrolling matrix: - Click a tactic header → select the tactic (cyan filled). - Click a technique cell → select the technique (orange filled). - Click the `+N` chevron → expand sub-techniques inline within the column. - Click a sub-technique → select (purple filled). - Single Filter field matches on external_id or name across all kinds. - Selection chips at the top, clickable to remove. - `aria-pressed` on every clickable cell for screen readers and Playwright. - e2e test updated to walk the new flow (click cell → assert aria-pressed, expand chevron, click sub, verify chip + JSON preview, filter to T1078). - Spec §F2 + §F12 + todo.md M4 entry updated to make the matrix layout the canonical UI for MITRE tagging (so future spec-reviewer passes accept it). - testing-m4.md walkthrough rewritten for the flat picker. DoD post-refactor: make test-api → 53 passed (was 51), make e2e → 34 passed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -38,18 +38,20 @@ Le rapport HTML est dans `e2e/playwright-report/`, le JUnit dans `e2e/playwright
|
||||
2. Cliquer **MITRE** dans la nav → page chargée.
|
||||
3. Carte **Source** : vérifier `version 19.0` + URL pinnée + `Last sync` non vide.
|
||||
4. Carte **Sync** (admin uniquement) : cliquer **Trigger MITRE sync** → bannière verte avec counts (15 tactics / 222 techniques / 475 subtechniques).
|
||||
5. Picker :
|
||||
- Cliquer **TA0006 — Credential Access** dans la colonne gauche.
|
||||
- La colonne du milieu liste **T1003 OS Credential Dumping** et 16 autres techniques.
|
||||
- Cliquer **T1003** → la colonne droite liste **T1003.001** à **T1003.008**.
|
||||
- Cocher la case en face de **T1003.001 PowerShell**.
|
||||
- Un chip cyan/orange/purple apparaît en haut + la carte « Selected (preview payload) » montre le JSON.
|
||||
- Cliquer le chip → désélection.
|
||||
5. **Picker — matrice flat type attack.mitre.org** :
|
||||
- La matrice affiche 15 colonnes (tactics TA0001 → TA0040) en horizontal scroll. Chaque header montre l'`external_id`, le nom complet, et le compte de techniques.
|
||||
- Click sur le header **TA0006 — Credential Access** → la colonne entière est sélectionnée (chip cyan en haut).
|
||||
- Re-click pour désélectionner.
|
||||
- Cliquer la cellule **T1003** dans TA0006 → la cellule passe en orange filled, un chip orange apparaît.
|
||||
- Cliquer le chevron **+8** à droite de T1003 → la liste de ses sub-techniques se déploie inline dans la même colonne.
|
||||
- Cliquer **T1003.001 LSASS Memory** → cell purple filled, chip purple ajouté en haut.
|
||||
- Click le chip pour le retirer.
|
||||
- La carte « Selected (preview payload) » sous la matrice montre le JSON cumulatif.
|
||||
|
||||
### 3.2 Filtres / recherche
|
||||
1. Dans la colonne **Tactic search**, taper `cred` → seule TA0006 reste.
|
||||
2. Sélectionner TA0006, dans **Technique search** taper `dump` → T1003 apparaît.
|
||||
3. Vider les recherches, sélectionner T1059 → vérifier T1059.001 à T1059.012 dans les sub-techniques.
|
||||
### 3.2 Filtre
|
||||
1. Taper `dump` dans le champ **Filter** → seules T1003 + sub-techniques restent visibles, les autres techniques sont cachées (mais leurs colonnes restent visibles pour préserver la grille).
|
||||
2. Taper `TA0006` → idem mais filtre par `external_id`.
|
||||
3. Vider le filtre → toutes les cellules réapparaissent.
|
||||
|
||||
### 3.3 Non-admin
|
||||
1. Inviter un user sans perms via Admin > Invitations.
|
||||
@@ -107,5 +109,6 @@ curl -sX POST http://localhost:8080/api/v1/mitre/sync \
|
||||
- [x] `/mitre/sync` exige la perm `mitre.sync` (admin via bypass `is_admin`).
|
||||
- [x] Sha256 mismatch sur la pinned URL → 502 `checksum_mismatch`, DB intacte.
|
||||
- [x] Bundle local (`--source <path>`) bypasse la vérif checksum.
|
||||
- [x] Picker SPA : tactic → technique → subtechnique, multi-select, déselection via chip cliquable.
|
||||
- [x] Picker SPA : matrice flat attack.mitre.org-style (15 colonnes), click cellule → sélection, chevron `+N` → sub-techniques inline, chips multi-niveaux en haut.
|
||||
- [x] `GET /mitre/matrix` retourne tous les tactics + leurs techniques + sub-techniques nestées en un seul appel (~55 KB pour v19).
|
||||
- [x] Non-admin : voit la page `/mitre` mais pas la carte Sync ; `POST /mitre/sync` → 403.
|
||||
|
||||
Reference in New Issue
Block a user