Core changes for GlobalBlocking and TorBlock extensions, plus some core refactoring...
authorAndrew Garrett <werdna@users.mediawiki.org>
Fri, 23 May 2008 10:34:11 +0000 (10:34 +0000)
committerAndrew Garrett <werdna@users.mediawiki.org>
Fri, 23 May 2008 10:34:11 +0000 (10:34 +0000)
* Instead of saying 'do that' in a permissions error, actually list what the action is (drawn from the right-$1 messages). This isn't perfect - it says you don't have permission to edit pages when
you can't edit a single page, but it's better than 'do that'.
* Refactor out some code from various block files into Block::formatExpiry and Block::parseExpiryInput.
* Don't display 'you cannot edit special pages' when you're trying to execute, or create an account, or something like that.
* New AbortAutoblock hook (for use in TorBlock extension), which allows extensions to cancel autoblocks.

docs/hooks.txt
includes/Block.php
includes/EditPage.php
includes/OutputPage.php
includes/SpecialBlockip.php
includes/SpecialIpblocklist.php
includes/SpecialUserlogin.php
includes/Title.php
includes/User.php
languages/messages/MessagesEn.php

index cd95394..bc12558 100644 (file)
@@ -238,6 +238,10 @@ protocol came about after MediaWiki 1.4rc1.
 This is a list of known events and parameters; please add to it if
 you're going to add events to the MediaWiki code.
 
+'AbortAutoblock': Return false to cancel an autoblock.
+$autoblockip: The IP going to be autoblocked.
+$block: The block from which the autoblock is coming.
+
 'AbortLogin': Return false to cancel account login.
 $user: the User object being authenticated against
 $password: the password being submitted, not yet checked for validity
index 1c0bfb0..3e91cf5 100644 (file)
@@ -486,6 +486,12 @@ class Block
                                wfDebug( " No match\n" );
                        }
                }
+               
+               ## Allow hooks to cancel the autoblock.
+               if (!wfRunHooks( 'AbortAutoblock', array( $autoblockip, &$this ) )) {
+                       wfDebug( "Autoblock aborted by hook." );
+                       return false;
+               }
 
                # It's okay to autoblock. Go ahead and create/insert the block.
 
@@ -704,5 +710,48 @@ class Block
                return $infinity;
                 */
        }
+       
+       /**
+        * Convert a DB-encoded expiry into a real string that humans can read.
+        */
+       static function formatExpiry( $encoded_expiry ) {
+       
+               static $msg = null;
+               
+               if( is_null( $msg ) ) {
+                       $msg = array();
+                       $keys = array( 'infiniteblock', 'expiringblock' );
+                       foreach( $keys as $key ) {
+                               $msg[$key] = wfMsgHtml( $key );
+                       }
+               }
+               
+               $expiry = Block::decodeExpiry( $encoded_expiry );
+               if ($expiry == 'infinity') {
+                       $expirystr = $msg['infiniteblock'];
+               } else {
+                       global $wgLang;
+                       $expiretimestr = $wgLang->timeanddate( wfTimestamp( TS_MW, $expiry ), true );
+                       $expirystr = wfMsgReplaceArgs( $msg['expiringblock'], array($expiretimestr) );
+               }
+
+               return $expirystr;
+       }
+       
+       /**
+        * Convert a typed-in expiry time into something we can put into the database.
+        */
+       static function parseExpiryInput( $expiry_input ) {
+               if ( $expiry_input == 'infinite' || $expiry_input == 'indefinite' ) {
+                       $expiry = 'infinity';
+               } else {
+                       $expiry = strtotime( $expiry_input );
+                       if ($expiry < 0 || $expiry === false) {
+                               return false;
+                       }
+               }
+               
+               return $expiry;
+       }
 
 }
index cb25581..a9855ad 100644 (file)
@@ -389,6 +389,7 @@ class EditPage {
                }
 
                $permErrors = $this->mTitle->getUserPermissionsErrors('edit', $wgUser);
+               
                if( !$this->mTitle->exists() ) {
                        $permErrors = array_merge( $permErrors,
                                wfArrayDiff2( $this->mTitle->getUserPermissionsErrors('create', $wgUser), $permErrors ) );
@@ -414,10 +415,10 @@ class EditPage {
                        }
                }
                $permErrors = wfArrayDiff2( $permErrors, $remove );
-
+               
                if ( $permErrors ) {
                        wfDebug( __METHOD__.": User can't edit\n" );
-                       $this->readOnlyPage( $this->getContent(), true, $permErrors );
+                       $this->readOnlyPage( $this->getContent(), true, $permErrors, 'edit' );
                        wfProfileOut( __METHOD__ );
                        return;
                } else {
@@ -489,7 +490,7 @@ class EditPage {
         * Parameters are the same as OutputPage:readOnlyPage()
         * Redirect to the article page if redlink=1
         */
-       function readOnlyPage( $source = null, $protected = false, $reasons = array() ) {
+       function readOnlyPage( $source = null, $protected = false, $reasons = array(), $action = null ) {
                global $wgRequest, $wgOut;
                if ( $wgRequest->getBool( 'redlink' ) ) {
                        // The edit page was reached via a red link.
@@ -497,7 +498,7 @@ class EditPage {
                        // they really want a permission error.
                        $wgOut->redirect( $this->mTitle->getFullUrl() );
                } else {
-                       $wgOut->readOnlyPage( $source, $protected, $reasons );
+                       $wgOut->readOnlyPage( $source, $protected, $reasons, $action );
                }
        }
 
index 0922e14..0b2b6c5 100644 (file)
@@ -960,7 +960,7 @@ class OutputPage {
         *
         * @param array $errors Error message keys
         */
-       public function showPermissionsErrorPage( $errors )
+       public function showPermissionsErrorPage( $errors, $action = null )
        {
                global $wgTitle;
 
@@ -973,7 +973,7 @@ class OutputPage {
                $this->enableClientCache( false );
                $this->mRedirect = '';
                $this->mBodytext = '';
-               $this->addWikiText( $this->formatPermissionsErrorMessage( $errors ) );
+               $this->addWikiText( $this->formatPermissionsErrorMessage( $errors, $action ) );
        }
 
        /** @deprecated */
@@ -1096,8 +1096,14 @@ class OutputPage {
         * @param array $errors An array of arrays returned by Title::getUserPermissionsErrors
         * @return string The wikitext error-messages, formatted into a list.
         */
-       public function formatPermissionsErrorMessage( $errors ) {
-               $text = wfMsgNoTrans( 'permissionserrorstext', count( $errors ) ) . "\n\n";
+       public function formatPermissionsErrorMessage( $errors, $action = null ) {
+               if ($action == null) {
+                       $text = wfMsgNoTrans( 'permissionserrorstext', count($errors)). "\n\n";
+               } else {
+                       $action_desc = wfMsg( "right-$action" );
+                       $action_desc[0] = strtolower($action_desc[0]);
+                       $text = wfMsgNoTrans( 'permissionserrorstext-withaction', count($errors), $action_desc ) . "\n\n";
+               }
 
                if (count( $errors ) > 1) {
                        $text .= '<ul class="permissions-errors">' . "\n";
@@ -1135,7 +1141,7 @@ class OutputPage {
         * @param bool   $protected Is this a permissions error?
         * @param array  $reasons   List of reasons for this error, as returned by Title::getUserPermissionsErrors().
         */
-       public function readOnlyPage( $source = null, $protected = false, $reasons = array() ) {
+       public function readOnlyPage( $source = null, $protected = false, $reasons = array(), $action = null ) {
                global $wgUser, $wgTitle;
                $skin = $wgUser->getSkin();
 
@@ -1156,7 +1162,7 @@ class OutputPage {
                        } else {
                                $this->setPageTitle( wfMsg( 'badaccess' ) );
                        }
-                       $this->addWikiText( $this->formatPermissionsErrorMessage( $reasons ) );
+                       $this->addWikiText( $this->formatPermissionsErrorMessage( $reasons, $action ) );
                } else {
                        // Wiki is read only
                        $this->setPageTitle( wfMsg( 'readonly' ) );
index 2d3c50a..d456035 100644 (file)
@@ -342,18 +342,10 @@ class IPBlockForm {
                if (strlen($expirestr) == 0) {
                        return array('ipb_expiry_invalid');
                }
-
-               if ( $expirestr == 'infinite' || $expirestr == 'indefinite' ) {
-                       $expiry = Block::infinity();
-               } else {
-                       # Convert GNU-style date, on error returns -1 for PHP <5.1 and false for PHP >=5.1
-                       $expiry = strtotime( $expirestr );
-
-                       if ( $expiry < 0 || $expiry === false ) {
-                               return array('ipb_expiry_invalid');
-                       }
-
-                       $expiry = wfTimestamp( TS_MW, $expiry );
+               
+               if ( false === ($expiry = Block::parseExpiryInput( $expirestr )) ) {
+                       // Bad expiry.
+                       return array('ipb_expiry_invalid');
                }
 
                # Create block
index 3bca200..696c7ef 100644 (file)
@@ -327,12 +327,7 @@ class IPUnblockForm {
                $formattedTime = $wgLang->timeanddate( $block->mTimestamp, true );
 
                $properties = array();
-               if ( $block->mExpiry === "" || $block->mExpiry === Block::infinity() ) {
-                       $properties[] = $msg['infiniteblock'];
-               } else {
-                       $properties[] = wfMsgReplaceArgs( $msg['expiringblock'],
-                               array( $wgLang->timeanddate( $block->mExpiry, true ) ) );
-               }
+               $properties[] = Block::formatExpiry( $block->mExpiry );
                if ( $block->mAnonOnly ) {
                        $properties[] = $msg['anononlyblock'];
                }
index b4e67db..58b1280 100644 (file)
@@ -665,14 +665,16 @@ class LoginForm {
        }
 
        /** */
-       function userNotPrivilegedMessage() {
+       function userNotPrivilegedMessage($errors) {
                global $wgOut;
 
-               $wgOut->setPageTitle( wfMsg( 'whitelistacctitle' ) );
+               $wgOut->setPageTitle( wfMsg( 'permissionserrors' ) );
                $wgOut->setRobotpolicy( 'noindex,nofollow' );
                $wgOut->setArticleRelated( false );
 
-               $wgOut->addWikiMsg( 'whitelistacctext' );
+               $wgOut->addWikitext( $wgOut->formatPermissionsErrorMessage( $errors, 'createaccount' ) );
+               // Stuff that might want to be added at the end. For example, instructions if blocked.
+               $wgOut->addWikiMsg( 'cantcreateaccount-nonblock-text' );
 
                $wgOut->returnToMain( false );
        }
@@ -711,14 +713,16 @@ class LoginForm {
                global $wgUser, $wgOut, $wgAllowRealName, $wgEnableEmail;
                global $wgCookiePrefix, $wgAuth, $wgLoginLanguageSelector;
                global $wgAuth, $wgEmailConfirmToEdit;
+               
+               $titleObj = SpecialPage::getTitleFor( 'Userlogin' );
 
                if ( $this->mType == 'signup' ) {
-                       if ( !$wgUser->isAllowed( 'createaccount' ) ) {
-                               $this->userNotPrivilegedMessage();
-                               return;
-                       } elseif ( $wgUser->isBlockedFromCreateAccount() ) {
+                       if ( $wgUser->isBlockedFromCreateAccount() ) {
                                $this->userBlockedMessage();
                                return;
+                       } elseif ( count( $permErrors = $titleObj->getUserPermissionsErrors( 'createaccount', $wgUser, true ) )>0 ) {
+                               $wgOut->showPermissionsErrorPage( $permErrors, 'createaccount' );
+                               return;
                        }
                }
 
index 0a227d5..40257a6 100644 (file)
@@ -1158,8 +1158,9 @@ class Title {
                        else if ($result === false )
                                $errors[] = array('badaccess-group0'); # a generic "We don't want them to do that"
                }
-
-               if( NS_SPECIAL == $this->mNamespace ) {
+               
+               $specialOKActions = array( 'createaccount', 'execute' );
+               if( NS_SPECIAL == $this->mNamespace && !in_array( $action, $specialOKActions) ) {
                        $errors[] = array('ns-specialprotected');
                }
 
index 3eee728..4211917 100644 (file)
@@ -1036,7 +1036,6 @@ class User {
 
                # Proxy blocking
                if ( !$this->isAllowed('proxyunbannable') && !in_array( $ip, $wgProxyWhitelist ) ) {
-
                        # Local list
                        if ( wfIsLocallyBlockedProxy( $ip ) ) {
                                $this->mBlockedby = wfMsg( 'proxyblocker' );
index 7ead0c9..62f9648 100644 (file)
@@ -1130,6 +1130,7 @@ You can go back and edit an existing page, or [[Special:Userlogin|log in or crea
 'nocreate-loggedin'         => 'You do not have permission to create new pages on {{SITENAME}}.',
 'permissionserrors'         => 'Permissions Errors',
 'permissionserrorstext'     => 'You do not have permission to do that, for the following {{PLURAL:$1|reason|reasons}}:',
+'permissionserrorstext-withaction'  => 'You do not have permission to $2, for the following {{PLURAL:$1|reason|reasons}}:',
 'recreate-deleted-warn'     => "'''Warning: You are recreating a page that was previously deleted.'''
 
 You should consider whether it is appropriate to continue editing this page.
@@ -1158,6 +1159,7 @@ These arguments have been omitted.',
 'cantcreateaccount-text' => "Account creation from this IP address ('''$1''') has been blocked by [[User:$3|$3]].
 
 The reason given by $3 is ''$2''",
+'cantcreateaccount-nonblock-text' => '', # do not translate or duplicate this message to other languages
 
 # History pages
 'viewpagelogs'          => 'View logs for this page',