PageRenderTime 18ms CodeModel.GetById 8ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 0ms

/Gb/Session.php

https://bitbucket.org/gbouthenot/gbphpdb
PHP | 263 lines | 152 code | 46 blank | 65 comment | 31 complexity | 1b85267927366374a1c2a33058bd8f5c MD5 | raw file
  1<?php
  2/**
  3 * Gb_Session
  4 *
  5 * @author Gilles Bouthenot
  6 * @version $Revision$
  7 * @Id $Id$
  8 */
  9
 10if (!defined("_GB_PATH")) {
 11    define("_GB_PATH", dirname(__FILE__).DIRECTORY_SEPARATOR);
 12} elseif (_GB_PATH !== dirname(__FILE__).DIRECTORY_SEPARATOR) {
 13    throw new Exception("gbphpdb roots mismatch");
 14}
 15
 16require_once(_GB_PATH."Exception.php");
 17require_once(_GB_PATH."Glue.php");
 18require_once(_GB_PATH."String.php");
 19require_once(_GB_PATH."Log.php");
 20
 21
 22Class Gb_Session
 23{
 24    public static $sessionDir="";           // Répertoire des sessions par défaut session_path/PROJECTNAME/sessions
 25
 26    protected static $grandTimeOutMinutes;
 27
 28
 29    /**
 30     * Renvoie la revision de la classe ou un boolean si la version est plus petite que précisée, ou Gb_Exception
 31     *
 32     * @return boolean|integer
 33     * @throws Gb_Exception
 34     */
 35    public static function getRevision($mini=null, $throw=true)
 36    {
 37        $revision='$Revision$';
 38        $revision=(int) trim(substr($revision, strrpos($revision, ":")+2, -1));
 39        if ($mini===null) { return $revision; }
 40        if ($revision>=$mini) { return true; }
 41        if ($throw) { throw new Gb_Exception(__CLASS__." r".$revision."<r".$mini); }
 42        return false;
 43    }
 44
 45   /**
 46   * Renvoie le nom du repertoire de la session
 47   * crée le répertoire si besoin
 48   *
 49   * @return string sessionDir
 50   * @throws Gb_Exception
 51   */
 52    public static function getSessionDir()
 53    {
 54        if ( self::$sessionDir=="" ) {
 55            $updir=Gb_Glue::getOldSessionDir();
 56            $updir2=$updir.DIRECTORY_SEPARATOR.Gb_Glue::getProjectName();
 57            if ( (!is_dir($updir2) || !is_writable($updir2)) && is_dir($updir) && is_writable($updir) )
 58                @mkdir($updir2, 0700);
 59            $updir3=$updir2.DIRECTORY_SEPARATOR."sessions";
 60            if ( (!is_dir($updir3) || !is_writable($updir3)) && is_dir($updir2) && is_writable($updir2) )
 61                @mkdir($updir3, 0700);
 62            if ( !is_dir($updir3) || !is_writable($updir3) )
 63                throw new Gb_Exception("Impossible de créer le répertoire $updir3 pour stocker les sessions ! session_save_path()=$updir");
 64            session_save_path($updir3);
 65            self::$sessionDir=$updir3;
 66        }
 67        return self::$sessionDir;
 68    }
 69
 70
 71    /**
 72     * Positionne le répertoire des sessions
 73     *
 74     * @throws Gb_Exception
 75     */
 76    public static function setSessionDir($fn)
 77    {
 78        $dirname = realpath($fn);
 79        if (!is_dir($dirname)) {
 80            throw new Gb_Exception("cannot use this directory for sessions : directory does not exist");
 81        }
 82        if (!is_writable($dirname)) {
 83            throw new Gb_Exception("cannot write session to this directory : $dirname");
 84        }
 85        session_save_path($dirname);
 86        self::$sessionDir = $dirname;
 87    }
 88
 89
 90
 91    public static function getUniqId()
 92    {
 93        if (isset($_SESSION["Gb_Session"]))
 94            return $_SESSION["Gb_Session"]["uniqId"];
 95        else
 96            return "";
 97    }
 98
 99
100
101
102   /**
103    * Démarre une session sécurisée (id changeant, watch ip et l'user agent)
104    * Mettre echo Gb_Session::session_start() au début du script.
105    *
106    * @param int[optional] $relTimeOutMinutes Timeout depuis la dernière page (1h défaut)
107    * @param int[optional] $grandTimeOutMinutes Timeout depuis création de la session (6h défaut)
108    * @throws Gb_Exception si impossible de créer répertoire pour le sessions
109    * @return string texte de warning ou ""
110    */
111    public static function session_start($relTimeOutMinutes=60, $grandTimeOutMinutes=360)
112    {
113        self::$grandTimeOutMinutes=$grandTimeOutMinutes;
114        session_name(Gb_Glue::getProjectName()."_PHPID");
115        self::getSessionDir();
116        session_start();
117
118        $agent = isset($_SERVER["HTTP_USER_AGENT"])?$_SERVER["HTTP_USER_AGENT"]:"no agent";
119        $client=md5("U:".$agent." IP:". $_SERVER["REMOTE_ADDR"]);
120
121        $sWarning="";
122
123        $curSession=array();
124        if (isset($_SESSION["Gb_Session"])) {
125            $curSession=$_SESSION["Gb_Session"];
126        }
127        if (empty($curSession["client"]))       { $curSession["client"]="";       }
128        if (empty($curSession["uniqId"]))       { $curSession["uniqId"]="";       }
129        if (empty($curSession["grandTimeout"])) { $curSession["grandTimeout"]=0;  }
130        if (empty($curSession["relTimeout"]))   { $curSession["relTimeout"]=0;    }
131
132
133// j'enlève parce que ca engendre une dépendance sur Gb_Request
134//        $uniqId=Gb_Request::getForm("uniqId");
135//        if( strlen($uniqId) && $uniqId != $curSession["uniqId"] )
136//        { // session hijacking ? Teste l'uniqId du formulaire (ou get)
137//            $curSession=self::destroy();
138//            $sWarning.="<b>Votre session n'est pas authentifiée";
139//            $sWarning.=" Pour protéger votre confidentialité, veuillez vous réidentifier.</b><br />\n";
140//        }
141//        elseif (  $curSession["client"]!=$client )
142
143        $time=time();
144        if (  $curSession["client"]!=$client )
145        { // session hijacking ? Teste l'IP et l'user agent du client
146            //Gb_Log::logNotice("Session uniqId={$curSession['uniqId']} destroyed because client {$curSession['client']} != {$client} ");
147            $curSession=self::destroy();
148            $sWarning.="<b>Votre adresse IP ou votre navigateur a changé depuis la dernière page demandée.";
149            $sWarning.=" Pour protéger votre confidentialité, veuillez vous réidentifier.</b><br />\n";
150        }
151        elseif( ($curSession["grandTimeout"] && $time>$curSession["grandTimeout"])
152             ||  ($curSession["relTimeout"]   && $time>$curSession["relTimeout"]   )     )
153        {
154            //Gb_Log::logNotice("Session destroyed because $time > ({$curSession["grandTimeout"]} or {$curSession["relTimeout"]})");
155            $curSession=self::destroy();
156            $sWarning.="<b>Votre session a expiré";
157            $sWarning.=" Pour protéger votre confidentialité, veuillez vous réidentifier.</b><br />\n";
158        }
159
160        if (strlen($curSession["uniqId"])==0)
161        { // premier appel de la session: initialisation  du client
162            $curSession=self::destroy();
163        }
164        elseif (rand(1, 100)<=20)
165        { // 20% de chance de regénérer l'ID de session
166            //Gb_Log::logDebug("session_regenerate_id() uniqId={$curSession['uniqId']}");
167            session_regenerate_id(true);
168        }
169
170        $curSession["relTimeout"]=$time+60*$relTimeOutMinutes;
171
172        Gb_Glue::registerPlugin("Gb_Log", array(__CLASS__, "GbLogPlugin"));
173
174        $_SESSION["Gb_Session"]=$curSession;
175
176        //$gto=Gb_String::date_fr($curSession['grandTimeout']);
177        //$rto=Gb_String::date_fr($curSession['relTimeout']);
178        //Gb_Log::logDebug("Session is uniqId={$curSession['uniqId']} client={$curSession['client']} grandTimeout=$gto relTimeout=$rto}");
179
180        return $sWarning;
181    }
182
183
184
185
186    public static function destroy()
187    {
188        session_regenerate_id(true);
189        $agent = isset($_SERVER["HTTP_USER_AGENT"])?$_SERVER["HTTP_USER_AGENT"]:"no agent";
190        $client=md5("U:".$agent." IP:". $_SERVER["REMOTE_ADDR"]);
191        $a='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
192        $u=$a{mt_rand(0, 61)}; $u.=$a{mt_rand(0, 61)}; $u.=$a{mt_rand(0, 61)}; $u.=$a{mt_rand(0, 61)}; $u.=$a{mt_rand(0, 61)};
193        $uniqId=$u;
194        $time=time();
195        $curSession=array();
196        $curSession["uniqId"]=$uniqId;
197        $curSession["client"]=$client;
198        $curSession["grandTimeout"]=$time+60*self::$grandTimeOutMinutes;
199
200        $_SESSION=array();
201        $_SESSION["Gb_Session"]=$curSession;
202
203        //$gto=Gb_String::date_fr($curSession['grandTimeout']);
204        //Gb_Log::logInfo("Session created uniqId={$uniqId} client={$client} grandTimeout=$gto");
205        return $curSession;
206    }
207
208
209
210
211    public static function GbLogPlugin()
212    {
213        $uniqId=self::getUniqId();
214        $uniqId=str_pad($uniqId, 6);
215        return $uniqId;
216    }
217
218
219    /**
220     * Renvoie la valeur SESSION, sans slash ou default si elle n'est pas définie
221     *
222     * @param string $key valeur à chercher
223     * @param mixed[optional=false] $value valeur à renvoyer si non trouvé
224     * @return mixed| $_SESSION[$key]
225     */
226    public static function get($key, $default=false)
227    {
228        if ( isset($_SESSION[$key]) ) {
229            return $_SESSION[$key];
230        } else {
231            return $default;
232        }
233    }
234
235    /**
236     * Stocke une valeur dans SESSION
237     *
238     * @param string $key valeur à chercher
239     * @param mixed $key valeur à chercher
240     * @return mixed la valeur
241     */
242    public static function set($key, $value)
243    {
244        $_SESSION[$key]=$value;
245        return $value;
246    }
247
248    public static function _unset($key)
249    {
250        unset($_SESSION[$key]);
251    }
252
253    public static function _isset($key)
254    {
255        return isset($_SESSION[$key]);
256    }
257
258    public static function _empty($key)
259    {
260        return empty($_SESSION[$key]);
261    }
262
263}