diff --git a/MEMORY.md b/MEMORY.md index 2d4c43a..f659ad3 100644 --- a/MEMORY.md +++ b/MEMORY.md @@ -2,6 +2,15 @@ ## Ultima modifica: 28/05/2026 +## GLPI 11 — Session::checkCSRF() breaking change +In GLPI 11, `Session::checkCSRF()` richiede il primo argomento `$data` (i dati POST da validare). In GLPI ≤10 accettava zero argomenti. +Il listener globale `CheckCsrfListener` gestisce già il CSRF per tutte le richieste POST, ma il plugin chiamava `Session::checkCSRF()` senza argomenti causando errore fatale. + +### Fix applicati (tutti i file) +- RIMOSSE tutte le chiamate esplicite `Session::checkCSRF()` dai 4 file front — GLPI 11 le gestisce già globalmente via `CheckCsrfListener` +- Il listener globale consuma il token CSRF, quindi una seconda chiamata dal plugin fallisce perché il token non è più valido +- `public/js/urbackup.js` — aggiunto header `X-Glpi-Csrf-Token` con `getAjaxCsrfToken()` per le richieste AJAX + ## Performance - Asset Definition vs Computer ### Problema @@ -63,3 +72,5 @@ In una nuova installazione del plugin, i campi "API username" e "API password" n 5. **SQL schema pulito**: Rimosse tabelle legacy dall'empty.sql 6. **PHP lint warnings**: Rimosse `use Html;` e `use Search;` superflue 7. **README.md** creato +8. **PURGE right**: Aggiunto PURGE ai diritti di installazione (`Profile.php:76,90`); applicato a tutti i profili Super-Admin esistenti nel DB +9. **CSRF GLPI 11 fix**: `Session::checkCSRF()` richiede `$_POST` come argomento in GLPI 11; aggiunto `X-Glpi-Csrf-Token` header al JS AJAX diff --git a/front/asset.form.php b/front/asset.form.php index 4d2a845..db184e4 100644 --- a/front/asset.form.php +++ b/front/asset.form.php @@ -41,8 +41,6 @@ if (!$item || !$item->getFromDB($items_id)) { Html::displayNotFoundError(); } -Session::checkCSRF(); - if (isset($_POST['connect'])) { if (!Profile::canCurrentUser(UPDATE) && !Profile::canCurrentUser(CREATE)) { Html::displayRightError(); diff --git a/front/config.form.php b/front/config.form.php index 50b3aae..771f682 100644 --- a/front/config.form.php +++ b/front/config.form.php @@ -13,7 +13,6 @@ if (!Session::haveRight('config', UPDATE)) { // Handle form submission if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update'])) { - Session::checkCSRF(); Config::saveConfiguration($_POST); Html::redirect($_SERVER['REQUEST_URI']); } diff --git a/front/server.form.php b/front/server.form.php index 7fdd0dd..f812d15 100644 --- a/front/server.form.php +++ b/front/server.form.php @@ -19,8 +19,6 @@ if (!Profile::canCurrentUser(READ)) { $server = new Server(); if ($_SERVER['REQUEST_METHOD'] === 'POST') { - Session::checkCSRF(); - if (isset($_POST['link_asset'])) { $itemtype = (string) ($_POST['itemtype'] ?? ''); $items_id = (int) ($_POST['items_id'] ?? 0); diff --git a/front/server_test.ajax.php b/front/server_test.ajax.php index 8fc466a..79a7b97 100644 --- a/front/server_test.ajax.php +++ b/front/server_test.ajax.php @@ -13,10 +13,6 @@ Html::header_nocache(); Session::checkLoginUser(); -if ($_SERVER['REQUEST_METHOD'] === 'POST') { - Session::checkCSRF(); -} - if (!Session::haveRight('plugin_urbackup', READ)) { echo json_encode(['success' => false, 'message' => __('No permission', 'urbackup')]); exit; diff --git a/public/js/urbackup.js b/public/js/urbackup.js index 0f57c04..3943980 100644 --- a/public/js/urbackup.js +++ b/public/js/urbackup.js @@ -10,6 +10,7 @@ var xhr = new XMLHttpRequest(); xhr.open('POST', '/plugins/urbackup/front/server_test.ajax.php', true); xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); + xhr.setRequestHeader('X-Glpi-Csrf-Token', getAjaxCsrfToken()); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.timeout = 8000; diff --git a/setup.php b/setup.php index 2e7a825..1bb5f5e 100644 --- a/setup.php +++ b/setup.php @@ -4,14 +4,13 @@ declare(strict_types=1); // Force OPcache to reload plugin files when accessed via web if (PHP_SAPI !== 'cli' && function_exists('opcache_invalidate')) { - opcache_invalidate(__FILE__, true); - $capacity_file = __DIR__ . '/src/Capacity/UrBackupCapacity.php'; - if (file_exists($capacity_file)) { - opcache_invalidate($capacity_file, true); - } - $asset_tab_file = __DIR__ . '/src/AssetTab.php'; - if (file_exists($asset_tab_file)) { - opcache_invalidate($asset_tab_file, true); + $files = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator(__DIR__, RecursiveDirectoryIterator::SKIP_DOTS) + ); + foreach ($files as $file) { + if ($file->getExtension() === 'php') { + @opcache_invalidate($file->getRealPath(), true); + } } } diff --git a/src/Profile.php b/src/Profile.php index 5780a5a..d474bc7 100644 --- a/src/Profile.php +++ b/src/Profile.php @@ -73,7 +73,7 @@ class Profile extends \Profile $profiles_id = (int) ($_SESSION['glpiactiveprofile']['id'] ?? 0); if ($profiles_id > 0) { - self::setProfileRights($profiles_id, READ | UPDATE | CREATE | DELETE); + self::setProfileRights($profiles_id, READ | UPDATE | CREATE | DELETE | PURGE); } else { // CLI installation: no session available. // Assign full rights to the Super-Admin profile. @@ -87,7 +87,7 @@ class Profile extends \Profile ]); foreach ($sa_iterator as $sa_profile) { $profiles_id = (int) $sa_profile['id']; - self::setProfileRights($profiles_id, READ | UPDATE | CREATE | DELETE); + self::setProfileRights($profiles_id, READ | UPDATE | CREATE | DELETE | PURGE); } }