PageRenderTime 80ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/www/libs/nette-dev/Web/User.php

https://github.com/bazo/Mokuji
PHP | 431 lines | 197 code | 101 blank | 133 comment | 28 complexity | be9455e27cd7d8ff8703867b330674f6 MD5 | raw file
Possible License(s): BSD-3-Clause, MIT
  1. <?php
  2. /**
  3. * Nette Framework
  4. *
  5. * @copyright Copyright (c) 2004, 2010 David Grudl
  6. * @license http://nettephp.com/license Nette license
  7. * @link http://nettephp.com
  8. * @category Nette
  9. * @package Nette\Web
  10. */
  11. /**
  12. * Authentication and authorization.
  13. *
  14. * @copyright Copyright (c) 2004, 2010 David Grudl
  15. * @package Nette\Web
  16. *
  17. * @property-read IIdentity $identity
  18. * @property IAuthenticator $authenticationHandler
  19. * @property IAuthorizator $authorizationHandler
  20. * @property-read int $signOutReason
  21. * @property-read array $roles
  22. * @property-read bool $authenticated
  23. */
  24. class User extends Object implements IUser
  25. {
  26. /**#@+ sign-out reason {@link User::getSignOutReason()} */
  27. const MANUAL = 1;
  28. const INACTIVITY = 2;
  29. const BROWSER_CLOSED = 3;
  30. /**#@-*/
  31. /** @var string default role for unauthenticated user */
  32. public $guestRole = 'guest';
  33. /** @var string default role for authenticated user without own identity */
  34. public $authenticatedRole = 'authenticated';
  35. /** @var array of function(User $sender); Occurs when the user is successfully authenticated */
  36. public $onAuthenticated;
  37. /** @var array of function(User $sender); Occurs when the user is logged off */
  38. public $onSignedOut;
  39. /** @var IAuthenticator */
  40. private $authenticationHandler;
  41. /** @var IAuthorizator */
  42. private $authorizationHandler;
  43. /** @var string */
  44. private $namespace = '';
  45. /** @var SessionNamespace */
  46. private $session;
  47. /********************* Authentication ****************d*g**/
  48. /**
  49. * Conducts the authentication process.
  50. * @param string
  51. * @param string
  52. * @param mixed
  53. * @return void
  54. * @throws AuthenticationException if authentication was not successful
  55. */
  56. public function authenticate($username, $password, $extra = NULL)
  57. {
  58. $handler = $this->getAuthenticationHandler();
  59. if ($handler === NULL) {
  60. throw new InvalidStateException('Authentication handler has not been set.');
  61. }
  62. $this->signOut(TRUE);
  63. $credentials = array(
  64. IAuthenticator::USERNAME => $username,
  65. IAuthenticator::PASSWORD => $password,
  66. 'extra' => $extra,
  67. );
  68. $this->setIdentity($handler->authenticate($credentials));
  69. $this->setAuthenticated(TRUE);
  70. $this->onAuthenticated($this);
  71. }
  72. /**
  73. * Logs off the user from the current session.
  74. * @param bool clear the identity from persistent storage?
  75. * @return void
  76. */
  77. final public function signOut($clearIdentity = FALSE)
  78. {
  79. if ($this->isAuthenticated()) {
  80. $this->setAuthenticated(FALSE);
  81. $this->onSignedOut($this);
  82. }
  83. if ($clearIdentity) {
  84. $this->setIdentity(NULL);
  85. }
  86. }
  87. /**
  88. * Is this user authenticated?
  89. * @return bool
  90. */
  91. final public function isAuthenticated()
  92. {
  93. $session = $this->getSessionNamespace(FALSE);
  94. return $session && $session->authenticated;
  95. }
  96. /**
  97. * Returns current user identity, if any.
  98. * @return IIdentity
  99. */
  100. final public function getIdentity()
  101. {
  102. $session = $this->getSessionNamespace(FALSE);
  103. return $session ? $session->identity : NULL;
  104. }
  105. /**
  106. * Returns current user ID, if any.
  107. * @return mixed
  108. */
  109. public function getId()
  110. {
  111. $identity = $this->getIdentity();
  112. return $identity ? $identity->getId() : NULL;
  113. }
  114. /**
  115. * Sets authentication handler.
  116. * @param IAuthenticator
  117. * @return User provides a fluent interface
  118. */
  119. public function setAuthenticationHandler(IAuthenticator $handler)
  120. {
  121. $this->authenticationHandler = $handler;
  122. return $this;
  123. }
  124. /**
  125. * Returns authentication handler.
  126. * @return IAuthenticator
  127. */
  128. final public function getAuthenticationHandler()
  129. {
  130. if ($this->authenticationHandler === NULL) {
  131. $this->authenticationHandler = Environment::getService('Nette\Security\IAuthenticator');
  132. }
  133. return $this->authenticationHandler;
  134. }
  135. /**
  136. * Changes namespace; allows more users to share a session.
  137. * @param string
  138. * @return User provides a fluent interface
  139. */
  140. public function setNamespace($namespace)
  141. {
  142. if ($this->namespace !== $namespace) {
  143. $this->namespace = (string) $namespace;
  144. $this->session = NULL;
  145. }
  146. return $this;
  147. }
  148. /**
  149. * Returns current namespace.
  150. * @return string
  151. */
  152. final public function getNamespace()
  153. {
  154. return $this->namespace;
  155. }
  156. /**
  157. * Enables sign out after inactivity.
  158. * @param string|int|DateTime number of seconds or timestamp
  159. * @param bool sign out when the browser is closed?
  160. * @param bool clear the identity from persistent storage?
  161. * @return User provides a fluent interface
  162. */
  163. public function setExpiration($time, $whenBrowserIsClosed = TRUE, $clearIdentity = FALSE)
  164. {
  165. $session = $this->getSessionNamespace(TRUE);
  166. if ($time) {
  167. $time = Tools::createDateTime($time)->format('U');
  168. $session->expireTime = $time;
  169. $session->expireDelta = $time - time();
  170. } else {
  171. unset($session->expireTime, $session->expireDelta);
  172. }
  173. $session->expireIdentity = (bool) $clearIdentity;
  174. $session->expireBrowser = (bool) $whenBrowserIsClosed;
  175. $session->browserCheck = TRUE;
  176. $session->setExpiration(0, 'browserCheck');
  177. return $this;
  178. }
  179. /**
  180. * Why was user signed out?
  181. * @return int
  182. */
  183. final public function getSignOutReason()
  184. {
  185. $session = $this->getSessionNamespace(FALSE);
  186. return $session ? $session->reason : NULL;
  187. }
  188. /**
  189. * Returns and initializes $this->session.
  190. * @return SessionNamespace
  191. */
  192. protected function getSessionNamespace($need)
  193. {
  194. if ($this->session !== NULL) {
  195. return $this->session;
  196. }
  197. $sessionHandler = $this->getSession();
  198. if (!$need && !$sessionHandler->exists()) {
  199. return NULL;
  200. }
  201. $this->session = $session = $sessionHandler->getNamespace('Nette.Web.User/' . $this->namespace);
  202. if (!($session->identity instanceof IIdentity) || !is_bool($session->authenticated)) {
  203. $session->remove();
  204. }
  205. if ($session->authenticated && $session->expireBrowser && !$session->browserCheck) { // check if browser was closed?
  206. $session->reason = self::BROWSER_CLOSED;
  207. $session->authenticated = FALSE;
  208. $this->onSignedOut($this);
  209. if ($session->expireIdentity) {
  210. unset($session->identity);
  211. }
  212. }
  213. if ($session->authenticated && $session->expireDelta > 0) { // check time expiration
  214. if ($session->expireTime < time()) {
  215. $session->reason = self::INACTIVITY;
  216. $session->authenticated = FALSE;
  217. $this->onSignedOut($this);
  218. if ($session->expireIdentity) {
  219. unset($session->identity);
  220. }
  221. }
  222. $session->expireTime = time() + $session->expireDelta; // sliding expiration
  223. }
  224. if (!$session->authenticated) {
  225. unset($session->expireTime, $session->expireDelta, $session->expireIdentity,
  226. $session->expireBrowser, $session->browserCheck, $session->authTime);
  227. }
  228. return $this->session;
  229. }
  230. /**
  231. * Sets the authenticated status of this user.
  232. * @param bool flag indicating the authenticated status of user
  233. * @return User provides a fluent interface
  234. */
  235. protected function setAuthenticated($state)
  236. {
  237. $session = $this->getSessionNamespace(TRUE);
  238. $session->authenticated = (bool) $state;
  239. // Session Fixation defence
  240. $this->getSession()->regenerateId();
  241. if ($state) {
  242. $session->reason = NULL;
  243. $session->authTime = time(); // informative value
  244. } else {
  245. $session->reason = self::MANUAL;
  246. $session->authTime = NULL;
  247. }
  248. return $this;
  249. }
  250. /**
  251. * Sets the user identity.
  252. * @param IIdentity
  253. * @return User provides a fluent interface
  254. */
  255. protected function setIdentity(IIdentity $identity = NULL)
  256. {
  257. $this->getSessionNamespace(TRUE)->identity = $identity;
  258. return $this;
  259. }
  260. /********************* Authorization ****************d*g**/
  261. /**
  262. * Returns a list of effective roles that a user has been granted.
  263. * @return array
  264. */
  265. public function getRoles()
  266. {
  267. if (!$this->isAuthenticated()) {
  268. return array($this->guestRole);
  269. }
  270. $identity = $this->getIdentity();
  271. return $identity ? $identity->getRoles() : array($this->authenticatedRole);
  272. }
  273. /**
  274. * Is a user in the specified effective role?
  275. * @param string
  276. * @return bool
  277. */
  278. final public function isInRole($role)
  279. {
  280. return in_array($role, $this->getRoles(), TRUE);
  281. }
  282. /**
  283. * Has a user effective access to the Resource?
  284. * If $resource is NULL, then the query applies to all resources.
  285. * @param string resource
  286. * @param string privilege
  287. * @return bool
  288. */
  289. public function isAllowed($resource = NULL, $privilege = NULL)
  290. {
  291. $handler = $this->getAuthorizationHandler();
  292. if (!$handler) {
  293. throw new InvalidStateException("Authorization handler has not been set.");
  294. }
  295. foreach ($this->getRoles() as $role) {
  296. if ($handler->isAllowed($role, $resource, $privilege)) return TRUE;
  297. }
  298. return FALSE;
  299. }
  300. /**
  301. * Sets authorization handler.
  302. * @param IAuthorizator
  303. * @return User provides a fluent interface
  304. */
  305. public function setAuthorizationHandler(IAuthorizator $handler)
  306. {
  307. $this->authorizationHandler = $handler;
  308. return $this;
  309. }
  310. /**
  311. * Returns current authorization handler.
  312. * @return IAuthorizator
  313. */
  314. final public function getAuthorizationHandler()
  315. {
  316. if ($this->authorizationHandler === NULL) {
  317. $this->authorizationHandler = Environment::getService('Nette\Security\IAuthorizator');
  318. }
  319. return $this->authorizationHandler;
  320. }
  321. /********************* backend ****************d*g**/
  322. /**
  323. * Returns session handler.
  324. * @return Session
  325. */
  326. protected function getSession()
  327. {
  328. return Environment::getSession();
  329. }
  330. }