/** * Detecter les demande d'acces aux pages restreintes * et re-orienter vers une 401 si necessaire * * @param array $contexte * @return array */ function accesrestreint_page_indisponible($contexte) { if ($contexte['status'] == '404') { $objet = ""; if (isset($contexte['type'])) { $objet = $contexte['type']; } elseif (isset($contexte['type-page'])) { $objet = $contexte['type-page']; } elseif (isset($contexte['fond_erreur'])) { include_spip('inc/urls'); define('_DEFINIR_CONTEXTE_TYPE_PAGE', true); $c2 = $contexte; list($fond2, $c2, $url_redirect) = urls_decoder_url(nettoyer_uri(), $contexte['fond_erreur'], $c2, true); $objet = $c2['type-page']; } if ($objet) { $table_sql = table_objet_sql($objet); $id_table_objet = id_table_objet($objet); if ($id = intval($contexte[$id_table_objet])) { $publie = true; if (include_spip("base/objets") and function_exists("objet_test_si_publie")) { $publie = objet_test_si_publie($objet, $id); } else { $trouver_table = charger_fonction('trouver_table', 'base'); $desc = $trouver_table($table_sql); if (isset($desc['field']['statut'])) { $statut = sql_getfetsel('statut', $table_sql, "{$id_table_objet}=" . intval($id)); if ($statut != 'publie') { $publie = false; } } } include_spip('inc/autoriser'); if ($publie and !autoriser('voir', $objet, $id)) { // c'est un contenu restreint $contexte['status'] = '401'; $contexte['code'] = '401 Unauthorized'; $contexte['fond'] = '401'; $contexte['erreur'] = _T('accesrestreint:info_acces_restreint'); $contexte['cible'] = self(); if (!isset($contexte['objet'])) { $contexte['objet'] = $objet; $contexte['id_objet'] = $id; } } } } } return $contexte; }
function form_hidden($action) { $contexte = array(); include_spip('inc/urls'); if ($p = urls_decoder_url($action, '') and reset($p)) { $fond = array_shift($p); if ($fond != '404') { $contexte = array_shift($p); $contexte['page'] = $fond; $action = preg_replace('/([?]' . preg_quote($fond) . '[^&=]*[0-9]+)(&|$)/', '?&', $action); } } // defaire ce qu'a injecte urls_decoder_url : a revoir en modifiant la signature de urls_decoder_url if (defined('_DEFINIR_CONTEXTE_TYPE') and _DEFINIR_CONTEXTE_TYPE) { unset($contexte['type']); } if (defined('_DEFINIR_CONTEXTE_TYPE_PAGE') and _DEFINIR_CONTEXTE_TYPE_PAGE) { unset($contexte['type-page']); } // on va remplir un tableau de valeurs en prenant bien soin de ne pas // ecraser les elements de la forme mots[]=1&mots[]=2 $values = array(); // d'abord avec celles de l'url if (false !== ($p = strpos($action, '?'))) { foreach (preg_split('/&(amp;)?/S', substr($action, $p + 1)) as $c) { list($var, $val) = explode('=', $c, 2); if ($var) { $val = rawurldecode($val); $var = rawurldecode($var); // decoder les [] eventuels if (preg_match(',\\[\\]$,S', $var)) { $values[] = array($var, $val); } else { if (!isset($values[$var])) { $values[$var] = array($var, $val); } } } } } // ensuite avec celles du contexte, sans doublonner ! foreach ($contexte as $var => $val) { if (preg_match(',\\[\\]$,S', $var)) { $values[] = array($var, $val); } else { if (!isset($values[$var])) { $values[$var] = array($var, $val); } } } // puis on rassemble le tout $hidden = array(); foreach ($values as $value) { list($var, $val) = $value; $hidden[] = '<input name="' . entites_html($var) . '"' . (is_null($val) ? '' : ' value="' . entites_html($val) . '"') . ' type="hidden"' . "\n/>"; } return join("", $hidden); }
function assembler($fond, $connect = '') { // flag_preserver est modifie ici, et utilise en globale // use_cache sert a informer le bouton d'admin pr savoir s'il met un * // contexte est utilise en globale dans le formulaire d'admin $GLOBALS['contexte'] = calculer_contexte(); $page = array('contexte_implicite' => calculer_contexte_implicite()); $page['contexte_implicite']['cache'] = $fond . preg_replace(',\\.[a-zA-Z0-9]*$,', '', preg_replace('/[?].*$/', '', $GLOBALS['REQUEST_URI'])); // Cette fonction est utilisee deux fois $cacher = charger_fonction('cacher', 'public', true); // Les quatre derniers parametres sont modifies par la fonction: // emplacement, validite, et, s'il est valide, contenu & age if ($cacher) { $res = $cacher($GLOBALS['contexte'], $GLOBALS['use_cache'], $chemin_cache, $page, $lastmodified); } else { $GLOBALS['use_cache'] = -1; } // Si un resultat est retourne, c'est un message d'impossibilite if ($res) { return array('texte' => $res); } if (!$chemin_cache || !$lastmodified) { $lastmodified = time(); } $headers_only = $_SERVER['REQUEST_METHOD'] == 'HEAD'; $calculer_page = true; // Pour les pages non-dynamiques (indiquees par #CACHE{duree,cache-client}) // une perennite valide a meme reponse qu'une requete HEAD (par defaut les // pages sont dynamiques) if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) and (!defined('_VAR_MODE') or !_VAR_MODE) and $chemin_cache and isset($page['entetes']) and isset($page['entetes']['Cache-Control']) and strstr($page['entetes']['Cache-Control'], 'max-age=') and !strstr($_SERVER['SERVER_SOFTWARE'], 'IIS/')) { $since = preg_replace('/;.*/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']); $since = str_replace('GMT', '', $since); if (trim($since) == gmdate("D, d M Y H:i:s", $lastmodified)) { $page['status'] = 304; $headers_only = true; $calculer_page = false; } } // Si requete HEAD ou Last-modified compatible, ignorer le texte // et pas de content-type (pour contrer le bouton admin de inc-public) if (!$calculer_page) { $page['texte'] = ""; } else { // si la page est prise dans le cache if (!$GLOBALS['use_cache']) { // Informer les boutons d'admin du contexte // (fourni par urls_decoder_url ci-dessous lors de la mise en cache) $GLOBALS['contexte'] = $page['contexte']; // vider les globales url propres qui ne doivent plus etre utilisees en cas // d'inversion url => objet // plus necessaire si on utilise bien la fonction urls_decoder_url #unset($_SERVER['REDIRECT_url_propre']); #unset($_ENV['url_propre']); } else { // Compat ascendante : // 1. $contexte est global // (a evacuer car urls_decoder_url gere ce probleme ?) // et calculer la page if (!test_espace_prive()) { include_spip('inc/urls'); list($fond, $GLOBALS['contexte'], $url_redirect) = urls_decoder_url(nettoyer_uri(), $fond, $GLOBALS['contexte'], true); } // squelette par defaut if (!strlen($fond)) { $fond = 'sommaire'; } // produire la page : peut mettre a jour $lastmodified $produire_page = charger_fonction('produire_page', 'public'); $page = $produire_page($fond, $GLOBALS['contexte'], $GLOBALS['use_cache'], $chemin_cache, null, $page, $lastmodified, $connect); if ($page === '') { $erreur = _T('info_erreur_squelette2', array('fichier' => spip_htmlspecialchars($fond) . '.' . _EXTENSION_SQUELETTES)); erreur_squelette($erreur); // eviter des erreurs strictes ensuite sur $page['cle'] en PHP >= 5.4 $page = array('texte' => '', 'erreur' => $erreur); } } if ($page and $chemin_cache) { $page['cache'] = $chemin_cache; } auto_content_type($page); $GLOBALS['flag_preserver'] |= headers_sent(); // Definir les entetes si ce n'est fait if (!$GLOBALS['flag_preserver']) { if ($GLOBALS['flag_ob']) { // Si la page est vide, produire l'erreur 404 ou message d'erreur pour les inclusions if (trim($page['texte']) === '' and _VAR_MODE != 'debug' and !isset($page['entetes']['Location'])) { $GLOBALS['contexte']['fond_erreur'] = $fond; $page = message_page_indisponible($page, $GLOBALS['contexte']); } // pas de cache client en mode 'observation' if (defined('_VAR_MODE') and _VAR_MODE) { $page['entetes']["Cache-Control"] = "no-cache,must-revalidate"; $page['entetes']["Pragma"] = "no-cache"; } } } } // Entete Last-Modified: // eviter d'etre incoherent en envoyant un lastmodified identique // a celui qu'on a refuse d'honorer plus haut (cf. #655) if ($lastmodified and !isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) and !isset($page['entetes']["Last-Modified"])) { $page['entetes']["Last-Modified"] = gmdate("D, d M Y H:i:s", $lastmodified) . " GMT"; } // fermer la connexion apres les headers si requete HEAD if ($headers_only) { $page['entetes']["Connection"] = "close"; } return $page; }