[FIX] Epic C / C1 — correzioni post-verifica flotta (1 major + 5 minor)
Flotta di verifica (14 agenti): sicurezza pulita, fedeltà del dato perfetta (codifica Simon intatta, 0 scostamenti). Corretti i 6 finding confermati: - MAJOR: PolicyController::ensureFrameworkProcedures ora in transazione + SELECT...FOR UPDATE sulla riga org -> no procedure duplicate su fallimento parziale (rollback) o richieste concorrenti. - MINOR: importer idempotente committato application/cli/seed_framework.php (DDL + upsert da nis2_framework_seed.json) -> re-seed riproducibile/versionato (verificato 2 run = 0 duplicati). - MINOR: allineato '92 requisiti' importanti (dato autoritativo Simon) in help.js + nis2_sources.php (era 87, contraddizione interna); coerente '24 requisiti aggiuntivi essenziali' (116-92). - MINOR (UI): troncamento anteprima valutazione sul RAW prima di esc() (no entita HTML spezzate). - MINOR (UI a11y/AGID): modale valutazione con focus iniziale, ripristino focus, focus-trap. Cache-buster ?v=20260623, version 1.18.2, SW nis2-shell-v1.18.2. NB residuo da verificare: data esatta Determinazione 333017/2025 (mese senza giorno) in nis2_sources.php. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
1f2d48df7c
commit
45e6c3599c
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
/**
|
||||
* NIS2 Agile — Importer idempotente del framework canonico (Epic C / C1).
|
||||
* ----------------------------------------------------------------------------
|
||||
* Crea (se mancanti) le tabelle di configurazione cfg_nis2_* (mig.046) e le
|
||||
* popola dal seed autoritativo application/data/nis2_framework_seed.json
|
||||
* (generato dai file docs/simon/*.xlsx — codifica NON variabile).
|
||||
*
|
||||
* Idempotente: CREATE TABLE IF NOT EXISTS + INSERT ... ON DUPLICATE KEY UPDATE.
|
||||
* Rilanciabile senza duplicare né rompere le FK. Pensato per ricreare/riseedare
|
||||
* un ambiente in modo versionato (sostituisce i runner temporanei usa-e-getta).
|
||||
*
|
||||
* Uso (dentro il container app):
|
||||
* docker exec nis2-app php /var/www/nis2-agile/application/cli/seed_framework.php
|
||||
*
|
||||
* NB: solo CLI. DB API via PDO singleton (Database::getInstance()), TLS gestito
|
||||
* dalla config dell'app.
|
||||
*/
|
||||
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
http_response_code(403);
|
||||
exit("Solo da CLI.\n");
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/../config/env.php';
|
||||
require_once __DIR__ . '/../config/database.php';
|
||||
|
||||
$pdo = Database::getInstance();
|
||||
$pdo->exec("SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci");
|
||||
|
||||
$ddl = [
|
||||
"CREATE TABLE IF NOT EXISTS cfg_nis2_ambiti (
|
||||
nist_code VARCHAR(16) NOT NULL, nist_descr TEXT NOT NULL,
|
||||
PRIMARY KEY (nist_code)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
|
||||
"CREATE TABLE IF NOT EXISTS cfg_nis2_procedure (
|
||||
proc_code VARCHAR(16) NOT NULL, proc_descr TEXT NOT NULL,
|
||||
PRIMARY KEY (proc_code)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
|
||||
"CREATE TABLE IF NOT EXISTS cfg_nis2_rischi (
|
||||
risk_code VARCHAR(16) NOT NULL, risk_descr TEXT NOT NULL,
|
||||
PRIMARY KEY (risk_code)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
|
||||
"CREATE TABLE IF NOT EXISTS cfg_nis2_misure (
|
||||
misura_code VARCHAR(16) NOT NULL, nist_code VARCHAR(16) NOT NULL,
|
||||
area_politica VARCHAR(255) NOT NULL, misura_descr TEXT NOT NULL, ord INT NOT NULL,
|
||||
applies_important TINYINT(1) NOT NULL DEFAULT 1, applies_essential TINYINT(1) NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (misura_code), KEY idx_misura_nist (nist_code), KEY idx_misura_ord (ord),
|
||||
CONSTRAINT fk_misura_ambito FOREIGN KEY (nist_code) REFERENCES cfg_nis2_ambiti (nist_code)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
|
||||
"CREATE TABLE IF NOT EXISTS cfg_nis2_requisiti (
|
||||
id INT NOT NULL AUTO_INCREMENT, n INT NULL, misura_code VARCHAR(16) NOT NULL,
|
||||
requisito_code VARCHAR(32) NOT NULL, requisito_descr TEXT NOT NULL,
|
||||
proc_code VARCHAR(16) NULL, risk_code VARCHAR(16) NULL,
|
||||
applies_important TINYINT(1) NOT NULL DEFAULT 0, applies_essential TINYINT(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (id), UNIQUE KEY uq_req (misura_code, requisito_code),
|
||||
KEY idx_req_misura (misura_code), KEY idx_req_proc (proc_code), KEY idx_req_risk (risk_code),
|
||||
CONSTRAINT fk_req_misura FOREIGN KEY (misura_code) REFERENCES cfg_nis2_misure (misura_code),
|
||||
CONSTRAINT fk_req_proc FOREIGN KEY (proc_code) REFERENCES cfg_nis2_procedure (proc_code),
|
||||
CONSTRAINT fk_req_risk FOREIGN KEY (risk_code) REFERENCES cfg_nis2_rischi (risk_code)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
|
||||
];
|
||||
foreach ($ddl as $stmt) {
|
||||
try { $pdo->exec($stmt); }
|
||||
catch (PDOException $e) { if (!in_array($e->errorInfo[1] ?? 0, [1050, 1061], true)) { throw $e; } }
|
||||
}
|
||||
|
||||
$seedPath = __DIR__ . '/../data/nis2_framework_seed.json';
|
||||
$seed = json_decode(@file_get_contents($seedPath), true);
|
||||
if (!$seed) { fwrite(STDERR, "SEED non leggibile: $seedPath\n"); exit(1); }
|
||||
|
||||
$pdo->beginTransaction();
|
||||
try {
|
||||
$st = $pdo->prepare("INSERT INTO cfg_nis2_ambiti (nist_code,nist_descr) VALUES (?,?)
|
||||
ON DUPLICATE KEY UPDATE nist_descr=VALUES(nist_descr)");
|
||||
foreach ($seed['ambiti_nist'] as $a) { $st->execute([$a['nist_code'], $a['nist_descr']]); }
|
||||
|
||||
$st = $pdo->prepare("INSERT INTO cfg_nis2_procedure (proc_code,proc_descr) VALUES (?,?)
|
||||
ON DUPLICATE KEY UPDATE proc_descr=VALUES(proc_descr)");
|
||||
foreach ($seed['procedure'] as $p) { $st->execute([$p['proc_code'], $p['proc_descr']]); }
|
||||
|
||||
$st = $pdo->prepare("INSERT INTO cfg_nis2_rischi (risk_code,risk_descr) VALUES (?,?)
|
||||
ON DUPLICATE KEY UPDATE risk_descr=VALUES(risk_descr)");
|
||||
foreach ($seed['rischi'] as $r) { $st->execute([$r['risk_code'], $r['risk_descr']]); }
|
||||
|
||||
$st = $pdo->prepare("INSERT INTO cfg_nis2_misure
|
||||
(misura_code,nist_code,area_politica,misura_descr,ord,applies_important,applies_essential)
|
||||
VALUES (?,?,?,?,?,?,?)
|
||||
ON DUPLICATE KEY UPDATE nist_code=VALUES(nist_code),area_politica=VALUES(area_politica),
|
||||
misura_descr=VALUES(misura_descr),ord=VALUES(ord),
|
||||
applies_important=VALUES(applies_important),applies_essential=VALUES(applies_essential)");
|
||||
foreach ($seed['misure'] as $m) {
|
||||
$st->execute([$m['misura_code'], $m['nist_code'], $m['area_politica'], $m['misura_descr'],
|
||||
$m['ord'], $m['applies_important'], $m['applies_essential']]);
|
||||
}
|
||||
|
||||
$st = $pdo->prepare("INSERT INTO cfg_nis2_requisiti
|
||||
(n,misura_code,requisito_code,requisito_descr,proc_code,risk_code,applies_important,applies_essential)
|
||||
VALUES (?,?,?,?,?,?,?,?)
|
||||
ON DUPLICATE KEY UPDATE n=VALUES(n),requisito_descr=VALUES(requisito_descr),
|
||||
proc_code=VALUES(proc_code),risk_code=VALUES(risk_code),
|
||||
applies_important=VALUES(applies_important),applies_essential=VALUES(applies_essential)");
|
||||
foreach ($seed['requisiti'] as $q) {
|
||||
$st->execute([$q['n'], $q['misura_code'], $q['requisito_code'], $q['requisito_descr'],
|
||||
$q['proc_code'], $q['risk_code'], $q['applies_important'], $q['applies_essential']]);
|
||||
}
|
||||
$pdo->commit();
|
||||
} catch (Throwable $e) {
|
||||
$pdo->rollBack();
|
||||
fwrite(STDERR, "SEED FALLITO: " . $e->getMessage() . "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$counts = [
|
||||
'ambiti' => (int) $pdo->query("SELECT COUNT(*) FROM cfg_nis2_ambiti")->fetchColumn(),
|
||||
'procedure' => (int) $pdo->query("SELECT COUNT(*) FROM cfg_nis2_procedure")->fetchColumn(),
|
||||
'rischi' => (int) $pdo->query("SELECT COUNT(*) FROM cfg_nis2_rischi")->fetchColumn(),
|
||||
'misure' => (int) $pdo->query("SELECT COUNT(*) FROM cfg_nis2_misure")->fetchColumn(),
|
||||
'requisiti' => (int) $pdo->query("SELECT COUNT(*) FROM cfg_nis2_requisiti")->fetchColumn(),
|
||||
];
|
||||
echo "OK seed-framework — " . json_encode($counts, JSON_UNESCAPED_UNICODE) . "\n";
|
||||
Reference in New Issue
Block a user