From: David Barratt Date: Thu, 21 Feb 2019 17:54:35 +0000 (-0500) Subject: Block Special pages only if the user is sitewide blocked X-Git-Tag: 1.34.0-rc.0~2642^2 X-Git-Url: http://git.cyclocoop.org/data/%24oldEdit?a=commitdiff_plain;h=a574f4c065e787166613dae3c7e5849b38d614c5;p=lhc%2Fweb%2Fwiklou.git Block Special pages only if the user is sitewide blocked Update the default implementation of FormSpecialPage::checkExecutePermissions() so that a Special page is only blocked if the user has a sitewide block. This change allows the user to continue performing critical functions (like resetting their password) even if they are partially blocked. Bug: T209097 Change-Id: I5190297b7b235b6ebbdfa522323ce9bbd46b6729 --- diff --git a/includes/specialpage/FormSpecialPage.php b/includes/specialpage/FormSpecialPage.php index 81a0036e83..d1c6aea294 100644 --- a/includes/specialpage/FormSpecialPage.php +++ b/includes/specialpage/FormSpecialPage.php @@ -203,9 +203,11 @@ abstract class FormSpecialPage extends SpecialPage { protected function checkExecutePermissions( User $user ) { $this->checkPermissions(); - if ( $this->requiresUnblock() && $user->isBlocked() ) { + if ( $this->requiresUnblock() ) { $block = $user->getBlock(); - throw new UserBlockedError( $block ); + if ( $block && $block->isSitewide() ) { + throw new UserBlockedError( $block ); + } } if ( $this->requiresWrite() ) { diff --git a/tests/common/TestsAutoLoader.php b/tests/common/TestsAutoLoader.php index 024557248d..cf786fbe77 100644 --- a/tests/common/TestsAutoLoader.php +++ b/tests/common/TestsAutoLoader.php @@ -154,6 +154,7 @@ $wgAutoloadClasses += [ # tests/phpunit/includes/specialpage 'SpecialPageTestHelper' => "$testDir/phpunit/includes/specialpage/SpecialPageTestHelper.php", 'AbstractChangesListSpecialPageTestCase' => "$testDir/phpunit/includes/specialpage/AbstractChangesListSpecialPageTestCase.php", + 'FormSpecialPageTestCase' => "$testDir/phpunit/includes/specialpage/FormSpecialPageTestCase.php", # tests/phpunit/includes/specials 'SpecialPageTestBase' => "$testDir/phpunit/includes/specials/SpecialPageTestBase.php", diff --git a/tests/phpunit/includes/specialpage/FormSpecialPageTestCase.php b/tests/phpunit/includes/specialpage/FormSpecialPageTestCase.php new file mode 100644 index 0000000000..a3b5adb858 --- /dev/null +++ b/tests/phpunit/includes/specialpage/FormSpecialPageTestCase.php @@ -0,0 +1,79 @@ +newSpecialPage(); + $checkExecutePermissions = $this->getMethod( $special, 'checkExecutePermissions' ); + + $user = clone $this->getTestUser()->getUser(); + $user->mBlockedby = $user->getName(); + $user->mBlock = new Block( [ + 'address' => '127.0.8.1', + 'by' => $user->getId(), + 'reason' => 'sitewide block', + 'timestamp' => time(), + 'sitewide' => true, + 'expiry' => 10, + ] ); + + $this->expectException( UserBlockedError::class ); + $checkExecutePermissions( $user ); + } + + /** + * @covers FormSpecialPage::checkExecutePermissions + */ + public function testCheckExecutePermissionsPartialBlock() { + $special = $this->newSpecialPage(); + $checkExecutePermissions = $this->getMethod( $special, 'checkExecutePermissions' ); + + $user = clone $this->getTestUser()->getUser(); + $user->mBlockedby = $user->getName(); + $user->mBlock = new Block( [ + 'address' => '127.0.8.1', + 'by' => $user->getId(), + 'reason' => 'partial block', + 'timestamp' => time(), + 'sitewide' => false, + 'expiry' => 10, + ] ); + + $this->assertNull( $checkExecutePermissions( $user ) ); + } + + /** + * Get a protected/private method. + * + * @param object $obj + * @param string $name + * @return callable + */ + protected function getMethod( $obj, $name ) { + $method = new ReflectionMethod( $obj, $name ); + $method->setAccessible( true ); + return $method->getClosure( $obj ); + } +} diff --git a/tests/phpunit/includes/specials/SpecialPasswordResetTest.php b/tests/phpunit/includes/specials/SpecialPasswordResetTest.php new file mode 100644 index 0000000000..273b428f4a --- /dev/null +++ b/tests/phpunit/includes/specials/SpecialPasswordResetTest.php @@ -0,0 +1,10 @@ +