PageRenderTime 26ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/application/extlib/Gb/Session.php

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