Browse Source

Changement dans le changement du token de prévisualisation par r23636 (toujours activable par define).

Le token n’est plus calculé avec le type/id de l’objet mais à partir de l’URL. 
Corrolaire 1 : si l’URL de l’objet change (parce qu’on a changé son titre), le token ne sera plus valable. 
Corrolaire 2 : on peut demander un token pour n’importe quelle URL (Bonux va l’utiliser pour son bouton de relecture)

De plus, on ne permet d’accéder aux redirections que si l’objet de destination est publié ou qu’on est en mode preview et qu’on a l’autorisation de voir.
On retourne sur une page 404 sinon.
update_jquery
Matthieu Marcillaud 5 years ago
parent
commit
475e6c33db
  1. 100
      ecrire/action/redirect.php
  2. 31
      ecrire/inc/securiser_action.php
  3. 13
      ecrire/inc/utils.php

100
ecrire/action/redirect.php

@ -38,50 +38,92 @@ if (!defined('_ECRIRE_INC_VERSION')) {
function action_redirect_dist() {
$type = _request('type');
$id = intval(_request('id'));
$page = false;
if ($m = _request('var_mode')) {
// verifier le type ou page transmis
if (!preg_match('/^\w+$/', $type)) {
$page = _request('page');
if (!preg_match('/^\w+$/', $page)) {
return;
}
}
if ($var_mode = _request('var_mode')) {
// forcer la mise a jour de l'url de cet objet !
if (!defined('_VAR_URLS')) {
define('_VAR_URLS', true);
}
}
if (preg_match('/^\w+$/', $type)) {
$h = generer_url_entite_absolue($id, $type, '', '', true);
if ($page) {
$url = generer_url_public($page, '', true);
} else {
if ($page = _request('page')
and preg_match('/^\w+$/', $page)
$url = calculer_url_redirect_entite($type, $id, $var_mode);
}
$status = '302';
if ($url) {
if ($var_mode) {
$url = parametre_url($url, 'var_mode', $var_mode);
}
if ($var_mode == 'preview'
and defined('_PREVIEW_TOKEN')
and _PREVIEW_TOKEN
and autoriser('previsualiser')
) {
$h = generer_url_public($page, '', true);
} else {
return;
include_spip('inc/securiser_action');
$token = calculer_token_previsu($url);
$url = parametre_url($url, 'var_previewtoken', $token);
}
}
if ($m > '') {
$h = parametre_url($h, 'var_mode', $m);
if (_request('status') and _request('status') == '301') {
$status = '301';
}
} else {
$url = generer_url_public('404', '', true);
}
if ($m == 'preview'
and defined('_PREVIEW_TOKEN')
and _PREVIEW_TOKEN
and $type
and $id
and autoriser('previsualiser')
) {
include_spip('inc/securiser_action');
$token = calculer_token_previsu($type, $id);
$h = parametre_url($h, 'var_previewtoken', $token);
redirige_par_entete(str_replace('&', '&', $url), '', $status);
}
/**
* Retourne l’URL de l’objet sur lequel on doit rediriger
*
* On met en cache les calculs (si memoization),
* et on ne donne pas l’URL si la personne n’y a pas accès
*
* @param string $type
* @param int $id
* @param string $var_mode
*/
function calculer_url_redirect_entite($type, $id, $var_mode) {
// invalider le cache à chaque modif en bdd
$date = 0;
if (isset($GLOBALS['meta']['derniere_modif'])) {
$date = $GLOBALS['meta']['derniere_modif'];
}
$key = "url-$date-$type-$id";
$status = '302';
if (_request('status') and _request('status') == '301') {
$status = '301';
// Obtenir l’url et si elle est publié du cache memoization
if (function_exists('cache_get') and $desc = cache_get($key)) {
list($url, $publie) = $desc;
}
// Si on ne l’a pas trouvé, ou si var mode, on calcule l’url et son état publie
if (!$desc or $var_mode) {
$publie = objet_test_si_publie($type, $id);
$url = generer_url_entite_absolue($id, $type, '', '', true);
if (function_exists('cache_set')) {
cache_set($key, array($url, $publie), 3600);
}
}
if ($h) {
redirige_par_entete(str_replace('&', '&', $h), '', $status);
} else {
redirige_par_entete('/', '', $status);
// On valide l’url si elle est publiee ; sinon si preview on teste l’autorisation
if ($publie) {
return $url;
} elseif (defined('_VAR_PREVIEW') and _VAR_PREVIEW and autoriser('voir', $type, $id)) {
return $url;
}
}
return;
}

31
ecrire/inc/securiser_action.php

@ -301,13 +301,12 @@ function verifier_cle_action($action, $cle) {
* pour qu’une personne tierce le relise. Valable quelques temps.
*
* @see verifier_token_previsu()
* @param string $type Type d’objet
* @param int $id_objet Identifiant de l’objet
* @param string $url Url à autoriser en prévisu
* @param int|null id_auteur qui génère le token de prévisu. Null utilisera auteur courant.
* @param string $alea Nom de l’alea à utiliser
* @return string Token, de la forme "{id}*{hash}"
*/
function calculer_token_previsu($type, $id_objet, $id_auteur = null, $alea = 'alea_ephemere') {
function calculer_token_previsu($url, $id_auteur = null, $alea = 'alea_ephemere') {
if (is_null($id_auteur)) {
if (!empty($GLOBALS['visiteur_session']['id_auteur'])) {
$id_auteur = $GLOBALS['visiteur_session']['id_auteur'];
@ -316,7 +315,10 @@ function calculer_token_previsu($type, $id_objet, $id_auteur = null, $alea = 'al
if (!$id_auteur = intval($id_auteur)) {
return "";
}
$token = _action_auteur('previsualiser-' . $type . '-' . $id_objet, $id_auteur, null, $alea);
// On nettoie l’URL de tous les var_.
$url = nettoyer_uri_var($url);
$token = _action_auteur('previsualiser-' . $url, $id_auteur, null, $alea);
return "$id_auteur-$token";
}
@ -338,8 +340,7 @@ function verifier_token_previsu($token) {
// retrouver auteur / hash
$e = explode('-', $token, 2);
if (count($e) == 2 and is_numeric(reset($e))) {
list($id_auteur, $hash) = $e;
$id_auteur = intval($id_auteur);
$id_auteur = intval(reset($e));
} else {
return false;
}
@ -347,22 +348,12 @@ function verifier_token_previsu($token) {
// calculer le type et id de l’url actuelle
include_spip('inc/urls');
include_spip('inc/filtres_mini');
$self = url_absolue(self());
$contexte = urls_decoder_url($self);
list($type, $contexte) = $contexte;
if (is_numeric($type)) {
return false;
}
$_id_table = id_table_objet($type);
if (empty($contexte[$_id_table])) {
return false;
}
$id = $contexte[$_id_table];
$url = url_absolue(self());
// verifier le token
$_token = calculer_token_previsu($type, $id, $id_auteur, 'alea_ephemere');
$_token = calculer_token_previsu($url, $id_auteur, 'alea_ephemere');
if (!$_token or $token !== $_token) {
$_token = calculer_token_previsu($type, $id, $id_auteur, 'alea_ephemere_ancien');
$_token = calculer_token_previsu($url, $id_auteur, 'alea_ephemere_ancien');
if (!$_token or $token !== $_token) {
return false;
}
@ -370,8 +361,6 @@ function verifier_token_previsu($token) {
return array(
'id_auteur' => $id_auteur,
'type' => $type,
'id_objet' => $id
);
}

13
ecrire/inc/utils.php

@ -591,15 +591,22 @@ function nettoyer_uri($reset = null) {
return $propre;
}
$done = true;
return $propre = nettoyer_uri_var($GLOBALS['REQUEST_URI']);
}
$uri1 = $GLOBALS['REQUEST_URI'];
/**
* Nettoie une request_uri des paramètres var_xxx
* @param $request_uri
* @return string
*/
function nettoyer_uri_var($request_uri) {
$uri1 = $request_uri;
do {
$uri = $uri1;
$uri1 = preg_replace(',([?&])(PHPSESSID|(var_[^=&]*))=[^&]*(&|$),i',
'\1', $uri);
} while ($uri <> $uri1);
return $propre = (preg_replace(',[?&]$,', '', $uri1));
return preg_replace(',[?&]$,', '', $uri1);
}

Loading…
Cancel
Save