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

/libs/Nette/Web/User.php

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