Glaisher has uploaded a new change for review.
https://gerrit.wikimedia.org/r/275528
Change subject: Allow IP whitelist to be modified on wiki
......................................................................
Allow IP whitelist to be modified on wiki
Local administrators can now use [[MediaWiki:Captcha-ip-whitelist]]
page to exempt specific IP addresses and IP ranges from captchas.
This is useful for modifying in a short notice such as editathons and
other events like this where captchas add unnecessary complexity for
new users.
The page is disabled by default and IPs should be added separated by
newlines. If any other character is found on a line, it will be ignored
but leading and trailing whitespace characters are allowed.
Bug: T103122
Change-Id: I54866b5bfca80debcf3d3fb7963932ed03b48548
---
M SimpleCaptcha/Captcha.php
M extension.json
M i18n/en.json
M i18n/qqq.json
M includes/ConfirmEditHooks.php
5 files changed, 107 insertions(+), 10 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/ConfirmEdit
refs/changes/28/275528/1
diff --git a/SimpleCaptcha/Captcha.php b/SimpleCaptcha/Captcha.php
index dc97dcf..ea2d712 100755
--- a/SimpleCaptcha/Captcha.php
+++ b/SimpleCaptcha/Captcha.php
@@ -237,26 +237,88 @@
}
/**
- * Check if the IP is allowed to skip captchas
+ * Check if the current IP is allowed to skip captchas. This checks
+ * the whitelist from two sources.
+ * 1) From the server-side config array $wgCaptchaWhitelistIP
+ * 2) From the local [[MediaWiki:Captcha-ip-whitelist]] message
+ *
+ * @return bool true if whitelisted, false if not
*/
function isIPWhitelisted() {
- global $wgCaptchaWhitelistIP;
+ global $wgCaptchaWhitelistIP, $wgRequest;
+ $ip = $wgRequest->getIP();
if ( $wgCaptchaWhitelistIP ) {
- global $wgRequest;
-
- $ip = $wgRequest->getIP();
-
- foreach ( $wgCaptchaWhitelistIP as $range ) {
- if ( IP::isInRange( $ip, $range ) ) {
- return true;
- }
+ if ( IP::isInRanges( $ip, $wgCaptchaWhitelistIP ) ) {
+ return true;
}
}
+
+ $isMsgEnabled = !( wfMessage( 'captcha-ip-whitelist'
)->inContentLanguage()->isDisabled() );
+ if ( $isMsgEnabled ) {
+ $whitelistedIPs = $this->getWikiIPWhitelist();
+ if ( IP::isInRanges( $ip, $whitelistedIPs ) ) {
+ return true;
+ }
+ }
+
return false;
}
/**
+ * Get the on-wiki IP whitelist stored in
[[MediaWiki:Captcha-ip-whitelist]]
+ * page from cache if possible.
+ *
+ * @return array whitelisted IP addresses or IP ranges, empty array if
no whitelist
+ */
+ private function getWikiIPWhitelist() {
+ $cache = ObjectCache::getMainWANInstance();
+ $cacheKey = $cache->makeKey( 'confirmedit', 'ipwhitelist' );
+
+ $cachedWhitelist = $cache->get( $cacheKey );
+ if ( $cachedWhitelist === false ) {
+ // Could not retrieve from cache so build the whitelist
directly
+ // from the wikipage
+ $whitelist = self::buildValidIPs(
+ explode( "\n", wfMessage(
'captcha-ip-whitelist' )->inContentLanguage()->plain() )
+ );
+ // And then store it in cache for one day.
+ $cache->set( $cacheKey, $whitelist, 86400 );
+ } else {
+ // Whitelist from the cache
+ $whitelist = $cachedWhitelist;
+ }
+
+ return $whitelist;
+ }
+
+ /**
+ * From a list of unvalidated input, get all the valid
+ * IP addresses and IP ranges from it.
+ *
+ * Note that only lines with just the IP address or IP range is
considered
+ * as valid. Whitespace is allowed but if there is any other character
on
+ * the line, it's not considered as a valid entry.
+ *
+ * @param string[] $input
+ * @return string[] of valid IP addresses and IP ranges
+ */
+ private function buildValidIPs( array $input ) {
+ // Remove whitespace and blank lines first
+ $ips = array_map( 'trim', $input );
+ $ips = array_filter( $ips );
+
+ $validIPs = array();
+ foreach( $ips as $ip ) {
+ if ( IP::isIPAddress( $ip ) ) {
+ $validIPs[] = $ip;
+ }
+ }
+
+ return $validIPs;
+ }
+
+ /**
* Internal cache key for badlogin checks.
* @return string
* @access private
diff --git a/extension.json b/extension.json
index e1b8663..cb7a42d 100644
--- a/extension.json
+++ b/extension.json
@@ -79,6 +79,9 @@
"EmailUser": [
"ConfirmEditHooks::confirmEmailUser"
],
+ "PageContentSaveComplete": [
+ "ConfirmEditHooks::onPageContentSaveComplete"
+ ],
"EditPage::showEditForm:fields": [
"ConfirmEditHooks::showEditFormFields"
],
diff --git a/i18n/en.json b/i18n/en.json
index 8977ab5..84d27ab 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -6,6 +6,7 @@
"captcha-edit-fail": "Incorrect or missing CAPTCHA.",
"captcha-desc": "Provides CAPTCHA techniques to protect against spam
and password-guessing",
"captcha-label": "CAPTCHA",
+ "captcha-ip-whitelist": "-",
"captcha-addurl": "Your edit includes new external links.\nTo protect
the wiki against automated spam, we kindly ask you to solve the simple sum
below and enter the answer in the box in order to save your edit
([[Special:Captcha/help|more info]]):",
"captcha-badlogin": "To protect the wiki against automated password
cracking, we kindly ask you to solve the simple sum below and enter the answer
in the box ([[Special:Captcha/help|more info]]):",
"captcha-createaccount": "To protect the wiki against automated account
creation, we kindly ask you to solve the simple sum below and enter the answer
in the box ([[Special:Captcha/help|more info]]):",
diff --git a/i18n/qqq.json b/i18n/qqq.json
index 9890932..29b49b6 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -18,6 +18,7 @@
"captcha-edit-fail": "Used as failure message.\n\nSee also:\n*
{{msg-mw|Captcha-createaccount-fail}}\n* {{msg-mw|Captcha-sendemail-fail}}",
"captcha-desc": "{{desc|name=Confirm
Edit|url=https://www.mediawiki.org/wiki/Extension:ConfirmEdit}}",
"captcha-label": "Label field for input field shown in forms",
+ "captcha-ip-whitelist": "{{Notranslate}}",
"captcha-addurl": "The explanation of CAPTCHA shown to users trying to
add new external links.\n{{Related|ConfirmEdit-addurl}}",
"captcha-badlogin": "The explanation of CAPTCHA shown to users failed
three times to type in correct password.\n{{Related|ConfirmEdit-badlogin}}",
"captcha-createaccount": "The explanation of CAPTCHA shown to users
trying to create a new account.\n{{Related|ConfirmEdit-createaccount}}",
diff --git a/includes/ConfirmEditHooks.php b/includes/ConfirmEditHooks.php
index de5b36e..30585ca 100644
--- a/includes/ConfirmEditHooks.php
+++ b/includes/ConfirmEditHooks.php
@@ -24,6 +24,36 @@
$user, $minorEdit );
}
+ /**
+ * PageContentSaveComplete hook handler.
+ * Clear IP whitelist cache on page saves for
[[MediaWiki:captcha-ip-whitelist]].
+ *
+ * @param Page $wikiPage
+ * @param User $user
+ * @param Content $content
+ * @param string $summary
+ * @param bool $isMinor
+ * @param bool $isWatch
+ * @param string $section
+ * @param int $flags
+ * @param int $revision
+ * @param Status $status
+ * @param int $baseRevId
+ *
+ * @return bool true
+ */
+ static function onPageContentSaveComplete( Page $wikiPage, User $user,
Content $content, $summary,
+ $isMinor, $isWatch, $section, $flags, $revision, Status
$status, $baseRevId
+ ) {
+ $title = $wikiPage->getTitle();
+ if ( $title->getText() === 'Captcha-ip-whitelist' &&
$title->getNamespace() === NS_MEDIAWIKI ) {
+ $cache = ObjectCache::getMainWANInstance();
+ $cache->delete( $cache->makeKey( 'confirmedit',
'ipwhitelist' ) );
+ }
+
+ return true;
+ }
+
static function confirmEditPage( $editpage, $buttons, $tabindex ) {
self::getInstance()->editShowCaptcha( $editpage );
}
--
To view, visit https://gerrit.wikimedia.org/r/275528
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I54866b5bfca80debcf3d3fb7963932ed03b48548
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/ConfirmEdit
Gerrit-Branch: master
Gerrit-Owner: Glaisher <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits