Valider 475e6c33 rédigé par marcimat's avatar marcimat
Parcourir les fichiers

Changement dans le changement du token de prévisualisation par r23636...

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.
parent b3d0259f
Chargement en cours
Chargement en cours
Chargement en cours
Chargement en cours
+71 −29
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -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)
		) {
			$h = generer_url_public($page, '', true);
		} else {
			return;
		}
		$url = calculer_url_redirect_entite($type, $id, $var_mode);
	}

	if ($m > '') {
		$h = parametre_url($h, 'var_mode', $m);
	$status = '302';
	if ($url) {
		if ($var_mode) {
			$url = parametre_url($url, 'var_mode', $var_mode);
		}

	if ($m == 'preview'
		if ($var_mode == '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);
			$token = calculer_token_previsu($url);
			$url = parametre_url($url, 'var_previewtoken', $token);
		}

	$status = '302';
		if (_request('status') and _request('status') == '301') {
			$status = '301';
		}

	if ($h) {
		redirige_par_entete(str_replace('&', '&', $h), '', $status);
	} else {
		redirige_par_entete('/', '', $status);
		$url = generer_url_public('404', '', true);
	}

	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";

	// 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);
		}
	}

	// 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;
}
 No newline at end of file
+10 −21
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -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
	);
}

+10 −3
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -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);
}