Form : bouton tout supprimer + faille CSRF

This commit is contained in:
fredtempez 2019-01-26 11:09:47 +01:00
parent 0dcb72b151
commit 59481e8b3a
4 changed files with 124 additions and 44 deletions

View File

@ -3,17 +3,22 @@
## Préversion 9.0.0
- Modification :
- Stockage distinct du thème et des autres données (core, config, page, module et users ) avec import des données d'une version 8
- Exporter un thème (avec les images) sous forme d'une archive ZIP à télécharger ou stocker dans Fichiers.
- Importer un thème à partir des fichiers
- Gabarits de pages : deux blocs (colonnes) à droite ou à gauche contenant des informations fixes, le paramétrage est dans le thème, mais les contenus sont stockés dans les pages.
- gestion des thèmes :
- Exporter un thème (avec les images) sous forme d'une archive ZIP à télécharger ou stocker dans Fichiers.
- Importer un thème à partir des fichiers
- Option de position fixe du menu type Facebook
- Gabarits de pages : deux barres latérales, une à droite ou à gauche contenant des informations fixes.
- Changement du libellé Modérateur devient Editeur
- VisualBlocks dans TinyMCE
- CodeMirror dans TinyMCE
- Case à cocher dans les formulaires
- Option de position fixe du menu type Facebook
- Editeur :
- VisualBlocks dans TinyMCE
- CodeMirror dans TinyMCE
- Mini barre pour les membres simples
- Activation de la procédure d'update en ligne
- Update : affichage de la version proposée dans la popup de mise à jour
- Module Formulaire :
- Case à cocher dans les formulaires
- Bouton d'export au format CSV
- Bouton effacer toutes les données
- Correction faille CSRF
Correctif :
- contrôle CSRF de la configuration du compte connecté
- Problème dans data/.htaccess

View File

