Don't consult ActionFactory for pages that can't exist
Since 65f89072e3, the Article constructor will throw if a page
can't exist, which means that the Action hierarchy cannot act on pages
that can't exist. So guard the Article construction in
PermissionManager::checkUserBlock(), by assuming that the relevant
Action has nothing to say about such pages.
Bug: T306358
Change-Id: I9fd1324f1df98e8adb9daf4d3e63eb00499bad8e
This commit is contained in:
parent
6eb9aaa43f
commit
28db3e6181
2 changed files with 38 additions and 16 deletions
|
|
@ -827,23 +827,26 @@ class PermissionManager {
|
|||
// There is no way to instantiate an action by restriction. However, this
|
||||
// will get the action where the restriction is the same. This may result
|
||||
// in actions being blocked that shouldn't be.
|
||||
// TODO: this drags a ton of dependencies in, would be good to avoid Article
|
||||
// instantiation and decouple it creating an ActionPermissionChecker interface
|
||||
// Creating an action will perform several database queries to ensure that
|
||||
// the action has not been overridden by the content type.
|
||||
// FIXME: avoid use of RequestContext since it drags in User and Title dependencies
|
||||
// probably we may use fake context object since it's unlikely that Action uses it
|
||||
// anyway. It would be nice if we could avoid instantiating the Action at all.
|
||||
$actionObj = null;
|
||||
$title = Title::newFromLinkTarget( $page, 'clone' );
|
||||
$context = RequestContext::getMain();
|
||||
$actionObj = Action::factory(
|
||||
$action,
|
||||
Article::newFromTitle( $title, $context ),
|
||||
$context
|
||||
);
|
||||
// Ensure that the retrieved action matches the restriction.
|
||||
if ( $actionObj && $actionObj->getRestriction() !== $action ) {
|
||||
$actionObj = null;
|
||||
if ( $title->canExist() ) {
|
||||
// TODO: this drags a ton of dependencies in, would be good to avoid Article
|
||||
// instantiation and decouple it creating an ActionPermissionChecker interface
|
||||
// Creating an action will perform several database queries to ensure that
|
||||
// the action has not been overridden by the content type.
|
||||
// FIXME: avoid use of RequestContext since it drags in User and Title dependencies
|
||||
// probably we may use fake context object since it's unlikely that Action uses it
|
||||
// anyway. It would be nice if we could avoid instantiating the Action at all.
|
||||
$context = RequestContext::getMain();
|
||||
$actionObj = Action::factory(
|
||||
$action,
|
||||
Article::newFromTitle( $title, $context ),
|
||||
$context
|
||||
);
|
||||
// Ensure that the retrieved action matches the restriction.
|
||||
if ( $actionObj && $actionObj->getRestriction() !== $action ) {
|
||||
$actionObj = null;
|
||||
}
|
||||
}
|
||||
|
||||
// If no action object is returned, assume that the action requires unblock
|
||||
|
|
|
|||
|
|
@ -1359,4 +1359,23 @@ class PermissionManagerTest extends MediaWikiLangTestCase {
|
|||
$this->assertFalse( $permManager->userCan( 'undelete', $admin, $userJs ) );
|
||||
$this->assertTrue( $permManager->userCan( 'undelete', $interfaceAdmin, $userJs ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Regression test for T306358 -- proper page assertion when checking
|
||||
* blocked status on a special page
|
||||
*/
|
||||
public function testBlockedFromNonProperPage() {
|
||||
$page = Title::newFromText( 'Special:Blankpage' );
|
||||
$pm = $this->getServiceContainer()->getPermissionManager();
|
||||
$user = $this->getMockBuilder( User::class )
|
||||
->onlyMethods( [ 'getBlock' ] )
|
||||
->getMock();
|
||||
$user->method( 'getBlock' )
|
||||
->willReturn( new DatabaseBlock( [
|
||||
'address' => '127.0.8.1',
|
||||
'by' => $this->user,
|
||||
] ) );
|
||||
$errors = $pm->getPermissionErrors( 'test', $user, $page );
|
||||
$this->assertNotEmpty( $errors );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue