Changeset 84556 in spip-zone for _plugins_/acces_restreint
- Timestamp:
- Sep 10, 2014, 2:02:12 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
_plugins_/acces_restreint/trunk/action/api_docrestreint.php
r74479 r84556 16 16 17 17 /** 18 * acces aux documents joints securise 18 * Acces aux documents joints securise 19 * 19 20 * verifie soit que le demandeur est authentifie 20 21 * soit que le document est publie, c'est-a-dire … … 27 28 */ 28 29 function action_api_docrestreint_dist($arg=null) { 29 $status = 404; 30 31 if (is_null($arg)) 32 $arg =_request('arg'); 33 34 $arg = explode("/",$arg); 35 36 // supprimer et vider les buffers qui posent des problemes de memory limit 37 // http://www.php.net/manual/en/function.readfile.php#81032 30 31 // Obtenir l'argument '{id_document}/{cle_action}/{chemin_fichier.ext}' 32 if (is_null($arg)) { 33 $arg = _request('arg'); 34 } 35 $arg = explode("/", $arg); 36 37 // Supprimer et vider les buffers qui posent des problemes de memory limit 38 accesrestreint_vider_buffers(); 39 40 // manque des arguments : 404 41 if (count($arg) < 3) { 42 accesrestreint_afficher_404_document(); 43 return; 44 } 45 46 // Séparer les 3 arguments 47 // file ($f) exige pour eviter le scan id_document par id_document 48 $id_document = intval(array_shift($arg)); 49 $cle = array_shift($arg); 50 $f = implode("/", $arg); 51 52 /** 53 * URL de test de fonctionnement 54 * @see accesrestreint_gerer_htaccess() 55 */ 56 if ($id_document==0 AND $cle==1 AND $f=="test/.test") { 57 echo "OK"; 58 return; 59 } 60 61 include_spip('inc/documents'); 62 63 $file = get_spip_doc($f); 64 spip_log($file, 'dbg'); 65 66 $status = $doc = false; 67 $dossiers_a_exclure = array('nl'); 68 69 // securite : on refuse tout ../ ou url absolue 70 if ((strpos($f, '../') !== false) OR (preg_match(',^\w+://,', $f))) { 71 $status = 403; 72 } elseif (!file_exists($file) OR !is_readable($file)) { 73 $status = 404; 74 } 75 76 // Si c'est dans un sous-dossier explicitement utilisé pour autre chose que les documents 77 // (exemple : les newsletters) 78 // et bien on ne teste pas l'accès 79 elseif (preg_match('%^(' . join('|', $dossiers_a_exclure) . ')/%', $f)){ 80 $status = 200; 81 } 82 else { 83 $where = "documents.fichier=".sql_quote(set_spip_doc($file)) 84 . ($id_document ? " AND documents.id_document=".intval($id_document): ''); 85 spip_log($where,'dbg'); 86 87 $doc = sql_fetsel("documents.id_document, documents.titre, documents.fichier, types.mime_type, types.inclus, documents.extension", "spip_documents AS documents LEFT JOIN spip_types_documents AS types ON documents.extension=types.extension",$where); 88 spip_log($doc,'dbg'); 89 if (!$doc) { 90 $status = 404; 91 } 92 else { 93 94 // ETag pour gerer le status 304 95 $ETag = md5($file . ': '. filemtime($file)); 96 if (isset($_SERVER['HTTP_IF_NONE_MATCH']) 97 AND $_SERVER['HTTP_IF_NONE_MATCH'] == $ETag) { 98 http_status(304); // Not modified 99 exit; 100 } 101 else { 102 header('ETag: '.$ETag); 103 } 104 105 // 106 // Verifier les droits de lecture du document 107 108 // en controlant la cle passee en argument si elle est dispo 109 // (perf issue : toutes les urls ont en principe cette cle fournie dans la page au moment du calcul de la page) 110 if ($cle){ 111 include_spip('inc/securiser_action'); 112 if (!verifier_cle_action($doc['id_document'].','.$f, $cle)) { 113 spip_log("acces interdit $cle erronee"); 114 $status = 403; 115 } 116 } 117 // en verifiant le droit explicitement sinon, plus lent ! 118 else { 119 if (!function_exists("autoriser")) 120 include_spip("inc/autoriser"); 121 if (!autoriser('voir', 'document', $doc['id_document'])) { 122 $status = 403; 123 spip_log("acces interdit $cle erronee"); 124 } 125 } 126 } 127 } 128 129 130 switch($status) { 131 132 case 403: 133 include_spip('inc/minipres'); 134 echo minipres("","","",true); 135 break; 136 137 case 404: 138 accesrestreint_afficher_404_document(); 139 break; 140 141 default: 142 header("Content-Type: ". $doc['mime_type']); 143 // pour les images ne pas passer en attachment 144 // sinon, lorsqu'on pointe directement sur leur adresse, 145 // le navigateur les downloade au lieu de les afficher 146 147 if ($doc['inclus']=='non') { 148 149 $f = basename($file); 150 // ce content-type est necessaire pour eviter des corruptions de zip dans ie6 151 header('Content-Type: application/octet-stream'); 152 153 header("Content-Disposition: attachment; filename=\"$f\";"); 154 header("Content-Transfer-Encoding: binary"); 155 156 // fix for IE catching or PHP bug issue 157 header("Pragma: public"); 158 header("Expires: 0"); // set expiration time 159 header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); 160 161 } 162 else { 163 header("Expires: 3600"); // set expiration time 164 } 165 166 if ($cl = filesize($file)) 167 header("Content-Length: ". $cl); 168 169 readfile($file); 170 break; 171 } 172 173 } 174 175 /** 176 * Supprimer et vider les buffers qui posent des problemes de memory limit 177 * 178 * @link http://www.php.net/manual/en/function.readfile.php#81032 179 * 180 * @return void 181 **/ 182 function accesrestreint_vider_buffers() { 38 183 @ini_set("zlib.output_compression","0"); // pour permettre l'affichage au fur et a mesure 39 184 @ini_set("output_buffering","off"); … … 44 189 @ob_end_clean(); 45 190 } 46 47 48 if (count($arg)>=3){49 50 $id_document = intval(array_shift($arg));51 $cle = array_shift($arg);52 // file exige pour eviter le scan id_document par id_document53 $f = implode("/",$arg);54 55 if ($id_document==056 AND $cle==157 AND $f=="test/.test") {58 echo "OK";59 return;60 }61 62 include_spip('inc/documents');63 64 $file = get_spip_doc($f);65 spip_log($file,'dbg');66 67 $status = $dcc = false;68 $dossiers_a_exclure = array('nl');69 70 // securite : on refuse tout ../ ou url absolue71 if (strpos($f,'../') !== false72 OR preg_match(',^\w+://,', $f)) {73 $status = 403;74 }75 else if (!file_exists($file) OR !is_readable($file)) {76 $status = 404;77 }78 // Si c'est dans un sous-dossier explicitement utilisé pour autre chose que les documents79 // (exemple : les newsletters)80 // et bien on ne teste pas l'accès81 elseif (preg_match('%^(' . join('|', $dossiers_a_exclure) . ')/%', $f)){82 $status = 200;83 }84 else {85 $where = "documents.fichier=".sql_quote(set_spip_doc($file))86 . ($id_document ? " AND documents.id_document=".intval($id_document): '');87 spip_log($where,'dbg');88 89 $doc = sql_fetsel("documents.id_document, documents.titre, documents.fichier, types.mime_type, types.inclus, documents.extension", "spip_documents AS documents LEFT JOIN spip_types_documents AS types ON documents.extension=types.extension",$where);90 spip_log($doc,'dbg');91 if (!$doc) {92 $status = 404;93 }94 else {95 96 // ETag pour gerer le status 30497 $ETag = md5($file . ': '. filemtime($file));98 if (isset($_SERVER['HTTP_IF_NONE_MATCH'])99 AND $_SERVER['HTTP_IF_NONE_MATCH'] == $ETag) {100 http_status(304); // Not modified101 exit;102 }103 else {104 header('ETag: '.$ETag);105 }106 107 //108 // Verifier les droits de lecture du document109 110 // en controlant la cle passee en argument si elle est dispo111 // (perf issue : toutes les urls ont en principe cette cle fournie dans la page au moment du calcul de la page)112 if ($cle){113 include_spip('inc/securiser_action');114 if (!verifier_cle_action($doc['id_document'].','.$f, $cle)) {115 spip_log("acces interdit $cle erronee");116 $status = 403;117 }118 }119 // en verifiant le droit explicitement sinon, plus lent !120 else {121 if (!function_exists("autoriser"))122 include_spip("inc/autoriser");123 if (!autoriser('voir', 'document', $doc['id_document'])) {124 $status = 403;125 spip_log("acces interdit $cle erronee");126 }127 }128 }129 }130 }131 132 133 switch($status) {134 135 case 403:136 include_spip('inc/minipres');137 echo minipres("","","",true);138 break;139 140 case 404:141 http_status(404);142 include_spip('inc/minipres');143 echo minipres(_T('erreur').' 404',144 _T('medias:info_document_indisponible'),"",true);145 break;146 147 default:148 header("Content-Type: ". $doc['mime_type']);149 // pour les images ne pas passer en attachment150 // sinon, lorsqu'on pointe directement sur leur adresse,151 // le navigateur les downloade au lieu de les afficher152 153 if ($doc['inclus']=='non') {154 155 $f = basename($file);156 // ce content-type est necessaire pour eviter des corruptions de zip dans ie6157 header('Content-Type: application/octet-stream');158 159 header("Content-Disposition: attachment; filename=\"$f\";");160 header("Content-Transfer-Encoding: binary");161 162 // fix for IE catching or PHP bug issue163 header("Pragma: public");164 header("Expires: 0"); // set expiration time165 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");166 167 }168 else {169 header("Expires: 3600"); // set expiration time170 }171 172 if ($cl = filesize($file))173 header("Content-Length: ". $cl);174 175 readfile($file);176 break;177 }178 179 191 } 180 192 181 ?> 193 /** 194 * Retourne une page 404 indiquant un document introuvable 195 * 196 * @return void 197 **/ 198 function accesrestreint_afficher_404_document() { 199 http_status(404); 200 include_spip('inc/minipres'); 201 echo minipres(_T('erreur') . ' 404', _T('medias:info_document_indisponible'), "", true); 202 }
Note: See TracChangeset
for help on using the changeset viewer.