1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Nette\Web;
13:
14: use Nette,
15: Nette\Environment,
16: Nette\Security\IAuthenticator,
17: Nette\Security\IAuthorizator,
18: Nette\Security\IIdentity;
19:
20:
21:
22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:
34: class User extends Nette\Object implements IUser
35: {
36:
37: const MANUAL = 1;
38: const INACTIVITY = 2;
39: const BROWSER_CLOSED = 3;
40:
41:
42:
43: public $guestRole = 'guest';
44:
45:
46: public $authenticatedRole = 'authenticated';
47:
48:
49: public $onLoggedIn;
50:
51:
52: public $onLoggedOut;
53:
54:
55: private $authenticationHandler;
56:
57:
58: private $authorizationHandler;
59:
60:
61: private $namespace = '';
62:
63:
64: private $session;
65:
66:
67:
68:
69:
70:
71:
72: 73: 74: 75: 76: 77: 78:
79: public function login($username = NULL, $password = NULL)
80: {
81: $handler = $this->getAuthenticationHandler();
82: if ($handler === NULL) {
83: throw new \InvalidStateException('Authentication handler has not been set.');
84: }
85:
86: $this->logout(TRUE);
87:
88: $credentials = func_get_args();
89: $this->setIdentity($handler->authenticate($credentials));
90: $this->setAuthenticated(TRUE);
91: $this->onLoggedIn($this);
92: }
93:
94:
95:
96: 97: 98: 99: 100:
101: final public function logout($clearIdentity = FALSE)
102: {
103: if ($this->isLoggedIn()) {
104: $this->setAuthenticated(FALSE);
105: $this->onLoggedOut($this);
106: }
107:
108: if ($clearIdentity) {
109: $this->setIdentity(NULL);
110: }
111: }
112:
113:
114:
115: 116: 117: 118:
119: final public function isLoggedIn()
120: {
121: $session = $this->getSessionNamespace(FALSE);
122: return $session && $session->authenticated;
123: }
124:
125:
126:
127: 128: 129: 130:
131: final public function getIdentity()
132: {
133: $session = $this->getSessionNamespace(FALSE);
134: return $session ? $session->identity : NULL;
135: }
136:
137:
138:
139: 140: 141: 142:
143: public function getId()
144: {
145: $identity = $this->getIdentity();
146: return $identity ? $identity->getId() : NULL;
147: }
148:
149:
150:
151: 152: 153: 154: 155:
156: public function setAuthenticationHandler(IAuthenticator $handler)
157: {
158: $this->authenticationHandler = $handler;
159: return $this;
160: }
161:
162:
163:
164: 165: 166: 167:
168: final public function getAuthenticationHandler()
169: {
170: if ($this->authenticationHandler === NULL) {
171: $this->authenticationHandler = Environment::getService('Nette\\Security\\IAuthenticator');
172: }
173: return $this->authenticationHandler;
174: }
175:
176:
177:
178: 179: 180: 181: 182:
183: public function setNamespace($namespace)
184: {
185: if ($this->namespace !== $namespace) {
186: $this->namespace = (string) $namespace;
187: $this->session = NULL;
188: }
189: return $this;
190: }
191:
192:
193:
194: 195: 196: 197:
198: final public function getNamespace()
199: {
200: return $this->namespace;
201: }
202:
203:
204:
205: 206: 207: 208: 209: 210: 211:
212: public function setExpiration($time, $whenBrowserIsClosed = TRUE, $clearIdentity = FALSE)
213: {
214: $session = $this->getSessionNamespace(TRUE);
215: if ($time) {
216: $time = Nette\Tools::createDateTime($time)->format('U');
217: $session->expireTime = $time;
218: $session->expireDelta = $time - time();
219:
220: } else {
221: unset($session->expireTime, $session->expireDelta);
222: }
223:
224: $session->expireIdentity = (bool) $clearIdentity;
225: $session->expireBrowser = (bool) $whenBrowserIsClosed;
226: $session->browserCheck = TRUE;
227: $session->setExpiration(0, 'browserCheck');
228: return $this;
229: }
230:
231:
232:
233: 234: 235: 236:
237: final public function getLogoutReason()
238: {
239: $session = $this->getSessionNamespace(FALSE);
240: return $session ? $session->reason : NULL;
241: }
242:
243:
244:
245: 246: 247: 248:
249: protected function getSessionNamespace($need)
250: {
251: if ($this->session !== NULL) {
252: return $this->session;
253: }
254:
255: $sessionHandler = $this->getSession();
256: if (!$need && !$sessionHandler->exists()) {
257: return NULL;
258: }
259:
260: $this->session = $session = $sessionHandler->getNamespace('Nette.Web.User/' . $this->namespace);
261:
262: if (!($session->identity instanceof IIdentity) || !is_bool($session->authenticated)) {
263: $session->remove();
264: }
265:
266: if ($session->authenticated && $session->expireBrowser && !$session->browserCheck) { 267: $session->reason = self::BROWSER_CLOSED;
268: $session->authenticated = FALSE;
269: $this->onLoggedOut($this);
270: if ($session->expireIdentity) {
271: unset($session->identity);
272: }
273: }
274:
275: if ($session->authenticated && $session->expireDelta > 0) { 276: if ($session->expireTime < time()) {
277: $session->reason = self::INACTIVITY;
278: $session->authenticated = FALSE;
279: $this->onLoggedOut($this);
280: if ($session->expireIdentity) {
281: unset($session->identity);
282: }
283: }
284: $session->expireTime = time() + $session->expireDelta; 285: }
286:
287: if (!$session->authenticated) {
288: unset($session->expireTime, $session->expireDelta, $session->expireIdentity,
289: $session->expireBrowser, $session->browserCheck, $session->authTime);
290: }
291:
292: return $this->session;
293: }
294:
295:
296:
297: 298: 299: 300: 301:
302: protected function setAuthenticated($state)
303: {
304: $session = $this->getSessionNamespace(TRUE);
305: $session->authenticated = (bool) $state;
306:
307: 308: $this->getSession()->regenerateId();
309:
310: if ($state) {
311: $session->reason = NULL;
312: $session->authTime = time(); 313:
314: } else {
315: $session->reason = self::MANUAL;
316: $session->authTime = NULL;
317: }
318: return $this;
319: }
320:
321:
322:
323: 324: 325: 326: 327:
328: protected function setIdentity(IIdentity $identity = NULL)
329: {
330: $this->getSessionNamespace(TRUE)->identity = $identity;
331: return $this;
332: }
333:
334:
335:
336:
337:
338:
339:
340: 341: 342: 343:
344: public function getRoles()
345: {
346: if (!$this->isLoggedIn()) {
347: return array($this->guestRole);
348: }
349:
350: $identity = $this->getIdentity();
351: return $identity ? $identity->getRoles() : array($this->authenticatedRole);
352: }
353:
354:
355:
356: 357: 358: 359: 360:
361: final public function isInRole($role)
362: {
363: return in_array($role, $this->getRoles(), TRUE);
364: }
365:
366:
367:
368: 369: 370: 371: 372: 373: 374:
375: public function isAllowed($resource = IAuthorizator::ALL, $privilege = IAuthorizator::ALL)
376: {
377: $handler = $this->getAuthorizationHandler();
378: if (!$handler) {
379: throw new \InvalidStateException("Authorization handler has not been set.");
380: }
381:
382: foreach ($this->getRoles() as $role) {
383: if ($handler->isAllowed($role, $resource, $privilege)) return TRUE;
384: }
385:
386: return FALSE;
387: }
388:
389:
390:
391: 392: 393: 394: 395:
396: public function setAuthorizationHandler(IAuthorizator $handler)
397: {
398: $this->authorizationHandler = $handler;
399: return $this;
400: }
401:
402:
403:
404: 405: 406: 407:
408: final public function getAuthorizationHandler()
409: {
410: if ($this->authorizationHandler === NULL) {
411: $this->authorizationHandler = Environment::getService('Nette\\Security\\IAuthorizator');
412: }
413: return $this->authorizationHandler;
414: }
415:
416:
417:
418:
419:
420:
421:
422: 423: 424: 425:
426: protected function getSession()
427: {
428: return Environment::getSession();
429: }
430:
431: }
432: