Overview
Comment: | Implémentation définitive vérification de signature à l'import de fichier, et plutôt que bloquer si le membre n'est plus admin, mettre toutes les catégories en admin. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | dev |
Files: | files | file ages | folders |
SHA1: |
623defddc25d9f875c95683b9b4921aa |
User & Date: | bohwaz on 2017-05-09 07:03:34 |
Other Links: | branch diff | manifest | tags |
Context
2017-05-10
| ||
07:02 | Modernisation des fiches membres + amélioration UX avec des transitions check-in: 2bcf5d3c6a user: bohwaz tags: dev | |
2017-05-09
| ||
07:03 | Implémentation définitive vérification de signature à l'import de fichier, et plutôt que bloquer si le membre n'est plus admin, mettre toutes les catégories en admin. check-in: 623defddc2 user: bohwaz tags: dev | |
06:59 | Simplification script mise à jour de la session check-in: b159a9fb16 user: bohwaz tags: dev | |
Changes
Modified src/include/init.php from [17ebcf2ead] to [4bc86e819b].
︙ | ︙ | |||
85 86 87 88 89 90 91 | $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost'); define('Garradin\WWW_URL', 'http' . (!empty($_SERVER['HTTPS']) ? 's' : '') . '://' . $host . WWW_URI); } static $default_config = [ | | | | | | > | | | | | | | | | | | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost'); define('Garradin\WWW_URL', 'http' . (!empty($_SERVER['HTTPS']) ? 's' : '') . '://' . $host . WWW_URI); } static $default_config = [ 'CACHE_ROOT' => DATA_ROOT . '/cache', 'DB_FILE' => DATA_ROOT . '/association.sqlite', 'DB_SCHEMA' => ROOT . '/include/data/schema.sql', 'PLUGINS_ROOT' => DATA_ROOT . '/plugins', 'PREFER_HTTPS' => false, 'ALLOW_MODIFIED_IMPORT' => true, 'PLUGINS_SYSTEM' => '', 'SHOW_ERRORS' => false, 'MAIL_ERRORS' => false, 'USE_CRON' => false, 'ENABLE_XSENDFILE' => false, 'SMTP_HOST' => false, 'SMTP_USER' => null, 'SMTP_PASSWORD' => null, 'SMTP_PORT' => 587, 'SMTP_SECURITY' => 'STARTTLS', ]; foreach ($default_config as $const => $value) { $const = sprintf('Garradin\\%s', $const); if (!defined($const)) |
︙ | ︙ |
Modified src/include/lib/Garradin/Sauvegarde.php from [b0e237675e] to [ace718c666].
1 2 3 4 5 6 | <?php namespace Garradin; class Sauvegarde { | | > > | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?php namespace Garradin; 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 * @param boolean $auto Si true ne renvoie que la liste des sauvegardes automatiques * @return array Liste des fichiers */ public function getList($auto = false) |
︙ | ︙ | |||
196 197 198 199 200 201 202 | if ($check_integrity) { $integrity = $this->checkIntegrity($file['tmp_name']); if ($integrity === null) { | | | | 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | 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'], $user_id); if ($r) { |
︙ | ︙ | |||
268 269 270 271 272 273 274 275 276 277 278 279 280 281 | * 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, $user_id = false) { // Essayons déjà d'ouvrir la base de données à restaurer en lecture try { $db = new \SQLite3($file, SQLITE3_OPEN_READONLY); } catch (\Exception $e) { throw new UserException('Le fichier fourni n\'est pas une base de données valide. ' . | > > | | | | | | | > > > > > > > > > > > > | | | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 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 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 | * 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, $user_id = false) { $return = 1; // Essayons déjà d'ouvrir la base de données à restaurer en lecture try { $db = new \SQLite3($file, SQLITE3_OPEN_READONLY); } catch (\Exception $e) { throw new UserException('Le fichier fourni n\'est pas une base de données valide. ' . 'Message d\'erreur de SQLite : ' . $e->getMessage(), self::NOT_A_DB); } try { // Regardons ensuite si la base de données n'est pas corrompue $check = $db->querySingle('PRAGMA integrity_check;', false); } catch (\Exception $e) { // Ici SQLite peut rejeter un message type "file is encrypted or is not a db" throw new UserException('Le fichier fourni n\'est pas une base de données valide. ' . 'Message d\'erreur de SQLite : ' . $e->getMessage(), self::NOT_A_DB); } if (strtolower(trim($check)) != 'ok') { throw new UserException('Le fichier fourni est corrompu. SQLite a trouvé ' . $check . ' erreurs.'); } // On ne peut pas faire de vérifications très poussées sur la structure de la base de données, // celle-ci pouvant changer d'une version à l'autre et on peut vouloir importer une base // un peu vieille, mais on vérifie quand même que ça ressemble un minimum à une base garradin $table = $db->querySingle('SELECT 1 FROM sqlite_master WHERE type=\'table\' AND tbl_name=\'config\';', false); if (!$table) { throw new UserException('Le fichier fourni ne semble pas contenir de données liées à Garradin.'); } // On récupère la version $version = $db->querySingle('SELECT valeur FROM config WHERE cle=\'version\';'); // Vérification de l'AppID pour les versions récentes if (version_compare($version, '0.8.0', '>=')) { $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); } } if ($user_id) { // Empêchons l'admin de se tirer une balle dans le pied $is_still_admin = $db->querySingle('SELECT 1 FROM membres_categories WHERE id = (SELECT id_categorie FROM membres WHERE id = ' . (int) $user_id . ') AND droit_config >= ' . Membres::DROIT_ADMIN . ' AND droit_connexion >= ' . Membres::DROIT_ACCES); if (!$is_still_admin) { $return |= self::NOT_AN_ADMIN; } } $db->close(); $backup = str_replace('.sqlite', date('.Y-m-d-His') . '.avant_restauration.sqlite', DB_FILE); DB::getInstance()->close(); if (!rename(DB_FILE, $backup)) { throw new \RuntimeException('Unable to backup current DB file.'); } if (!copy($file, DB_FILE)) { rename($backup, DB_FILE); throw new \RuntimeException('Unable to copy backup DB to main location.'); } if ($return & self::NOT_AN_ADMIN) { // Forcer toutes les catégories à pouvoir gérer les droits $db = DB::getInstance(); $db->update('membres_categories', [ 'droit_membres' => Membres::DROIT_ADMIN, 'droit_connexion' => Membres::DROIT_ACCES ]); } if ($version != garradin_version()) { $return |= self::NEED_UPGRADE; } return $return; } /** * Taille de la base de données actuelle * @return integer Taille en octets du fichier SQLite */ public function getDBSize() |
︙ | ︙ |
Modified src/templates/admin/config/donnees.tpl from [6569f6241f] to [815a847b92].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | {include file="admin/_head.tpl" title="Données — Sauvegarde et restauration" current="config"} {include file="admin/config/_menu.tpl" current="donnees"} {if $error} <p class="error">{$error}</p> {elseif $ok} <p class="confirm"> {if $ok == 'config'}La configuration a bien été enregistrée. {elseif $ok == 'create'}Une nouvelle sauvegarde a été créée. {elseif $ok == 'restore'}La restauration a bien été effectuée. Si vous désirez revenir en arrière, vous pouvez utiliser la sauvegarde automatique nommée <em>date-du-jour.avant_restauration.sqlite</em>, sinon vous pouvez l'effacer. {elseif $ok == 'remove'}La sauvegarde a été supprimée. {/if} </p> {/if} <form method="post" action="{$self_url}"> | > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | {include file="admin/_head.tpl" title="Données — Sauvegarde et restauration" current="config"} {include file="admin/config/_menu.tpl" current="donnees"} {if $error} <p class="error">{$error}</p> {if $code == Garradin\Sauvegarde::INTEGRITY_FAIL && Garradin\ALLOW_MODIFIED_IMPORT} <p class="alert">Pour passer outre, renvoyez le fichier en cochant la case « Ignorer les erreurs ». Attention, si vous avez effectué des modifications dans la base de données, cela peut créer des bugs !</p> {/if} {elseif $ok} <p class="confirm"> {if $ok == 'config'}La configuration a bien été enregistrée. {elseif $ok == 'create'}Une nouvelle sauvegarde a été créée. {elseif $ok == 'restore'}La restauration a bien été effectuée. Si vous désirez revenir en arrière, vous pouvez utiliser la sauvegarde automatique nommée <em>date-du-jour.avant_restauration.sqlite</em>, sinon vous pouvez l'effacer. {if $ok_code & Garradin\Sauvegarde::NOT_AN_ADMIN} </p> <p class="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} <form method="post" action="{$self_url}"> |
︙ | ︙ | |||
126 127 128 129 130 131 132 133 134 135 136 137 | <p> {csrf_field key="backup_restore"} <input type="hidden" name="MAX_FILE_SIZE" value="{$max_file_size}" /> <input type="file" name="file" id="f_file" required="required" /> (maximum {$max_file_size|format_bytes}) <input type="submit" name="restore_file" value="Restaurer depuis le fichier sélectionné →" /> </p> </fieldset> </form> {include file="admin/_foot.tpl"} | > > > > > | 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | <p> {csrf_field key="backup_restore"} <input type="hidden" name="MAX_FILE_SIZE" value="{$max_file_size}" /> <input type="file" name="file" id="f_file" required="required" /> (maximum {$max_file_size|format_bytes}) <input type="submit" name="restore_file" value="Restaurer depuis le fichier sélectionné →" /> </p> {if $error && ($code == Garradin\Sauvegarde::INTEGRITY_FAIL && Garradin\ALLOW_MODIFIED_IMPORT)} <p> <label><input type="checkbox" name="force_import" value="1" /> Ignorer les erreurs, je sais ce que je fait</label> </p> {/if} </fieldset> </form> {include file="admin/_foot.tpl"} |
Modified src/www/admin/config/donnees.php from [695392fbd6] to [b991b2d410].
1 2 3 4 5 6 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; $s = new Sauvegarde; | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <?php namespace Garradin; require_once __DIR__ . '/_inc.php'; $s = new Sauvegarde; $code = $error = false; if (Utils::post('config')) { if (!Utils::CSRF_check('backup_config')) { $error = 'Une erreur est survenue, merci de renvoyer le formulaire.'; } |
︙ | ︙ | |||
61 62 63 64 65 66 67 | if (!Utils::CSRF_check('backup_manage')) { $error = 'Une erreur est survenue, merci de renvoyer le formulaire.'; } else { try { | | | | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | if (!Utils::CSRF_check('backup_manage')) { $error = 'Une erreur est survenue, merci de renvoyer le formulaire.'; } else { try { $r = $s->restoreFromLocal(Utils::post('file')); Utils::redirect('/admin/config/donnees.php?ok=restore&code=' . (int)$r); } catch (UserException $e) { $error = $e->getMessage(); } } } elseif (Utils::post('remove')) { |
︙ | ︙ | |||
92 93 94 95 96 97 98 99 | { if (!Utils::CSRF_check('backup_restore')) { $error = 'Une erreur est survenue, merci de renvoyer le formulaire.'; } else { try { | > > > | | > > > | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | { if (!Utils::CSRF_check('backup_restore')) { $error = 'Une erreur est survenue, merci de renvoyer le formulaire.'; } else { // Ignorer la vérification d'intégrité si autorisé et demandé $check = (ALLOW_MODIFIED_IMPORT && Utils::post('force_import')) ? false : true; try { $r = $s->restoreFromUpload($_FILES['file'], $user->id, $check); Utils::redirect('/admin/config/donnees.php?ok=restore&code=' . (int)$r); } catch (UserException $e) { $error = $e->getMessage(); $code = $e->getCode(); } } } $tpl->assign('error', $error); $tpl->assign('code', $code); $tpl->assign('ok_code', Utils::get('code')); $tpl->assign('ok', Utils::get('ok')); $tpl->assign('liste', $s->getList()); $tpl->assign('max_file_size', Utils::getMaxUploadSize()); $tpl->assign('db_size', $s->getDBSize()); $tpl->assign('files_size', $s->getDBFilesSize()); $tpl->display('admin/config/donnees.tpl'); |