diff options
Diffstat (limited to 'extensions/ConfirmEdit/includes')
-rw-r--r-- | extensions/ConfirmEdit/includes/CaptchaStore.php | 116 | ||||
-rw-r--r-- | extensions/ConfirmEdit/includes/ConfirmEditHooks.php | 149 | ||||
-rw-r--r-- | extensions/ConfirmEdit/includes/specials/SpecialCaptcha.php | 22 |
3 files changed, 287 insertions, 0 deletions
diff --git a/extensions/ConfirmEdit/includes/CaptchaStore.php b/extensions/ConfirmEdit/includes/CaptchaStore.php new file mode 100644 index 00000000..b0854df1 --- /dev/null +++ b/extensions/ConfirmEdit/includes/CaptchaStore.php @@ -0,0 +1,116 @@ +<?php + +abstract class CaptchaStore { + /** + * Store the correct answer for a given captcha + * @param $index String + * @param $info String the captcha result + */ + public abstract function store( $index, $info ); + + /** + * Retrieve the answer for a given captcha + * @param $index String + * @return String + */ + public abstract function retrieve( $index ); + + /** + * Delete a result once the captcha has been used, so it cannot be reused + * @param $index + */ + public abstract function clear( $index ); + + /** + * Whether this type of CaptchaStore needs cookies + * @return Bool + */ + public abstract function cookiesNeeded(); + + /** + * The singleton instance + * @var CaptchaStore + */ + private static $instance; + + /** + * Get somewhere to store captcha data that will persist between requests + * + * @throws Exception + * @return CaptchaStore + */ + public final static function get() { + if ( !self::$instance instanceof self ) { + global $wgCaptchaStorageClass; + if ( in_array( 'CaptchaStore', class_parents( $wgCaptchaStorageClass ) ) ) { + self::$instance = new $wgCaptchaStorageClass; + } else { + throw new Exception( "Invalid CaptchaStore class $wgCaptchaStorageClass" ); + } + } + return self::$instance; + } + + /** + * Protected constructor: no creating instances except through the factory method above + */ + protected function __construct() {} +} + +class CaptchaSessionStore extends CaptchaStore { + + protected function __construct() { + // Make sure the session is started + if ( session_id() === '' ) { + wfSetupSession(); + } + } + + function store( $index, $info ) { + $_SESSION['captcha' . $info['index']] = $info; + } + + function retrieve( $index ) { + if ( isset( $_SESSION['captcha' . $index] ) ) { + return $_SESSION['captcha' . $index]; + } else { + return false; + } + } + + function clear( $index ) { + unset( $_SESSION['captcha' . $index] ); + } + + function cookiesNeeded() { + return true; + } +} + +class CaptchaCacheStore extends CaptchaStore { + + function store( $index, $info ) { + global $wgMemc, $wgCaptchaSessionExpiration; + $wgMemc->set( wfMemcKey( 'captcha', $index ), $info, + $wgCaptchaSessionExpiration ); + } + + function retrieve( $index ) { + global $wgMemc; + $info = $wgMemc->get( wfMemcKey( 'captcha', $index ) ); + if ( $info ) { + return $info; + } else { + return false; + } + } + + function clear( $index ) { + global $wgMemc; + $wgMemc->delete( wfMemcKey( 'captcha', $index ) ); + } + + function cookiesNeeded() { + return false; + } +} diff --git a/extensions/ConfirmEdit/includes/ConfirmEditHooks.php b/extensions/ConfirmEdit/includes/ConfirmEditHooks.php new file mode 100644 index 00000000..5f9c3384 --- /dev/null +++ b/extensions/ConfirmEdit/includes/ConfirmEditHooks.php @@ -0,0 +1,149 @@ +<?php + +class ConfirmEditHooks { + /** + * Get the global Captcha instance + * + * @return SimpleCaptcha + */ + static function getInstance() { + global $wgCaptcha, $wgCaptchaClass; + + static $done = false; + + if ( !$done ) { + $done = true; + $wgCaptcha = new $wgCaptchaClass; + } + + return $wgCaptcha; + } + + static function confirmEditMerged( $context, $content, $status, $summary, $user, $minorEdit ) { + return self::getInstance()->confirmEditMerged( $context, $content, $status, $summary, + $user, $minorEdit ); + } + + static function confirmEditPage( $editpage, $buttons, $tabindex ) { + self::getInstance()->editShowCaptcha( $editpage ); + } + + static function confirmEditAPI( $editPage, $newtext, &$resultArr ) { + return self::getInstance()->confirmEditAPI( $editPage, $newtext, $resultArr ); + } + + static function showEditFormFields( &$editPage, &$out ) { + return self::getInstance()->showEditFormFields( $editPage, $out ); + } + + static function addNewAccountApiForm( $apiModule, $loginForm ) { + return self::getInstance()->addNewAccountApiForm( $apiModule, $loginForm ); + } + + static function addNewAccountApiResult( $apiModule, $loginPage, &$result ) { + return self::getInstance()->addNewAccountApiResult( $apiModule, $loginPage, $result ); + } + + static function injectUserCreate( &$template ) { + return self::getInstance()->injectUserCreate( $template ); + } + + static function confirmUserCreate( $u, &$message, &$status = null ) { + return self::getInstance()->confirmUserCreate( $u, $message, $status ); + } + + static function triggerUserLogin( $user, $password, $retval ) { + return self::getInstance()->triggerUserLogin( $user, $password, $retval ); + } + + static function injectUserLogin( &$template ) { + return self::getInstance()->injectUserLogin( $template ); + } + + static function confirmUserLogin( $u, $pass, &$retval ) { + return self::getInstance()->confirmUserLogin( $u, $pass, $retval ); + } + + static function injectEmailUser( &$form ) { + return self::getInstance()->injectEmailUser( $form ); + } + + static function confirmEmailUser( $from, $to, $subject, $text, &$error ) { + return self::getInstance()->confirmEmailUser( $from, $to, $subject, $text, $error ); + } + + // Default $flags to 1 for backwards-compatible behavior + public static function APIGetAllowedParams( &$module, &$params, $flags = 1 ) { + return self::getInstance()->APIGetAllowedParams( $module, $params, $flags ); + } + + public static function APIGetParamDescription( &$module, &$desc ) { + return self::getInstance()->APIGetParamDescription( $module, $desc ); + } + + /** + * Hook to add PHPUnit test cases. + * @see https://www.mediawiki.org/wiki/Manual:Hooks/UnitTestsList + * + * @param array &$files + * @return boolean + */ + public static function onUnitTestsList( array &$files ) { + // @codeCoverageIgnoreStart + $directoryIterator = new RecursiveDirectoryIterator( dirname( __DIR__ ) . '/tests/' ); + + /** + * @var SplFileInfo $fileInfo + */ + $ourFiles = array(); + foreach ( new RecursiveIteratorIterator( $directoryIterator ) as $fileInfo ) { + if ( substr( $fileInfo->getFilename(), -8 ) === 'Test.php' ) { + $ourFiles[] = $fileInfo->getPathname(); + } + } + + $files = array_merge( $files, $ourFiles ); + return true; + // @codeCoverageIgnoreEnd + } + + /** + * Set up $wgWhitelistRead + */ + public static function confirmEditSetup() { + global $wgGroupPermissions, $wgCaptchaTriggers, $wgWikimediaJenkinsCI; + + // There is no need to run (core) tests with enabled ConfirmEdit - bug T44145 + if ( isset( $wgWikimediaJenkinsCI ) && $wgWikimediaJenkinsCI === true ) { + $wgCaptchaTriggers = false; + } + + if ( !$wgGroupPermissions['*']['read'] && $wgCaptchaTriggers['badlogin'] ) { + // We need to ensure that the captcha interface is accessible + // so that unauthenticated users can actually get in after a + // mistaken password typing. + global $wgWhitelistRead; + $image = SpecialPage::getTitleFor( 'Captcha', 'image' ); + $help = SpecialPage::getTitleFor( 'Captcha', 'help' ); + $wgWhitelistRead[] = $image->getPrefixedText(); + $wgWhitelistRead[] = $help->getPrefixedText(); + } + } + /** + * Callback for extension.json of FancyCaptcha to set a default captcha directory, + * which depends on wgUploadDirectory + */ + public static function onFancyCaptchaSetup() { + global $wgCaptchaDirectory, $wgUploadDirectory; + if ( !$wgCaptchaDirectory ) { + $wgCaptchaDirectory = "$wgUploadDirectory/captcha"; + } + } + /** + * Callback for extension.json of ReCaptcha to require the recaptcha library php file. + * FIXME: This should be done in a better way, e.g. only load the libraray, if really needed. + */ + public static function onReCaptchaSetup() { + require_once( "ReCaptcha/recaptchalib.php" ); + } +} diff --git a/extensions/ConfirmEdit/includes/specials/SpecialCaptcha.php b/extensions/ConfirmEdit/includes/specials/SpecialCaptcha.php new file mode 100644 index 00000000..63305791 --- /dev/null +++ b/extensions/ConfirmEdit/includes/specials/SpecialCaptcha.php @@ -0,0 +1,22 @@ +<?php +class CaptchaSpecialPage extends UnlistedSpecialPage { + public function __construct() { + parent::__construct( 'Captcha' ); + } + + function execute( $par ) { + $this->setHeaders(); + + $instance = ConfirmEditHooks::getInstance(); + + switch( $par ) { + case "image": + if ( method_exists( $instance, 'showImage' ) ) { + return $instance->showImage(); + } + case "help": + default: + return $instance->showHelp(); + } + } +} |