jenkins-bot has submitted this change and it was merged.

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, 110 insertions(+), 10 deletions(-)

Approvals:
  Florianschmidtwelzow: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/SimpleCaptcha/Captcha.php b/SimpleCaptcha/Captcha.php
index cd61d02..7697ab7 100755
--- a/SimpleCaptcha/Captcha.php
+++ b/SimpleCaptcha/Captcha.php
@@ -281,26 +281,91 @@
        }
 
        /**
-        * 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;
                        }
                }
+
+               $whitelistMsg = wfMessage( 'captcha-ip-whitelist' 
)->inContentLanguage();
+               if ( !$whitelistMsg->isDisabled() ) {
+                       $whitelistedIPs = $this->getWikiIPWhitelist( 
$whitelistMsg );
+                       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.
+        *
+        * @param Message $msg whitelist Message on wiki
+        * @return array whitelisted IP addresses or IP ranges, empty array if 
no whitelist
+        */
+       private function getWikiIPWhitelist( Message $msg ) {
+               $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 = $this->buildValidIPs(
+                               explode( "\n", $msg->plain() )
+                       );
+                       // And then store it in cache for one day. This cache 
is cleared on
+                       // modifications to the whitelist page.
+                       // @see ConfirmEditHooks::onPageContentSaveComplete()
+                       $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 4eb01ef..89db1b0 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..1b6c757 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}} This message is used for 
storing a list of IP addresses and IP ranges whitelisted from CAPTCHA on the 
wiki. New entries should be separated by newlines and the line should contain 
only a valid IP address or IP range. Leading and trailing whitespace is allowed 
but if there is any other character, that line will be ignored.",
        "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: merged
Gerrit-Change-Id: I54866b5bfca80debcf3d3fb7963932ed03b48548
Gerrit-PatchSet: 4
Gerrit-Project: mediawiki/extensions/ConfirmEdit
Gerrit-Branch: master
Gerrit-Owner: Glaisher <[email protected]>
Gerrit-Reviewer: Florianschmidtwelzow <[email protected]>
Gerrit-Reviewer: Glaisher <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to