diff options
-rw-r--r-- | application/security/LoginManager.php | 9 | ||||
-rw-r--r-- | tests/security/LoginManagerTest.php | 149 | ||||
-rw-r--r-- | tests/security/SessionManagerTest.php | 2 | ||||
-rw-r--r-- | tests/utils/FakeConfigManager.php | 12 |
4 files changed, 161 insertions, 11 deletions
diff --git a/application/security/LoginManager.php b/application/security/LoginManager.php index 41fa9a20..4946850b 100644 --- a/application/security/LoginManager.php +++ b/application/security/LoginManager.php | |||
@@ -46,7 +46,7 @@ class LoginManager | |||
46 | $this->sessionManager = $sessionManager; | 46 | $this->sessionManager = $sessionManager; |
47 | $this->banFile = $this->configManager->get('resource.ban_file', 'data/ipbans.php'); | 47 | $this->banFile = $this->configManager->get('resource.ban_file', 'data/ipbans.php'); |
48 | $this->readBanFile(); | 48 | $this->readBanFile(); |
49 | if ($this->configManager->get('security.open_shaarli')) { | 49 | if ($this->configManager->get('security.open_shaarli') === true) { |
50 | $this->openShaarli = true; | 50 | $this->openShaarli = true; |
51 | } | 51 | } |
52 | } | 52 | } |
@@ -80,8 +80,6 @@ class LoginManager | |||
80 | * | 80 | * |
81 | * @param array $cookie The $_COOKIE array | 81 | * @param array $cookie The $_COOKIE array |
82 | * @param string $clientIpId Client IP address identifier | 82 | * @param string $clientIpId Client IP address identifier |
83 | * | ||
84 | * @return bool true if the user session is valid, false otherwise | ||
85 | */ | 83 | */ |
86 | public function checkLoginState($cookie, $clientIpId) | 84 | public function checkLoginState($cookie, $clientIpId) |
87 | { | 85 | { |
@@ -94,11 +92,12 @@ class LoginManager | |||
94 | if (isset($cookie[self::$STAY_SIGNED_IN_COOKIE]) | 92 | if (isset($cookie[self::$STAY_SIGNED_IN_COOKIE]) |
95 | && $cookie[self::$STAY_SIGNED_IN_COOKIE] === $this->staySignedInToken | 93 | && $cookie[self::$STAY_SIGNED_IN_COOKIE] === $this->staySignedInToken |
96 | ) { | 94 | ) { |
95 | // The user client has a valid stay-signed-in cookie | ||
96 | // Session information is updated with the current client information | ||
97 | $this->sessionManager->storeLoginInfo($clientIpId); | 97 | $this->sessionManager->storeLoginInfo($clientIpId); |
98 | $this->isLoggedIn = true; | 98 | $this->isLoggedIn = true; |
99 | } | ||
100 | 99 | ||
101 | if ($this->sessionManager->hasSessionExpired() | 100 | } elseif ($this->sessionManager->hasSessionExpired() |
102 | || $this->sessionManager->hasClientIpChanged($clientIpId) | 101 | || $this->sessionManager->hasClientIpChanged($clientIpId) |
103 | ) { | 102 | ) { |
104 | $this->sessionManager->logout(); | 103 | $this->sessionManager->logout(); |
diff --git a/tests/security/LoginManagerTest.php b/tests/security/LoginManagerTest.php index 633f1bb9..fad09992 100644 --- a/tests/security/LoginManagerTest.php +++ b/tests/security/LoginManagerTest.php | |||
@@ -9,13 +9,40 @@ use \PHPUnit\Framework\TestCase; | |||
9 | */ | 9 | */ |
10 | class LoginManagerTest extends TestCase | 10 | class LoginManagerTest extends TestCase |
11 | { | 11 | { |
12 | /** @var \FakeConfigManager Configuration Manager instance */ | ||
12 | protected $configManager = null; | 13 | protected $configManager = null; |
14 | |||
15 | /** @var LoginManager Login Manager instance */ | ||
13 | protected $loginManager = null; | 16 | protected $loginManager = null; |
17 | |||
18 | /** @var SessionManager Session Manager instance */ | ||
19 | protected $sessionManager = null; | ||
20 | |||
21 | /** @var string Banned IP filename */ | ||
14 | protected $banFile = 'sandbox/ipbans.php'; | 22 | protected $banFile = 'sandbox/ipbans.php'; |
23 | |||
24 | /** @var string Log filename */ | ||
15 | protected $logFile = 'sandbox/shaarli.log'; | 25 | protected $logFile = 'sandbox/shaarli.log'; |
26 | |||
27 | /** @var array Simulates the $_COOKIE array */ | ||
28 | protected $cookie = []; | ||
29 | |||
30 | /** @var array Simulates the $GLOBALS array */ | ||
16 | protected $globals = []; | 31 | protected $globals = []; |
17 | protected $ipAddr = '127.0.0.1'; | 32 | |
33 | /** @var array Simulates the $_SERVER array */ | ||
18 | protected $server = []; | 34 | protected $server = []; |
35 | |||
36 | /** @var array Simulates the $_SESSION array */ | ||
37 | protected $session = []; | ||
38 | |||
39 | /** @var string Advertised client IP address */ | ||
40 | protected $clientIpAddress = '10.1.47.179'; | ||
41 | |||
42 | /** @var string Local client IP address */ | ||
43 | protected $ipAddr = '127.0.0.1'; | ||
44 | |||
45 | /** @var string Trusted proxy IP address */ | ||
19 | protected $trustedProxy = '10.1.1.100'; | 46 | protected $trustedProxy = '10.1.1.100'; |
20 | 47 | ||
21 | /** @var string User login */ | 48 | /** @var string User login */ |
@@ -52,10 +79,18 @@ class LoginManagerTest extends TestCase | |||
52 | 'security.trusted_proxies' => [$this->trustedProxy], | 79 | 'security.trusted_proxies' => [$this->trustedProxy], |
53 | ]); | 80 | ]); |
54 | 81 | ||
82 | $this->cookie = []; | ||
83 | |||
55 | $this->globals = &$GLOBALS; | 84 | $this->globals = &$GLOBALS; |
56 | unset($this->globals['IPBANS']); | 85 | unset($this->globals['IPBANS']); |
57 | 86 | ||
58 | $this->loginManager = new LoginManager($this->globals, $this->configManager, null); | 87 | $this->session = [ |
88 | 'expires_on' => time() + 100, | ||
89 | 'ip' => $this->clientIpAddress, | ||
90 | ]; | ||
91 | |||
92 | $this->sessionManager = new SessionManager($this->session, $this->configManager); | ||
93 | $this->loginManager = new LoginManager($this->globals, $this->configManager, $this->sessionManager); | ||
59 | $this->server['REMOTE_ADDR'] = $this->ipAddr; | 94 | $this->server['REMOTE_ADDR'] = $this->ipAddr; |
60 | } | 95 | } |
61 | 96 | ||
@@ -219,12 +254,116 @@ class LoginManagerTest extends TestCase | |||
219 | */ | 254 | */ |
220 | public function testGenerateStaySignedInToken() | 255 | public function testGenerateStaySignedInToken() |
221 | { | 256 | { |
222 | $ipAddress = '10.1.47.179'; | 257 | $this->loginManager->generateStaySignedInToken($this->clientIpAddress); |
223 | $this->loginManager->generateStaySignedInToken($ipAddress); | ||
224 | 258 | ||
225 | $this->assertEquals( | 259 | $this->assertEquals( |
226 | sha1($this->passwordHash . $ipAddress . $this->salt), | 260 | sha1($this->passwordHash . $this->clientIpAddress . $this->salt), |
227 | $this->loginManager->getStaySignedInToken() | 261 | $this->loginManager->getStaySignedInToken() |
228 | ); | 262 | ); |
229 | } | 263 | } |
264 | |||
265 | /** | ||
266 | * Check user login - Shaarli has not yet been configured | ||
267 | */ | ||
268 | public function testCheckLoginStateNotConfigured() | ||
269 | { | ||
270 | $configManager = new \FakeConfigManager([ | ||
271 | 'resource.ban_file' => $this->banFile, | ||
272 | ]); | ||
273 | $loginManager = new LoginManager($this->globals, $configManager, null); | ||
274 | $loginManager->checkLoginState([], ''); | ||
275 | |||
276 | $this->assertFalse($loginManager->isLoggedIn()); | ||
277 | } | ||
278 | |||
279 | /** | ||
280 | * Check user login - the client cookie does not match the server token | ||
281 | */ | ||
282 | public function testCheckLoginStateStaySignedInWithInvalidToken() | ||
283 | { | ||
284 | $this->loginManager->generateStaySignedInToken($this->clientIpAddress); | ||
285 | $this->cookie[LoginManager::$STAY_SIGNED_IN_COOKIE] = 'nope'; | ||
286 | |||
287 | $this->loginManager->checkLoginState($this->cookie, $this->clientIpAddress); | ||
288 | |||
289 | $this->assertFalse($this->loginManager->isLoggedIn()); | ||
290 | } | ||
291 | |||
292 | /** | ||
293 | * Check user login - the client cookie matches the server token | ||
294 | */ | ||
295 | public function testCheckLoginStateStaySignedInWithValidToken() | ||
296 | { | ||
297 | $this->loginManager->generateStaySignedInToken($this->clientIpAddress); | ||
298 | $this->cookie[LoginManager::$STAY_SIGNED_IN_COOKIE] = $this->loginManager->getStaySignedInToken(); | ||
299 | |||
300 | $this->loginManager->checkLoginState($this->cookie, $this->clientIpAddress); | ||
301 | |||
302 | $this->assertTrue($this->loginManager->isLoggedIn()); | ||
303 | } | ||
304 | |||
305 | /** | ||
306 | * Check user login - the session has expired | ||
307 | */ | ||
308 | public function testCheckLoginStateSessionExpired() | ||
309 | { | ||
310 | $this->loginManager->generateStaySignedInToken($this->clientIpAddress); | ||
311 | $this->session['expires_on'] = time() - 100; | ||
312 | |||
313 | $this->loginManager->checkLoginState($this->cookie, $this->clientIpAddress); | ||
314 | |||
315 | $this->assertFalse($this->loginManager->isLoggedIn()); | ||
316 | } | ||
317 | |||
318 | /** | ||
319 | * Check user login - the remote client IP has changed | ||
320 | */ | ||
321 | public function testCheckLoginStateClientIpChanged() | ||
322 | { | ||
323 | $this->loginManager->generateStaySignedInToken($this->clientIpAddress); | ||
324 | |||
325 | $this->loginManager->checkLoginState($this->cookie, '10.7.157.98'); | ||
326 | |||
327 | $this->assertFalse($this->loginManager->isLoggedIn()); | ||
328 | } | ||
329 | |||
330 | /** | ||
331 | * Check user credentials - wrong login supplied | ||
332 | */ | ||
333 | public function testCheckCredentialsWrongLogin() | ||
334 | { | ||
335 | $this->assertFalse( | ||
336 | $this->loginManager->checkCredentials('', '', 'b4dl0g1n', $this->password) | ||
337 | ); | ||
338 | } | ||
339 | |||
340 | /** | ||
341 | * Check user credentials - wrong password supplied | ||
342 | */ | ||
343 | public function testCheckCredentialsWrongPassword() | ||
344 | { | ||
345 | $this->assertFalse( | ||
346 | $this->loginManager->checkCredentials('', '', $this->login, 'b4dp455wd') | ||
347 | ); | ||
348 | } | ||
349 | |||
350 | /** | ||
351 | * Check user credentials - wrong login and password supplied | ||
352 | */ | ||
353 | public function testCheckCredentialsWrongLoginAndPassword() | ||
354 | { | ||
355 | $this->assertFalse( | ||
356 | $this->loginManager->checkCredentials('', '', 'b4dl0g1n', 'b4dp455wd') | ||
357 | ); | ||
358 | } | ||
359 | |||
360 | /** | ||
361 | * Check user credentials - correct login and password supplied | ||
362 | */ | ||
363 | public function testCheckCredentialsGoodLoginAndPassword() | ||
364 | { | ||
365 | $this->assertTrue( | ||
366 | $this->loginManager->checkCredentials('', '', $this->login, $this->password) | ||
367 | ); | ||
368 | } | ||
230 | } | 369 | } |
diff --git a/tests/security/SessionManagerTest.php b/tests/security/SessionManagerTest.php index ae10ffa6..9bd868f8 100644 --- a/tests/security/SessionManagerTest.php +++ b/tests/security/SessionManagerTest.php | |||
@@ -17,7 +17,7 @@ class SessionManagerTest extends TestCase | |||
17 | /** @var array Session ID hashes */ | 17 | /** @var array Session ID hashes */ |
18 | protected static $sidHashes = null; | 18 | protected static $sidHashes = null; |
19 | 19 | ||
20 | /** @var FakeConfigManager ConfigManager substitute for testing */ | 20 | /** @var \FakeConfigManager ConfigManager substitute for testing */ |
21 | protected $conf = null; | 21 | protected $conf = null; |
22 | 22 | ||
23 | /** @var array $_SESSION array for testing */ | 23 | /** @var array $_SESSION array for testing */ |
diff --git a/tests/utils/FakeConfigManager.php b/tests/utils/FakeConfigManager.php index 85434de7..360b34a9 100644 --- a/tests/utils/FakeConfigManager.php +++ b/tests/utils/FakeConfigManager.php | |||
@@ -42,4 +42,16 @@ class FakeConfigManager | |||
42 | } | 42 | } |
43 | return $key; | 43 | return $key; |
44 | } | 44 | } |
45 | |||
46 | /** | ||
47 | * Check if a setting exists | ||
48 | * | ||
49 | * @param string $setting Asked setting, keys separated with dots | ||
50 | * | ||
51 | * @return bool true if the setting exists, false otherwise | ||
52 | */ | ||
53 | public function exists($setting) | ||
54 | { | ||
55 | return array_key_exists($setting, $this->values); | ||
56 | } | ||
45 | } | 57 | } |