diff options
Diffstat (limited to 'tests/security')
-rw-r--r-- | tests/security/SessionManagerTest.php | 181 |
1 files changed, 159 insertions, 22 deletions
diff --git a/tests/security/SessionManagerTest.php b/tests/security/SessionManagerTest.php index e4e1cfbc..e1c72707 100644 --- a/tests/security/SessionManagerTest.php +++ b/tests/security/SessionManagerTest.php | |||
@@ -14,11 +14,17 @@ use \PHPUnit\Framework\TestCase; | |||
14 | */ | 14 | */ |
15 | class SessionManagerTest extends TestCase | 15 | class SessionManagerTest extends TestCase |
16 | { | 16 | { |
17 | // Session ID hashes | 17 | /** @var array Session ID hashes */ |
18 | protected static $sidHashes = null; | 18 | protected static $sidHashes = null; |
19 | 19 | ||
20 | // Fake ConfigManager | 20 | /** @var FakeConfigManager ConfigManager substitute for testing */ |
21 | protected static $conf = null; | 21 | protected $conf = null; |
22 | |||
23 | /** @var array $_SESSION array for testing */ | ||
24 | protected $session = []; | ||
25 | |||
26 | /** @var SessionManager Server-side session management abstraction */ | ||
27 | protected $sessionManager = null; | ||
22 | 28 | ||
23 | /** | 29 | /** |
24 | * Assign reference data | 30 | * Assign reference data |
@@ -26,7 +32,20 @@ class SessionManagerTest extends TestCase | |||
26 | public static function setUpBeforeClass() | 32 | public static function setUpBeforeClass() |
27 | { | 33 | { |
28 | self::$sidHashes = ReferenceSessionIdHashes::getHashes(); | 34 | self::$sidHashes = ReferenceSessionIdHashes::getHashes(); |
29 | self::$conf = new FakeConfigManager(); | 35 | } |
36 | |||
37 | /** | ||
38 | * Initialize or reset test resources | ||
39 | */ | ||
40 | public function setUp() | ||
41 | { | ||
42 | $this->conf = new FakeConfigManager([ | ||
43 | 'credentials.login' => 'johndoe', | ||
44 | 'credentials.salt' => 'salt', | ||
45 | 'security.session_protection_disabled' => false, | ||
46 | ]); | ||
47 | $this->session = []; | ||
48 | $this->sessionManager = new SessionManager($this->session, $this->conf); | ||
30 | } | 49 | } |
31 | 50 | ||
32 | /** | 51 | /** |
@@ -34,12 +53,9 @@ class SessionManagerTest extends TestCase | |||
34 | */ | 53 | */ |
35 | public function testGenerateToken() | 54 | public function testGenerateToken() |
36 | { | 55 | { |
37 | $session = []; | 56 | $token = $this->sessionManager->generateToken(); |
38 | $sessionManager = new SessionManager($session, self::$conf); | ||
39 | |||
40 | $token = $sessionManager->generateToken(); | ||
41 | 57 | ||
42 | $this->assertEquals(1, $session['tokens'][$token]); | 58 | $this->assertEquals(1, $this->session['tokens'][$token]); |
43 | $this->assertEquals(40, strlen($token)); | 59 | $this->assertEquals(40, strlen($token)); |
44 | } | 60 | } |
45 | 61 | ||
@@ -54,7 +70,7 @@ class SessionManagerTest extends TestCase | |||
54 | $token => 1, | 70 | $token => 1, |
55 | ], | 71 | ], |
56 | ]; | 72 | ]; |
57 | $sessionManager = new SessionManager($session, self::$conf); | 73 | $sessionManager = new SessionManager($session, $this->conf); |
58 | 74 | ||
59 | // check and destroy the token | 75 | // check and destroy the token |
60 | $this->assertTrue($sessionManager->checkToken($token)); | 76 | $this->assertTrue($sessionManager->checkToken($token)); |
@@ -69,21 +85,18 @@ class SessionManagerTest extends TestCase | |||
69 | */ | 85 | */ |
70 | public function testGenerateAndCheckToken() | 86 | public function testGenerateAndCheckToken() |
71 | { | 87 | { |
72 | $session = []; | 88 | $token = $this->sessionManager->generateToken(); |
73 | $sessionManager = new SessionManager($session, self::$conf); | ||
74 | |||
75 | $token = $sessionManager->generateToken(); | ||
76 | 89 | ||
77 | // ensure a token has been generated | 90 | // ensure a token has been generated |
78 | $this->assertEquals(1, $session['tokens'][$token]); | 91 | $this->assertEquals(1, $this->session['tokens'][$token]); |
79 | $this->assertEquals(40, strlen($token)); | 92 | $this->assertEquals(40, strlen($token)); |
80 | 93 | ||
81 | // check and destroy the token | 94 | // check and destroy the token |
82 | $this->assertTrue($sessionManager->checkToken($token)); | 95 | $this->assertTrue($this->sessionManager->checkToken($token)); |
83 | $this->assertFalse(isset($session['tokens'][$token])); | 96 | $this->assertFalse(isset($this->session['tokens'][$token])); |
84 | 97 | ||
85 | // ensure the token has been destroyed | 98 | // ensure the token has been destroyed |
86 | $this->assertFalse($sessionManager->checkToken($token)); | 99 | $this->assertFalse($this->sessionManager->checkToken($token)); |
87 | } | 100 | } |
88 | 101 | ||
89 | /** | 102 | /** |
@@ -91,10 +104,7 @@ class SessionManagerTest extends TestCase | |||
91 | */ | 104 | */ |
92 | public function testCheckInvalidToken() | 105 | public function testCheckInvalidToken() |
93 | { | 106 | { |
94 | $session = []; | 107 | $this->assertFalse($this->sessionManager->checkToken('4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b')); |
95 | $sessionManager = new SessionManager($session, self::$conf); | ||
96 | |||
97 | $this->assertFalse($sessionManager->checkToken('4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b')); | ||
98 | } | 108 | } |
99 | 109 | ||
100 | /** | 110 | /** |
@@ -146,4 +156,131 @@ class SessionManagerTest extends TestCase | |||
146 | SessionManager::checkId('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=') | 156 | SessionManager::checkId('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=') |
147 | ); | 157 | ); |
148 | } | 158 | } |
159 | |||
160 | /** | ||
161 | * Store login information after a successful login | ||
162 | */ | ||
163 | public function testStoreLoginInfo() | ||
164 | { | ||
165 | $this->sessionManager->storeLoginInfo('ip_id'); | ||
166 | |||
167 | $this->assertTrue(isset($this->session['uid'])); | ||
168 | $this->assertGreaterThan(time(), $this->session['expires_on']); | ||
169 | $this->assertEquals('ip_id', $this->session['ip']); | ||
170 | $this->assertEquals('johndoe', $this->session['username']); | ||
171 | } | ||
172 | |||
173 | /** | ||
174 | * Extend a server-side session by SessionManager::$SHORT_TIMEOUT | ||
175 | */ | ||
176 | public function testExtendSession() | ||
177 | { | ||
178 | $this->sessionManager->extendSession(); | ||
179 | |||
180 | $this->assertGreaterThan(time(), $this->session['expires_on']); | ||
181 | $this->assertLessThanOrEqual( | ||
182 | time() + SessionManager::$SHORT_TIMEOUT, | ||
183 | $this->session['expires_on'] | ||
184 | ); | ||
185 | } | ||
186 | |||
187 | /** | ||
188 | * Extend a server-side session by SessionManager::$LONG_TIMEOUT | ||
189 | */ | ||
190 | public function testExtendSessionStaySignedIn() | ||
191 | { | ||
192 | $this->sessionManager->setStaySignedIn(true); | ||
193 | $this->sessionManager->extendSession(); | ||
194 | |||
195 | $this->assertGreaterThan(time(), $this->session['expires_on']); | ||
196 | $this->assertGreaterThan( | ||
197 | time() + SessionManager::$LONG_TIMEOUT - 10, | ||
198 | $this->session['expires_on'] | ||
199 | ); | ||
200 | $this->assertLessThanOrEqual( | ||
201 | time() + SessionManager::$LONG_TIMEOUT, | ||
202 | $this->session['expires_on'] | ||
203 | ); | ||
204 | } | ||
205 | |||
206 | /** | ||
207 | * Unset session variables after logging out | ||
208 | */ | ||
209 | public function testLogout() | ||
210 | { | ||
211 | $this->session = [ | ||
212 | 'uid' => 'some-uid', | ||
213 | 'ip' => 'ip_id', | ||
214 | 'expires_on' => time() + 1000, | ||
215 | 'username' => 'johndoe', | ||
216 | 'visibility' => 'public', | ||
217 | 'untaggedonly' => false, | ||
218 | ]; | ||
219 | $this->sessionManager->logout(); | ||
220 | |||
221 | $this->assertFalse(isset($this->session['uid'])); | ||
222 | $this->assertFalse(isset($this->session['ip'])); | ||
223 | $this->assertFalse(isset($this->session['expires_on'])); | ||
224 | $this->assertFalse(isset($this->session['username'])); | ||
225 | $this->assertFalse(isset($this->session['visibility'])); | ||
226 | $this->assertFalse(isset($this->session['untaggedonly'])); | ||
227 | } | ||
228 | |||
229 | /** | ||
230 | * The session is considered as expired because the UID is missing | ||
231 | */ | ||
232 | public function testHasExpiredNoUid() | ||
233 | { | ||
234 | $this->assertTrue($this->sessionManager->hasSessionExpired()); | ||
235 | } | ||
236 | |||
237 | /** | ||
238 | * The session is active and expiration time has been reached | ||
239 | */ | ||
240 | public function testHasExpiredTimeElapsed() | ||
241 | { | ||
242 | $this->session['uid'] = 'some-uid'; | ||
243 | $this->session['expires_on'] = time() - 10; | ||
244 | |||
245 | $this->assertTrue($this->sessionManager->hasSessionExpired()); | ||
246 | } | ||
247 | |||
248 | /** | ||
249 | * The session is active and expiration time has not been reached | ||
250 | */ | ||
251 | public function testHasNotExpired() | ||
252 | { | ||
253 | $this->session['uid'] = 'some-uid'; | ||
254 | $this->session['expires_on'] = time() + 1000; | ||
255 | |||
256 | $this->assertFalse($this->sessionManager->hasSessionExpired()); | ||
257 | } | ||
258 | |||
259 | /** | ||
260 | * Session hijacking protection is disabled, we assume the IP has not changed | ||
261 | */ | ||
262 | public function testHasClientIpChangedNoSessionProtection() | ||
263 | { | ||
264 | $this->conf->set('security.session_protection_disabled', true); | ||
265 | |||
266 | $this->assertFalse($this->sessionManager->hasClientIpChanged('')); | ||
267 | } | ||
268 | |||
269 | /** | ||
270 | * The client IP identifier has not changed | ||
271 | */ | ||
272 | public function testHasClientIpChangedNope() | ||
273 | { | ||
274 | $this->session['ip'] = 'ip_id'; | ||
275 | $this->assertFalse($this->sessionManager->hasClientIpChanged('ip_id')); | ||
276 | } | ||
277 | |||
278 | /** | ||
279 | * The client IP identifier has changed | ||
280 | */ | ||
281 | public function testHasClientIpChanged() | ||
282 | { | ||
283 | $this->session['ip'] = 'ip_id_one'; | ||
284 | $this->assertTrue($this->sessionManager->hasClientIpChanged('ip_id_two')); | ||
285 | } | ||
149 | } | 286 | } |