From 01e73fed156a7546a0a1f34b7e5ea99748841efa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Georges=20Dup=C3=A9ron?= Date: Fri, 15 Oct 2010 16:59:20 +0200 Subject: [PATCH] =?UTF-8?q?Set=20sur=20des=20propri=C3=A9t=C3=A9s=20et=20a?= =?UTF-8?q?ctions=20=C3=A0=20partir=20de=20$=5FGET=20/=20$=5FPOST.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cms2/code/bdd.php5 | 21 ++++++++++++-- cms2/code/configuration.php5 | 5 ++-- cms2/code/debug.php5 | 46 ++++++++++++++++++++++--------- cms2/code/document.php5 | 2 +- cms2/code/main.php5 | 43 +++++++++++++++++++++++++++-- cms2/code/page.php5 | 45 ++++++++++++++++++------------ cms2/modules/galerie/galerie.php5 | 8 ------ 7 files changed, 125 insertions(+), 45 deletions(-) diff --git a/cms2/code/bdd.php5 b/cms2/code/bdd.php5 index 9817bce..48f05b2 100644 --- a/cms2/code/bdd.php5 +++ b/cms2/code/bdd.php5 @@ -4,6 +4,7 @@ // le droit de voir. Filtrage après la requête (attention au LIMIT et OFFSET !) ? // ou y a-t-il moyen d'exprimer ça directement dans la requête ? +// TODO : sécurité : faire une méthode select qui construise une requête sans risques de triche de la part de l'utilisateur. Idem pour insert / update etc. class BDD { private static $handle = null; @@ -33,7 +34,7 @@ class BDD { self::unbuf_query('create table if not exists ' . self::table("_modules") . ' (' . 'nom_module varchar(50) primary key' . ')'); - foreach (self::select('select * from ' . self::table("_modules")) as $module) { + foreach (self::select('select nom_module from ' . self::table("_modules")) as $module) { self::unbuf_query('drop table if exists ' . self::table($module["nom_module"])); } self::unbuf_query('drop table if exists ' . self::table("_modules")); @@ -148,9 +149,20 @@ class BDD { } public static function table($nom) { + if (! preg_match('/^[a-zA-Z_]*$/', $nom)) { + Debug("erreur", "Nom de table malformé : " . htmlspecialchars(var_export($nom, true)) . "."); + } return Config::get('db_prefixe') . $nom; } + public static function escape($str) { + return mysql_real_escape_string($str, self::get()); + } + + public static function escape_int($str) { + return intval($str); + } + public static function close() { if (is_resource(self::$handle)) { self::commit(); @@ -163,10 +175,12 @@ class BDD { class BDDCell { private $uid_page; private $propriete; + private $type; private $valeur; - public function __construct($uid_page, $propriete, $valeur) { + public function __construct($uid_page, $propriete, $type, $valeur) { $this->uid_page = $uid_page; $this->propriete = $propriete; + $this->type = $type; $this->valeur = $valeur; } public function uid_page() { @@ -175,6 +189,9 @@ class BDDCell { public function propriete() { return $this->propriete; } + public function type() { + return $this->type; + } public function valeur() { return $this->valeur; } diff --git a/cms2/code/configuration.php5 b/cms2/code/configuration.php5 index 6942fbf..2da975c 100644 --- a/cms2/code/configuration.php5 +++ b/cms2/code/configuration.php5 @@ -10,7 +10,7 @@ class Config { public static function get($nom) { if (!isset(self::$config[$nom])) { - // Utilisation de die() plutôt que de $Debug->erreur car Debug n'est peut-être pas encore chargé. + // Utilisation de die() plutôt que de Debug("erreur") car Debug n'est peut-être pas encore chargé. echo "Variable de configuration manquante : $nom"; die(); } @@ -27,7 +27,8 @@ require_once(dirname(__FILE__) . "/../config.php5"); if (Config::get('courriel_admin') === null) { echo "Vous devez indiquer le courriel de l'administrateur dans le fichier config.php5 ."; - exit; + // Utilisation de die() plutôt que de Debug("erreur") car Debug n'est peut-être pas encore chargé. + die(); } diff --git a/cms2/code/debug.php5 b/cms2/code/debug.php5 index 61a142a..6879fda 100644 --- a/cms2/code/debug.php5 +++ b/cms2/code/debug.php5 @@ -1,22 +1,40 @@ 'Erreur', - "niy" => 'Pas encore implémenté', - "info" => 'Info', - "sql" => 'Requête SQL', - "erreur_sql" => 'Erreur SQL', - "permission" => 'Permission non accordée' + "erreur" => 'Erreur', + "warn" => 'Attention', + "info" => 'Info', + "utilisateur" => 'Erreur', + "niy" => 'Pas encore implémenté', + "sql" => 'Requête SQL', + "erreur_sql" => 'Erreur SQL', + "permission" => 'Permission non accordée' ); public static $filtre_erreurs = array( - "erreur" => true, - "niy" => true, - "info" => true, - "sql" => false, - "erreur_sql" => true, - "permission" => true + "erreur" => true, + "warn" => true, + "info" => true, + "niy" => true, + "sql" => false, + "erreur_sql" => true, + "utilisateur" => true, + "permission" => true ); + public static $filtre_erreurs_en_production = array( + "erreur" => false, + "warn" => false, + "info" => false, + "niy" => false, + "sql" => false, + "erreur_sql" => false, + "utilisateur" => true, // erreur générée par des données de l'utilisateur. + "permission" => true // permission non accordée. + ); + public static $toutes_erreurs = false; // true <=> ignorer le filtre. public static $erreurs = array(); @@ -55,7 +73,9 @@ class _Debug { } if ($print) { foreach (self::$erreurs as $e) { - if (self::$toutes_erreurs === true || self::$filtre_erreurs[$e[0]] === true) { + if (self::$toutes_erreurs === true + || (array_key_exists($e[0], self::$filtre_erreurs) + && self::$filtre_erreurs[$e[0]] === true)) { $ret .= self::$types_erreur[$e[0]] . " : " . $e[1] . "\n"; } } diff --git a/cms2/code/document.php5 b/cms2/code/document.php5 index b16b824..30bef10 100644 --- a/cms2/code/document.php5 +++ b/cms2/code/document.php5 @@ -210,7 +210,7 @@ ElementDocument::add_widget("description", create_function('$d, $cell', ' ElementDocument::add_widget("field", create_function('$d, $cell', ' $f = $d->span("field"); - $f->text("NIY : " . toString($cell)); + $f->text("[(" . $cell->type() .")". $cell->propriete() . " = " . toString($cell) . "]"); return $f; ')); diff --git a/cms2/code/main.php5 b/cms2/code/main.php5 index e2d3c39..bf7d65e 100644 --- a/cms2/code/main.php5 +++ b/cms2/code/main.php5 @@ -9,8 +9,47 @@ verifications(); function main() { initModules(); - // Attention ! ne pas garder BDD::reset() en production ! - BDD::reset(); + Debug("warn", "BDD::reset() est toujours activé, ne pas le garder en production !"); + if (array_key_exists("reset_bdd", $_GET) && $_GET['reset_bdd'] == 'true') { + BDD::reset(); + } + + // TODO : should be $_POST . + foreach ($_GET as $k => $v) { + if (substr($k, 0, 4) == 'set_') { + $k = substr($k, 4); + $set_uid_page = substr($k, 0, strpos($k, '_')); + $set_nom_prop = substr($k, strpos($k, '_') + 1); + $set_page = mPage::page_uid($set_uid_page); + + if ($set_page->has_prop($set_nom_prop)) { + $set_page->$set_nom_prop = $v; + } else { + Debug("warn", "Impossible d'effecturer la modification " + . "(uid_page = " . htmlspecialchars($set_uid_page) + . ", " . htmlspecialchars($set_nom_prop) + . " = " . htmlspecialchars($v) . ")."); + } + } + } + + // TODO : should be $_POST . + foreach ($_GET as $k => $v) { + if (substr($k, 0, 4) == 'act_') { + $k = substr($k, 4); + $act_uid_page = substr($k, 0, strpos($k, '_')); + $act_nom_action = "act_" . substr($k, strpos($k, '_') + 1); + $act_page = mPage::page_uid($act_uid_page); + + if (method_exists($act_page, $act_nom_action)) { + call_user_func(array($act_page, $act_nom_action), $v); + } else { + Debug("warn", "Impossible d'exécuter l'action " + . htmlspecialchars($act_nom_action) + . " (uid_page = " . htmlspecialchars($act_uid_page) . ")."); + } + } + } $res = array_key_exists('res', $_GET) ? $_GET['res'] : null; if (array_key_exists('uid_page', $_GET)) { diff --git a/cms2/code/page.php5 b/cms2/code/page.php5 index 399bcb6..dc16c70 100644 --- a/cms2/code/page.php5 +++ b/cms2/code/page.php5 @@ -141,7 +141,7 @@ class mPage { attribut_global("composant_url", "text_nix", "page"); } - public static function est_propriete_globale($prop) { + public static function est_attribut_global($prop) { return array_key_exists($prop, self::$attributs_globaux); } @@ -205,11 +205,16 @@ class mPage { // Renvoie l'uid de la page dans la base de données. return $this->uid; } - + + public function has_prop($nom) { + return array_key_exists($nom, self::$attributs_globaux) + || array_key_exists($nom, $this->module['attributs']); + } + public function parent() { return self::page_uid( BDD::select_one( - "select uid_page_de from " . BDD::table("_liens") . " where uid_page_vers = " . $this->uid() + "select uid_page_de from " . BDD::table("_liens") . " where uid_page_vers = " . BDD::escape_int($this->uid()) ) ); } @@ -222,7 +227,7 @@ class mPage { // limit = null || limit = 0 => pas de limite // offset = null => offset = 0 - // TODO : nettoyer la condition + // TODO : nettoyer la condition (pbs de sécurité + bugs !!!). if ($condition !== true) $condition = " and ($condition)"; else @@ -240,15 +245,15 @@ class mPage { $select_order .= substr($o,1) . " "; $select_order .= (substr($o,0,1) == "+") ? "asc" : "desc"; } - $select_limit = ($limit == 0) ? "" : " limit $limit"; - $select_offset = ($offset == 0) ? "" : " offset $offset"; + $select_limit = ($limit == 0) ? "" : " limit " . BDD::escape_int($limit); + $select_offset = ($offset == 0) ? "" : " offset " . BDD::escape_int($offset); // TODO : "natural join" $select = "select uid_page_vers from " . BDD::table("_liens") . " join " . BDD::table("_pages") . " on _uid_page = uid_page_vers" . " natural join " . BDD::table($this->type_liens("enfants")) - . " where groupe = 'enfants' and uid_page_de = " . $this->uid() + . " where groupe = 'enfants' and uid_page_de = " . BDD::escape_int($this->uid()) . $condition . $select_order . $select_limit @@ -272,9 +277,9 @@ class mPage { $insert .= ", _type = '" . $nom_module . "'"; foreach (self::$attributs_globaux as $nom => $attr) { if (array_key_exists($nom, $module['attributs'])) { - $insert .= ", $nom = '" . mysql_real_escape_string($module['attributs'][$nom]['defaut']) . "'"; + $insert .= ", $nom = '" . BDD::escape($module['attributs'][$nom]['defaut']) . "'"; } else { - $insert .= ", $nom = '" . mysql_real_escape_string($attr['defaut']) . "'"; + $insert .= ", $nom = '" . BDD::escape($attr['defaut']) . "'"; } } @@ -286,7 +291,7 @@ class mPage { $insert .= "_uid_page = " . $uid_nouvelle_page; foreach ($module['attributs'] as $nom => $attr) { if (!$attr['global']) { - $insert .= ", $nom = '" . mysql_real_escape_string($attr['defaut']) . "'"; + $insert .= ", $nom = '" . BDD::escape($attr['defaut']) . "'"; } } @@ -319,13 +324,13 @@ class mPage { public static function page_systeme($nom) { return self::page_uid( BDD::select_one( - "select _uid_page from " . BDD::table("_pages") . " where nom_systeme = '" . mysql_real_escape_string($nom) . "';" + "select _uid_page from " . BDD::table("_pages") . " where nom_systeme = '" . BDD::escape($nom) . "';" ) ); } public static function page_uid($uid) { - $select = "select _type from " . BDD::table("_pages") . " where _uid_page = " . $uid . ";"; + $select = "select _type from " . BDD::table("_pages") . " where _uid_page = " . BDD::escape_int($uid) . ";"; $type = BDD::select_one($select); $ret = new $type(); $ret->uid = $uid; @@ -374,9 +379,15 @@ class mPage { private function get_prop_direct($nom) { // Récupère l'attribut "$nom" depuis la BDD. - $select_table = (self::est_propriete_globale($nom)) ? "_pages" : $this->nom_module(); - $select = "select $nom from " . BDD::table($select_table) . " where _uid_page = " . $this->uid() . ";"; - return new BDDCell($this->uid(), $nom, BDD::select_one($select)); + if (self::est_attribut_global($nom)) { + $select_table = "_pages"; + $type = self::$attributs_globaux[$nom]['type']; + } else { + $select_table = $this->nom_module(); + $type = $this->module['attributs'][$nom]['type']; + } + $select = "select $nom from " . BDD::table($select_table) . " where _uid_page = " . BDD::escape_int($this->uid()) . ";"; + return new BDDCell($this->uid(), $nom, $type, BDD::select_one($select)); } public function __set($nom, $val) { @@ -391,8 +402,8 @@ class mPage { public function set_prop_direct($nom, $val) { // Modifie l'attribut "$nom" dans la BDD. - $update_table = (self::est_propriete_globale($nom)) ? "_pages" : $this->nom_module(); - $update = "update " . BDD::table($update_table) . " set $nom = '" . mysql_real_escape_string(toString($val)) . "' where _uid_page = " . $this->uid(); + $update_table = (self::est_attribut_global($nom)) ? "_pages" : $this->nom_module(); + $update = "update " . BDD::table($update_table) . " set $nom = '" . BDD::escape(toString($val)) . "' where _uid_page = " . $this->uid(); BDD::unbuf_query($update); if ($nom != "date_modification") { $this->date_modification = time(); diff --git a/cms2/modules/galerie/galerie.php5 b/cms2/modules/galerie/galerie.php5 index f3caee6..11ab79c 100644 --- a/cms2/modules/galerie/galerie.php5 +++ b/cms2/modules/galerie/galerie.php5 @@ -8,14 +8,6 @@ abstract class mGalerieBase extends mPage { public static function info($module) { $cvars = get_class_vars($module); - /* echo "
";
-		var_dump($module);
-		var_dump($cvars);
-		echo "\n\n\n";
-		$cvars = get_class_vars("mGalerieBase");
-		var_dump($cvars);
-		echo "
"; - exit;*/ ressources_statiques("i_icone_nouvelle_page c_style"); ressources_dynamiques("h_page h_miniature h_mini_miniature"); type_liens("enfants", $cvars['type_enfants']);