Changeset 84556 in spip-zone


Ignore:
Timestamp:
Sep 10, 2014, 2:02:12 PM (6 years ago)
Author:
marcimat@…
Message:

Petit reformattage pour y voir un rien plus clair dans la fonction api_docrestreint. À suivre...

File:
1 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/acces_restreint/trunk/action/api_docrestreint.php

    r74479 r84556  
    1616
    1717/**
    18  * acces aux documents joints securise
     18 * Acces aux documents joints securise
     19 *
    1920 * verifie soit que le demandeur est authentifie
    2021 * soit que le document est publie, c'est-a-dire
     
    2728 */
    2829function 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**/
     182function accesrestreint_vider_buffers() {
    38183        @ini_set("zlib.output_compression","0"); // pour permettre l'affichage au fur et a mesure
    39184        @ini_set("output_buffering","off");
     
    44189                @ob_end_clean();
    45190        }
    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_document
    53                 $f = implode("/",$arg);
    54 
    55                 if ($id_document==0
    56                         AND $cle==1
    57                   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 absolue
    71                 if (strpos($f,'../') !== false
    72                   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 documents
    79                 // (exemple : les newsletters)
    80                 // et bien on ne teste pas l'accès
    81                 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 304
    97                                 $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 modified
    101                                         exit;
    102                                 }
    103                                 else {
    104                                         header('ETag: '.$ETag);
    105                                 }
    106 
    107                                 //
    108                                 // Verifier les droits de lecture du document
    109 
    110                                 // en controlant la cle passee en argument si elle est dispo
    111                                 // (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 attachment
    150                 // sinon, lorsqu'on pointe directement sur leur adresse,
    151                 // le navigateur les downloade au lieu de les afficher
    152 
    153                 if ($doc['inclus']=='non') {
    154 
    155                         $f = basename($file);
    156                         // ce content-type est necessaire pour eviter des corruptions de zip dans ie6
    157                         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 issue
    163                         header("Pragma: public");
    164                         header("Expires: 0"); // set expiration time
    165                         header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    166 
    167                 }
    168                 else {
    169                         header("Expires: 3600"); // set expiration time
    170                 }
    171 
    172                 if ($cl = filesize($file))
    173                         header("Content-Length: ". $cl);
    174 
    175                 readfile($file);
    176                 break;
    177         }
    178 
    179191}
    180192
    181 ?>
     193/**
     194 * Retourne une page 404 indiquant un document introuvable
     195 *
     196 * @return void
     197**/
     198function 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.