Merge "Exclude redirects from Special:Fewestrevisions"
[lhc/web/wiklou.git] / tests / phpunit / includes / Permissions / PermissionManagerTest.php
index 3da73c1..8a98217 100644 (file)
@@ -3,7 +3,18 @@
 namespace MediaWiki\Tests\Permissions;
 
 use Action;
+use ContentHandler;
 use FauxRequest;
+use MediaWiki\Block\DatabaseBlock;
+use MediaWiki\Block\Restriction\NamespaceRestriction;
+use MediaWiki\Block\Restriction\PageRestriction;
+use MediaWiki\Block\SystemBlock;
+use MediaWiki\Linker\LinkTarget;
+use MediaWiki\MediaWikiServices;
+use MediaWiki\Permissions\PermissionManager;
+use MediaWiki\Revision\MutableRevisionRecord;
+use MediaWiki\Revision\RevisionLookup;
+use Wikimedia\ScopedCallback;
 use MediaWiki\Session\SessionId;
 use MediaWiki\Session\TestUtils;
 use MediaWikiLangTestCase;
@@ -11,12 +22,6 @@ use RequestContext;
 use stdClass;
 use Title;
 use User;
-use MediaWiki\Block\DatabaseBlock;
-use MediaWiki\Block\Restriction\NamespaceRestriction;
-use MediaWiki\Block\Restriction\PageRestriction;
-use MediaWiki\Block\SystemBlock;
-use MediaWiki\MediaWikiServices;
-use MediaWiki\Permissions\PermissionManager;
 use Wikimedia\TestingAccessWrapper;
 
 /**
@@ -41,11 +46,6 @@ class PermissionManagerTest extends MediaWikiLangTestCase {
         */
        protected $user, $anonUser, $userUser, $altUser;
 
-       /**
-        * @var PermissionManager
-        */
-       protected $permissionManager;
-
        /** Constant for self::testIsBlockedFrom */
        const USER_TALK_PAGE = '<user talk page>';
 
@@ -702,6 +702,64 @@ class PermissionManagerTest extends MediaWikiLangTestCase {
                );
        }
 
