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