@ -20,6 +20,7 @@ class form extends common {
'config' => self::GROUP_MODERATOR,
'data' => self::GROUP_MODERATOR,
'delete' => self::GROUP_MODERATOR,
'deleteall' => self::GROUP_MODERATOR,
'index' => self::GROUP_VISITOR,
'export2csv' => self::GROUP_MODERATOR,
'output2csv' => self::GROUP_MODERATOR
@ -126,7 +127,7 @@ class form extends common {
$content,
template::button('formDataDelete' . $dataIds[$i], [
'class' => 'formDataDelete buttonRed',
'href' => helper::baseUrl() . $this->getUrl(0) . '/delete/' . $dataIds[$i],
'href' => helper::baseUrl() . $this->getUrl(0) . '/delete/' . $dataIds[$i] . '/' . $_SESSION['csrf'],
'value' => template::ico('cancel')
])
];
@ -145,29 +146,38 @@ class form extends common {
* @copyright Copyright (C) 2018-2019, Frédéric Tempez
*/
public function export2csv() {
$data = $this->getData(['module', $this->getUrl(0), 'data']);
if ($data !== []) {
$csvfilename = 'data-'.date('dmY').'-'.date('hm').'-'.rand(10,99).'.csv';
if (!file_exists('site/file/source/data')) {
mkdir('site/file/source/data');
}
$fp = fopen('site/file/source/data/'.$csvfilename, 'w');
fputcsv($fp, array_keys($data[1]), ';','"');
foreach ($data as $fields) {
fputcsv($fp, $fields, ';','"');
}
fclose($fp);
// Jeton incorrect
if ($this->getUrl(2) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'notification' => ' Export CSV effectué dans :<br />'.$csvfilename,
'redirect' => helper::baseUrl() . $this->getUrl(0) .'/data',
'state' => true
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/data',
'notification' => 'Action non autorisée'
]);
} else {
$this->addOutput([
'notification' => 'Aucune donnée à exporter',
'redirect' => helper::baseUrl() . $this->getUrl(0) .'/data'
]);
$data = $this->getData(['module', $this->getUrl(0), 'data']);
if ($data !== []) {
$csvfilename = 'data-'.date('dmY').'-'.date('hm').'-'.rand(10,99).'.csv';
if (!file_exists('site/file/source/data')) {
mkdir('site/file/source/data');
}
$fp = fopen('site/file/source/data/'.$csvfilename, 'w');
fputcsv($fp, array_keys($data[1]), ';','"');
foreach ($data as $fields) {
fputcsv($fp, $fields, ';','"');
}
fclose($fp);
// Valeurs en sortie
$this->addOutput([
'notification' => ' Export CSV effectué dans :<br />'.$csvfilename,
'redirect' => helper::baseUrl() . $this->getUrl(0) .'/data',
'state' => true
]);
} else {
$this->addOutput([
'notification' => 'Aucune donnée à exporter',
'redirect' => helper::baseUrl() . $this->getUrl(0) .'/data'
]);
}
}
}
@ -175,26 +185,73 @@ class form extends common {
/**
* Suppression
*/
public function delete() {
// La donnée n'existe pas
if($this->getData(['module', $this->getUrl(0), 'data', $this->getUrl(2)]) === null) {
public function deleteall() {
// Jeton incorrect
if ($this->getUrl(2) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
}
// Suppression
else {
$this->deleteData(['module', $this->getUrl(0), 'data', $this->getUrl(2)]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/data',
'notification' => 'Donnée supprimée',
'state' => true
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/data',
'notification' => 'Action non autorisée'
]);
} else {
$data = ($this->getData(['module', $this->getUrl(0), 'data']));
if (count($data) > 0 ) {
// Suppression multiple
for ($i = 1; $i <= count($data) ; $i++) {
$this->deleteData(['module', $this->getUrl(0), 'data', $i]);
}
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/data',
'notification' => 'Toutes les données ont été supprimées',
'state' => true
]);
} else {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/data',
'notification' => 'Aucune donnée à supprimer'
]);
}
}
}
/**
* Suppression
*/
public function delete() {
// Jeton incorrect
if ($this->getUrl(3) !== $_SESSION['csrf']) {
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/data',
'notification' => 'Action non autorisée'
]);
} else {
// La donnée n'existe pas
if($this->getData(['module', $this->getUrl(0), 'data', $this->getUrl(2)]) === null) {
// Valeurs en sortie
$this->addOutput([
'access' => false
]);
}
// Suppression
else {
$this->deleteData(['module', $this->getUrl(0), 'data', $this->getUrl(2)]);
// Valeurs en sortie
$this->addOutput([
'redirect' => helper::baseUrl() . $this->getUrl(0) . '/data',
'notification' => 'Donnée supprimée',
'state' => true
]);
}
}
}
/**
* Accueil
*/

View File

@ -18,4 +18,14 @@ $(".formDataDelete").on("click", function() {
return core.confirm("Êtes-vous sûr de vouloir supprimer cette donnée ?", function() {
$(location).attr("href", _this.attr("href"));
});
});
/**
* Confirmation de suppression de toutes les donénes
*/
$(".formDataDeleteAll").on("click", function() {
var _this = $(this);
return core.confirm("Êtes-vous sûr de vouloir supprimer toutes les données ?", function() {
$(location).attr("href", _this.attr("href"));
});
});

View File

@ -7,10 +7,18 @@
'value' => 'Retour'
]); ?>
</div>
<div class="col2 offset8">
<div class="col2 offset6">
<?php echo template::button('formDataDeleteAll', [
'class' => 'formDataDeleteAll buttonRed',
'href' => helper::baseUrl() . $this->getUrl(0) . '/deleteall' . '/' . $_SESSION['csrf'],
'ico' => 'cancel',
'value' => 'Tout effacer'
]); ?>
</div>
<div class="col2">
<?php echo template::button('formDataBack', [
'class' => 'buttonBlue',
'href' => helper::baseUrl() . $this->getUrl(0) . '/export2csv',
'href' => helper::baseUrl() . $this->getUrl(0) . '/export2csv' . '/' . $_SESSION['csrf'],
'ico' => 'download',
'value' => 'Export CSV'
]); ?>