+       public function testJsConfigRedirectEditPermissions() {
+               $revision = null;
+               $user = $this->getTestUser()->getUser();
+               $otherUser = $this->getTestUser( 'sysop' )->getUser();
+               $localJsTitle = Title::newFromText( 'User:' . $user->getName() . '/foo.js' );
+               $otherLocalJsTitle = Title::newFromText( 'User:' . $user->getName() . '/foo2.js' );
+               $nonlocalJsTitle = Title::newFromText( 'User:' . $otherUser->getName() . '/foo.js' );
+
+               $services = MediaWikiServices::getInstance();
+               $revisionLookup = $this->getMockBuilder( RevisionLookup::class )
+                       ->setMethods( [ 'getRevisionByTitle' ] )
+                       ->getMockForAbstractClass();
+               $revisionLookup->method( 'getRevisionByTitle' )
+                       ->willReturnCallback( function ( LinkTarget $page ) use (
+                               $services, &$revision, $localJsTitle
+                       ) {
+                               if ( $localJsTitle->equals( Title::newFromLinkTarget( $page ) ) ) {
+                                       return $revision;
+                               } else {
+                                       return $services->getRevisionLookup()->getRevisionByTitle( $page );
+                               }
+                       } );
+               $permissionManager = new PermissionManager(
+                       $services->getSpecialPageFactory(),
+                       $revisionLookup,
+                       [],
+                       [],
+                       false,
+                       false,
+                       [],
+                       [],
+                       [],
+                       MediaWikiServices::getInstance()->getNamespaceInfo()
+               );
+               $this->setService( 'PermissionManager', $permissionManager );
+
+               $permissionManager->overrideUserRightsForTesting( $user, [ 'edit', 'editmyuserjs' ] );
+
+               $revision = $this->getJavascriptRevision( $localJsTitle, $user, '/* script */' );
+               $errors = $permissionManager->getPermissionErrors( 'edit', $user, $localJsTitle );
+               $this->assertSame( [], $errors );
+
+               $revision = $this->getJavascriptRedirectRevision( $localJsTitle, $otherLocalJsTitle, $user );
+               $errors = $permissionManager->getPermissionErrors( 'edit', $user, $localJsTitle );
+               $this->assertSame( [], $errors );
+
+               $revision = $this->getJavascriptRedirectRevision( $localJsTitle, $nonlocalJsTitle, $user );
+               $errors = $permissionManager->getPermissionErrors( 'edit', $user, $localJsTitle );
+               $this->assertSame( [ [ 'mycustomjsredirectprotected', 'edit' ] ], $errors );
+
+               $permissionManager->overrideUserRightsForTesting( $user,
+                       [ 'edit', 'editmyuserjs', 'editmyuserjsredirect' ] );
+
+               $revision = $this->getJavascriptRedirectRevision( $localJsTitle, $nonlocalJsTitle, $user );
+               $errors = $permissionManager->getPermissionErrors( 'edit', $user, $localJsTitle );
+               $this->assertSame( [], $errors );
+       }
+
        /**
         * @todo This test method should be split up into separate test methods and
         * data providers
@@ -1653,4 +1711,69 @@ class PermissionManagerTest extends MediaWikiLangTestCase {
                $this->assertFalse( $result );
        }
 
+       /**
+        * @covers \MediaWiki\Permissions\PermissionManager::addTemporaryUserRights
+        */
+       public function testAddTemporaryUserRights() {
+               $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
+               $this->overrideUserPermissions( $this->user, [ 'read', 'edit' ] );
+               // sanity checks
+               $this->assertEquals( [ 'read', 'edit' ], $permissionManager->getUserPermissions( $this->user ) );
+               $this->assertFalse( $permissionManager->userHasRight( $this->user, 'move' ) );
+
+               $scope = $permissionManager->addTemporaryUserRights( $this->user, [ 'move', 'delete' ] );
+               $this->assertEquals( [ 'read', 'edit', 'move', 'delete' ],
+                       $permissionManager->getUserPermissions( $this->user ) );
+               $this->assertTrue( $permissionManager->userHasRight( $this->user, 'move' ) );
+
+               $scope2 = $permissionManager->addTemporaryUserRights( $this->user, [ 'delete', 'upload' ] );
+               $this->assertEquals( [ 'read', 'edit', 'move', 'delete', 'upload' ],
+                       $permissionManager->getUserPermissions( $this->user ) );
+
+               ScopedCallback::consume( $scope );
+               $this->assertEquals( [ 'read', 'edit', 'delete', 'upload' ],
+                       $permissionManager->getUserPermissions( $this->user ) );
+               ScopedCallback::consume( $scope2 );
+               $this->assertEquals( [ 'read', 'edit' ],
+                       $permissionManager->getUserPermissions( $this->user ) );
+               $this->assertFalse( $permissionManager->userHasRight( $this->user, 'move' ) );
+
+               ( function () use ( $permissionManager ) {
+                       $scope = $permissionManager->addTemporaryUserRights( $this->user, 'move' );
+                       $this->assertTrue( $permissionManager->userHasRight( $this->user, 'move' ) );
+               } )();
+               $this->assertFalse( $permissionManager->userHasRight( $this->user, 'move' ) );
+       }
+
+       /**
+        * Create a RevisionRecord with a single Javascript main slot.
+        * @param Title $title
+        * @param User $user
+        * @param string $text
+        * @return MutableRevisionRecord
+        */
+       private function getJavascriptRevision( Title $title, User $user, $text ) {
+               $content = ContentHandler::makeContent( $text, $title, CONTENT_MODEL_JAVASCRIPT );
+               $revision = new MutableRevisionRecord( $title );
+               $revision->setContent( 'main', $content );
+               return $revision;
+       }
+
+       /**
+        * Create a RevisionRecord with a single Javascript redirect main slot.
+        * @param Title $title
+        * @param Title $redirectTargetTitle
+        * @param User $user
+        * @return MutableRevisionRecord
+        */
+       private function getJavascriptRedirectRevision(
+               Title $title, Title $redirectTargetTitle, User $user
+       ) {
+               $content = ContentHandler::getForModelID( CONTENT_MODEL_JAVASCRIPT )
+                       ->makeRedirectContent( $redirectTargetTitle );
+               $revision = new MutableRevisionRecord( $title );
+               $revision->setContent( 'main', $content );
+               return $revision;
+       }
+
 }