1: <?php
2:
3: /**
4: * This file is part of the Nette Framework (http://nette.org)
5: *
6: * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
7: *
8: * For the full copyright and license information, please view
9: * the file license.txt that was distributed with this source code.
10: * @package Nette\Http
11: */
12:
13:
14:
15: /**
16: * Session storage for user object.
17: *
18: * @author David Grudl, Jan Tichý
19: * @package Nette\Http
20: */
21: class UserStorage extends Object implements IUserStorage
22: {
23: /** @var string */
24: private $namespace = '';
25:
26: /** @var Session */
27: private $sessionHandler;
28:
29: /** @var SessionSection */
30: private $sessionSection;
31:
32:
33: public function __construct(Session $sessionHandler)
34: {
35: $this->sessionHandler = $sessionHandler;
36: }
37:
38:
39: /**
40: * Sets the authenticated status of this user.
41: * @param bool
42: * @return self
43: */
44: public function setAuthenticated($state)
45: {
46: $section = $this->getSessionSection(TRUE);
47: $section->authenticated = (bool) $state;
48:
49: // Session Fixation defence
50: $this->sessionHandler->regenerateId();
51:
52: if ($state) {
53: $section->reason = NULL;
54: $section->authTime = time(); // informative value
55:
56: } else {
57: $section->reason = self::MANUAL;
58: $section->authTime = NULL;
59: }
60: return $this;
61: }
62:
63:
64: /**
65: * Is this user authenticated?
66: * @return bool
67: */
68: public function isAuthenticated()
69: {
70: $session = $this->getSessionSection(FALSE);
71: return $session && $session->authenticated;
72: }
73:
74:
75: /**
76: * Sets the user identity.
77: * @return self
78: */
79: public function setIdentity(IIdentity $identity = NULL)
80: {
81: $this->getSessionSection(TRUE)->identity = $identity;
82: return $this;
83: }
84:
85:
86: /**
87: * Returns current user identity, if any.
88: * @return IIdentity|NULL
89: */
90: public function getIdentity()
91: {
92: $session = $this->getSessionSection(FALSE);
93: return $session ? $session->identity : NULL;
94: }
95:
96:
97: /**
98: * Changes namespace; allows more users to share a session.
99: * @param string
100: * @return self
101: */
102: public function setNamespace($namespace)
103: {
104: if ($this->namespace !== $namespace) {
105: $this->namespace = (string) $namespace;
106: $this->sessionSection = NULL;
107: }
108: return $this;
109: }
110:
111:
112: /**
113: * Returns current namespace.
114: * @return string
115: */
116: public function getNamespace()
117: {
118: return $this->namespace;
119: }
120:
121:
122: /**
123: * Enables log out after inactivity.
124: * @param string|int|DateTime Number of seconds or timestamp
125: * @param int Log out when the browser is closed | Clear the identity from persistent storage?
126: * @return self
127: */
128: public function setExpiration($time, $flags = 0)
129: {
130: $section = $this->getSessionSection(TRUE);
131: if ($time) {
132: $time = DateTime53::from($time)->format('U');
133: $section->expireTime = $time;
134: $section->expireDelta = $time - time();
135:
136: } else {
137: unset($section->expireTime, $section->expireDelta);
138: }
139:
140: $section->expireIdentity = (bool) ($flags & self::CLEAR_IDENTITY);
141: $section->expireBrowser = (bool) ($flags & self::BROWSER_CLOSED);
142: $section->browserCheck = TRUE;
143: $section->setExpiration(0, 'browserCheck');
144: $section->setExpiration($time, 'foo'); // time check
145: return $this;
146: }
147:
148:
149: /**
150: * Why was user logged out?
151: * @return int
152: */
153: public function getLogoutReason()
154: {
155: $session = $this->getSessionSection(FALSE);
156: return $session ? $session->reason : NULL;
157: }
158:
159:
160: /**
161: * Returns and initializes $this->sessionSection.
162: * @return SessionSection
163: */
164: protected function getSessionSection($need)
165: {
166: if ($this->sessionSection !== NULL) {
167: return $this->sessionSection;
168: }
169:
170: if (!$need && !$this->sessionHandler->exists()) {
171: return NULL;
172: }
173:
174: $this->sessionSection = $section = $this->sessionHandler->getSection('Nette.Http.UserStorage/' . $this->namespace);
175:
176: if (!$section->identity instanceof IIdentity || !is_bool($section->authenticated)) {
177: $section->remove();
178: }
179:
180: if ($section->authenticated && $section->expireBrowser && !$section->browserCheck) { // check if browser was closed?
181: $section->reason = self::BROWSER_CLOSED;
182: $section->authenticated = FALSE;
183: if ($section->expireIdentity) {
184: unset($section->identity);
185: }
186: }
187:
188: if ($section->authenticated && $section->expireDelta > 0) { // check time expiration
189: if ($section->expireTime < time()) {
190: $section->reason = self::INACTIVITY;
191: $section->authenticated = FALSE;
192: if ($section->expireIdentity) {
193: unset($section->identity);
194: }
195: }
196: $section->expireTime = time() + $section->expireDelta; // sliding expiration
197: }
198:
199: if (!$section->authenticated) {
200: unset($section->expireTime, $section->expireDelta, $section->expireIdentity,
201: $section->expireBrowser, $section->browserCheck, $section->authTime);
202: }
203:
204: return $this->sessionSection;
205: }
206:
207: }
208: