]> git.immae.eu Git - github/shaarli/Shaarli.git/blame - tests/security/SessionManagerTest.php
Process Shaarli install through Slim controller
[github/shaarli/Shaarli.git] / tests / security / SessionManagerTest.php
CommitLineData
ebd650c0 1<?php
dd883aaf 2
c4ad3d4f 3namespace Shaarli\Security;
ebd650c0 4
dea72c71 5use PHPUnit\Framework\TestCase;
ebd650c0 6
ebd650c0
V
7/**
8 * Test coverage for SessionManager
9 */
10class SessionManagerTest extends TestCase
11{
51f0128c 12 /** @var array Session ID hashes */
fd7d8461
V
13 protected static $sidHashes = null;
14
704637bf 15 /** @var \FakeConfigManager ConfigManager substitute for testing */
51f0128c
V
16 protected $conf = null;
17
18 /** @var array $_SESSION array for testing */
19 protected $session = [];
20
21 /** @var SessionManager Server-side session management abstraction */
22 protected $sessionManager = null;
dd883aaf 23
fd7d8461
V
24 /**
25 * Assign reference data
26 */
27 public static function setUpBeforeClass()
28 {
c4ad3d4f 29 self::$sidHashes = \ReferenceSessionIdHashes::getHashes();
51f0128c
V
30 }
31
32 /**
33 * Initialize or reset test resources
34 */
35 public function setUp()
36 {
c4ad3d4f 37 $this->conf = new \FakeConfigManager([
51f0128c
V
38 'credentials.login' => 'johndoe',
39 'credentials.salt' => 'salt',
40 'security.session_protection_disabled' => false,
41 ]);
42 $this->session = [];
c4ad3d4f 43 $this->sessionManager = new SessionManager($this->session, $this->conf, 'session_path');
fd7d8461
V
44 }
45
ebd650c0
V
46 /**
47 * Generate a session token
48 */
49 public function testGenerateToken()
50 {
51f0128c 51 $token = $this->sessionManager->generateToken();
ebd650c0 52
51f0128c 53 $this->assertEquals(1, $this->session['tokens'][$token]);
ebd650c0
V
54 $this->assertEquals(40, strlen($token));
55 }
56
ae7c954b
V
57 /**
58 * Check a session token
59 */
60 public function testCheckToken()
61 {
62 $token = '4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b';
63 $session = [
64 'tokens' => [
65 $token => 1,
66 ],
67 ];
c4ad3d4f 68 $sessionManager = new SessionManager($session, $this->conf, 'session_path');
ae7c954b
V
69
70 // check and destroy the token
71 $this->assertTrue($sessionManager->checkToken($token));
72 $this->assertFalse(isset($session['tokens'][$token]));
73
74 // ensure the token has been destroyed
75 $this->assertFalse($sessionManager->checkToken($token));
76 }
77
ebd650c0
V
78 /**
79 * Generate and check a session token
80 */
81 public function testGenerateAndCheckToken()
82 {
51f0128c 83 $token = $this->sessionManager->generateToken();
ebd650c0
V
84
85 // ensure a token has been generated
51f0128c 86 $this->assertEquals(1, $this->session['tokens'][$token]);
ebd650c0
V
87 $this->assertEquals(40, strlen($token));
88
89 // check and destroy the token
51f0128c
V
90 $this->assertTrue($this->sessionManager->checkToken($token));
91 $this->assertFalse(isset($this->session['tokens'][$token]));
ebd650c0
V
92
93 // ensure the token has been destroyed
51f0128c 94 $this->assertFalse($this->sessionManager->checkToken($token));
ebd650c0
V
95 }
96
97 /**
98 * Check an invalid session token
99 */
100 public function testCheckInvalidToken()
101 {
51f0128c 102 $this->assertFalse($this->sessionManager->checkToken('4dccc3a45ad9d03e5542b90c37d8db6d10f2b38b'));
ebd650c0 103 }
fd7d8461
V
104
105 /**
106 * Test SessionManager::checkId with a valid ID - TEST ALL THE HASHES!
107 *
108 * This tests extensively covers all hash algorithms / bit representations
109 */
110 public function testIsAnyHashSessionIdValid()
111 {
112 foreach (self::$sidHashes as $algo => $bpcs) {
113 foreach ($bpcs as $bpc => $hash) {
114 $this->assertTrue(SessionManager::checkId($hash));
115 }
116 }
117 }
118
119 /**
120 * Test checkId with a valid ID - SHA-1 hashes
121 */
122 public function testIsSha1SessionIdValid()
123 {
124 $this->assertTrue(SessionManager::checkId(sha1('shaarli')));
125 }
126
127 /**
128 * Test checkId with a valid ID - SHA-256 hashes
129 */
130 public function testIsSha256SessionIdValid()
131 {
132 $this->assertTrue(SessionManager::checkId(hash('sha256', 'shaarli')));
133 }
134
135 /**
136 * Test checkId with a valid ID - SHA-512 hashes
137 */
138 public function testIsSha512SessionIdValid()
139 {
140 $this->assertTrue(SessionManager::checkId(hash('sha512', 'shaarli')));
141 }
142
143 /**
144 * Test checkId with invalid IDs.
145 */
146 public function testIsSessionIdInvalid()
147 {
148 $this->assertFalse(SessionManager::checkId(''));
149 $this->assertFalse(SessionManager::checkId([]));
150 $this->assertFalse(
151 SessionManager::checkId('c0ZqcWF3VFE2NmJBdm1HMVQ0ZHJ3UmZPbTFsNGhkNHI=')
152 );
153 }
51f0128c
V
154
155 /**
156 * Store login information after a successful login
157 */
158 public function testStoreLoginInfo()
159 {
160 $this->sessionManager->storeLoginInfo('ip_id');
161
51f0128c
V
162 $this->assertGreaterThan(time(), $this->session['expires_on']);
163 $this->assertEquals('ip_id', $this->session['ip']);
164 $this->assertEquals('johndoe', $this->session['username']);
165 }
166
167 /**
168 * Extend a server-side session by SessionManager::$SHORT_TIMEOUT
169 */
170 public function testExtendSession()
171 {
172 $this->sessionManager->extendSession();
173
174 $this->assertGreaterThan(time(), $this->session['expires_on']);
175 $this->assertLessThanOrEqual(
176 time() + SessionManager::$SHORT_TIMEOUT,
177 $this->session['expires_on']
178 );
179 }
180
181 /**
182 * Extend a server-side session by SessionManager::$LONG_TIMEOUT
183 */
184 public function testExtendSessionStaySignedIn()
185 {
186 $this->sessionManager->setStaySignedIn(true);
187 $this->sessionManager->extendSession();
188
189 $this->assertGreaterThan(time(), $this->session['expires_on']);
190 $this->assertGreaterThan(
191 time() + SessionManager::$LONG_TIMEOUT - 10,
192 $this->session['expires_on']
193 );
194 $this->assertLessThanOrEqual(
195 time() + SessionManager::$LONG_TIMEOUT,
196 $this->session['expires_on']
197 );
198 }
199
200 /**
201 * Unset session variables after logging out
202 */
203 public function testLogout()
204 {
205 $this->session = [
51f0128c
V
206 'ip' => 'ip_id',
207 'expires_on' => time() + 1000,
208 'username' => 'johndoe',
209 'visibility' => 'public',
210 'untaggedonly' => false,
211 ];
212 $this->sessionManager->logout();
213
51f0128c
V
214 $this->assertFalse(isset($this->session['ip']));
215 $this->assertFalse(isset($this->session['expires_on']));
216 $this->assertFalse(isset($this->session['username']));
217 $this->assertFalse(isset($this->session['visibility']));
218 $this->assertFalse(isset($this->session['untaggedonly']));
219 }
220
51f0128c
V
221 /**
222 * The session is active and expiration time has been reached
223 */
224 public function testHasExpiredTimeElapsed()
225 {
51f0128c
V
226 $this->session['expires_on'] = time() - 10;
227
228 $this->assertTrue($this->sessionManager->hasSessionExpired());
229 }
230
231 /**
232 * The session is active and expiration time has not been reached
233 */
234 public function testHasNotExpired()
235 {
51f0128c
V
236 $this->session['expires_on'] = time() + 1000;
237
238 $this->assertFalse($this->sessionManager->hasSessionExpired());
239 }
240
241 /**
242 * Session hijacking protection is disabled, we assume the IP has not changed
243 */
244 public function testHasClientIpChangedNoSessionProtection()
245 {
246 $this->conf->set('security.session_protection_disabled', true);
247
248 $this->assertFalse($this->sessionManager->hasClientIpChanged(''));
249 }
250
251 /**
252 * The client IP identifier has not changed
253 */
254 public function testHasClientIpChangedNope()
255 {
256 $this->session['ip'] = 'ip_id';
257 $this->assertFalse($this->sessionManager->hasClientIpChanged('ip_id'));
258 }
259
260 /**
261 * The client IP identifier has changed
262 */
263 public function testHasClientIpChanged()
264 {
265 $this->session['ip'] = 'ip_id_one';
266 $this->assertTrue($this->sessionManager->hasClientIpChanged('ip_id_two'));
267 }
af290059
A
268
269 /**
270 * Test creating an entry in the session array
271 */
272 public function testSetSessionParameterCreate(): void
273 {
274 $this->sessionManager->setSessionParameter('abc', 'def');
275
276 static::assertSame('def', $this->session['abc']);
277 }
278
279 /**
280 * Test updating an entry in the session array
281 */
282 public function testSetSessionParameterUpdate(): void
283 {
284 $this->session['abc'] = 'ghi';
285
286 $this->sessionManager->setSessionParameter('abc', 'def');
287
288 static::assertSame('def', $this->session['abc']);
289 }
290
291 /**
292 * Test updating an entry in the session array with null value
293 */
294 public function testSetSessionParameterUpdateNull(): void
295 {
296 $this->session['abc'] = 'ghi';
297
298 $this->sessionManager->setSessionParameter('abc', null);
299
300 static::assertArrayHasKey('abc', $this->session);
301 static::assertNull($this->session['abc']);
302 }
303
304 /**
305 * Test deleting an existing entry in the session array
306 */
307 public function testDeleteSessionParameter(): void
308 {
309 $this->session['abc'] = 'def';
310
311 $this->sessionManager->deleteSessionParameter('abc');
312
313 static::assertArrayNotHasKey('abc', $this->session);
314 }
315
316 /**
317 * Test deleting a non existent entry in the session array
318 */
319 public function testDeleteSessionParameterNotExisting(): void
320 {
321 $this->sessionManager->deleteSessionParameter('abc');
322
323 static::assertArrayNotHasKey('abc', $this->session);
324 }
ebd650c0 325}