From 36bd54e4ec53a4887f04887c9d9e6dbb42ae4393 Mon Sep 17 00:00:00 2001 From: Reedy Date: Mon, 15 Jan 2024 15:17:21 +0000 Subject: [PATCH] FancyCaptcha: Allow configuration of the actual directory captchas are stored in Change-Id: Iecc48db5237adc5b89c99019faac0af425e4eb5d --- FancyCaptcha/extension.json | 4 +++ FancyCaptcha/includes/FancyCaptcha.php | 43 ++++++++++++++++---------- includes/Store/CaptchaCacheStore.php | 18 ++++------- maintenance/CountFancyCaptchas.php | 16 ++++++++-- maintenance/DeleteOldFancyCaptchas.php | 14 ++++++++- maintenance/GenerateFancyCaptchas.php | 17 ++++++++-- 6 files changed, 78 insertions(+), 34 deletions(-) diff --git a/FancyCaptcha/extension.json b/FancyCaptcha/extension.json index fd0053347..f7e268144 100644 --- a/FancyCaptcha/extension.json +++ b/FancyCaptcha/extension.json @@ -60,6 +60,10 @@ }, "CaptchaDeleteOnSolve": { "value": false + }, + "CaptchaStorageDirectory": { + "description": "The directory that captchas will be stored in on the CaptchaFileBackend. You probably don't need to change this!", + "value": "captcha-render" } }, "manifest_version": 2 diff --git a/FancyCaptcha/includes/FancyCaptcha.php b/FancyCaptcha/includes/FancyCaptcha.php index 0102fe85d..ebc04ea4a 100644 --- a/FancyCaptcha/includes/FancyCaptcha.php +++ b/FancyCaptcha/includes/FancyCaptcha.php @@ -37,21 +37,22 @@ class FancyCaptcha extends SimpleCaptcha { if ( $wgCaptchaFileBackend ) { return MediaWikiServices::getInstance()->getFileBackendGroup() ->get( $wgCaptchaFileBackend ); - } else { - static $backend = null; - if ( !$backend ) { - $backend = new FSFileBackend( [ - 'name' => 'captcha-backend', - 'wikiId' => WikiMap::getCurrentWikiId(), - 'lockManager' => new NullLockManager( [] ), - 'containerPaths' => [ 'captcha-render' => $wgCaptchaDirectory ], - 'fileMode' => 777, - 'obResetFunc' => 'wfResetOutputBuffers', - 'streamMimeFunc' => [ 'StreamFile', 'contentTypeFromPath' ] - ] ); - } - return $backend; } + + static $backend = null; + if ( !$backend ) { + $backend = new FSFileBackend( [ + 'name' => 'captcha-backend', + 'wikiId' => WikiMap::getCurrentWikiId(), + 'lockManager' => new NullLockManager( [] ), + 'containerPaths' => [ $this->getStorageDir() => $wgCaptchaDirectory ], + 'fileMode' => 777, + 'obResetFunc' => 'wfResetOutputBuffers', + 'streamMimeFunc' => [ 'StreamFile', 'contentTypeFromPath' ] + ] ); + } + + return $backend; } /** @@ -60,12 +61,20 @@ class FancyCaptcha extends SimpleCaptcha { public function getCaptchaCount() { $backend = $this->getBackend(); $files = $backend->getFileList( - [ 'dir' => $backend->getRootStoragePath() . '/captcha-render' ] + [ 'dir' => $backend->getRootStoragePath() . '/' . $this->getStorageDir() ] ); return iterator_count( $files ); } + /** + * @return string + */ + public function getStorageDir() { + global $wgCaptchaStorageDirectory; + return $wgCaptchaStorageDirectory; + } + /** * Check if the submitted form matches the captcha session data provided * by the plugin when the form was generated. @@ -203,7 +212,7 @@ class FancyCaptcha extends SimpleCaptcha { // number of times another process claimed a file before this one $lockouts = 0; - $baseDir = $this->getBackend()->getRootStoragePath() . '/captcha-render'; + $baseDir = $this->getBackend()->getRootStoragePath() . '/' . $this->getStorageDir(); return $this->pickImageDir( $baseDir, $wgCaptchaDirectoryLevels, $lockouts ); } @@ -417,7 +426,7 @@ class FancyCaptcha extends SimpleCaptcha { public function imagePath( $salt, $hash ) { global $wgCaptchaDirectoryLevels; - $file = $this->getBackend()->getRootStoragePath() . '/captcha-render/'; + $file = $this->getBackend()->getRootStoragePath() . '/' . $this->getStorageDir(); for ( $i = 0; $i < $wgCaptchaDirectoryLevels; $i++ ) { $file .= $hash[ $i ] . '/'; } diff --git a/includes/Store/CaptchaCacheStore.php b/includes/Store/CaptchaCacheStore.php index 7bf5229d3..c72ba921a 100644 --- a/includes/Store/CaptchaCacheStore.php +++ b/includes/Store/CaptchaCacheStore.php @@ -11,9 +11,7 @@ class CaptchaCacheStore extends CaptchaStore { public function __construct() { parent::__construct(); - - $services = MediaWikiServices::getInstance(); - $this->store = $services->getMicroStash(); + $this->store = MediaWikiServices::getInstance()->getMicroStash(); } /** @@ -22,14 +20,13 @@ class CaptchaCacheStore extends CaptchaStore { public function store( $index, $info ) { global $wgCaptchaSessionExpiration; - $store = $this->store; - $store->set( - $store->makeKey( 'captcha', $index ), + $this->store->set( + $this->store->makeKey( 'captcha', $index ), $info, $wgCaptchaSessionExpiration, // Assume the write will reach the master DC before the user sends the // HTTP POST request attempted to solve the captcha and perform an action - $store::WRITE_BACKGROUND + $this->store::WRITE_BACKGROUND ); } @@ -37,17 +34,14 @@ class CaptchaCacheStore extends CaptchaStore { * @inheritDoc */ public function retrieve( $index ) { - $store = $this->store; - - return $store->get( $store->makeKey( 'captcha', $index ) ); + return $this->store->get( $this->store->makeKey( 'captcha', $index ) ); } /** * @inheritDoc */ public function clear( $index ) { - $store = $this->store; - $store->delete( $store->makeKey( 'captcha', $index ) ); + $this->store->delete( $this->store->makeKey( 'captcha', $index ) ); } public function cookiesNeeded() { diff --git a/maintenance/CountFancyCaptchas.php b/maintenance/CountFancyCaptchas.php index 0a4924438..90a1dd1e8 100644 --- a/maintenance/CountFancyCaptchas.php +++ b/maintenance/CountFancyCaptchas.php @@ -39,7 +39,13 @@ use MediaWiki\Extension\ConfirmEdit\Hooks; class CountFancyCaptchas extends Maintenance { public function __construct() { parent::__construct(); - $this->addDescription( "Counts the number of fancy aptchas in storage" ); + $this->addDescription( "Counts the number of fancy captchas in storage" ); + $this->addOption( + 'captchastoragedir', + 'Overrides the value of $wgCaptchaStorageDirectory', + false, + true + ); $this->requireExtension( "FancyCaptcha" ); } @@ -49,8 +55,14 @@ class CountFancyCaptchas extends Maintenance { $this->fatalError( "\$wgCaptchaClass is not FancyCaptcha.\n", 1 ); } + // Overrides $wgCaptchaStorageDirectory for this script run + if ( $this->hasOption( 'captchastoragedir' ) ) { + global $wgCaptchaStorageDirectory; + $wgCaptchaStorageDirectory = $this->getOption( 'captchastoragedir' ); + } + $countAct = $instance->getCaptchaCount(); - $this->output( "Current number of captchas is $countAct.\n" ); + $this->output( "Current number of stored captchas is $countAct.\n" ); } } diff --git a/maintenance/DeleteOldFancyCaptchas.php b/maintenance/DeleteOldFancyCaptchas.php index f94e775cc..c77491d64 100644 --- a/maintenance/DeleteOldFancyCaptchas.php +++ b/maintenance/DeleteOldFancyCaptchas.php @@ -47,6 +47,12 @@ class DeleteOldFancyCaptchas extends Maintenance { true, true ); + $this->addOption( + 'captchastoragedir', + 'Overrides the value of $wgCaptchaStorageDirectory', + false, + true + ); $this->requireExtension( "FancyCaptcha" ); } @@ -56,11 +62,17 @@ class DeleteOldFancyCaptchas extends Maintenance { $this->fatalError( "\$wgCaptchaClass is not FancyCaptcha.\n", 1 ); } + // Overrides $wgCaptchaStorageDirectory for this script run + if ( $this->hasOption( 'captchastoragedir' ) ) { + global $wgCaptchaStorageDirectory; + $wgCaptchaStorageDirectory = $this->getOption( 'captchastoragedir' ); + } + $countAct = $instance->getCaptchaCount(); $this->output( "Current number of captchas is $countAct.\n" ); $backend = $instance->getBackend(); - $dir = $backend->getRootStoragePath() . '/captcha-render'; + $dir = $backend->getRootStoragePath() . '/' . $instance->getStorageDir(); $filesToDelete = []; $deleteDate = $this->getOption( 'date' ); diff --git a/maintenance/GenerateFancyCaptchas.php b/maintenance/GenerateFancyCaptchas.php index 982ba47f0..42598f04e 100644 --- a/maintenance/GenerateFancyCaptchas.php +++ b/maintenance/GenerateFancyCaptchas.php @@ -60,6 +60,12 @@ class GenerateFancyCaptchas extends Maintenance { $this->addOption( "delete", "Deletes all the old captchas" ); $this->addOption( "threads", "The number of threads to use to generate the images", false, true ); + $this->addOption( + 'captchastoragedir', + 'Overrides the value of $wgCaptchaStorageDirectory', + false, + true + ); $this->addDescription( "Generate new fancy captchas and move them into storage" ); $this->requireExtension( "FancyCaptcha" ); @@ -74,6 +80,13 @@ class GenerateFancyCaptchas extends Maintenance { if ( !( $instance instanceof FancyCaptcha ) ) { $this->fatalError( "\$wgCaptchaClass is not FancyCaptcha.\n", 1 ); } + + // Overrides $wgCaptchaStorageDirectory for this script run + if ( $this->hasOption( 'captchastoragedir' ) ) { + global $wgCaptchaStorageDirectory; + $wgCaptchaStorageDirectory = $this->getOption( 'captchastoragedir' ); + } + $backend = $instance->getBackend(); $deleteOldCaptchas = $this->getOption( 'delete' ); @@ -86,7 +99,7 @@ class GenerateFancyCaptchas extends Maintenance { } if ( $countGen <= 0 ) { - $this->output( "No need to generate anymore captchas.\n" ); + $this->output( "No need to generate any extra captchas.\n" ); return; } @@ -140,7 +153,7 @@ class GenerateFancyCaptchas extends Maintenance { $filesToDelete = []; if ( $deleteOldCaptchas ) { $this->output( "Getting a list of old captchas to delete..." ); - $path = $backend->getRootStoragePath() . '/captcha-render'; + $path = $backend->getRootStoragePath() . '/' . $instance->getStorageDir(); foreach ( $backend->getFileList( [ 'dir' => $path ] ) as $file ) { $filesToDelete[] = [ 'op' => 'delete',