[FIX] test-runner: aggiorna email/password ai valori del simulatore

Email corrette: admin@datacore-srl.demo, admin@medclinic-spa.demo,
admin@enernet-srl.demo, consultant@nis2agile.demo
Password: NIS2Demo2026! (era Demo2026!)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
DevEnv nis2-agile 2026-03-09 10:03:14 +01:00
parent 1602438aac
commit 086ffbd675

View File

@ -65,7 +65,7 @@ function getCommands(): array
$root = PROJECT_ROOT;
$api = API_BASE;
$loginAdmin = "curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"admin@datacore.demo\",\"password\":\"Demo2026!\"}' 2>/dev/null";
$loginAdmin = "curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"admin@datacore-srl.demo\",\"password\":\"NIS2Demo2026!\"}' 2>/dev/null";
$getToken = "\$({$loginAdmin} | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('data',{}).get('access_token',''))\" 2>/dev/null)";
return [
@ -83,10 +83,10 @@ function getCommands(): array
'level' => 'l1',
'bash' => implode(' && ', [
"echo '━━━ L1.1 Login valido ━━━'",
"curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"admin@datacore.demo\",\"password\":\"Demo2026!\"}' | python3 -m json.tool || echo '[SKIP] utente non trovato'",
"curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"admin@datacore-srl.demo\",\"password\":\"NIS2Demo2026!\"}' | python3 -m json.tool || echo '[SKIP] utente non trovato'",
"echo ''",
"echo '━━━ L1.2 Login password errata (401) ━━━'",
"curl -sf -o /dev/null -w 'HTTP %{http_code}' -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"admin@datacore.demo\",\"password\":\"WRONG\"}'",
"curl -sf -o /dev/null -w 'HTTP %{http_code}' -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"admin@datacore-srl.demo\",\"password\":\"WRONG\"}'",
"echo ''",
"echo '━━━ L1.3 /auth/me senza token (401) ━━━'",
"curl -sf -o /dev/null -w 'HTTP %{http_code}' {$api}/auth/me",
@ -195,27 +195,27 @@ function getCommands(): array
'bash' => implode(' && ', [
// Login come consultant (ha accesso a cross-analysis)
"echo '━━━ L6.0 Setup: login consultant ━━━'",
"TOKEN_CONS=\$(curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"consultant@nis2agile.demo\",\"password\":\"Demo2026!\"}' 2>/dev/null | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('data',{}).get('access_token',''))\" 2>/dev/null) && [ -n \"\$TOKEN_CONS\" ] && echo \"Token consultant: \${TOKEN_CONS:0:25}...\" || echo '[SKIP] consultant non trovato — eseguire SIM-01 prima'",
"TOKEN_CONS=\$(curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"consultant@nis2agile.demo\",\"password\":\"NIS2Demo2026!\"}' 2>/dev/null | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('data',{}).get('access_token',''))\" 2>/dev/null) && [ -n \"\$TOKEN_CONS\" ] && echo \"Token consultant: \${TOKEN_CONS:0:25}...\" || echo '[SKIP] consultant non trovato — eseguire SIM-01 prima'",
"echo ''",
// L6.1: portfolio (senza AI, solo dati aggregati)
"echo '━━━ L6.1 Cross-Analysis Portfolio (no AI) ━━━'",
"TOKEN_CONS=\$(curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"consultant@nis2agile.demo\",\"password\":\"Demo2026!\"}' 2>/dev/null | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('data',{}).get('access_token',''))\" 2>/dev/null) && [ -n \"\$TOKEN_CONS\" ] && curl -sf -H \"Authorization: Bearer \$TOKEN_CONS\" {$api}/cross-analysis/portfolio | python3 -m json.tool || echo '[SKIP] token non disponibile'",
"TOKEN_CONS=\$(curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"consultant@nis2agile.demo\",\"password\":\"NIS2Demo2026!\"}' 2>/dev/null | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('data',{}).get('access_token',''))\" 2>/dev/null) && [ -n \"\$TOKEN_CONS\" ] && curl -sf -H \"Authorization: Bearer \$TOKEN_CONS\" {$api}/cross-analysis/portfolio | python3 -m json.tool || echo '[SKIP] token non disponibile'",
"echo ''",
// L6.2: history (vuota, ma endpoint deve rispondere 200)
"echo '━━━ L6.2 Cross-Analysis History ━━━'",
"TOKEN_CONS=\$(curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"consultant@nis2agile.demo\",\"password\":\"Demo2026!\"}' 2>/dev/null | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('data',{}).get('access_token',''))\" 2>/dev/null) && [ -n \"\$TOKEN_CONS\" ] && curl -sf -H \"Authorization: Bearer \$TOKEN_CONS\" {$api}/cross-analysis/history | python3 -c \"import sys,json; d=json.load(sys.stdin); h=d.get('data',{}).get('history',[]); print(f'History entries: {len(h)} — HTTP OK')\" || echo '[SKIP]'",
"TOKEN_CONS=\$(curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"consultant@nis2agile.demo\",\"password\":\"NIS2Demo2026!\"}' 2>/dev/null | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('data',{}).get('access_token',''))\" 2>/dev/null) && [ -n \"\$TOKEN_CONS\" ] && curl -sf -H \"Authorization: Bearer \$TOKEN_CONS\" {$api}/cross-analysis/history | python3 -c \"import sys,json; d=json.load(sys.stdin); h=d.get('data',{}).get('history',[]); print(f'History entries: {len(h)} — HTTP OK')\" || echo '[SKIP]'",
"echo ''",
// L6.3: analyze con domanda breve (chiama AI Anthropic)
"echo '━━━ L6.3 Cross-Analysis AI Analyze ━━━'",
"TOKEN_CONS=\$(curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"consultant@nis2agile.demo\",\"password\":\"Demo2026!\"}' 2>/dev/null | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('data',{}).get('access_token',''))\" 2>/dev/null) && [ -n \"\$TOKEN_CONS\" ] && curl -sf -X POST -H \"Authorization: Bearer \$TOKEN_CONS\" -H 'Content-Type: application/json' -d '{\"question\":\"Qual e il livello medio di compliance e quali sono le categorie NIS2 piu deboli nel portfolio?\"}' {$api}/cross-analysis/analyze | python3 -c \"import sys,json; d=json.load(sys.stdin); r=d.get('data',{}); ans=r.get('result',{}).get('answer',''); orgs=r.get('org_count',0); print(f'Org analizzate: {orgs}'); print(f'Risposta AI ({len(ans)} chars): {ans[:300]}...' if len(ans)>300 else f'Risposta: {ans}')\" || echo '[SKIP/ERRORE]'",
"TOKEN_CONS=\$(curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"consultant@nis2agile.demo\",\"password\":\"NIS2Demo2026!\"}' 2>/dev/null | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('data',{}).get('access_token',''))\" 2>/dev/null) && [ -n \"\$TOKEN_CONS\" ] && curl -sf -X POST -H \"Authorization: Bearer \$TOKEN_CONS\" -H 'Content-Type: application/json' -d '{\"question\":\"Qual e il livello medio di compliance e quali sono le categorie NIS2 piu deboli nel portfolio?\"}' {$api}/cross-analysis/analyze | python3 -c \"import sys,json; d=json.load(sys.stdin); r=d.get('data',{}); ans=r.get('result',{}).get('answer',''); orgs=r.get('org_count',0); print(f'Org analizzate: {orgs}'); print(f'Risposta AI ({len(ans)} chars): {ans[:300]}...' if len(ans)>300 else f'Risposta: {ans}')\" || echo '[SKIP/ERRORE]'",
"echo ''",
// L6.4: accesso negato a utente normale (403)
"echo '━━━ L6.4 Cross-Analysis 403 per utente non-consultant ━━━'",
"TOKEN_EMP=\$(curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"admin@datacore.demo\",\"password\":\"Demo2026!\"}' 2>/dev/null | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('data',{}).get('access_token',''))\" 2>/dev/null) && [ -n \"\$TOKEN_EMP\" ] && curl -sf -o /dev/null -w 'GET /cross-analysis/portfolio (org_admin) → HTTP %{http_code}\\n' -H \"Authorization: Bearer \$TOKEN_EMP\" {$api}/cross-analysis/portfolio || echo '[SKIP]'",
"TOKEN_EMP=\$(curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"admin@datacore-srl.demo\",\"password\":\"NIS2Demo2026!\"}' 2>/dev/null | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('data',{}).get('access_token',''))\" 2>/dev/null) && [ -n \"\$TOKEN_EMP\" ] && curl -sf -o /dev/null -w 'GET /cross-analysis/portfolio (org_admin) → HTTP %{http_code}\\n' -H \"Authorization: Bearer \$TOKEN_EMP\" {$api}/cross-analysis/portfolio || echo '[SKIP]'",
"echo ''",
// L6.5: normative feed
@ -237,7 +237,7 @@ function getCommands(): array
'label' => 'Smoke Tests (curl rapido)',
'level' => 'infra',
'bash' => implode(' && ', [
"echo '=== Login demo ===' && curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"admin@datacore.demo\",\"password\":\"Demo2026!\"}' | python3 -m json.tool || echo '[SKIP]'",
"echo '=== Login demo ===' && curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"admin@datacore-srl.demo\",\"password\":\"NIS2Demo2026!\"}' | python3 -m json.tool || echo '[SKIP]'",
"echo '=== /auth/me senza token (401) ===' && curl -sf -o /dev/null -w 'HTTP %{http_code}' {$api}/auth/me",
"echo '=== /dashboard/overview (no token → 401) ===' && curl -sf -o /dev/null -w 'HTTP %{http_code}' {$api}/dashboard/overview",
"echo '=== API status ===' && curl -sf {$api}/../api-status.php | python3 -m json.tool",
@ -308,7 +308,7 @@ function getCommands(): array
'level' => 'infra',
'bash' => implode(' && ', [
"echo '════════════ L1 AUTH ════════════'",
"curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"admin@datacore.demo\",\"password\":\"Demo2026!\"}' | python3 -c \"import sys,json; d=json.load(sys.stdin); print('Login:', 'OK' if d.get('success') else 'FAIL')\" || echo 'L1 SKIP'",
"curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"admin@datacore-srl.demo\",\"password\":\"NIS2Demo2026!\"}' | python3 -c \"import sys,json; d=json.load(sys.stdin); print('Login:', 'OK' if d.get('success') else 'FAIL')\" || echo 'L1 SKIP'",
"echo '════════════ L2 TENANT ════════════'",
"TOKEN={$getToken} && curl -sf -H \"Authorization: Bearer \$TOKEN\" {$api}/organizations/list | python3 -c \"import sys,json; d=json.load(sys.stdin); orgs=d.get('data',[]); print(f'Orgs: {len(orgs)}')\" || echo 'L2 SKIP'",
"echo '════════════ L3 COMPLIANCE ════════════'",
@ -316,7 +316,7 @@ function getCommands(): array
"echo '════════════ L5 EXPORT ════════════'",
"curl -sf {$api}/../api-status.php | python3 -c \"import sys,json; d=json.load(sys.stdin); print('API:', d.get('status','?'))\"",
"echo '════════════ L6 AI CROSS ════════════'",
"TOKEN_CONS=\$(curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"consultant@nis2agile.demo\",\"password\":\"Demo2026!\"}' 2>/dev/null | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('data',{}).get('access_token',''))\" 2>/dev/null) && [ -n \"\$TOKEN_CONS\" ] && curl -sf -H \"Authorization: Bearer \$TOKEN_CONS\" {$api}/cross-analysis/portfolio | python3 -c \"import sys,json; d=json.load(sys.stdin); print('Portfolio orgs:', d.get('data',{}).get('org_count','?'))\" || echo 'L6 SKIP (eseguire SIM-01 prima)'",
"TOKEN_CONS=\$(curl -sf -X POST {$api}/auth/login -H 'Content-Type: application/json' -d '{\"email\":\"consultant@nis2agile.demo\",\"password\":\"NIS2Demo2026!\"}' 2>/dev/null | python3 -c \"import sys,json; d=json.load(sys.stdin); print(d.get('data',{}).get('access_token',''))\" 2>/dev/null) && [ -n \"\$TOKEN_CONS\" ] && curl -sf -H \"Authorization: Bearer \$TOKEN_CONS\" {$api}/cross-analysis/portfolio | python3 -c \"import sys,json; d=json.load(sys.stdin); print('Portfolio orgs:', d.get('data',{}).get('org_count','?'))\" || echo 'L6 SKIP (eseguire SIM-01 prima)'",
"echo '[OK] Full Suite L1→L6 completata'",
]),
'cwd' => $root, 'timeout' => 300, 'continue_on_fail' => true,
@ -581,10 +581,10 @@ function serveUI(): void
$demoCredentials = [
['role' => '★ Super Admin', 'email' => 'cristiano.benassati@gmail.com', 'password' => 'Silvia1978!@', 'org' => 'Tutte'],
['role' => 'Admin (DataCore)', 'email' => 'admin@datacore.demo', 'password' => 'Demo2026!', 'org' => 'DataCore S.r.l.'],
['role' => 'Compliance (MedClinic)', 'email' => 'compliance@medclinic.demo', 'password' => 'Demo2026!', 'org' => 'MedClinic Italia'],
['role' => 'CISO (EnerNet)', 'email' => 'ciso@enernet.demo', 'password' => 'Demo2026!', 'org' => 'EnerNet S.r.l.'],
['role' => 'Consultant', 'email' => 'consultant@nis2agile.demo', 'password' => 'Demo2026!', 'org' => 'Multi-azienda'],
['role' => 'Admin (DataCore)', 'email' => 'admin@datacore-srl.demo', 'password' => 'NIS2Demo2026!', 'org' => 'DataCore S.r.l.'],
['role' => 'Compliance (MedClinic)', 'email' => 'admin@medclinic-spa.demo', 'password' => 'NIS2Demo2026!', 'org' => 'MedClinic Italia'],
['role' => 'CISO (EnerNet)', 'email' => 'admin@enernet-srl.demo', 'password' => 'NIS2Demo2026!', 'org' => 'EnerNet S.r.l.'],
['role' => 'Consultant', 'email' => 'consultant@nis2agile.demo', 'password' => 'NIS2Demo2026!', 'org' => 'Multi-azienda'],
];
$credsRows = '';
foreach ($demoCredentials as $c) {