/lib/ezc/Authentication/src/session/authentication_session.php

https://bitbucket.org/ericsagnes/ezpublish-multisite · PHP · 273 lines · 71 code · 14 blank · 188 comment · 6 complexity · a5ffb4756d101a669072ae7eec3f208c MD5 · raw file

  1. <?php
  2. /**
  3. * File containing the ezcAuthenticationSession class.
  4. *
  5. * @copyright Copyright (C) 2005-2010 eZ Systems AS. All rights reserved.
  6. * @license http://ez.no/licenses/new_bsd New BSD License
  7. * @filesource
  8. * @package Authentication
  9. * @version //autogen//
  10. */
  11. /**
  12. * Support for session authentication and saving of authentication information
  13. * between requests.
  14. *
  15. * Contains the methods:
  16. * - start - starts the session, calling the PHP function session_start()
  17. * - load - returns the information stored in the session key ezcAuth_id
  18. * - save - saves information in the session key ezcAuth_id and also saves
  19. * the current timestamp in the session key ezcAuth_timestamp
  20. * - destroy - deletes the information stored in the session keys ezcAuth_id
  21. * and ezcAuth_timestamp
  22. * - regenerateId - regenerates the PHPSESSID value
  23. *
  24. * Example of use (combined with the Htpasswd filter):
  25. * <code>
  26. * // no headers should be sent before calling $session->start()
  27. * $session = new ezcAuthenticationSession();
  28. * $session->start();
  29. *
  30. * // retrieve the POST request information
  31. * $user = isset( $_POST['user'] ) ? $_POST['user'] : $session->load();
  32. * $password = isset( $_POST['password'] ) ? $_POST['password'] : null;
  33. * $credentials = new ezcAuthenticationPasswordCredentials( $user, $password );
  34. * $authentication = new ezcAuthentication( $credentials );
  35. * $authentication->session = $session;
  36. * $authentication->addFilter( new ezcAuthenticationHtpasswdFilter( '/etc/htpasswd' ) );
  37. * // add other filters if needed
  38. * if ( !$authentication->run() )
  39. * {
  40. * // authentication did not succeed, so inform the user
  41. * $status = $authentication->getStatus();
  42. * $err = array(
  43. * 'ezcAuthenticationHtpasswdFilter' => array(
  44. * ezcAuthenticationHtpasswdFilter::STATUS_USERNAME_INCORRECT => 'Incorrect username',
  45. * ezcAuthenticationHtpasswdFilter::STATUS_PASSWORD_INCORRECT => 'Incorrect password'
  46. * ),
  47. * 'ezcAuthenticationSession' => array(
  48. * ezcAuthenticationSession::STATUS_EMPTY => '',
  49. * ezcAuthenticationSession::STATUS_EXPIRED => 'Session expired'
  50. * )
  51. * );
  52. * foreach ( $status as $line )
  53. * {
  54. * list( $key, $value ) = each( $line );
  55. * echo $err[$key][$value] . "\n";
  56. * }
  57. * }
  58. * else
  59. * {
  60. * // authentication succeeded, so allow the user to see his content
  61. * }
  62. * </code>
  63. *
  64. * See {@link ezcAuthenticationSessionOptions} for options you can set to
  65. * session objects.
  66. *
  67. * @package Authentication
  68. * @version //autogen//
  69. * @mainclass
  70. */
  71. class ezcAuthenticationSession
  72. {
  73. /**
  74. * Successful authentication; normal behaviour is to skip the other filters.
  75. *
  76. * This should be the same value as ezcAuthenticationFilter::STATUS_OK.
  77. */
  78. const STATUS_OK = 0;
  79. /**
  80. * The session is empty; normal behaviour is to continue with the other filters.
  81. */
  82. const STATUS_EMPTY = 1;
  83. /**
  84. * The session expired; normal behaviour is to regenerate the session ID.
  85. */
  86. const STATUS_EXPIRED = 2;
  87. /**
  88. * Options for authentication filters.
  89. *
  90. * @var ezcAuthenticationFilterOptions
  91. */
  92. protected $options;
  93. /**
  94. * Creates a new object of this class.
  95. *
  96. * @param ezcAuthenticationSessionOptions $options Options for this class
  97. */
  98. public function __construct( ezcAuthenticationSessionOptions $options = null )
  99. {
  100. $this->options = ( $options === null ) ? new ezcAuthenticationSessionOptions() : $options;
  101. }
  102. /**
  103. * Runs through the session and returns a status code when finished.
  104. *
  105. * @param ezcAuthenticationCredentials $credentials Authentication credentials
  106. * @return int
  107. */
  108. public function run( $credentials )
  109. {
  110. $this->start();
  111. if ( isset( $_SESSION[$this->options->timestampKey] ) &&
  112. time() - $_SESSION[$this->options->timestampKey] >= $this->options->validity
  113. )
  114. {
  115. $this->destroy();
  116. $this->regenerateId();
  117. return self::STATUS_EXPIRED;
  118. }
  119. if ( $this->load() !== null )
  120. {
  121. return self::STATUS_OK;
  122. }
  123. return self::STATUS_EMPTY;
  124. }
  125. /**
  126. * Runs through the session and returns true if the session is correct.
  127. *
  128. * When using the session, it is often desirable to take advantage of the
  129. * fact that the authenticated state of the user is kept in the session and
  130. * not create and initialize the other filters (which might slow things
  131. * down on every request).
  132. *
  133. * The application can be structured like this:
  134. * <code>
  135. * $session = new ezcAuthenticationSession();
  136. * $session->start();
  137. *
  138. * $credentials = new ezcAuthenticationPasswordCredentials( $user, $pass );
  139. *
  140. * $authenticated = false;
  141. * if ( !$session->isValid( $credentials ) )
  142. * {
  143. * // create the authentication object
  144. * $authentication = new ezcAuthentication( $credentials );
  145. * $authentication->session = $session;
  146. *
  147. * // create filters and add them to the authentication object
  148. * $authentication->addFilter( new ezcAuthenticationOpenidFilter() );
  149. *
  150. * // run the authentication object
  151. * if ( !$authentication->run() )
  152. * {
  153. * $status = $authentication->getStatus();
  154. * // build an error message based on $status
  155. * }
  156. * else
  157. * {
  158. * $authenticated = true;
  159. * }
  160. * }
  161. * else
  162. * {
  163. * $authenticated = true;
  164. * }
  165. *
  166. * if ( $authenticated )
  167. * {
  168. * // the authentication succeeded and the user can see his content
  169. * }
  170. * else
  171. * {
  172. * // inform the user that the authentication failed (with the error
  173. * // message that was created earlier)
  174. * }
  175. * </code>
  176. *
  177. * In this way, the creation and initialization of the authentication
  178. * filters is not performed if the credentials are stored in the session.
  179. *
  180. * @param ezcAuthenticationCredentials $credentials Authentication credentials
  181. * @return bool
  182. */
  183. public function isValid( $credentials )
  184. {
  185. return ( $this->run( $credentials ) === self::STATUS_OK );
  186. }
  187. /**
  188. * Starts the session.
  189. *
  190. * This function must be called before sending any headers to the client.
  191. */
  192. public function start()
  193. {
  194. if ( session_id() === '' && PHP_SAPI !== 'cli' )
  195. {
  196. session_start();
  197. }
  198. }
  199. /**
  200. * Loads the authenticated username from the session or null if it doesn't exist.
  201. *
  202. * @return string
  203. */
  204. public function load()
  205. {
  206. return isset( $_SESSION[$this->options->idKey] ) ? $_SESSION[$this->options->idKey] :
  207. null;
  208. }
  209. /**
  210. * Saves the authenticated username and the current timestamp in the session
  211. * variables.
  212. *
  213. * @param string $data Information to save in the session, usually username
  214. */
  215. public function save( $data )
  216. {
  217. $_SESSION[$this->options->idKey] = $data;
  218. $_SESSION[$this->options->timestampKey] = time();
  219. }
  220. /**
  221. * Removes the variables used by this class from the session variables.
  222. */
  223. public function destroy()
  224. {
  225. unset( $_SESSION[$this->options->idKey] );
  226. unset( $_SESSION[$this->options->timestampKey] );
  227. }
  228. /**
  229. * Regenerates the session ID.
  230. */
  231. public function regenerateId()
  232. {
  233. if ( !headers_sent() )
  234. {
  235. // ???? seems that PHPSESSID is not regenerated if session is destroyed first????
  236. // session_destroy();
  237. session_regenerate_id();
  238. }
  239. }
  240. /**
  241. * Sets the options of this class to $options.
  242. *
  243. * @param ezcAuthenticationSessionOptions $options Options for this class
  244. */
  245. public function setOptions( ezcAuthenticationSessionOptions $options )
  246. {
  247. $this->options = $options;
  248. }
  249. /**
  250. * Returns the options of this class.
  251. *
  252. * @return ezcAuthenticationSessionOptions
  253. */
  254. public function getOptions()
  255. {
  256. return $this->options;
  257. }
  258. }
  259. ?>