diff --git a/_test/helper.test.php b/_test/helper.test.php index 18e8f5e..3e79923 100644 --- a/_test/helper.test.php +++ b/_test/helper.test.php @@ -5,12 +5,15 @@ class helper_plugin_captcha_public extends helper_plugin_captcha { public function get_field_in() { return $this->field_in; } + public function get_field_sec() { return $this->field_sec; } + public function get_field_hp() { return $this->field_hp; } + public function storeCaptchaCookie($fixed, $rand) { parent::storeCaptchaCookie($fixed, $rand); } @@ -90,10 +93,57 @@ public function testGenerate() { $rand = 0; $code = $helper->_generateCAPTCHA($helper->_fixedIdent(), $rand); - $newcode = $helper->_generateCAPTCHA($helper->_fixedIdent().'X', $rand); + $newcode = $helper->_generateCAPTCHA($helper->_fixedIdent() . 'X', $rand); $this->assertNotEquals($newcode, $code); - $newcode = $helper->_generateCAPTCHA($helper->_fixedIdent(), $rand+0.1); + $newcode = $helper->_generateCAPTCHA($helper->_fixedIdent(), $rand + 0.1); $this->assertNotEquals($newcode, $code); } + public function testCleanup() { + // we need a complete fresh environment: + $this->setUpBeforeClass(); + + global $conf; + $path = $conf['tmpdir'] . '/captcha/'; + $today = "$path/" . date('Y-m-d'); + + $helper = new helper_plugin_captcha_public(); + + // nothing at all + $dirs = glob("$path/*"); + $this->assertEquals(array(), $dirs); + + // store a cookie + $helper->storeCaptchaCookie('test', 0); + + // nothing but today's data + $dirs = glob("$path/*"); + $this->assertEquals(array($today), $dirs); + + // add some fake cookies + io_saveFile("$path/2017-01-01/foo.cookie", ''); + io_saveFile("$path/2017-01-02/foo.cookie", ''); + io_saveFile("$path/2017-01-03/foo.cookie", ''); + io_saveFile("$path/2017-01-04/foo.cookie", ''); + + // all directories there + $dirs = glob("$path/*"); + $this->assertEquals( + array( + "$path/2017-01-01", + "$path/2017-01-02", + "$path/2017-01-03", + "$path/2017-01-04", + $today + ), + $dirs + ); + + // clean up + $helper->_cleanCaptchaCookies(); + + // nothing but today's data + $dirs = glob("$path/*"); + $this->assertEquals(array($today), $dirs); + } } diff --git a/action.php b/action.php index 6fdf2f2..b775015 100644 --- a/action.php +++ b/action.php @@ -70,6 +70,15 @@ public function register(Doku_Event_Handler $controller) { array() ); } + + // clean up captcha cookies + $controller->register_hook( + 'INDEXER_TASKS_RUN', + 'AFTER', + $this, + 'handle_indexer', + array() + ); } /** @@ -195,5 +204,20 @@ public function handle_form_output(Doku_Event $event, $param) { $event->data->insertElement($pos + 1, $out); } + /** + * Clean cookies once per day + */ + public function handle_indexer(Doku_Event $event, $param) { + $lastrun = getCacheName('captcha', '.captcha'); + $last = @filemtime($lastrun); + if(time() - $last < 24 * 60 * 60) return; + + /** @var helper_plugin_captcha $helper */ + $helper = plugin_load('helper', 'captcha'); + $helper->_cleanCaptchaCookies(); + + $event->preventDefault(); + $event->stopPropagation(); + } } diff --git a/helper.php b/helper.php index b745b54..5a7e999 100644 --- a/helper.php +++ b/helper.php @@ -6,7 +6,7 @@ // must be run within Dokuwiki if(!defined('DOKU_INC')) die(); -if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/'); +if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/'); /** * Class helper_plugin_captcha @@ -145,7 +145,7 @@ public function check($msg = true) { } /** - * Get the path where a capture cookie would be stored + * Get the path where a captcha cookie would be stored * * We use a daily temp directory which is easy to clean up * @@ -160,6 +160,21 @@ protected function getCaptchaCookiePath($fixed, $rand) { return $path; } + /** + * remove all outdated captcha cookies + */ + public function _cleanCaptchaCookies() { + global $conf; + $path = $conf['tmpdir'] . '/captcha/'; + $dirs = glob("$path/*", GLOB_ONLYDIR); + $today = date('Y-m-d'); + foreach($dirs as $dir) { + if(basename($dir) === $today) continue; + if(!preg_match('/\/captcha\//', $dir)) continue; // safety net + io_rmdir($dir, true); + } + } + /** * Creates a one time captcha cookie * @@ -210,9 +225,9 @@ public function _fixedIdent() { global $ID; $lm = @filemtime(wikiFN($ID)); $td = date('Y-m-d'); - return auth_browseruid(). - auth_cookiesalt(). - $ID.$lm.$td; + return auth_browseruid() . + auth_cookiesalt() . + $ID . $lm . $td; } /**