Overview
Comment: | Fix restore backup where user does not exist anymore: force login as first admin account |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
70bfaa52e7181a5b1b5af7f3a55fca39 |
User & Date: | bohwaz on 2022-02-09 21:36:55 |
Other Links: | manifest | tags |
Context
2022-02-09
| ||
23:17 | Fix more PHP 8.1 depreciations check-in: 75e0d8d864 user: bohwaz tags: trunk | |
21:36 | Fix restore backup where user does not exist anymore: force login as first admin account check-in: 70bfaa52e7 user: bohwaz tags: trunk | |
2022-02-08
| ||
00:08 | Fix PHP 8.1 errors check-in: 4389c3dcc4 user: bohwaz tags: trunk | |
Changes
Modified src/include/lib/Garradin/Membres/Session.php from [f6b4098759] to [5ca1fff613].
︙ | ︙ | |||
156 157 158 159 160 161 162 | } protected function deleteAllRememberMeSelectors($user_id) { return $this->db->delete('membres_sessions', $this->db->where('id_membre', $user_id)); } | < > | < | < < < < < < < < < < < < > > > > > > > > > > > | > > > | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | } protected function deleteAllRememberMeSelectors($user_id) { return $this->db->delete('membres_sessions', $this->db->where('id_membre', $user_id)); } public function isLogged(bool $disable_local_login = false) { $logged = parent::isLogged(); // Ajout de la gestion de LOCAL_LOGIN if (!$disable_local_login && defined('\Garradin\LOCAL_LOGIN')) { $logged = $this->forceLogin(\Garradin\LOCAL_LOGIN); } return $logged; } public function forceLogin(int $id) { // On va chercher le premier membre avec le droit de gérer la config if (-1 === $id) { $id = $this->db->firstColumn('SELECT id FROM membres WHERE id_category IN (SELECT id FROM users_categories WHERE perm_config = ?) LIMIT 1', self::ACCESS_ADMIN); } $logged = parent::isLogged(); // Only login if required if ($id > 0 && (!$logged || ($logged && $this->user->id != $id))) { return $this->create($id); } return $logged; } // Ici checkOTP utilise NTP en second recours public function checkOTP($secret, $code) { if (Security_OTP::TOTP($secret, $code)) { |
︙ | ︙ |
Modified src/include/lib/Garradin/Sauvegarde.php from [dae05764ac] to [fb842afc09].
︙ | ︙ | |||
8 9 10 11 12 13 14 15 16 17 18 19 20 21 | use KD2\ZipWriter; class Sauvegarde { const NEED_UPGRADE = 0x01 << 2; const NOT_AN_ADMIN = 0x01 << 3; const INTEGRITY_FAIL = 41; const NOT_A_DB = 42; const NO_APP_ID = 43; /** * Renvoie la liste des fichiers SQLite sauvegardés | > | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | use KD2\ZipWriter; class Sauvegarde { const NEED_UPGRADE = 0x01 << 2; const NOT_AN_ADMIN = 0x01 << 3; const CHANGED_USER = 0x01 << 4; const INTEGRITY_FAIL = 41; const NOT_A_DB = 42; const NO_APP_ID = 43; /** * Renvoie la liste des fichiers SQLite sauvegardés |
︙ | ︙ | |||
321 322 323 324 325 326 327 | return $this->restoreDB(DATA_ROOT . '/' . $file, false, false); } /** * Restaure une copie distante (fichier envoyé) * @param array $file Tableau provenant de $_FILES | < < | | | 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 | return $this->restoreDB(DATA_ROOT . '/' . $file, false, false); } /** * Restaure une copie distante (fichier envoyé) * @param array $file Tableau provenant de $_FILES * @param boolean $check_integrity Vérifier l'intégrité de la sauvegarde avant de restaurer * @return boolean true */ public function restoreFromUpload($file, $check_integrity = true) { if (empty($file['size']) || empty($file['tmp_name']) || !empty($file['error'])) { throw new UserException('Le fichier n\'a pas été correctement envoyé. Essayer de le renvoyer à nouveau.'); } if ($check_integrity) { $integrity = $this->checkIntegrity($file['tmp_name']); if ($integrity === null) { throw new UserException('Le fichier fourni n\'est pas une base de donnée SQLite3.', self::NOT_A_DB); } elseif ($integrity === false) { throw new UserException('Le fichier fourni a été modifié par un programme externe.', self::INTEGRITY_FAIL); } } $r = $this->restoreDB($file['tmp_name'], true); if ($r) { Utils::safe_unlink($file['tmp_name']); } return $r; |
︙ | ︙ | |||
409 410 411 412 413 414 415 | /** * Restauration de base de données, la fonction qui le fait vraiment * @param string $file Chemin absolu vers la base de données à utiliser * @return mixed true si rien ne va plus, ou self::NEED_UPGRADE si la version de la DB * ne correspond pas à la version de Garradin (mise à jour nécessaire). */ | | | 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 | /** * Restauration de base de données, la fonction qui le fait vraiment * @param string $file Chemin absolu vers la base de données à utiliser * @return mixed true si rien ne va plus, ou self::NEED_UPGRADE si la version de la DB * ne correspond pas à la version de Garradin (mise à jour nécessaire). */ protected function restoreDB($file, $check_foreign_keys = false) { $return = 1; // Essayons déjà d'ouvrir la base de données à restaurer en lecture try { $db = new \SQLite3($file, \SQLITE3_OPEN_READONLY); } |
︙ | ︙ | |||
477 478 479 480 481 482 483 484 485 | // Vérification de l'AppID $appid = $db->querySingle('PRAGMA application_id;', false); if ($appid !== DB::APPID) { throw new UserException('Ce fichier n\'est pas une sauvegarde Garradin (application_id ne correspond pas).', self::NO_APP_ID); } // Empêchons l'admin de se tirer une balle dans le pied | > > | | | | 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 | // Vérification de l'AppID $appid = $db->querySingle('PRAGMA application_id;', false); if ($appid !== DB::APPID) { throw new UserException('Ce fichier n\'est pas une sauvegarde Garradin (application_id ne correspond pas).', self::NO_APP_ID); } $session = Session::getInstance(); // Empêchons l'admin de se tirer une balle dans le pied if ($session->isLogged()) { if (version_compare($version, '1.1', '<')) { // FIXME remove in 1.2 $sql = 'SELECT 1 FROM membres_categories WHERE id = (SELECT id_categorie FROM membres WHERE id = %d) AND droit_connexion >= %d AND droit_config >= %d'; } else { $sql = 'SELECT 1 FROM users_categories WHERE id = (SELECT id_category FROM membres WHERE id = %d) AND perm_connect >= %d AND perm_config >= %d'; } $sql = sprintf($sql, $session->getUser()->id, Session::ACCESS_READ, Session::ACCESS_ADMIN); $is_still_admin = $db->querySingle($sql); if (!$is_still_admin) { $return |= self::NOT_AN_ADMIN; } } |
︙ | ︙ | |||
526 527 528 529 530 531 532 533 534 535 536 537 538 539 | // Forcer toutes les catégories à pouvoir gérer les droits $db = DB::getInstance(); $db->update('users_categories', [ 'perm_users' => Session::ACCESS_ADMIN, 'perm_connect' => Session::ACCESS_READ ]); } if ($version != garradin_version()) { $return |= self::NEED_UPGRADE; } else { // Force l'installation de plugin système si non existant dans la sauvegarde existante | > > > > > | 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 | // Forcer toutes les catégories à pouvoir gérer les droits $db = DB::getInstance(); $db->update('users_categories', [ 'perm_users' => Session::ACCESS_ADMIN, 'perm_connect' => Session::ACCESS_READ ]); } if (!$session->refresh()) { $session->forceLogin(-1); $return |= self::CHANGED_USER; } if ($version != garradin_version()) { $return |= self::NEED_UPGRADE; } else { // Force l'installation de plugin système si non existant dans la sauvegarde existante |
︙ | ︙ |
Modified src/templates/admin/config/backup/restore.tpl from [fe1e0e7549] to [0ec7bed822].
︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <p class="block confirm"> {if $ok == 'restore'}La restauration a bien été effectuée. {if $ok_code & Sauvegarde::NOT_AN_ADMIN} </p> <p class="block alert"> <strong>Vous n'êtes pas administrateur dans cette sauvegarde.</strong> Garradin a donné les droits d'administration à toutes les catégories afin d'empêcher de ne plus pouvoir se connecter. Merci de corriger les droits des catégories maintenant. {/if} {elseif $ok == 'remove'}La sauvegarde a été supprimée. {/if} </p> {/if} | > > > > > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <p class="block confirm"> {if $ok == 'restore'}La restauration a bien été effectuée. {if $ok_code & Sauvegarde::NOT_AN_ADMIN} </p> <p class="block alert"> <strong>Vous n'êtes pas administrateur dans cette sauvegarde.</strong> Garradin a donné les droits d'administration à toutes les catégories afin d'empêcher de ne plus pouvoir se connecter. Merci de corriger les droits des catégories maintenant. {elseif $ok_code & Sauvegarde::CHANGED_USER} </p> <p class="block alert"> <strong>Votre compte membre n'existait pas dans la sauvegarde qui a été restaurée, vous êtes désormais connecté avec le premier compte administrateur.</strong> </p> {/if} {elseif $ok == 'remove'}La sauvegarde a été supprimée. {/if} </p> {/if} |
︙ | ︙ |
Modified src/www/admin/config/backup/restore.php from [1f7464bcbf] to [02133a1ff3].
︙ | ︙ | |||
25 26 27 28 29 30 31 | throw new UserException('Aucune sauvegarde sélectionnée'); } $s->remove(f('selected')); }, 'backup_manage', Utils::getSelfURI(['ok' => 'remove'])); | | | > < | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | throw new UserException('Aucune sauvegarde sélectionnée'); } $s->remove(f('selected')); }, 'backup_manage', Utils::getSelfURI(['ok' => 'remove'])); $form->runIf('restore_file', function () use ($s, &$code, $session, $form) { // Ignorer la vérification d'intégrité si autorisé et demandé $check = (ALLOW_MODIFIED_IMPORT && f('force_import')) ? false : true; try { $r = $s->restoreFromUpload($_FILES['file'], $check); Utils::redirect(Utils::getSelfURI(['ok' => 'restore', 'code' => (int)$r])); } catch (UserException $e) { $code = $e->getCode(); if ($code == 0) { throw $e; } $form->addError($e->getMessage()); } }, 'backup_restore'); $ok_code = qg('code'); // return code $ok = qg('ok'); // return message $list = $s->getList(); $tpl->assign(compact('code', 'list', 'ok', 'ok_code')); $tpl->display('admin/config/backup/restore.tpl'); |