diff options
-rw-r--r-- | application/Utils.php | 13 | ||||
-rw-r--r-- | index.php | 18 | ||||
-rw-r--r-- | tests/UtilsTest.php | 66 |
3 files changed, 84 insertions, 13 deletions
diff --git a/application/Utils.php b/application/Utils.php index aeaef9ff..a9a10ece 100644 --- a/application/Utils.php +++ b/application/Utils.php | |||
@@ -4,6 +4,19 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | /** | 6 | /** |
7 | * Logs a message to a text file | ||
8 | * | ||
9 | * @param string $logFile where to write the logs | ||
10 | * @param string $clientIp the client's remote IPv4/IPv6 address | ||
11 | * @param string $message the message to log | ||
12 | */ | ||
13 | function logm($logFile, $clientIp, $message) | ||
14 | { | ||
15 | $line = strval(date('Y/m/d_H:i:s')).' - '.$clientIp.' - '.strval($message).'\n'; | ||
16 | file_put_contents($logFile, $line, FILE_APPEND); | ||
17 | } | ||
18 | |||
19 | /** | ||
7 | * Returns the small hash of a string, using RFC 4648 base64url format | 20 | * Returns the small hash of a string, using RFC 4648 base64url format |
8 | * | 21 | * |
9 | * Small hashes: | 22 | * Small hashes: |
@@ -309,14 +309,6 @@ function setup_login_state() { | |||
309 | $userIsLoggedIn = setup_login_state(); | 309 | $userIsLoggedIn = setup_login_state(); |
310 | 310 | ||
311 | 311 | ||
312 | // ----------------------------------------------------------------------------------------------- | ||
313 | // Log to text file | ||
314 | function logm($message) | ||
315 | { | ||
316 | $t = strval(date('Y/m/d_H:i:s')).' - '.$_SERVER["REMOTE_ADDR"].' - '.strval($message)."\n"; | ||
317 | file_put_contents($GLOBALS['config']['LOG_FILE'], $t, FILE_APPEND); | ||
318 | } | ||
319 | |||
320 | // ------------------------------------------------------------------------------------------ | 312 | // ------------------------------------------------------------------------------------------ |
321 | // Sniff browser language to display dates in the right format automatically. | 313 | // Sniff browser language to display dates in the right format automatically. |
322 | // (Note that is may not work on your server if the corresponding local is not installed.) | 314 | // (Note that is may not work on your server if the corresponding local is not installed.) |
@@ -380,10 +372,10 @@ function check_auth($login,$password) | |||
380 | if ($login==$GLOBALS['login'] && $hash==$GLOBALS['hash']) | 372 | if ($login==$GLOBALS['login'] && $hash==$GLOBALS['hash']) |
381 | { // Login/password is correct. | 373 | { // Login/password is correct. |
382 | fillSessionInfo(); | 374 | fillSessionInfo(); |
383 | logm('Login successful'); | 375 | logm($GLOBALS['config']['LOG_FILE'], $_SERVER['REMOTE_ADDR'], 'Login successful'); |
384 | return True; | 376 | return True; |
385 | } | 377 | } |
386 | logm('Login failed for user '.$login); | 378 | logm($GLOBALS['config']['LOG_FILE'], $_SERVER['REMOTE_ADDR'], 'Login failed for user '.$login); |
387 | return False; | 379 | return False; |
388 | } | 380 | } |
389 | 381 | ||
@@ -420,7 +412,7 @@ function ban_loginFailed() | |||
420 | if ($gb['FAILURES'][$ip]>($GLOBALS['config']['BAN_AFTER']-1)) | 412 | if ($gb['FAILURES'][$ip]>($GLOBALS['config']['BAN_AFTER']-1)) |
421 | { | 413 | { |
422 | $gb['BANS'][$ip]=time()+$GLOBALS['config']['BAN_DURATION']; | 414 | $gb['BANS'][$ip]=time()+$GLOBALS['config']['BAN_DURATION']; |
423 | logm('IP address banned from login'); | 415 | logm($GLOBALS['config']['LOG_FILE'], $_SERVER['REMOTE_ADDR'], 'IP address banned from login'); |
424 | } | 416 | } |
425 | $GLOBALS['IPBANS'] = $gb; | 417 | $GLOBALS['IPBANS'] = $gb; |
426 | file_put_contents($GLOBALS['config']['IPBANS_FILENAME'], "<?php\n\$GLOBALS['IPBANS']=".var_export($gb,true).";\n?>"); | 418 | file_put_contents($GLOBALS['config']['IPBANS_FILENAME'], "<?php\n\$GLOBALS['IPBANS']=".var_export($gb,true).";\n?>"); |
@@ -444,7 +436,7 @@ function ban_canLogin() | |||
444 | // User is banned. Check if the ban has expired: | 436 | // User is banned. Check if the ban has expired: |
445 | if ($gb['BANS'][$ip]<=time()) | 437 | if ($gb['BANS'][$ip]<=time()) |
446 | { // Ban expired, user can try to login again. | 438 | { // Ban expired, user can try to login again. |
447 | logm('Ban lifted.'); | 439 | logm($GLOBALS['config']['LOG_FILE'], $_SERVER['REMOTE_ADDR'], 'Ban lifted.'); |
448 | unset($gb['FAILURES'][$ip]); unset($gb['BANS'][$ip]); | 440 | unset($gb['FAILURES'][$ip]); unset($gb['BANS'][$ip]); |
449 | file_put_contents($GLOBALS['config']['IPBANS_FILENAME'], "<?php\n\$GLOBALS['IPBANS']=".var_export($gb,true).";\n?>"); | 441 | file_put_contents($GLOBALS['config']['IPBANS_FILENAME'], "<?php\n\$GLOBALS['IPBANS']=".var_export($gb,true).";\n?>"); |
450 | return true; // Ban has expired, user can login. | 442 | return true; // Ban has expired, user can login. |
@@ -641,7 +633,7 @@ class pageBuilder | |||
641 | $this->tpl->assign('versionError', ''); | 633 | $this->tpl->assign('versionError', ''); |
642 | 634 | ||
643 | } catch (Exception $exc) { | 635 | } catch (Exception $exc) { |
644 | logm($exc->getMessage()); | 636 | logm($GLOBALS['config']['LOG_FILE'], $_SERVER['REMOTE_ADDR'], $exc->getMessage()); |
645 | $this->tpl->assign('newVersion', ''); | 637 | $this->tpl->assign('newVersion', ''); |
646 | $this->tpl->assign('versionError', escape($exc->getMessage())); | 638 | $this->tpl->assign('versionError', escape($exc->getMessage())); |
647 | } | 639 | } |
diff --git a/tests/UtilsTest.php b/tests/UtilsTest.php index 02eecda2..869a9695 100644 --- a/tests/UtilsTest.php +++ b/tests/UtilsTest.php | |||
@@ -18,6 +18,13 @@ class UtilsTest extends PHPUnit_Framework_TestCase | |||
18 | // Session ID hashes | 18 | // Session ID hashes |
19 | protected static $sidHashes = null; | 19 | protected static $sidHashes = null; |
20 | 20 | ||
21 | // Log file | ||
22 | protected static $testLogFile = 'tests.log'; | ||
23 | |||
24 | // Expected log date format | ||
25 | protected static $dateFormat = 'Y/m/d_H:i:s'; | ||
26 | |||
27 | |||
21 | /** | 28 | /** |
22 | * Assign reference data | 29 | * Assign reference data |
23 | */ | 30 | */ |
@@ -27,6 +34,65 @@ class UtilsTest extends PHPUnit_Framework_TestCase | |||
27 | } | 34 | } |
28 | 35 | ||
29 | /** | 36 | /** |
37 | * Resets test data before each test | ||
38 | */ | ||
39 | protected function setUp() | ||
40 | { | ||
41 | if (file_exists(self::$testLogFile)) { | ||
42 | unlink(self::$testLogFile); | ||
43 | } | ||
44 | } | ||
45 | |||
46 | /** | ||
47 | * Returns a list of the elements from the last logged entry | ||
48 | * | ||
49 | * @return list (date, ip address, message) | ||
50 | */ | ||
51 | protected function getLastLogEntry() | ||
52 | { | ||
53 | $logFile = file(self::$testLogFile); | ||
54 | return explode(' - ', trim(array_pop($logFile), '\n')); | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * Log a message to a file - IPv4 client address | ||
59 | */ | ||
60 | public function testLogmIp4() | ||
61 | { | ||
62 | $logMessage = 'IPv4 client connected'; | ||
63 | logm(self::$testLogFile, '127.0.0.1', $logMessage); | ||
64 | list($date, $ip, $message) = $this->getLastLogEntry(); | ||
65 | |||
66 | $this->assertInstanceOf( | ||
67 | 'DateTime', | ||
68 | DateTime::createFromFormat(self::$dateFormat, $date) | ||
69 | ); | ||
70 | $this->assertTrue( | ||
71 | filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false | ||
72 | ); | ||
73 | $this->assertEquals($logMessage, $message); | ||
74 | } | ||
75 | |||
76 | /** | ||
77 | * Log a message to a file - IPv6 client address | ||
78 | */ | ||
79 | public function testLogmIp6() | ||
80 | { | ||
81 | $logMessage = 'IPv6 client connected'; | ||
82 | logm(self::$testLogFile, '2001:db8::ff00:42:8329', $logMessage); | ||
83 | list($date, $ip, $message) = $this->getLastLogEntry(); | ||
84 | |||
85 | $this->assertInstanceOf( | ||
86 | 'DateTime', | ||
87 | DateTime::createFromFormat(self::$dateFormat, $date) | ||
88 | ); | ||
89 | $this->assertTrue( | ||
90 | filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false | ||
91 | ); | ||
92 | $this->assertEquals($logMessage, $message); | ||
93 | } | ||
94 | |||
95 | /** | ||
30 | * Represent a link by its hash | 96 | * Represent a link by its hash |
31 | */ | 97 | */ |
32 | public function testSmallHash() | 98 | public function testSmallHash() |