From 6b43064e5c15bcfa50355706b5176a61617c1c6d Mon Sep 17 00:00:00 2001 From: David Barratt Date: Thu, 18 Jul 2019 19:33:15 -0400 Subject: [PATCH] Allow users who are partially blocked to delete revisions. Currently, users who are partially blocked are prevented from deleting revisions. The system should check to see if the user can edit the page. Bug: T228486 Change-Id: Id08dfab9b0ebe9721d3552564ee9f9d1e1a4805a --- includes/api/ApiRevisionDelete.php | 10 +++--- includes/specialpage/SpecialPageFactory.php | 7 ++++- includes/specials/SpecialRevisionDelete.php | 25 ++++++++++----- .../includes/api/ApiRevisionDeleteTest.php | 31 +++++++++++++++++++ 4 files changed, 58 insertions(+), 15 deletions(-) diff --git a/includes/api/ApiRevisionDelete.php b/includes/api/ApiRevisionDelete.php index 1ee91c21f0..60b24f09f1 100644 --- a/includes/api/ApiRevisionDelete.php +++ b/includes/api/ApiRevisionDelete.php @@ -38,12 +38,6 @@ class ApiRevisionDelete extends ApiBase { $user = $this->getUser(); $this->checkUserRightsAny( RevisionDeleter::getRestriction( $params['type'] ) ); - // @TODO Use PermissionManager::isBlockedFrom() instead. - $block = $user->getBlock(); - if ( $block ) { - $this->dieBlocked( $block ); - } - if ( !$params['ids'] ) { $this->dieWithError( [ 'apierror-paramempty', 'ids' ], 'paramempty_ids' ); } @@ -97,6 +91,10 @@ class ApiRevisionDelete extends ApiBase { $this->dieWithError( [ 'apierror-revdel-needtarget' ], 'needtarget' ); } + if ( $this->getPermissionManager()->isBlockedFrom( $user, $targetObj ) ) { + $this->dieBlocked( $user->getBlock() ); + } + $list = RevisionDeleter::createList( $params['type'], $this->getContext(), $targetObj, $params['ids'] ); diff --git a/includes/specialpage/SpecialPageFactory.php b/includes/specialpage/SpecialPageFactory.php index 2737e356a0..38865fbf44 100644 --- a/includes/specialpage/SpecialPageFactory.php +++ b/includes/specialpage/SpecialPageFactory.php @@ -204,7 +204,12 @@ class SpecialPageFactory { 'NewSection' => \SpecialNewSection::class, 'PermanentLink' => \SpecialPermanentLink::class, 'Redirect' => \SpecialRedirect::class, - 'Revisiondelete' => \SpecialRevisionDelete::class, + 'Revisiondelete' => [ + 'class' => \SpecialRevisionDelete::class, + 'services' => [ + 'PermissionManager', + ], + ], 'RunJobs' => \SpecialRunJobs::class, 'Specialpages' => \SpecialSpecialpages::class, 'PageData' => \SpecialPageData::class, diff --git a/includes/specials/SpecialRevisionDelete.php b/includes/specials/SpecialRevisionDelete.php index 7444225360..437263f186 100644 --- a/includes/specials/SpecialRevisionDelete.php +++ b/includes/specials/SpecialRevisionDelete.php @@ -22,6 +22,7 @@ */ use MediaWiki\Storage\RevisionRecord; +use MediaWiki\Permissions\PermissionManager; /** * Special page allowing users with the appropriate permissions to view @@ -66,6 +67,9 @@ class SpecialRevisionDelete extends UnlistedSpecialPage { /** @var string */ private $otherReason; + /** @var PermissionManager */ + private $permissionManager; + /** * UI labels for each type. */ @@ -107,8 +111,15 @@ class SpecialRevisionDelete extends UnlistedSpecialPage { ], ]; - public function __construct() { + /** + * @inheritDoc + * + * @param PermissionManager $permissionManager + */ + public function __construct( PermissionManager $permissionManager ) { parent::__construct( 'Revisiondelete', 'deleterevision' ); + + $this->permissionManager = $permissionManager; } public function doesWrites() { @@ -124,13 +135,6 @@ class SpecialRevisionDelete extends UnlistedSpecialPage { $output = $this->getOutput(); $user = $this->getUser(); - // Check blocks - // @TODO Use PermissionManager::isBlockedFrom() instead. - $block = $user->getBlock(); - if ( $block ) { - throw new UserBlockedError( $block ); - } - $this->setHeaders(); $this->outputHeader(); $request = $this->getRequest(); @@ -180,6 +184,11 @@ class SpecialRevisionDelete extends UnlistedSpecialPage { return; } + // Check blocks + if ( $this->permissionManager->isBlockedFrom( $user, $this->targetObj ) ) { + throw new UserBlockedError( $user->getBlock() ); + } + $this->typeLabels = self::$UILabels[$this->typeName]; $list = $this->getList(); $list->reset(); diff --git a/tests/phpunit/includes/api/ApiRevisionDeleteTest.php b/tests/phpunit/includes/api/ApiRevisionDeleteTest.php index a4ca8a10a1..c2a9343615 100644 --- a/tests/phpunit/includes/api/ApiRevisionDeleteTest.php +++ b/tests/phpunit/includes/api/ApiRevisionDeleteTest.php @@ -1,5 +1,8 @@ assertTrue( $item['texthidden'], 'texthidden' ); $this->assertEquals( $item['id'], $revid ); } + + public function testPartiallyBlockedPage() { + $this->setExpectedApiException( 'apierror-blocked-partial' ); + + $user = static::getTestSysop()->getUser(); + + $block = new DatabaseBlock( [ + 'address' => $user, + 'by' => static::getTestSysop()->getUser()->getId(), + 'sitewide' => false, + ] ); + + $block->setRestrictions( [ + new PageRestriction( 0, Title::newFromText( self::$page )->getArticleID() ) + ] ); + $block->insert(); + + $revid = array_shift( $this->revs ); + + $this->doApiRequest( [ + 'action' => 'revisiondelete', + 'type' => 'revision', + 'target' => self::$page, + 'ids' => $revid, + 'hide' => 'content|user|comment', + 'token' => $user->getEditToken(), + ] ); + } } -- 2.20.1