diff --git a/includes/Revision/RevisionStoreFactory.php b/includes/Revision/RevisionStoreFactory.php index 0f4592fd858..7f38a5992bb 100644 --- a/includes/Revision/RevisionStoreFactory.php +++ b/includes/Revision/RevisionStoreFactory.php @@ -140,7 +140,7 @@ class RevisionStoreFactory { * * @return RevisionStore for the given wikiId with all necessary services */ - public function getRevisionStore( $dbDomain = false ) { + public function getRevisionStore( $dbDomain = false ): RevisionStore { return $this->getStore( $dbDomain, $this->actorStoreFactory->getActorStore( $dbDomain ) @@ -154,13 +154,27 @@ class RevisionStoreFactory { * * @return RevisionStore for the given wikiId with all necessary services */ - public function getRevisionStoreForImport( $dbDomain = false ) { + public function getRevisionStoreForImport( $dbDomain = false ): RevisionStore { return $this->getStore( $dbDomain, $this->actorStoreFactory->getActorStoreForImport( $dbDomain ) ); } + /** + * @since 1.43 + * + * @param false|string $dbDomain DB domain of the relevant wiki or false for the current one + * + * @return RevisionStore for the given wikiId with all necessary services + */ + public function getRevisionStoreForUndelete( $dbDomain = false ): RevisionStore { + return $this->getStore( + $dbDomain, + $this->actorStoreFactory->getActorStoreForUndelete( $dbDomain ) + ); + } + /** * @param false|string $dbDomain * @param ActorStore $actorStore diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index 07ebca1cbe1..9024c5e73d7 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -2624,7 +2624,7 @@ return [ $services->getRepoGroup(), $services->getReadOnlyMode(), $services->getContentHandlerFactory(), - $services->getRevisionStore(), + $services->getRevisionStoreFactory(), $services->getSpamChecker(), $services->getTitleFormatter(), $services->getHookContainer(), diff --git a/includes/page/PageCommandFactory.php b/includes/page/PageCommandFactory.php index 30755fc5496..71308d9d12f 100644 --- a/includes/page/PageCommandFactory.php +++ b/includes/page/PageCommandFactory.php @@ -36,7 +36,7 @@ use MediaWiki\Linker\LinkTargetLookup; use MediaWiki\Permissions\Authority; use MediaWiki\Permissions\RestrictionStore; use MediaWiki\Revision\ArchivedRevisionLookup; -use MediaWiki\Revision\RevisionStore; +use MediaWiki\Revision\RevisionStoreFactory; use MediaWiki\Storage\PageUpdaterFactory; use MediaWiki\Title\NamespaceInfo; use MediaWiki\Title\Title; @@ -90,8 +90,8 @@ class PageCommandFactory implements /** @var IContentHandlerFactory */ private $contentHandlerFactory; - /** @var RevisionStore */ - private $revisionStore; + /** @var RevisionStoreFactory */ + private $revisionStoreFactory; /** @var SpamChecker */ private $spamChecker; @@ -165,7 +165,7 @@ class PageCommandFactory implements RepoGroup $repoGroup, ReadOnlyMode $readOnlyMode, IContentHandlerFactory $contentHandlerFactory, - RevisionStore $revisionStore, + RevisionStoreFactory $revisionStoreFactory, SpamChecker $spamChecker, TitleFormatter $titleFormatter, HookContainer $hookContainer, @@ -196,7 +196,7 @@ class PageCommandFactory implements $this->repoGroup = $repoGroup; $this->readOnlyMode = $readOnlyMode; $this->contentHandlerFactory = $contentHandlerFactory; - $this->revisionStore = $revisionStore; + $this->revisionStoreFactory = $revisionStoreFactory; $this->spamChecker = $spamChecker; $this->titleFormatter = $titleFormatter; $this->hookContainer = $hookContainer; @@ -235,7 +235,7 @@ class PageCommandFactory implements return new ContentModelChange( $this->contentHandlerFactory, $this->hookContainer, - $this->revisionStore, + $this->revisionStoreFactory->getRevisionStore(), $this->userFactory, $performer, $wikipage, @@ -249,7 +249,7 @@ class PageCommandFactory implements public function newDeletePage( ProperPageIdentity $page, Authority $deleter ): DeletePage { return new DeletePage( $this->hookContainer, - $this->revisionStore, + $this->revisionStoreFactory->getRevisionStore(), $this->lbFactory, $this->jobQueueGroup, $this->commentStore, @@ -284,7 +284,7 @@ class PageCommandFactory implements $timestamp, $this->lbFactory, $this->contentHandlerFactory, - $this->revisionStore, + $this->revisionStoreFactory->getRevisionStore(), $this->watchedItemStore, $this->spamChecker, $this->hookContainer, @@ -310,7 +310,7 @@ class PageCommandFactory implements $this->watchedItemStore, $this->repoGroup, $this->contentHandlerFactory, - $this->revisionStore, + $this->revisionStoreFactory->getRevisionStore(), $this->spamChecker, $this->hookContainer, $this->wikiPageFactory, @@ -341,7 +341,7 @@ class PageCommandFactory implements $this->lbFactory, $this->userFactory, $this->readOnlyMode, - $this->revisionStore, + $this->revisionStoreFactory->getRevisionStore(), $this->titleFormatter, $this->hookContainer, $this->wikiPageFactory, @@ -364,7 +364,7 @@ class PageCommandFactory implements $this->readOnlyMode, $this->repoGroup, $this->undeletePageLogger, - $this->revisionStore, + $this->revisionStoreFactory->getRevisionStoreForUndelete(), $this->wikiPageFactory, $this->pageUpdaterFactory, $this->contentHandlerFactory, diff --git a/includes/user/ActorStoreFactory.php b/includes/user/ActorStoreFactory.php index 161e09e9006..4b17dc1e5c3 100644 --- a/includes/user/ActorStoreFactory.php +++ b/includes/user/ActorStoreFactory.php @@ -121,11 +121,20 @@ class ActorStoreFactory { } /** + * @since 1.43 * @param string|false $wikiId - * @param bool $forImport * @return ActorStore */ - private function getStore( $wikiId, $forImport ): ActorStore { + public function getActorStoreForUndelete( $wikiId = WikiAwareEntity::LOCAL ): ActorStore { + return $this->getStore( $wikiId, true ); + } + + /** + * @param string|false $wikiId + * @param bool $allowingIpActorCreation + * @return ActorStore + */ + private function getStore( $wikiId, bool $allowingIpActorCreation ): ActorStore { // During the transition from User, we still have old User objects // representing users from a different wiki, so we still have IDatabase::getDomainId // passed as $wikiId, so we need to remap it back to LOCAL. @@ -133,11 +142,11 @@ class ActorStoreFactory { $wikiId = WikiAwareEntity::LOCAL; } - $storeCacheKey = ( $forImport ? 'import' : '' ) . + $storeCacheKey = ( $allowingIpActorCreation ? 'allowing-ip-actor-creation-' : '' ) . ( $wikiId === WikiAwareEntity::LOCAL ? 'LOCAL' : $wikiId ); if ( !isset( $this->storeCache[$storeCacheKey] ) ) { - $store = $this->storeCache[$storeCacheKey] = new ActorStore( + $store = new ActorStore( $this->getLoadBalancerForTable( 'actor', $wikiId ), $this->userNameUtils, $this->tempUserConfig, @@ -145,7 +154,7 @@ class ActorStoreFactory { $this->hideUserUtils, $wikiId ); - if ( $forImport ) { + if ( $allowingIpActorCreation ) { $store->setAllowCreateIpActors( true ); } $this->storeCache[$storeCacheKey] = $store; diff --git a/tests/phpunit/includes/page/UndeletePageTest.php b/tests/phpunit/includes/page/UndeletePageTest.php index 6ea8ad87997..636db38fec5 100644 --- a/tests/phpunit/includes/page/UndeletePageTest.php +++ b/tests/phpunit/includes/page/UndeletePageTest.php @@ -3,6 +3,7 @@ use MediaWiki\CommentStore\CommentStoreComment; use MediaWiki\Page\UndeletePage; use MediaWiki\Revision\SlotRecord; +use MediaWiki\Tests\User\TempUser\TempUserTestTrait; use MediaWiki\Title\Title; use MediaWiki\User\UserIdentityValue; use Wikimedia\IPUtils; @@ -12,6 +13,9 @@ use Wikimedia\IPUtils; * @coversDefaultClass \MediaWiki\Page\UndeletePage */ class UndeletePageTest extends MediaWikiIntegrationTestCase { + + use TempUserTestTrait; + /** * @var array */ @@ -37,6 +41,7 @@ class UndeletePageTest extends MediaWikiIntegrationTestCase { * @param string $content */ private function setupPage( string $titleText, int $ns, string $content ): void { + $this->disableAutoCreateTempUser(); $title = Title::makeTitle( $ns, $titleText ); $page = $this->getServiceContainer()->getWikiPageFactory()->newFromTitle( $title ); $performer = static::getTestUser()->getUser(); @@ -56,6 +61,8 @@ class UndeletePageTest extends MediaWikiIntegrationTestCase { /** * @covers ::undeleteUnsafe * @covers ::undeleteRevisions + * @covers \MediaWiki\Revision\RevisionStoreFactory::getRevisionStoreForUndelete + * @covers \MediaWiki\User\ActorStoreFactory::getActorStoreForUndelete */ public function testUndeleteRevisions() { // TODO: MCR: Test undeletion with multiple slots. Check that slots remain untouched. @@ -88,6 +95,9 @@ class UndeletePageTest extends MediaWikiIntegrationTestCase { $this->assertFalse( $row ); } + // Enable autocreation of temporary users to test that undeletion of revisions performed by IP addresses works + // when temporary accounts are enabled. + $this->enableAutoCreateTempUser(); // Restore the page $undeletePage = $this->getServiceContainer()->getUndeletePageFactory()->newUndeletePage( $this->pages[0]['page'],