Skip to content
Extraits de code Groupes Projets
Valider bf58623c rédigé par cerdic's avatar cerdic
Parcourir les fichiers

Ferme #1963 : calculer une url d'action pour un n'importe quel auteur (par son id_auteur)

En mode url/array de securiser_action on peut lui passer un id_auteur dans l'argument $att, auquel cas l'url sera construite pour cet id_auteur précis.
PHPDoc sur securiser_action et fonctions satellites, pour expliciter/documenter les différents arguments a tiroir
La fonction calculer_action_auteur() parfois appelée directement prend aussi un $id_auteur optionnel en second argument

A contrario, le mode formulaire qui suppose une interaction avec l'auteur connecté ne peut être généré que pour celui-ci, et la verification de signature de l'action, qui s'entend aussi pour l'auteur connecté, ne peut se faire que pour celui-ci également
parent e92a1c24
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -12,11 +12,26 @@ ...@@ -12,11 +12,26 @@
if (!defined('_ECRIRE_INC_VERSION')) return; if (!defined('_ECRIRE_INC_VERSION')) return;
// interface d'appel: /**
// - au moins un argument: retourne une URL ou un formulaire securises * interface d'appel:
// - sans argument: verifie la securite et retourne _request('arg'), ou exit. * - au moins un argument: retourne une URL ou un formulaire securises
* - sans argument: verifie la securite et retourne _request('arg'), ou exit.
// http://doc.spip.org/@inc_securiser_action_dist *
* http://doc.spip.org/@inc_securiser_action_dist
*
* @param string $action
* @param string $arg
* @param string $redirect
* @param bool|int|string $mode
* -1 : renvoyer action, arg et hash sous forme de array()
* true ou false : renvoyer une url, avec & (false) ou & (true)
* string : renvoyer un formulaire
* @param string|int $att
* id_auteur pour lequel generer l'action en mode url ou array()
* atributs du formulaire en mode formulaire
* @param bool $public
* @return array|string
*/
function inc_securiser_action_dist($action='', $arg='', $redirect="", $mode=false, $att='', $public=false) function inc_securiser_action_dist($action='', $arg='', $redirect="", $mode=false, $att='', $public=false)
{ {
if ($action) if ($action)
...@@ -33,24 +48,39 @@ function inc_securiser_action_dist($action='', $arg='', $redirect="", $mode=fals ...@@ -33,24 +48,39 @@ function inc_securiser_action_dist($action='', $arg='', $redirect="", $mode=fals
} }
} }
// Attention: PHP applique urldecode sur $_GET mais pas sur $_POST /**
// cf http://fr.php.net/urldecode#48481 * Attention: PHP applique urldecode sur $_GET mais pas sur $_POST
// http://doc.spip.org/@securiser_action_auteur * cf http://fr.php.net/urldecode#48481
function securiser_action_auteur($action, $arg, $redirect="", $mode=false, $att='', $public=false) * http://doc.spip.org/@securiser_action_auteur
{ *
static $id_auteur=0, $pass; * @param string $action
if (!$id_auteur) { * @param string $arg
list($id_auteur, $pass) = caracteriser_auteur(); * @param string $redirect
} * @param bool|int|string $mode
$hash = _action_auteur("$action-$arg", $id_auteur, $pass, 'alea_ephemere'); * -1 : renvoyer action, arg et hash sous forme de array()
* true ou false : renvoyer une url, avec & (false) ou & (true)
* string : renvoyer un formulaire
* @param string|int $att
* id_auteur pour lequel generer l'action en mode url ou array()
* atributs du formulaire en mode formulaire
* @param bool $public
* @return array|string
*/
function securiser_action_auteur($action, $arg, $redirect="", $mode=false, $att='', $public=false) {
// mode URL ou array
if (!is_string($mode)){ if (!is_string($mode)){
$hash = calculer_action_auteur("$action-$arg",is_numeric($att)?$att:null);
$r = rawurlencode($redirect); $r = rawurlencode($redirect);
if ($mode===-1) if ($mode===-1)
return array('action'=>$action,'arg'=>$arg,'hash'=>$hash); return array('action'=>$action,'arg'=>$arg,'hash'=>$hash);
else else
return generer_url_action($action, "arg=$arg&hash=$hash" . (!$r ? '' : "&redirect=$r"), $mode, $att); return generer_url_action($action, "arg=$arg&hash=$hash" . (!$r ? '' : "&redirect=$r"), $mode, $public);
} }
// mode formulaire
$hash = calculer_action_auteur("$action-$arg");
$att .= " style='margin: 0px; border: 0px'"; $att .= " style='margin: 0px; border: 0px'";
if ($redirect) if ($redirect)
$redirect = "\n\t\t<input name='redirect' type='hidden' value='". str_replace("'", '&#39;', $redirect) ."' />"; $redirect = "\n\t\t<input name='redirect' type='hidden' value='". str_replace("'", '&#39;', $redirect) ."' />";
...@@ -61,14 +91,18 @@ function securiser_action_auteur($action, $arg, $redirect="", $mode=false, $att= ...@@ -61,14 +91,18 @@ function securiser_action_auteur($action, $arg, $redirect="", $mode=false, $att=
return generer_form_action($action, $mode, $att, $public); return generer_form_action($action, $mode, $att, $public);
} }
// http://doc.spip.org/@caracteriser_auteur /**
function caracteriser_auteur() { * Caracteriser un auteur : l'auteur loge si $id_auteur=null
global $visiteur_session; *
* http://doc.spip.org/@caracteriser_auteur
*
* @param int|null $id_auteur
* @return array
*/
function caracteriser_auteur($id_auteur=null) {
static $caracterisation = array(); static $caracterisation = array();
if ($caracterisation) return $caracterisation; if (is_null($id_auteur) AND !isset($GLOBALS['visiteur_session']['id_auteur'])) {
if (!isset($visiteur_session['id_auteur'])) {
// si l'auteur courant n'est pas connu alors qu'il peut demander une action // si l'auteur courant n'est pas connu alors qu'il peut demander une action
// c'est une connexion par php_auth ou 1 instal, on se rabat sur le cookie. // c'est une connexion par php_auth ou 1 instal, on se rabat sur le cookie.
// S'il n'avait pas le droit de realiser cette action, le hash sera faux. // S'il n'avait pas le droit de realiser cette action, le hash sera faux.
...@@ -80,14 +114,19 @@ function caracteriser_auteur() { ...@@ -80,14 +114,19 @@ function caracteriser_auteur() {
} else return array('0',''); } else return array('0','');
} }
// Eviter l'acces SQL si le pass est connu de PHP // Eviter l'acces SQL si le pass est connu de PHP
$id_auteur = $visiteur_session['id_auteur']; if (is_null($id_auteur)){
if (isset($visiteur_session['pass']) AND $visiteur_session['pass']) $id_auteur = isset($GLOBALS['visiteur_session']['id_auteur'])?$GLOBALS['visiteur_session']['id_auteur']:0;
return $caracterisation = array($id_auteur, $visiteur_session['pass']); if (isset($GLOBALS['visiteur_session']['pass']) AND $GLOBALS['visiteur_session']['pass'])
else if ($id_auteur>0) { return $caracterisation[$id_auteur] = array($id_auteur, $GLOBALS['visiteur_session']['pass']);
}
if ($caracterisation[$id_auteur]) return $caracterisation[$id_auteur];
if ($id_auteur) {
include_spip('base/abstract_sql'); include_spip('base/abstract_sql');
$t = sql_fetsel("id_auteur, pass", "spip_auteurs", "id_auteur=$id_auteur"); $t = sql_fetsel("id_auteur, pass", "spip_auteurs", "id_auteur=$id_auteur");
if ($t) if ($t)
return $caracterisation = array($t['id_auteur'], $t['pass']); return $caracterisation[$id_auteur] = array($t['id_auteur'], $t['pass']);
include_spip('inc/minipres'); include_spip('inc/minipres');
echo minipres(); echo minipres();
exit; exit;
...@@ -98,7 +137,19 @@ function caracteriser_auteur() { ...@@ -98,7 +137,19 @@ function caracteriser_auteur() {
} }
} }
// http://doc.spip.org/@_action_auteur /**
* Calcule une cle securisee pour une action et un auteur donnes
* utilisee pour generer des urls personelles pour executer une action qui modifie la base
* et verifier la legitimite de l'appel a l'action
*
* http://doc.spip.org/@_action_auteur
*
* @param string $action
* @param int $id_auteur
* @param string $pass
* @param string $alea
* @return string
*/
function _action_auteur($action, $id_auteur, $pass, $alea) { function _action_auteur($action, $id_auteur, $pass, $alea) {
static $sha = array(); static $sha = array();
if (!isset($sha[$id_auteur.$pass.$alea])){ if (!isset($sha[$id_auteur.$pass.$alea])){
...@@ -121,18 +172,34 @@ function _action_auteur($action, $id_auteur, $pass, $alea) { ...@@ -121,18 +172,34 @@ function _action_auteur($action, $id_auteur, $pass, $alea) {
return md5($action.$sha[$id_auteur.$pass.$alea]); return md5($action.$sha[$id_auteur.$pass.$alea]);
} }
// http://doc.spip.org/@calculer_action_auteur /**
function calculer_action_auteur($action) { * Calculer le hash qui signe une action pour un auteur
list($id_auteur, $pass) = caracteriser_auteur(); * http://doc.spip.org/@calculer_action_auteur
*
* @param string $action
* @param int|null $id_auteur
* @return string
*/
function calculer_action_auteur($action, $id_auteur=null) {
list($id_auteur, $pass) = caracteriser_auteur($id_auteur);
return _action_auteur($action, $id_auteur, $pass, 'alea_ephemere'); return _action_auteur($action, $id_auteur, $pass, 'alea_ephemere');
} }
// http://doc.spip.org/@verifier_action_auteur
function verifier_action_auteur($action, $valeur) { /**
* Verifier le hash de signature d'une action
* toujours exclusivement pour l'auteur en cours
* http://doc.spip.org/@verifier_action_auteur
*
* @param $action
* @param $hash
* @return bool
*/
function verifier_action_auteur($action, $hash) {
list($id_auteur, $pass) = caracteriser_auteur(); list($id_auteur, $pass) = caracteriser_auteur();
if ($valeur == _action_auteur($action, $id_auteur, $pass, 'alea_ephemere')) if ($hash == _action_auteur($action, $id_auteur, $pass, 'alea_ephemere'))
return true; return true;
if ($valeur == _action_auteur($action, $id_auteur, $pass, 'alea_ephemere_ancien')) if ($hash == _action_auteur($action, $id_auteur, $pass, 'alea_ephemere_ancien'))
return true; return true;
return false; return false;
} }
...@@ -142,9 +209,15 @@ function verifier_action_auteur($action, $valeur) { ...@@ -142,9 +209,15 @@ function verifier_action_auteur($action, $valeur) {
// par exemple que l'URL d'un document a la bonne cle de lecture // par exemple que l'URL d'un document a la bonne cle de lecture
// //
// Le secret du site doit rester aussi secret que possible, et est eternel /**
// On ne doit pas l'exporter * Renvoyer le secret du site, et le generer si il n'existe pas encore
// http://doc.spip.org/@secret_du_site * Le secret du site doit rester aussi secret que possible, et est eternel
* On ne doit pas l'exporter
*
* http://doc.spip.org/@secret_du_site
*
* @return string
*/
function secret_du_site() { function secret_du_site() {
if (!isset($GLOBALS['meta']['secret_du_site'])){ if (!isset($GLOBALS['meta']['secret_du_site'])){
include_spip('base/abstract_sql'); include_spip('base/abstract_sql');
...@@ -160,7 +233,13 @@ function secret_du_site() { ...@@ -160,7 +233,13 @@ function secret_du_site() {
return $GLOBALS['meta']['secret_du_site']; return $GLOBALS['meta']['secret_du_site'];
} }
// http://doc.spip.org/@calculer_cle_action /**
* Calculer une signature valable pour une action et pour le site
* http://doc.spip.org/@calculer_cle_action
*
* @param string $action
* @return string
*/
function calculer_cle_action($action) { function calculer_cle_action($action) {
if (function_exists('sha1')) if (function_exists('sha1'))
return sha1($action . secret_du_site()); return sha1($action . secret_du_site());
...@@ -168,7 +247,14 @@ function calculer_cle_action($action) { ...@@ -168,7 +247,14 @@ function calculer_cle_action($action) {
return md5($action . secret_du_site()); return md5($action . secret_du_site());
} }
// http://doc.spip.org/@verifier_cle_action /**
* Verifier la cle de signature d'une action valable pour le site
* http://doc.spip.org/@verifier_cle_action
*
* @param string $action
* @param string $cle
* @return bool
*/
function verifier_cle_action($action, $cle) { function verifier_cle_action($action, $cle) {
return ($cle == calculer_cle_action($action)); return ($cle == calculer_cle_action($action));
} }
......
...@@ -1347,11 +1347,20 @@ function generer_form_ecrire($script, $corps, $atts='', $submit='') { ...@@ -1347,11 +1347,20 @@ function generer_form_ecrire($script, $corps, $atts='', $submit='') {
. "</div></form>\n"; . "</div></form>\n";
} }
// Attention, JS/Ajax n'aime pas le melange de param GET/POST /**
// On n'applique pas la recommandation ci-dessus pour les scripts publics * Generer un formulaire pour lancer une action vers $script
// qui ne sont pas destines a etre mis en signets *
* Attention, JS/Ajax n'aime pas le melange de param GET/POST
// http://doc.spip.org/@generer_form_action * On n'applique pas la recommandation ci-dessus pour les scripts publics
* qui ne sont pas destines a etre mis en signets
* http://doc.spip.org/@generer_form_action
*
* @param string $script
* @param string $corps
* @param string $atts
* @param bool $public
* @return string
*/
function generer_form_action($script, $corps, $atts='', $public=false) { function generer_form_action($script, $corps, $atts='', $public=false) {
// si l'on est dans l'espace prive, on garde dans l'url // si l'on est dans l'espace prive, on garde dans l'url
// l'exec a l'origine de l'action, qui permet de savoir si il est necessaire // l'exec a l'origine de l'action, qui permet de savoir si il est necessaire
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter