From 7b96bc9010cb332723d1cbe8797af7abcdee40f5 Mon Sep 17 00:00:00 2001 From: Alexandre Emsenhuber Date: Thu, 5 Jan 2012 20:29:53 +0000 Subject: [PATCH] Per request of Aaron Schulz, follow-up r102187: added new 'TitleReadWhitelist' hook to allow extensions to bypass core (and other extensions) checks to allow an user to read the page --- docs/hooks.txt | 8 ++++++ includes/Title.php | 65 ++++++++++++++++++++++------------------------ 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/docs/hooks.txt b/docs/hooks.txt index 865ac11f31..b1a153c8a1 100644 --- a/docs/hooks.txt +++ b/docs/hooks.txt @@ -1926,6 +1926,14 @@ $user: user who did the move $pageid: database ID of the page that's been moved $redirid: database ID of the created redirect +'TitleReadWhitelist': called at the end of read permissions checks, just before + adding the default error message if nothing allows the user to read the page. + Return false will prevent core from adding its error message, but you need + to removed extensions' error messages from $errors yourself. +$title: Title object being checked against +$user: Current user object +&$errors: errors + 'UndeleteForm::showHistory': called in UndeleteForm::showHistory, after a PageArchive object has been created but before any further processing is done. &$archive: PageArchive object diff --git a/includes/Title.php b/includes/Title.php index 87f97b62a2..86aa4ee668 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -1965,6 +1965,7 @@ class Title { * @return Array list of errors */ private function checkReadPermissions( $action, $user, $errors, $doExpensiveQueries, $short ) { + global $wgWhitelistRead; static $useShortcut = null; # Initialize the $useShortcut boolean, to determine if we can skip quite a bit of code below @@ -1991,61 +1992,57 @@ class Title { } } - # Shortcut for public wikis, allows skipping quite a bit of code - if ( $useShortcut ) { - return $errors; - } + $whitelisted = false; - # If the user is allowed to read pages, he is allowed to read all pages - if ( $user->isAllowed( 'read' ) ) { - return $errors; - } - - # Always grant access to the login page. - # Even anons need to be able to log in. - if ( $this->isSpecial( 'Userlogin' ) + if ( $useShortcut ) { + # Shortcut for public wikis, allows skipping quite a bit of code + $whitelisted = true; + } elseif ( $user->isAllowed( 'read' ) ) { + # If the user is allowed to read pages, he is allowed to read all pages + $whitelisted = true; + } elseif ( $this->isSpecial( 'Userlogin' ) || $this->isSpecial( 'ChangePassword' ) || $this->isSpecial( 'PasswordReset' ) ) { - return $errors; - } - - # Time to check the whitelist - global $wgWhitelistRead; - - # Only do these checks is there's something to check against - if ( is_array( $wgWhitelistRead ) && count( $wgWhitelistRead ) ) { - # Check for explicit whitelisting + # Always grant access to the login page. + # Even anons need to be able to log in. + $whitelisted = true; + } elseif ( is_array( $wgWhitelistRead ) && count( $wgWhitelistRead ) ) { + # Time to check the whitelist + # Only do these checks is there's something to check against $name = $this->getPrefixedText(); $dbName = $this->getPrefixedDBKey(); // Check with and without underscores if ( in_array( $name, $wgWhitelistRead, true ) || in_array( $dbName, $wgWhitelistRead, true ) ) { - return $errors; - } - - # Old settings might have the title prefixed with - # a colon for main-namespace pages - if ( $this->getNamespace() == NS_MAIN ) { + # Check for explicit whitelisting + $whitelisted = true; + } elseif ( $this->getNamespace() == NS_MAIN ) { + # Old settings might have the title prefixed with + # a colon for main-namespace pages if ( in_array( ':' . $name, $wgWhitelistRead ) ) { - return $errors; + $whitelisted = true; } - } - - # If it's a special page, ditch the subpage bit and check again - if ( $this->isSpecialPage() ) { + } elseif ( $this->isSpecialPage() ) { + # If it's a special page, ditch the subpage bit and check again $name = $this->getDBkey(); list( $name, /* $subpage */ ) = SpecialPageFactory::resolveAlias( $name ); if ( $name !== false ) { $pure = SpecialPage::getTitleFor( $name )->getPrefixedText(); if ( in_array( $pure, $wgWhitelistRead, true ) ) { - return $errors; + $whitelisted = true; } } } } - $errors[] = $this->missingPermissionError( $action, $short ); + # If the user is allowed to read tge page; don't call the hook + if ( $whitelisted && !count( $errors ) ) { + return array(); + } elseif ( wfRunHooks( 'TitleReadWhitelist', array( $this, $user, &$errors ) ) && !$whitelisted ) { + $errors[] = $this->missingPermissionError( $action, $short ); + } + return $errors; } -- 2.20.1