2021-07-26 13:24:22 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace MediaWiki\Tests\Integration\Permissions;
|
|
|
|
|
|
|
|
|
|
use IDBAccessObject;
|
|
|
|
|
use MediaWiki\Cache\CacheKeyHelper;
|
2024-02-08 19:09:50 +00:00
|
|
|
use MediaWiki\Cache\LinkCache;
|
2023-12-04 11:27:42 +00:00
|
|
|
use MediaWiki\CommentStore\CommentStore;
|
2021-07-26 13:24:22 +00:00
|
|
|
use MediaWiki\Config\ServiceOptions;
|
2022-05-28 06:56:01 +00:00
|
|
|
use MediaWiki\HookContainer\HookContainer;
|
|
|
|
|
use MediaWiki\Linker\LinksMigration;
|
2024-07-09 15:36:08 +00:00
|
|
|
use MediaWiki\MainConfigNames;
|
2021-07-26 13:24:22 +00:00
|
|
|
use MediaWiki\Page\PageIdentityValue;
|
2022-05-28 06:56:01 +00:00
|
|
|
use MediaWiki\Page\PageStore;
|
2021-07-26 13:24:22 +00:00
|
|
|
use MediaWiki\Permissions\RestrictionStore;
|
2023-09-15 09:32:18 +00:00
|
|
|
use MediaWiki\SpecialPage\SpecialPage;
|
2023-03-01 20:33:26 +00:00
|
|
|
use MediaWiki\Title\Title;
|
2021-07-26 13:24:22 +00:00
|
|
|
use MediaWikiIntegrationTestCase;
|
2022-05-28 06:56:01 +00:00
|
|
|
use WANObjectCache;
|
|
|
|
|
use Wikimedia\Rdbms\ILoadBalancer;
|
2021-07-26 13:24:22 +00:00
|
|
|
use Wikimedia\TestingAccessWrapper;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @group Database
|
|
|
|
|
*
|
2024-04-11 21:11:56 +00:00
|
|
|
* See \MediaWiki\Tests\Unit\Permissions\RestrictionStoreTest for unit tests
|
2021-07-26 13:24:22 +00:00
|
|
|
*
|
2024-04-11 21:11:56 +00:00
|
|
|
* @covers \MediaWiki\Permissions\RestrictionStore
|
2021-07-26 13:24:22 +00:00
|
|
|
*/
|
|
|
|
|
class RestrictionStoreTest extends MediaWikiIntegrationTestCase {
|
|
|
|
|
private const DEFAULT_RESTRICTION_TYPES = [ 'create', 'edit', 'move', 'upload' ];
|
|
|
|
|
|
2024-07-30 22:04:51 +00:00
|
|
|
private WANObjectCache $wanCache;
|
|
|
|
|
private ILoadBalancer $loadBalancer;
|
|
|
|
|
private LinkCache $linkCache;
|
|
|
|
|
private LinksMigration $linksMigration;
|
|
|
|
|
private HookContainer $hookContainer;
|
|
|
|
|
private CommentStore $commentStore;
|
|
|
|
|
private PageStore $pageStore;
|
2021-07-26 13:24:22 +00:00
|
|
|
|
|
|
|
|
private static $testPageRestrictionSource;
|
|
|
|
|
private static $testPageRestrictionCascade;
|
|
|
|
|
|
|
|
|
|
protected function setUp(): void {
|
|
|
|
|
parent::setUp();
|
|
|
|
|
|
|
|
|
|
$services = $this->getServiceContainer();
|
|
|
|
|
$this->wanCache = $services->getMainWANObjectCache();
|
|
|
|
|
$this->loadBalancer = $services->getDBLoadBalancer();
|
|
|
|
|
$this->linkCache = $services->getLinkCache();
|
2022-05-12 09:12:38 +00:00
|
|
|
$this->linksMigration = $services->getLinksMigration();
|
2021-07-26 13:24:22 +00:00
|
|
|
$this->hookContainer = $services->getHookContainer();
|
2024-07-30 22:04:51 +00:00
|
|
|
$this->commentStore = $services->getCommentStore();
|
2021-07-26 13:24:22 +00:00
|
|
|
$this->pageStore = $services->getPageStore();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function addDBDataOnce() {
|
|
|
|
|
self::$testPageRestrictionCascade =
|
|
|
|
|
$this->insertPage( 'Template:RestrictionStoreTestA', 'wooooooo' );
|
|
|
|
|
$this->insertPage( 'Template:RestrictionStoreTestB', '{{RestrictionStoreTestA}}' );
|
|
|
|
|
|
|
|
|
|
self::$testPageRestrictionSource =
|
|
|
|
|
$this->insertPage( 'RestrictionStoreTest_1', '{{RestrictionStoreTestB}}' );
|
|
|
|
|
|
|
|
|
|
$this->updateRestrictions( self::$testPageRestrictionSource['title'], [ 'edit' => 'sysop' ] );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function newRestrictionStore( array $options = [] ) {
|
|
|
|
|
return new RestrictionStore(
|
|
|
|
|
new ServiceOptions( RestrictionStore::CONSTRUCTOR_OPTIONS, $options + [
|
2024-07-09 15:36:08 +00:00
|
|
|
MainConfigNames::NamespaceProtection => [],
|
|
|
|
|
MainConfigNames::RestrictionLevels => [ '', 'autoconfirmed', 'sysop' ],
|
|
|
|
|
MainConfigNames::RestrictionTypes => self::DEFAULT_RESTRICTION_TYPES,
|
|
|
|
|
MainConfigNames::SemiprotectedRestrictionLevels => [ 'autoconfirmed' ],
|
|
|
|
|
] ),
|
2021-07-26 13:24:22 +00:00
|
|
|
$this->wanCache,
|
|
|
|
|
$this->loadBalancer,
|
|
|
|
|
$this->linkCache,
|
2022-05-12 09:12:38 +00:00
|
|
|
$this->linksMigration,
|
2021-07-26 13:24:22 +00:00
|
|
|
$this->commentStore,
|
|
|
|
|
$this->hookContainer,
|
|
|
|
|
$this->pageStore
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function updateRestrictions( $page, array $limit, int $cascade = 1 ) {
|
|
|
|
|
$this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $page )
|
|
|
|
|
->doUpdateRestrictions(
|
|
|
|
|
$limit,
|
|
|
|
|
[],
|
|
|
|
|
$cascade,
|
|
|
|
|
'test',
|
|
|
|
|
$this->getTestSysop()->getUser()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testGetCascadeProtectionSources() {
|
|
|
|
|
$page = self::$testPageRestrictionCascade['title'];
|
|
|
|
|
$pageSource = self::$testPageRestrictionSource['title'];
|
|
|
|
|
|
|
|
|
|
[ $sources, $restrictions ] = $this->newRestrictionStore()
|
|
|
|
|
->getCascadeProtectionSources( $page );
|
|
|
|
|
$this->assertCount( 1, $sources );
|
|
|
|
|
$this->assertTrue( $pageSource->isSamePageAs( $sources[$pageSource->getId()] ) );
|
|
|
|
|
$this->assertArrayEquals( [ 'edit' => [ 'sysop' ] ], $restrictions );
|
|
|
|
|
|
|
|
|
|
[ $sources, $restrictions ] = $this->newRestrictionStore()
|
|
|
|
|
->getCascadeProtectionSources( $pageSource );
|
|
|
|
|
$this->assertCount( 0, $sources );
|
|
|
|
|
$this->assertCount( 0, $restrictions );
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-23 20:57:58 +00:00
|
|
|
public function testGetCascadeProtectionSourcesSpecialPage() {
|
|
|
|
|
[ $sources, $restrictions ] = $this->newRestrictionStore()
|
|
|
|
|
->getCascadeProtectionSources( SpecialPage::getTitleFor( 'Whatlinkshere' ) );
|
|
|
|
|
$this->assertCount( 0, $sources );
|
|
|
|
|
$this->assertCount( 0, $restrictions );
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-26 13:24:22 +00:00
|
|
|
/**
|
|
|
|
|
* @dataProvider provideLoadRestrictions
|
|
|
|
|
*/
|
|
|
|
|
public function testLoadRestrictions( $page, $expectedCacheSubmap, ?array $restrictions = null ) {
|
|
|
|
|
$cacheKey = CacheKeyHelper::getKeyForPage( $page );
|
|
|
|
|
|
|
|
|
|
if ( $restrictions ) {
|
|
|
|
|
$this->updateRestrictions( $page, $restrictions );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$restrictionStore = $this->newRestrictionStore();
|
|
|
|
|
$restrictionStore->loadRestrictions( $page );
|
|
|
|
|
$wrapper = TestingAccessWrapper::newFromObject( $restrictionStore );
|
|
|
|
|
$this->assertArraySubmapSame(
|
|
|
|
|
$expectedCacheSubmap,
|
|
|
|
|
$wrapper->cache[$cacheKey]
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-23 11:36:19 +00:00
|
|
|
public static function provideLoadRestrictions(): array {
|
2021-07-26 13:24:22 +00:00
|
|
|
return [
|
|
|
|
|
'Regular page with restrictions' => [
|
2021-12-08 14:16:05 +00:00
|
|
|
Title::makeTitle( NS_MAIN, 'RestrictionStoreTest_1' ),
|
2021-07-26 13:24:22 +00:00
|
|
|
[ 'restrictions' => [ 'edit' => [ 'sysop' ] ] ]
|
|
|
|
|
],
|
|
|
|
|
'Nonexistent page' => [
|
|
|
|
|
PageIdentityValue::localIdentity( 0, NS_MAIN, 'X' ),
|
|
|
|
|
[ 'create_protection' => null ]
|
|
|
|
|
],
|
|
|
|
|
'Nonexistent page with restrictions' => [
|
|
|
|
|
PageIdentityValue::localIdentity( 0, NS_MAIN, 'X' ),
|
|
|
|
|
[ 'create_protection' => [ 'expiry' => 'infinity' ] ],
|
|
|
|
|
[ 'create' => 'sysop' ]
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function testLoadRestrictions_latest() {
|
|
|
|
|
$pageSource = self::$testPageRestrictionSource['title'];
|
|
|
|
|
$cacheKey = CacheKeyHelper::getKeyForPage( $pageSource );
|
|
|
|
|
|
|
|
|
|
$restrictionStore = $this->newRestrictionStore();
|
|
|
|
|
$restrictionStore->loadRestrictions( $pageSource );
|
|
|
|
|
$wrapper = TestingAccessWrapper::newFromObject( $restrictionStore );
|
|
|
|
|
$this->assertArraySubmapSame(
|
|
|
|
|
[ 'restrictions' => [ 'edit' => [ 'sysop' ] ] ],
|
|
|
|
|
$wrapper->cache[$cacheKey]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$this->updateRestrictions( $pageSource, [ 'move' => 'sysop' ] );
|
|
|
|
|
$restrictionStore->loadRestrictions( $pageSource, IDBAccessObject::READ_LATEST );
|
|
|
|
|
$this->assertArraySubmapSame(
|
|
|
|
|
[ 'restrictions' => [ 'move' => [ 'sysop' ] ] ],
|
|
|
|
|
$wrapper->cache[$cacheKey]
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|