diff options
Diffstat (limited to 'extensions/ConfirmEdit/Captcha.php')
-rw-r--r-- | extensions/ConfirmEdit/Captcha.php | 170 |
1 files changed, 35 insertions, 135 deletions
diff --git a/extensions/ConfirmEdit/Captcha.php b/extensions/ConfirmEdit/Captcha.php index 20b2dfd4..3be6d917 100644 --- a/extensions/ConfirmEdit/Captcha.php +++ b/extensions/ConfirmEdit/Captcha.php @@ -355,38 +355,26 @@ class SimpleCaptcha { */ function filterLink( $url ) { global $wgCaptchaWhitelist; - static $regexes = null; + $source = wfMessage( 'captcha-addurl-whitelist' )->inContentLanguage()->text(); - if ( $regexes === null ) { - $source = wfMessage( 'captcha-addurl-whitelist' )->inContentLanguage(); + $whitelist = wfMessage( 'captcha-addurl-whitelist', $source )->isDisabled() + ? false + : $this->buildRegexes( explode( "\n", $source ) ); - $regexes = $source->isDisabled() - ? array() - : $this->buildRegexes( explode( "\n", $source->plain() ) ); + $cwl = $wgCaptchaWhitelist !== false ? preg_match( $wgCaptchaWhitelist, $url ) : false; + $wl = $whitelist !== false ? preg_match( $whitelist, $url ) : false; - if ( $wgCaptchaWhitelist !== false ) { - array_unshift( $regexes, $wgCaptchaWhitelist ); - } - } - - foreach ( $regexes as $regex ) { - if ( preg_match( $regex, $url ) ) { - return false; - } - } - - return true; + return !( $cwl || $wl ); } /** * Build regex from whitelist * @param $lines string from [[MediaWiki:Captcha-addurl-whitelist]] - * @return array Regexes + * @return string Regex or bool false if whitelist is empty * @access private */ function buildRegexes( $lines ) { # Code duplicated from the SpamBlacklist extension (r19197) - # and later modified. # Strip comments and whitespace, then remove blanks $lines = array_filter( array_map( 'trim', preg_replace( '/#.*$/', '', $lines ) ) ); @@ -394,59 +382,34 @@ class SimpleCaptcha { # No lines, don't make a regex which will match everything if ( count( $lines ) == 0 ) { wfDebug( "No lines\n" ); - return array(); + return false; } else { # Make regex # It's faster using the S modifier even though it will usually only be run once // $regex = 'http://+[a-z0-9_\-.]*(' . implode( '|', $lines ) . ')'; // return '/' . str_replace( '/', '\/', preg_replace('|\\\*/|', '/', $regex) ) . '/Si'; - $regexes = array(); - $regexStart = array( - 'normal' => '/^https?:\/\/+[a-z0-9_\-.]*(?:', - 'noprotocol' => '/^(?:', - ); - $regexEnd = array( - 'normal' => ')/Si', - 'noprotocol' => ')/Si', - ); + $regexes = ''; + $regexStart = '/^https?:\/\/+[a-z0-9_\-.]*('; + $regexEnd = ')/Si'; $regexMax = 4096; - $build = array(); + $build = false; foreach ( $lines as $line ) { - # Extract flags from the line - $options = array(); - if ( preg_match( '/^(.*?)\s*<([^<>]*)>$/', $line, $matches ) ) { - if ( $matches[1] === '' ) { - wfDebug( "Line with empty regex\n" ); - continue; - } - $line = $matches[1]; - $opts = preg_split( '/\s*\|\s*/', trim( $matches[2] ) ); - foreach ( $opts as $opt ) { - $opt = strtolower( $opt ); - if ( $opt == 'noprotocol' ) { - $options['noprotocol'] = true; - } - } - } - - $key = isset( $options['noprotocol'] ) ? 'noprotocol' : 'normal'; - // FIXME: not very robust size check, but should work. :) - if ( !isset( $build[$key] ) ) { - $build[$key] = $line; - } elseif ( strlen( $build[$key] ) + strlen( $line ) > $regexMax ) { - $regexes[] = $regexStart[$key] . - str_replace( '/', '\/', preg_replace( '|\\\*/|', '/', $build[$key] ) ) . - $regexEnd[$key]; - $build[$key] = $line; + if ( $build === false ) { + $build = $line; + } elseif ( strlen( $build ) + strlen( $line ) > $regexMax ) { + $regexes .= $regexStart . + str_replace( '/', '\/', preg_replace( '|\\\*/|', '/', $build ) ) . + $regexEnd; + $build = $line; } else { - $build[$key] .= '|' . $line; + $build .= '|' . $line; } } - foreach ( $build as $key => $value ) { - $regexes[] = $regexStart[$key] . - str_replace( '/', '\/', preg_replace( '|\\\*/|', '/', $build[$key] ) ) . - $regexEnd[$key]; + if ( $build !== false ) { + $regexes .= $regexStart . + str_replace( '/', '\/', preg_replace( '|\\\*/|', '/', $build ) ) . + $regexEnd; } return $regexes; } @@ -537,42 +500,25 @@ class SimpleCaptcha { * Hook for user creation form submissions. * @param User $u * @param string $message - * @param Status $status * @return bool true to continue, false to abort user creation */ - function confirmUserCreate( $u, &$message, &$status = null ) { - if ( $this->needCreateAccountCaptcha() ) { - $this->trigger = "new account '" . $u->getName() . "'"; - if ( !$this->passCaptcha() ) { - // For older MediaWiki - $message = wfMessage( 'captcha-createaccount-fail' )->text(); - // For MediaWiki 1.23+ - $status = Status::newFatal( 'captcha-createaccount-fail' ); - return false; - } - } - return true; - } - - /** - * Logic to check if we need to pass a captcha for the current user - * to create a new account, or not - * - * @return bool true to show captcha, false to skip captcha - */ - function needCreateAccountCaptcha() { + function confirmUserCreate( $u, &$message ) { global $wgCaptchaTriggers, $wgUser; if ( $wgCaptchaTriggers['createaccount'] ) { if ( $wgUser->isAllowed( 'skipcaptcha' ) ) { wfDebug( "ConfirmEdit: user group allows skipping captcha on account creation\n" ); - return false; + return true; } - if ( $this->isIPWhitelisted() ) { + if ( $this->isIPWhitelisted() ) + return true; + + $this->trigger = "new account '" . $u->getName() . "'"; + if ( !$this->passCaptcha() ) { + $message = wfMessage( 'captcha-createaccount-fail' )->text(); return false; } - return true; } - return false; + return true; } /** @@ -636,7 +582,7 @@ class SimpleCaptcha { * @return bool */ protected function isAPICaptchaModule( $module ) { - return $module instanceof ApiEditPage || $module instanceof ApiCreateAccount; + return $module instanceof ApiEditPage; } /** @@ -787,50 +733,4 @@ class SimpleCaptcha { $wgOut->addWikiMsg( 'captchahelp-cookies-needed' ); } } - - /** - * Pass API captcha parameters on to the login form when using - * API account creation. - * - * @param ApiCreateAccount $apiModule - * @param LoginForm $loginForm - * @return hook return value - */ - function addNewAccountApiForm( $apiModule, $loginForm ) { - global $wgRequest; - $main = $apiModule->getMain(); - - $id = $main->getVal( 'captchaid' ); - if ( $id ) { - $wgRequest->setVal( 'wpCaptchaId', $id ); - - // Suppress "unrecognized parameter" warning: - $main->getVal( 'wpCaptchaId' ); - } - - $word = $main->getVal( 'captchaword' ); - if ( $word ) { - $wgRequest->setVal( 'wpCaptchaWord', $word ); - - // Suppress "unrecognized parameter" warning: - $main->getVal( 'wpCaptchaWord' ); - } - - return true; - } - - /** - * Pass extra data back in API results for account creation. - * - * @param ApiCreateAccount $apiModule - * @param LoginForm &loginForm - * @param array &$params - * @return hook return value - */ - function addNewAccountApiResult( $apiModule, $loginPage, &$result ) { - if ( $result['result'] !== 'Success' && $this->needCreateAccountCaptcha() ) { - $this->addCaptchaAPI( $result ); - } - return true; - } } |