1. sfBasicSecurityUser.class.php
  2. /** * sfBasicSecurityUser will handle any type of data as a credential. * * @package symfony * @subpackage user * @author Fabien Potencier * @author Sean Kerr * @version SVN: $Id: sfBasicSecurityUser.class.php 24045 2009-11-16 18:24:48Z Kris.Wallsmith $ */
  3. class sfBasicSecurityUser extends sfUser implements sfSecurityUser
  4. {
  5. const LAST_REQUEST_NAMESPACE = 'symfony/user/sfUser/lastRequest';
  6. const AUTH_NAMESPACE = 'symfony/user/sfUser/authenticated';
  7. const CREDENTIAL_NAMESPACE = 'symfony/user/sfUser/credentials';
  8. protected $lastRequest = null;
  9. protected $credentials = null;
  10. protected $authenticated = null;
  11. protected $timedout = false;
  12. /**
  13. * Clears all credentials.
  14. *
  15. */
  16. public function clearCredentials()
  17. {
  18. $this->credentials = null;
  19. $this->credentials = array();
  20. }
  21. /**
  22. * Returns the current user's credentials.
  23. *
  24. * @return array
  25. */
  26. public function getCredentials()
  27. {
  28. return $this->credentials;
  29. }
  30. /**
  31. * Removes a credential.
  32. *
  33. * @param mixed $credential credential
  34. */
  35. public function removeCredential($credential)
  36. {
  37. if ($this->hasCredential($credential))
  38. {
  39. foreach ($this->credentials as $key => $value)
  40. {
  41. if ($credential == $value)
  42. {
  43. if ($this->options['logging'])
  44. {
  45. $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Remove credential "%s"', $credential))));
  46. }
  47. unset($this->credentials[$key]);
  48. $this->storage->regenerate(false);
  49. return;
  50. }
  51. }
  52. }
  53. }
  54. /**
  55. * Adds a credential.
  56. *
  57. * @param mixed $credential
  58. */
  59. public function addCredential($credential)
  60. {
  61. $this->addCredentials(func_get_args());
  62. }
  63. /**
  64. * Adds several credential at once.
  65. *
  66. * @param mixed array or list of credentials
  67. */
  68. public function addCredentials()
  69. {
  70. if (func_num_args() == 0) return;
  71. // Add all credentials
  72. $credentials = (is_array(func_get_arg(0))) ? func_get_arg(0) : func_get_args();
  73. if ($this->options['logging'])
  74. {
  75. $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Add credential(s) "%s"', implode(', ', $credentials)))));
  76. }
  77. $added = false;
  78. foreach ($credentials as $aCredential)
  79. {
  80. if (!in_array($aCredential, $this->credentials))
  81. {
  82. $added = true;
  83. $this->credentials[] = $aCredential;
  84. }
  85. }
  86. if ($added)
  87. {
  88. $this->storage->regenerate(false);
  89. }
  90. }
  91. /**
  92. * Returns true if user has credential.
  93. *
  94. * @param mixed $credentials
  95. * @param bool $useAnd specify the mode, either AND or OR
  96. * @return bool
  97. *
  98. * @author Olivier Verdier <Olivier.Verdier@free.fr>
  99. */
  100. public function hasCredential($credentials, $useAnd = true)
  101. {
  102. if (!is_array($credentials))
  103. {
  104. return in_array($credentials, $this->credentials);
  105. }
  106. // now we assume that $credentials is an array
  107. $test = false;
  108. foreach ($credentials as $credential)
  109. {
  110. // recursively check the credential with a switched AND/OR mode
  111. $test = $this->hasCredential($credential, $useAnd ? false : true);
  112. if ($useAnd)
  113. {
  114. $test = $test ? false : true;
  115. }
  116. if ($test) // either passed one in OR mode or failed one in AND mode
  117. {
  118. break; // the matter is settled
  119. }
  120. }
  121. if ($useAnd) // in AND mode we succeed if $test is false
  122. {
  123. $test = $test ? false : true;
  124. }
  125. return $test;
  126. }
  127. /**
  128. * Returns true if user is authenticated.
  129. *
  130. * @return boolean
  131. */
  132. public function isAuthenticated()
  133. {
  134. return $this->authenticated;
  135. }
  136. /**
  137. * Sets authentication for user.
  138. *
  139. * @param bool $authenticated
  140. */
  141. public function setAuthenticated($authenticated)
  142. {
  143. if ($this->options['logging'])
  144. {
  145. $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('User is %sauthenticated', $authenticated === true ? '' : 'not '))));
  146. }
  147. if ((bool) $authenticated !== $this->authenticated)
  148. {
  149. if ($authenticated === true)
  150. {
  151. $this->authenticated = true;
  152. }
  153. else
  154. {
  155. $this->authenticated = false;
  156. $this->clearCredentials();
  157. }
  158. $this->dispatcher->notify(new sfEvent($this, 'user.change_authentication', array('authenticated' => $this->authenticated)));
  159. $this->storage->regenerate(false);
  160. }
  161. }
  162. public function setTimedOut()
  163. {
  164. $this->timedout = true;
  165. }
  166. public function isTimedOut()
  167. {
  168. return $this->timedout;
  169. }
  170. /**
  171. * Returns the timestamp of the last user request.
  172. *
  173. * @return int
  174. */
  175. public function getLastRequestTime()
  176. {
  177. return $this->lastRequest;
  178. }
  179. /**
  180. * Available options:
  181. *
  182. * * timeout: Timeout to automatically log out the user in seconds (1800 by default)
  183. * Set to false to disable
  184. *
  185. * @param sfEventDispatcher $dispatcher An sfEventDispatcher instance.
  186. * @param sfStorage $storage An sfStorage instance.
  187. * @param array $options An associative array of options.
  188. *
  189. * @see sfUser
  190. */
  191. public function initialize(sfEventDispatcher $dispatcher, sfStorage $storage, $options = array())
  192. {
  193. // initialize parent
  194. parent::initialize($dispatcher, $storage, $options);
  195. if (!array_key_exists('timeout', $this->options))
  196. {
  197. $this->options['timeout'] = 1800;
  198. }
  199. // force the max lifetime for session garbage collector to be greater than timeout
  200. if (ini_get('session.gc_maxlifetime') < $this->options['timeout'])
  201. {
  202. ini_set('session.gc_maxlifetime', $this->options['timeout']);
  203. }
  204. // read data from storage
  205. $this->authenticated = $storage->read(self::AUTH_NAMESPACE);
  206. $this->credentials = $storage->read(self::CREDENTIAL_NAMESPACE);
  207. $this->lastRequest = $storage->read(self::LAST_REQUEST_NAMESPACE);
  208. if (null === $this->authenticated)
  209. {
  210. $this->authenticated = false;
  211. $this->credentials = array();
  212. }
  213. else
  214. {
  215. // Automatic logout logged in user if no request within timeout parameter seconds
  216. $timeout = $this->options['timeout'];
  217. if (false !== $timeout && null !== $this->lastRequest && time() - $this->lastRequest >= $timeout)
  218. {
  219. if ($this->options['logging'])
  220. {
  221. $this->dispatcher->notify(new sfEvent($this, 'application.log', array('Automatic user logout due to timeout')));
  222. }
  223. $this->setTimedOut();
  224. $this->setAuthenticated(false);
  225. }
  226. }
  227. $this->lastRequest = time();
  228. }
  229. public function shutdown()
  230. {
  231. // write the last request time to the storage
  232. $this->storage->write(self::LAST_REQUEST_NAMESPACE, $this->lastRequest);
  233. $this->storage->write(self::AUTH_NAMESPACE, $this->authenticated);
  234. $this->storage->write(self::CREDENTIAL_NAMESPACE, $this->credentials);
  235. // call the parent shutdown method
  236. parent::shutdown();
  237. }
  238. }

Debug toolbar