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