From dd6b94024c53516506f74ac14d954cddabfe17ac Mon Sep 17 00:00:00 2001 From: Vedmaka Date: Tue, 9 Apr 2019 09:58:04 +0300 Subject: [PATCH] Re-apply: Factors out permissions check from User into PermissionManager service Was reverted by I549810a4cd2e424cc4a438887d2f24614a24cc00 due to T224607. Original change by Vedmaka Wakalaka was Ia0d840b772ea5f20c9594ce151cc57adc270e48b. Original commit message: The following methods should are factored out of the User class into PermissionManager, leaving only deprecated stubs: - User::isAllowed -> PermissionManager::userHasRight - User::getRights -> PermissionManager::getUserPermissions - User::groupHasPermission -> PermissionManager::groupHasPermission - User::getGroupPermissions -> PermissionManager::getGroupPermissions -User::getGroupsWithPermission -> PermissionManager::getGroupsWithPermission - User::groupHasPermission -> PermissionManager::groupHasPermission - User::isEveryoneAllowed -> PermissionManager::isEveryoneAllowed - User::getAllRights -> PermissionManager::getAllPermissions Depends-On: I7909e9bd6bbfbd708c0a00b861a9b22a38c6665d Bug: T218558 Bug: T223294 Change-Id: I8899240378f636ea70f447616710516c0a3c5c31 --- includes/Permissions/PermissionManager.php | 384 ++++++++- includes/Revision/RevisionRecord.php | 11 +- includes/ServiceWiring.php | 3 + includes/user/User.php | 283 ++----- .../phpunit/MediaWikiIntegrationTestCase.php | 15 + .../Permissions/PermissionManagerTest.php | 739 ++++++++++++------ .../Revision/RevisionRendererTest.php | 27 +- tests/phpunit/includes/RevisionDbTestBase.php | 6 +- .../includes/TemplateCategoriesTest.php | 2 +- .../phpunit/includes/TitlePermissionTest.php | 182 +++-- tests/phpunit/includes/TitleTest.php | 2 +- tests/phpunit/includes/actions/ActionTest.php | 6 +- tests/phpunit/includes/api/ApiBlockTest.php | 5 + tests/phpunit/includes/api/ApiDeleteTest.php | 1 + .../phpunit/includes/api/ApiEditPageTest.php | 12 + tests/phpunit/includes/api/ApiMainTest.php | 4 +- tests/phpunit/includes/api/ApiMoveTest.php | 2 +- tests/phpunit/includes/api/ApiParseTest.php | 2 +- .../phpunit/includes/api/ApiStashEditTest.php | 2 + .../includes/api/ApiUserrightsTest.php | 5 + .../phpunit/includes/auth/AuthManagerTest.php | 7 +- .../includes/page/ArticleTablesTest.php | 3 +- .../includes/page/WikiPageDbTestBase.php | 1 + .../includes/user/UserGroupMembershipTest.php | 2 + tests/phpunit/includes/user/UserTest.php | 14 +- 25 files changed, 1113 insertions(+), 607 deletions(-) diff --git a/includes/Permissions/PermissionManager.php b/includes/Permissions/PermissionManager.php index 202014f072..defcb656de 100644 --- a/includes/Permissions/PermissionManager.php +++ b/includes/Permissions/PermissionManager.php @@ -21,12 +21,12 @@ namespace MediaWiki\Permissions; use Action; use Exception; -use FatalError; use Hooks; use MediaWiki\Linker\LinkTarget; +use MediaWiki\Session\SessionManager; use MediaWiki\Special\SpecialPageFactory; +use MediaWiki\User\UserIdentity; use MessageSpecifier; -use MWException; use NamespaceInfo; use RequestContext; use SpecialPage; @@ -69,12 +69,121 @@ class PermissionManager { /** @var NamespaceInfo */ private $nsInfo; + /** @var string[][] Access rights for groups and users in these groups */ + private $groupPermissions; + + /** @var string[][] Permission keys revoked from users in each group */ + private $revokePermissions; + + /** @var string[] A list of available rights, in addition to the ones defined by the core */ + private $availableRights; + + /** @var string[] Cached results of getAllRights() */ + private $allRights = false; + + /** @var string[][] Cached user rights */ + private $usersRights = null; + + /** @var string[] Cached rights for isEveryoneAllowed */ + private $cachedRights = []; + + /** + * Array of Strings Core rights. + * Each of these should have a corresponding message of the form + * "right-$right". + * @showinitializer + */ + private $coreRights = [ + 'apihighlimits', + 'applychangetags', + 'autoconfirmed', + 'autocreateaccount', + 'autopatrol', + 'bigdelete', + 'block', + 'blockemail', + 'bot', + 'browsearchive', + 'changetags', + 'createaccount', + 'createpage', + 'createtalk', + 'delete', + 'deletechangetags', + 'deletedhistory', + 'deletedtext', + 'deletelogentry', + 'deleterevision', + 'edit', + 'editcontentmodel', + 'editinterface', + 'editprotected', + 'editmyoptions', + 'editmyprivateinfo', + 'editmyusercss', + 'editmyuserjson', + 'editmyuserjs', + 'editmywatchlist', + 'editsemiprotected', + 'editsitecss', + 'editsitejson', + 'editsitejs', + 'editusercss', + 'edituserjson', + 'edituserjs', + 'hideuser', + 'import', + 'importupload', + 'ipblock-exempt', + 'managechangetags', + 'markbotedits', + 'mergehistory', + 'minoredit', + 'move', + 'movefile', + 'move-categorypages', + 'move-rootuserpages', + 'move-subpages', + 'nominornewtalk', + 'noratelimit', + 'override-export-depth', + 'pagelang', + 'patrol', + 'patrolmarks', + 'protect', + 'purge', + 'read', + 'reupload', + 'reupload-own', + 'reupload-shared', + 'rollback', + 'sendemail', + 'siteadmin', + 'suppressionlog', + 'suppressredirect', + 'suppressrevision', + 'unblockself', + 'undelete', + 'unwatchedpages', + 'upload', + 'upload_by_url', + 'userrights', + 'userrights-interwiki', + 'viewmyprivateinfo', + 'viewmywatchlist', + 'viewsuppressed', + 'writeapi', + ]; + /** * @param SpecialPageFactory $specialPageFactory * @param string[] $whitelistRead * @param string[] $whitelistReadRegexp * @param bool $emailConfirmToEdit * @param bool $blockDisablesLogin + * @param string[][] $groupPermissions + * @param string[][] $revokePermissions + * @param string[] $availableRights * @param NamespaceInfo $nsInfo */ public function __construct( @@ -83,6 +192,9 @@ class PermissionManager { $whitelistReadRegexp, $emailConfirmToEdit, $blockDisablesLogin, + $groupPermissions, + $revokePermissions, + $availableRights, NamespaceInfo $nsInfo ) { $this->specialPageFactory = $specialPageFactory; @@ -90,6 +202,9 @@ class PermissionManager { $this->whitelistReadRegexp = $whitelistReadRegexp; $this->emailConfirmToEdit = $emailConfirmToEdit; $this->blockDisablesLogin = $blockDisablesLogin; + $this->groupPermissions = $groupPermissions; + $this->revokePermissions = $revokePermissions; + $this->availableRights = $availableRights; $this->nsInfo = $nsInfo; } @@ -111,7 +226,6 @@ class PermissionManager { * - RIGOR_SECURE : does cheap and expensive checks, using the master as needed * * @return bool - * @throws Exception */ public function userCan( $action, User $user, LinkTarget $page, $rigor = self::RIGOR_SECURE ) { return !count( $this->getPermissionErrorsInternal( $action, $user, $page, $rigor, true ) ); @@ -133,7 +247,6 @@ class PermissionManager { * whose corresponding errors may be ignored. * * @return array Array of arrays of the arguments to wfMessage to explain permissions problems. - * @throws Exception */ public function getPermissionErrors( $action, @@ -167,8 +280,6 @@ class PermissionManager { * @param bool $fromReplica Whether to check the replica DB instead of the master * * @return bool - * @throws FatalError - * @throws MWException */ public function isBlockedFrom( User $user, LinkTarget $page, $fromReplica = false ) { $blocked = $user->isHidden(); @@ -286,8 +397,6 @@ class PermissionManager { * @param LinkTarget $page * * @return array List of errors - * @throws FatalError - * @throws MWException */ private function checkPermissionHooks( $action, @@ -363,8 +472,6 @@ class PermissionManager { * @param LinkTarget $page * * @return array List of errors - * @throws FatalError - * @throws MWException */ private function checkReadPermissions( $action, @@ -497,7 +604,6 @@ class PermissionManager { * @param LinkTarget $page * * @return array List of errors - * @throws MWException */ private function checkUserBlock( $action, @@ -583,8 +689,6 @@ class PermissionManager { * @param LinkTarget $page * * @return array List of errors - * @throws FatalError - * @throws MWException */ private function checkQuickPermissions( $action, @@ -762,6 +866,7 @@ class PermissionManager { } if ( $right != '' && !$user->isAllowedAll( 'protect', $right ) ) { $wikiPages = ''; + /** @var Title $wikiPage */ foreach ( $cascadingSources as $wikiPage ) { $wikiPages .= '* [[:' . $wikiPage->getPrefixedText() . "]]\n"; } @@ -789,7 +894,6 @@ class PermissionManager { * @param LinkTarget $page * * @return array List of errors - * @throws Exception */ private function checkActionPermissions( $action, @@ -1052,4 +1156,256 @@ class PermissionManager { return $errors; } + /** + * Testing a permission + * + * @since 1.34 + * + * @param UserIdentity $user + * @param string $action + * + * @return bool + */ + public function userHasRight( UserIdentity $user, $action = '' ) { + if ( $action === '' ) { + return true; // In the spirit of DWIM + } + // Use strict parameter to avoid matching numeric 0 accidentally inserted + // by misconfiguration: 0 == 'foo' + return in_array( $action, $this->getUserPermissions( $user ), true ); + } + + /** + * Get the permissions this user has. + * + * @since 1.34 + * + * @param UserIdentity $user + * + * @return string[] permission names + */ + public function getUserPermissions( UserIdentity $user ) { + $user = User::newFromIdentity( $user ); + if ( !isset( $this->usersRights[ $user->getId() ] ) ) { + $this->usersRights[ $user->getId() ] = $this->getGroupPermissions( + $user->getEffectiveGroups() + ); + Hooks::run( 'UserGetRights', [ $user, &$this->usersRights[ $user->getId() ] ] ); + + // Deny any rights denied by the user's session, unless this + // endpoint has no sessions. + if ( !defined( 'MW_NO_SESSION' ) ) { + // FIXME: $user->getRequest().. need to be replaced with something else + $allowedRights = $user->getRequest()->getSession()->getAllowedUserRights(); + if ( $allowedRights !== null ) { + $this->usersRights[ $user->getId() ] = array_intersect( + $this->usersRights[ $user->getId() ], + $allowedRights + ); + } + } + + Hooks::run( 'UserGetRightsRemove', [ $user, &$this->usersRights[ $user->getId() ] ] ); + // Force reindexation of rights when a hook has unset one of them + $this->usersRights[ $user->getId() ] = array_values( + array_unique( $this->usersRights[ $user->getId() ] ) + ); + + if ( + $user->isLoggedIn() && + $this->blockDisablesLogin && + $user->getBlock() + ) { + $anon = new User; + $this->usersRights[ $user->getId() ] = array_intersect( + $this->usersRights[ $user->getId() ], + $this->getUserPermissions( $anon ) + ); + } + } + return $this->usersRights[ $user->getId() ]; + } + + /** + * Clears users permissions cache, if specific user is provided it tries to clear + * permissions cache only for provided user. + * + * @since 1.34 + * + * @param User|null $user + */ + public function invalidateUsersRightsCache( $user = null ) { + if ( $user !== null ) { + if ( isset( $this->usersRights[ $user->getId() ] ) ) { + unset( $this->usersRights[$user->getId()] ); + } + } else { + $this->usersRights = null; + } + } + + /** + * Check, if the given group has the given permission + * + * If you're wanting to check whether all users have a permission, use + * PermissionManager::isEveryoneAllowed() instead. That properly checks if it's revoked + * from anyone. + * + * @since 1.34 + * + * @param string $group Group to check + * @param string $role Role to check + * + * @return bool + */ + public function groupHasPermission( $group, $role ) { + return isset( $this->groupPermissions[$group][$role] ) && + $this->groupPermissions[$group][$role] && + !( isset( $this->revokePermissions[$group][$role] ) && + $this->revokePermissions[$group][$role] ); + } + + /** + * Get the permissions associated with a given list of groups + * + * @since 1.34 + * + * @param array $groups Array of Strings List of internal group names + * @return array Array of Strings List of permission key names for given groups combined + */ + public function getGroupPermissions( $groups ) { + $rights = []; + // grant every granted permission first + foreach ( $groups as $group ) { + if ( isset( $this->groupPermissions[$group] ) ) { + $rights = array_merge( $rights, + // array_filter removes empty items + array_keys( array_filter( $this->groupPermissions[$group] ) ) ); + } + } + // now revoke the revoked permissions + foreach ( $groups as $group ) { + if ( isset( $this->revokePermissions[$group] ) ) { + $rights = array_diff( $rights, + array_keys( array_filter( $this->revokePermissions[$group] ) ) ); + } + } + return array_unique( $rights ); + } + + /** + * Get all the groups who have a given permission + * + * @since 1.34 + * + * @param string $role Role to check + * @return array Array of Strings List of internal group names with the given permission + */ + public function getGroupsWithPermission( $role ) { + $allowedGroups = []; + foreach ( array_keys( $this->groupPermissions ) as $group ) { + if ( $this->groupHasPermission( $group, $role ) ) { + $allowedGroups[] = $group; + } + } + return $allowedGroups; + } + + /** + * Check if all users may be assumed to have the given permission + * + * We generally assume so if the right is granted to '*' and isn't revoked + * on any group. It doesn't attempt to take grants or other extension + * limitations on rights into account in the general case, though, as that + * would require it to always return false and defeat the purpose. + * Specifically, session-based rights restrictions (such as OAuth or bot + * passwords) are applied based on the current session. + * + * @param string $right Right to check + * + * @return bool + * @since 1.34 + */ + public function isEveryoneAllowed( $right ) { + // Use the cached results, except in unit tests which rely on + // being able change the permission mid-request + if ( isset( $this->cachedRights[$right] ) ) { + return $this->cachedRights[$right]; + } + + if ( !isset( $this->groupPermissions['*'][$right] ) + || !$this->groupPermissions['*'][$right] ) { + $this->cachedRights[$right] = false; + return false; + } + + // If it's revoked anywhere, then everyone doesn't have it + foreach ( $this->revokePermissions as $rights ) { + if ( isset( $rights[$right] ) && $rights[$right] ) { + $this->cachedRights[$right] = false; + return false; + } + } + + // Remove any rights that aren't allowed to the global-session user, + // unless there are no sessions for this endpoint. + if ( !defined( 'MW_NO_SESSION' ) ) { + + // XXX: think what could be done with the below + $allowedRights = SessionManager::getGlobalSession()->getAllowedUserRights(); + if ( $allowedRights !== null && !in_array( $right, $allowedRights, true ) ) { + $this->cachedRights[$right] = false; + return false; + } + } + + // Allow extensions to say false + if ( !Hooks::run( 'UserIsEveryoneAllowed', [ $right ] ) ) { + $this->cachedRights[$right] = false; + return false; + } + + $this->cachedRights[$right] = true; + return true; + } + + /** + * Get a list of all available permissions. + * + * @since 1.34 + * + * @return string[] Array of permission names + */ + public function getAllPermissions() { + if ( $this->allRights === false ) { + if ( count( $this->availableRights ) ) { + $this->allRights = array_unique( array_merge( + $this->coreRights, + $this->availableRights + ) ); + } else { + $this->allRights = $this->coreRights; + } + Hooks::run( 'UserGetAllRights', [ &$this->allRights ] ); + } + return $this->allRights; + } + + /** + * Overrides user permissions cache + * + * @since 1.34 + * + * @param User $user + * @param string[]|string $rights + * + * @throws Exception + */ + public function overrideUserRightsForTesting( $user, $rights = [] ) { + if ( !defined( 'MW_PHPUNIT_TEST' ) ) { + throw new Exception( __METHOD__ . ' can not be called outside of tests' ); + } + $this->usersRights[ $user->getId() ] = is_array( $rights ) ? $rights : [ $rights ]; + } + } diff --git a/includes/Revision/RevisionRecord.php b/includes/Revision/RevisionRecord.php index 70a891cfed..7bd127e710 100644 --- a/includes/Revision/RevisionRecord.php +++ b/includes/Revision/RevisionRecord.php @@ -515,10 +515,19 @@ abstract class RevisionRecord { } else { $permissions = [ 'deletedhistory' ]; } + + // XXX: How can we avoid global scope here? + // Perhaps the audience check should be done in a callback. + $permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); $permissionlist = implode( ', ', $permissions ); if ( $title === null ) { wfDebug( "Checking for $permissionlist due to $field match on $bitfield\n" ); - return $user->isAllowedAny( ...$permissions ); + foreach ( $permissions as $perm ) { + if ( $permissionManager->userHasRight( $user, $perm ) ) { + return true; + } + } + return false; } else { $text = $title->getPrefixedText(); wfDebug( "Checking for $permissionlist on $text due to $field match on $bitfield\n" ); diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index e371b5a5c8..041bb518c4 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -464,6 +464,9 @@ return [ $config->get( 'WhitelistReadRegexp' ), $config->get( 'EmailConfirmToEdit' ), $config->get( 'BlockDisablesLogin' ), + $config->get( 'GroupPermissions' ), + $config->get( 'RevokePermissions' ), + $config->get( 'AvailableRights' ), $services->getNamespaceInfo() ); }, diff --git a/includes/user/User.php b/includes/user/User.php index 6025d3cf1a..97d47023f7 100644 --- a/includes/user/User.php +++ b/includes/user/User.php @@ -111,95 +111,7 @@ class User implements IDBAccessObject, UserIdentity { ]; /** - * Array of Strings Core rights. - * Each of these should have a corresponding message of the form - * "right-$right". - * @showinitializer * @var string[] - */ - protected static $mCoreRights = [ - 'apihighlimits', - 'applychangetags', - 'autoconfirmed', - 'autocreateaccount', - 'autopatrol', - 'bigdelete', - 'block', - 'blockemail', - 'bot', - 'browsearchive', - 'changetags', - 'createaccount', - 'createpage', - 'createtalk', - 'delete', - 'deletechangetags', - 'deletedhistory', - 'deletedtext', - 'deletelogentry', - 'deleterevision', - 'edit', - 'editcontentmodel', - 'editinterface', - 'editprotected', - 'editmyoptions', - 'editmyprivateinfo', - 'editmyusercss', - 'editmyuserjson', - 'editmyuserjs', - 'editmywatchlist', - 'editsemiprotected', - 'editsitecss', - 'editsitejson', - 'editsitejs', - 'editusercss', - 'edituserjson', - 'edituserjs', - 'hideuser', - 'import', - 'importupload', - 'ipblock-exempt', - 'managechangetags', - 'markbotedits', - 'mergehistory', - 'minoredit', - 'move', - 'movefile', - 'move-categorypages', - 'move-rootuserpages', - 'move-subpages', - 'nominornewtalk', - 'noratelimit', - 'override-export-depth', - 'pagelang', - 'patrol', - 'patrolmarks', - 'protect', - 'purge', - 'read', - 'reupload', - 'reupload-own', - 'reupload-shared', - 'rollback', - 'sendemail', - 'siteadmin', - 'suppressionlog', - 'suppressredirect', - 'suppressrevision', - 'unblockself', - 'undelete', - 'unwatchedpages', - 'upload', - 'upload_by_url', - 'userrights', - 'userrights-interwiki', - 'viewmyprivateinfo', - 'viewmywatchlist', - 'viewsuppressed', - 'writeapi', - ]; - - /** * @var string[] Cached results of getAllRights() */ protected static $mAllRights = false; @@ -274,8 +186,6 @@ class User implements IDBAccessObject, UserIdentity { public $mBlockedby; /** @var string */ protected $mHash; - /** @var array */ - public $mRights; /** @var string */ protected $mBlockreason; /** @var array */ @@ -333,6 +243,24 @@ class User implements IDBAccessObject, UserIdentity { return (string)$this->getName(); } + public function __get( $name ) { + // A shortcut for $mRights deprecation phase + if ( $name === 'mRights' ) { + return $this->getRights(); + } + } + + public function __set( $name, $value ) { + // A shortcut for $mRights deprecation phase, only known legitimate use was for + // testing purposes, other uses seem bad in principle + if ( $name === 'mRights' ) { + MediaWikiServices::getInstance()->getPermissionManager()->overrideUserRightsForTesting( + $this, + is_null( $value ) ? [] : $value + ); + } + } + /** * Test if it's safe to load this User object. * @@ -1699,11 +1627,12 @@ class User implements IDBAccessObject, UserIdentity { * given source. May be "name", "id", "actor", "defaults", "session", or false for no reload. */ public function clearInstanceCache( $reloadFrom = false ) { + global $wgFullyInitialised; + $this->mNewtalk = -1; $this->mDatePreference = null; $this->mBlockedby = -1; # Unset $this->mHash = false; - $this->mRights = null; $this->mEffectiveGroups = null; $this->mImplicitGroups = null; $this->mGroupMemberships = null; @@ -1711,6 +1640,13 @@ class User implements IDBAccessObject, UserIdentity { $this->mOptionsLoaded = false; $this->mEditCount = null; + // Replacement of former `$this->mRights = null` line + if ( $wgFullyInitialised && $this->mFrom ) { + MediaWikiServices::getInstance()->getPermissionManager()->invalidateUsersRightsCache( + $this + ); + } + if ( $reloadFrom ) { $this->mLoadedItems = []; $this->mFrom = $reloadFrom; @@ -2149,7 +2085,6 @@ class User implements IDBAccessObject, UserIdentity { * @param Title $title Title to check * @param bool $fromReplica Whether to check the replica DB instead of the master * @return bool - * @throws MWException * * @deprecated since 1.33, * use MediaWikiServices::getInstance()->getPermissionManager()->isBlockedFrom(..) @@ -3395,44 +3330,13 @@ class User implements IDBAccessObject, UserIdentity { /** * Get the permissions this user has. * @return string[] permission names + * + * @deprecated since 1.34, use MediaWikiServices::getInstance()->getPermissionManager() + * ->getUserPermissions(..) instead + * */ public function getRights() { - if ( is_null( $this->mRights ) ) { - $this->mRights = self::getGroupPermissions( $this->getEffectiveGroups() ); - Hooks::run( 'UserGetRights', [ $this, &$this->mRights ] ); - - // Deny any rights denied by the user's session, unless this - // endpoint has no sessions. - if ( !defined( 'MW_NO_SESSION' ) ) { - $allowedRights = $this->getRequest()->getSession()->getAllowedUserRights(); - if ( $allowedRights !== null ) { - $this->mRights = array_intersect( $this->mRights, $allowedRights ); - } - } - - Hooks::run( 'UserGetRightsRemove', [ $this, &$this->mRights ] ); - // Force reindexation of rights when a hook has unset one of them - $this->mRights = array_values( array_unique( $this->mRights ) ); - - // If block disables login, we should also remove any - // extra rights blocked users might have, in case the - // blocked user has a pre-existing session (T129738). - // This is checked here for cases where people only call - // $user->isAllowed(). It is also checked in Title::checkUserBlock() - // to give a better error message in the common case. - $config = RequestContext::getMain()->getConfig(); - // @TODO Partial blocks should not prevent the user from logging in. - // see: https://phabricator.wikimedia.org/T208895 - if ( - $this->isLoggedIn() && - $config->get( 'BlockDisablesLogin' ) && - $this->getBlock() - ) { - $anon = new User; - $this->mRights = array_intersect( $this->mRights, $anon->getRights() ); - } - } - return $this->mRights; + return MediaWikiServices::getInstance()->getPermissionManager()->getUserPermissions( $this ); } /** @@ -3601,8 +3505,7 @@ class User implements IDBAccessObject, UserIdentity { // Refresh the groups caches, and clear the rights cache so it will be // refreshed on the next call to $this->getRights(). $this->getEffectiveGroups( true ); - $this->mRights = null; - + MediaWikiServices::getInstance()->getPermissionManager()->invalidateUsersRightsCache( $this ); $this->invalidateCache(); return true; @@ -3633,8 +3536,7 @@ class User implements IDBAccessObject, UserIdentity { // Refresh the groups caches, and clear the rights cache so it will be // refreshed on the next call to $this->getRights(). $this->getEffectiveGroups( true ); - $this->mRights = null; - + MediaWikiServices::getInstance()->getPermissionManager()->invalidateUsersRightsCache( $this ); $this->invalidateCache(); return true; @@ -3717,16 +3619,17 @@ class User implements IDBAccessObject, UserIdentity { /** * Internal mechanics of testing a permission + * + * @deprecated since 1.34, use MediaWikiServices::getInstance() + * ->getPermissionManager()->userHasRight(...) instead + * * @param string $action + * * @return bool */ public function isAllowed( $action = '' ) { - if ( $action === '' ) { - return true; // In the spirit of DWIM - } - // Use strict parameter to avoid matching numeric 0 accidentally inserted - // by misconfiguration: 0 == 'foo' - return in_array( $action, $this->getRights(), true ); + return MediaWikiServices::getInstance()->getPermissionManager() + ->userHasRight( $this, $action ); } /** @@ -4875,45 +4778,27 @@ class User implements IDBAccessObject, UserIdentity { /** * Get the permissions associated with a given list of groups * + * @deprecated since 1.34, use MediaWikiServices::getInstance()->getPermissionManager() + * ->getGroupPermissions() instead + * * @param array $groups Array of Strings List of internal group names * @return array Array of Strings List of permission key names for given groups combined */ public static function getGroupPermissions( $groups ) { - global $wgGroupPermissions, $wgRevokePermissions; - $rights = []; - // grant every granted permission first - foreach ( $groups as $group ) { - if ( isset( $wgGroupPermissions[$group] ) ) { - $rights = array_merge( $rights, - // array_filter removes empty items - array_keys( array_filter( $wgGroupPermissions[$group] ) ) ); - } - } - // now revoke the revoked permissions - foreach ( $groups as $group ) { - if ( isset( $wgRevokePermissions[$group] ) ) { - $rights = array_diff( $rights, - array_keys( array_filter( $wgRevokePermissions[$group] ) ) ); - } - } - return array_unique( $rights ); + return MediaWikiServices::getInstance()->getPermissionManager()->getGroupPermissions( $groups ); } /** * Get all the groups who have a given permission * + * @deprecated since 1.34, use MediaWikiServices::getInstance()->getPermissionManager() + * ->getGroupsWithPermission() instead + * * @param string $role Role to check * @return array Array of Strings List of internal group names with the given permission */ public static function getGroupsWithPermission( $role ) { - global $wgGroupPermissions; - $allowedGroups = []; - foreach ( array_keys( $wgGroupPermissions ) as $group ) { - if ( self::groupHasPermission( $group, $role ) ) { - $allowedGroups[] = $group; - } - } - return $allowedGroups; + return MediaWikiServices::getInstance()->getPermissionManager()->getGroupsWithPermission( $role ); } /** @@ -4923,15 +4808,17 @@ class User implements IDBAccessObject, UserIdentity { * User::isEveryoneAllowed() instead. That properly checks if it's revoked * from anyone. * + * @deprecated since 1.34, use MediaWikiServices::getInstance()->getPermissionManager() + * ->groupHasPermission(..) instead + * * @since 1.21 * @param string $group Group to check * @param string $role Role to check * @return bool */ public static function groupHasPermission( $group, $role ) { - global $wgGroupPermissions, $wgRevokePermissions; - return isset( $wgGroupPermissions[$group][$role] ) && $wgGroupPermissions[$group][$role] - && !( isset( $wgRevokePermissions[$group][$role] ) && $wgRevokePermissions[$group][$role] ); + return MediaWikiServices::getInstance()->getPermissionManager() + ->groupHasPermission( $group, $role ); } /** @@ -4944,51 +4831,16 @@ class User implements IDBAccessObject, UserIdentity { * Specifically, session-based rights restrictions (such as OAuth or bot * passwords) are applied based on the current session. * - * @since 1.22 + * @deprecated since 1.34, use MediaWikiServices::getInstance()->getPermissionManager() + * ->isEveryoneAllowed() instead + * * @param string $right Right to check + * * @return bool + * @since 1.22 */ public static function isEveryoneAllowed( $right ) { - global $wgGroupPermissions, $wgRevokePermissions; - static $cache = []; - - // Use the cached results, except in unit tests which rely on - // being able change the permission mid-request - if ( isset( $cache[$right] ) && !defined( 'MW_PHPUNIT_TEST' ) ) { - return $cache[$right]; - } - - if ( !isset( $wgGroupPermissions['*'][$right] ) || !$wgGroupPermissions['*'][$right] ) { - $cache[$right] = false; - return false; - } - - // If it's revoked anywhere, then everyone doesn't have it - foreach ( $wgRevokePermissions as $rights ) { - if ( isset( $rights[$right] ) && $rights[$right] ) { - $cache[$right] = false; - return false; - } - } - - // Remove any rights that aren't allowed to the global-session user, - // unless there are no sessions for this endpoint. - if ( !defined( 'MW_NO_SESSION' ) ) { - $allowedRights = SessionManager::getGlobalSession()->getAllowedUserRights(); - if ( $allowedRights !== null && !in_array( $right, $allowedRights, true ) ) { - $cache[$right] = false; - return false; - } - } - - // Allow extensions to say false - if ( !Hooks::run( 'UserIsEveryoneAllowed', [ $right ] ) ) { - $cache[$right] = false; - return false; - } - - $cache[$right] = true; - return true; + return MediaWikiServices::getInstance()->getPermissionManager()->isEveryoneAllowed( $right ); } /** @@ -5007,19 +4859,14 @@ class User implements IDBAccessObject, UserIdentity { /** * Get a list of all available permissions. + * + * @deprecated since 1.34, use MediaWikiServices::getInstance()->getPermissionManager() + * ->getAllPermissions() instead + * * @return string[] Array of permission names */ public static function getAllRights() { - if ( self::$mAllRights === false ) { - global $wgAvailableRights; - if ( count( $wgAvailableRights ) ) { - self::$mAllRights = array_unique( array_merge( self::$mCoreRights, $wgAvailableRights ) ); - } else { - self::$mAllRights = self::$mCoreRights; - } - Hooks::run( 'UserGetAllRights', [ &self::$mAllRights ] ); - } - return self::$mAllRights; + return MediaWikiServices::getInstance()->getPermissionManager()->getAllPermissions(); } /** diff --git a/tests/phpunit/MediaWikiIntegrationTestCase.php b/tests/phpunit/MediaWikiIntegrationTestCase.php index 999ba47a42..a5c9ab19a2 100644 --- a/tests/phpunit/MediaWikiIntegrationTestCase.php +++ b/tests/phpunit/MediaWikiIntegrationTestCase.php @@ -1220,8 +1220,23 @@ abstract class MediaWikiIntegrationTestCase extends PHPUnit\Framework\TestCase { } /** + * Overrides specific user permissions until services are reloaded * * @since 1.34 + * + * @param User $user + * @param string[]|string $permissions + * + * @throws Exception + */ + public function overrideUserPermissions( $user, $permissions = [] ) { + MediaWikiServices::getInstance()->getPermissionManager()->overrideUserRightsForTesting( + $user, + $permissions + ); + } + + /** * Sets the logger for a specified channel, for the duration of the test. * @since 1.27 * @param string $channel diff --git a/tests/phpunit/includes/Permissions/PermissionManagerTest.php b/tests/phpunit/includes/Permissions/PermissionManagerTest.php index 2ce50b7e9d..88a3f43f0e 100644 --- a/tests/phpunit/includes/Permissions/PermissionManagerTest.php +++ b/tests/phpunit/includes/Permissions/PermissionManagerTest.php @@ -3,8 +3,12 @@ namespace MediaWiki\Tests\Permissions; use Action; +use FauxRequest; +use MediaWiki\Session\SessionId; +use MediaWiki\Session\TestUtils; use MediaWikiLangTestCase; use RequestContext; +use stdClass; use Title; use User; use MediaWiki\Block\DatabaseBlock; @@ -13,6 +17,7 @@ use MediaWiki\Block\Restriction\PageRestriction; use MediaWiki\Block\SystemBlock; use MediaWiki\MediaWikiServices; use MediaWiki\Permissions\PermissionManager; +use Wikimedia\TestingAccessWrapper; /** * @group Database @@ -56,7 +61,32 @@ class PermissionManagerTest extends MediaWikiLangTestCase { 'wgNamespaceProtection' => [ NS_MEDIAWIKI => 'editinterface', ], + 'wgRevokePermissions' => [ + 'formertesters' => [ + 'runtest' => true + ] + ], + 'wgAvailableRights' => [ + 'test', + 'runtest', + 'writetest', + 'nukeworld', + 'modifytest', + 'editmyoptions' + ] ] ); + + $this->setGroupPermissions( 'unittesters', 'test', true ); + $this->setGroupPermissions( 'unittesters', 'runtest', true ); + $this->setGroupPermissions( 'unittesters', 'writetest', false ); + $this->setGroupPermissions( 'unittesters', 'nukeworld', false ); + + $this->setGroupPermissions( 'testwriters', 'test', true ); + $this->setGroupPermissions( 'testwriters', 'writetest', true ); + $this->setGroupPermissions( 'testwriters', 'modifytest', true ); + + $this->setGroupPermissions( '*', 'editmyoptions', true ); + // Without this testUserBlock will use a non-English context on non-English MediaWiki // installations (because of how Title::checkUserBlock is implemented) and fail. RequestContext::resetMain(); @@ -89,19 +119,12 @@ class PermissionManagerTest extends MediaWikiLangTestCase { $this->user = $this->userUser; } - $this->permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); - - $this->overrideMwServices(); + $this->resetServices(); } - protected function setUserPerm( $perm ) { - // Setting member variables is evil!!! - - if ( is_array( $perm ) ) { - $this->user->mRights = $perm; - } else { - $this->user->mRights = [ $perm ]; - } + public function tearDown() { + parent::tearDown(); + $this->restoreMwServices(); } protected function setTitle( $ns, $title = "Main_Page" ) { @@ -116,6 +139,7 @@ class PermissionManagerTest extends MediaWikiLangTestCase { } else { $this->user = $this->altUser; } + $this->resetServices(); } /** @@ -133,163 +157,165 @@ class PermissionManagerTest extends MediaWikiLangTestCase { $this->setUser( 'anon' ); $this->setTitle( NS_TALK ); - $this->setUserPerm( "createtalk" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "createtalk" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'create', $this->user, $this->title ); $this->assertEquals( [], $res ); $this->setTitle( NS_TALK ); - $this->setUserPerm( "createpage" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "createpage" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'create', $this->user, $this->title ); $this->assertEquals( [ [ "nocreatetext" ] ], $res ); $this->setTitle( NS_TALK ); - $this->setUserPerm( "" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'create', $this->user, $this->title ); $this->assertEquals( [ [ 'nocreatetext' ] ], $res ); $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createpage" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "createpage" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'create', $this->user, $this->title ); $this->assertEquals( [], $res ); $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createtalk" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "createtalk" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'create', $this->user, $this->title ); $this->assertEquals( [ [ 'nocreatetext' ] ], $res ); $this->setUser( $this->userName ); $this->setTitle( NS_TALK ); - $this->setUserPerm( "createtalk" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "createtalk" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'create', $this->user, $this->title ); $this->assertEquals( [], $res ); $this->setTitle( NS_TALK ); - $this->setUserPerm( "createpage" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "createpage" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'create', $this->user, $this->title ); $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res ); $this->setTitle( NS_TALK ); - $this->setUserPerm( "" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'create', $this->user, $this->title ); $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res ); $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createpage" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "createpage" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'create', $this->user, $this->title ); $this->assertEquals( [], $res ); $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createtalk" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "createtalk" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'create', $this->user, $this->title ); $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res ); $this->setTitle( NS_MAIN ); - $this->setUserPerm( "" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'create', $this->user, $this->title ); $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res ); $this->setUser( 'anon' ); $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move', $this->user, $this->title ); $this->assertEquals( [ [ 'cant-move-user-page' ], [ 'movenologintext' ] ], $res ); $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move', $this->user, $this->title ); $this->assertEquals( [ [ 'movenologintext' ] ], $res ); $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "move-rootuserpages" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move', $this->user, $this->title ); $this->assertEquals( [ [ 'movenologintext' ] ], $res ); $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "move-rootuserpages" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move', $this->user, $this->title ); $this->assertEquals( [ [ 'movenologintext' ] ], $res ); $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move', $this->user, $this->title ); $this->assertEquals( [ [ 'cant-move-user-page' ], [ 'movenologintext' ] ], $res ); $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move', $this->user, $this->title ); $this->assertEquals( [ [ 'movenologintext' ] ], $res ); $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "move-rootuserpages" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move', $this->user, $this->title ); $this->assertEquals( [ [ 'movenologintext' ] ], $res ); $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "move-rootuserpages" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "move-rootuserpages" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move', $this->user, $this->title ); $this->assertEquals( [ [ 'movenologintext' ] ], $res ); $this->setUser( $this->userName ); $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move', $this->user, $this->title ); $this->assertEquals( [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ], $res ); $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "movefile" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "movefile" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move', $this->user, $this->title ); $this->assertEquals( [ [ 'movenotallowed' ] ], $res ); $this->setUser( 'anon' ); $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move', $this->user, $this->title ); $this->assertEquals( [ [ 'movenotallowedfile' ], [ 'movenologintext' ] ], $res ); $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "movefile" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "movefile" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move', $this->user, $this->title ); $this->assertEquals( [ [ 'movenologintext' ] ], $res ); $this->setUser( $this->userName ); - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', [ [ 'movenotallowedfile' ] ] ); + // $this->setUserPerm( "move" ); + $this->runGroupPermissions( 'move', 'move', [ [ 'movenotallowedfile' ] ] ); - $this->setUserPerm( "" ); + // $this->setUserPerm( "" ); $this->runGroupPermissions( + '', 'move', [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ] ); $this->setUser( 'anon' ); - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', [ [ 'movenotallowedfile' ] ] ); + //$this->setUserPerm( "move" ); + $this->runGroupPermissions( 'move', 'move', [ [ 'movenotallowedfile' ] ] ); - $this->setUserPerm( "" ); + // $this->setUserPerm( "" ); $this->runGroupPermissions( + '', 'move', [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ], [ [ 'movenotallowedfile' ], [ 'movenologintext' ] ] @@ -301,58 +327,58 @@ class PermissionManagerTest extends MediaWikiLangTestCase { $this->setTitle( NS_MAIN ); $this->setUser( 'anon' ); - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', [] ); + // $this->setUserPerm( "move" ); + $this->runGroupPermissions( 'move', 'move', [] ); - $this->setUserPerm( "" ); - $this->runGroupPermissions( 'move', [ [ 'movenotallowed' ] ], + // $this->setUserPerm( "" ); + $this->runGroupPermissions( '', 'move', [ [ 'movenotallowed' ] ], [ [ 'movenologintext' ] ] ); $this->setUser( $this->userName ); - $this->setUserPerm( "" ); - $this->runGroupPermissions( 'move', [ [ 'movenotallowed' ] ] ); + // $this->setUserPerm( "" ); + $this->runGroupPermissions( '', 'move', [ [ 'movenotallowed' ] ] ); - $this->setUserPerm( "move" ); - $this->runGroupPermissions( 'move', [] ); + //$this->setUserPerm( "move" ); + $this->runGroupPermissions( 'move', 'move', [] ); $this->setUser( 'anon' ); - $this->setUserPerm( 'move' ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, 'move' ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move-target', $this->user, $this->title ); $this->assertEquals( [], $res ); - $this->setUserPerm( '' ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, '' ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move-target', $this->user, $this->title ); $this->assertEquals( [ [ 'movenotallowed' ] ], $res ); } $this->setTitle( NS_USER ); $this->setUser( $this->userName ); - $this->setUserPerm( [ "move", "move-rootuserpages" ] ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, [ "move", "move-rootuserpages" ] ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move-target', $this->user, $this->title ); $this->assertEquals( [], $res ); - $this->setUserPerm( "move" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "move" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move-target', $this->user, $this->title ); $this->assertEquals( [ [ 'cant-move-to-user-page' ] ], $res ); $this->setUser( 'anon' ); - $this->setUserPerm( [ "move", "move-rootuserpages" ] ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, [ "move", "move-rootuserpages" ] ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move-target', $this->user, $this->title ); $this->assertEquals( [], $res ); $this->setTitle( NS_USER, "User/subpage" ); - $this->setUserPerm( [ "move", "move-rootuserpages" ] ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, [ "move", "move-rootuserpages" ] ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move-target', $this->user, $this->title ); $this->assertEquals( [], $res ); - $this->setUserPerm( "move" ); - $res = $this->permissionManager + $this->overrideUserPermissions( $this->user, "move" ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move-target', $this->user, $this->title ); $this->assertEquals( [], $res ); @@ -378,54 +404,58 @@ class PermissionManagerTest extends MediaWikiLangTestCase { ]; foreach ( [ "edit", "protect", "" ] as $action ) { - $this->setUserPerm( null ); + $this->overrideUserPermissions( $this->user ); $this->assertEquals( $check[$action][0], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( $action, $this->user, $this->title, true ) ); $this->assertEquals( $check[$action][0], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( $action, $this->user, $this->title, 'full' ) ); $this->assertEquals( $check[$action][0], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( $action, $this->user, $this->title, 'secure' ) ); global $wgGroupPermissions; $old = $wgGroupPermissions; $wgGroupPermissions = []; + $this->resetServices(); $this->assertEquals( $check[$action][1], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( $action, $this->user, $this->title, true ) ); $this->assertEquals( $check[$action][1], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( $action, $this->user, $this->title, 'full' ) ); $this->assertEquals( $check[$action][1], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( $action, $this->user, $this->title, 'secure' ) ); $wgGroupPermissions = $old; + $this->resetServices(); - $this->setUserPerm( $action ); + $this->overrideUserPermissions( $this->user, $action ); $this->assertEquals( $check[$action][2], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( $action, $this->user, $this->title, true ) ); $this->assertEquals( $check[$action][2], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( $action, $this->user, $this->title, 'full' ) ); $this->assertEquals( $check[$action][2], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( $action, $this->user, $this->title, 'secure' ) ); - $this->setUserPerm( $action ); + $this->overrideUserPermissions( $this->user, $action ); $this->assertEquals( $check[$action][3], - $this->permissionManager->userCan( $action, $this->user, $this->title, true ) ); + MediaWikiServices::getInstance()->getPermissionManager() + ->userCan( $action, $this->user, $this->title, true ) ); $this->assertEquals( $check[$action][3], - $this->permissionManager->userCan( $action, $this->user, $this->title, + MediaWikiServices::getInstance()->getPermissionManager() + ->userCan( $action, $this->user, $this->title, PermissionManager::RIGOR_QUICK ) ); # count( User::getGroupsWithPermissions( $action ) ) < 1 } } - protected function runGroupPermissions( $action, $result, $result2 = null ) { + protected function runGroupPermissions( $perm, $action, $result, $result2 = null ) { global $wgGroupPermissions; if ( $result2 === null ) { @@ -434,25 +464,33 @@ class PermissionManagerTest extends MediaWikiLangTestCase { $wgGroupPermissions['autoconfirmed']['move'] = false; $wgGroupPermissions['user']['move'] = false; - $res = $this->permissionManager + $this->resetServices(); + $this->overrideUserPermissions( $this->user, $perm ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( $action, $this->user, $this->title ); $this->assertEquals( $result, $res ); $wgGroupPermissions['autoconfirmed']['move'] = true; $wgGroupPermissions['user']['move'] = false; - $res = $this->permissionManager + $this->resetServices(); + $this->overrideUserPermissions( $this->user, $perm ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( $action, $this->user, $this->title ); $this->assertEquals( $result2, $res ); $wgGroupPermissions['autoconfirmed']['move'] = true; $wgGroupPermissions['user']['move'] = true; - $res = $this->permissionManager + $this->resetServices(); + $this->overrideUserPermissions( $this->user, $perm ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( $action, $this->user, $this->title ); $this->assertEquals( $result2, $res ); $wgGroupPermissions['autoconfirmed']['move'] = false; $wgGroupPermissions['user']['move'] = true; - $res = $this->permissionManager + $this->resetServices(); + $this->overrideUserPermissions( $this->user, $perm ); + $res = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( $action, $this->user, $this->title ); $this->assertEquals( $result2, $res ); } @@ -469,57 +507,59 @@ class PermissionManagerTest extends MediaWikiLangTestCase { $this->setTitle( NS_SPECIAL ); $this->assertEquals( [ [ 'badaccess-group0' ], [ 'ns-specialprotected' ] ], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'bogus', $this->user, $this->title ) ); $this->setTitle( NS_MAIN ); - $this->setUserPerm( 'bogus' ); + $this->overrideUserPermissions( $this->user, 'bogus' ); $this->assertEquals( [], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'bogus', $this->user, $this->title ) ); $this->setTitle( NS_MAIN ); - $this->setUserPerm( '' ); + $this->overrideUserPermissions( $this->user, '' ); $this->assertEquals( [ [ 'badaccess-group0' ] ], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'bogus', $this->user, $this->title ) ); $wgNamespaceProtection[NS_USER] = [ 'bogus' ]; $this->setTitle( NS_USER ); - $this->setUserPerm( '' ); + $this->overrideUserPermissions( $this->user, '' ); $this->assertEquals( [ [ 'badaccess-group0' ], [ 'namespaceprotected', 'User', 'bogus' ] ], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'bogus', $this->user, $this->title ) ); $this->setTitle( NS_MEDIAWIKI ); - $this->setUserPerm( 'bogus' ); + $this->overrideUserPermissions( $this->user, 'bogus' ); $this->assertEquals( [ [ 'protectedinterface', 'bogus' ] ], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'bogus', $this->user, $this->title ) ); $this->setTitle( NS_MEDIAWIKI ); - $this->setUserPerm( 'bogus' ); + $this->overrideUserPermissions( $this->user, 'bogus' ); $this->assertEquals( [ [ 'protectedinterface', 'bogus' ] ], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'bogus', $this->user, $this->title ) ); $wgNamespaceProtection = null; - $this->setUserPerm( 'bogus' ); + $this->overrideUserPermissions( $this->user, 'bogus' ); $this->assertEquals( [], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'bogus', $this->user, $this->title ) ); $this->assertEquals( true, - $this->permissionManager->userCan( 'bogus', $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager() + ->userCan( 'bogus', $this->user, $this->title ) ); - $this->setUserPerm( '' ); + $this->overrideUserPermissions( $this->user, '' ); $this->assertEquals( [ [ 'badaccess-group0' ] ], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'bogus', $this->user, $this->title ) ); $this->assertEquals( false, - $this->permissionManager->userCan( 'bogus', $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager() + ->userCan( 'bogus', $this->user, $this->title ) ); } /** @@ -716,48 +756,48 @@ class PermissionManagerTest extends MediaWikiLangTestCase { $resultUserJs, $resultPatrol ) { - $this->setUserPerm( '' ); - $result = $this->permissionManager + $this->overrideUserPermissions( $this->user ); + $result = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'bogus', $this->user, $this->title ); $this->assertEquals( $resultNone, $result ); - $this->setUserPerm( 'editmyusercss' ); - $result = $this->permissionManager + $this->overrideUserPermissions( $this->user, 'editmyusercss' ); + $result = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'bogus', $this->user, $this->title ); $this->assertEquals( $resultMyCss, $result ); - $this->setUserPerm( 'editmyuserjson' ); - $result = $this->permissionManager + $this->overrideUserPermissions( $this->user, 'editmyuserjson' ); + $result = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'bogus', $this->user, $this->title ); $this->assertEquals( $resultMyJson, $result ); - $this->setUserPerm( 'editmyuserjs' ); - $result = $this->permissionManager + $this->overrideUserPermissions( $this->user, 'editmyuserjs' ); + $result = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'bogus', $this->user, $this->title ); $this->assertEquals( $resultMyJs, $result ); - $this->setUserPerm( 'editusercss' ); - $result = $this->permissionManager + $this->overrideUserPermissions( $this->user, 'editusercss' ); + $result = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'bogus', $this->user, $this->title ); $this->assertEquals( $resultUserCss, $result ); - $this->setUserPerm( 'edituserjson' ); - $result = $this->permissionManager + $this->overrideUserPermissions( $this->user, 'edituserjson' ); + $result = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'bogus', $this->user, $this->title ); $this->assertEquals( $resultUserJson, $result ); - $this->setUserPerm( 'edituserjs' ); - $result = $this->permissionManager + $this->overrideUserPermissions( $this->user, 'edituserjs' ); + $result = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'bogus', $this->user, $this->title ); $this->assertEquals( $resultUserJs, $result ); - $this->setUserPerm( '' ); - $result = $this->permissionManager + $this->overrideUserPermissions( $this->user ); + $result = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'patrol', $this->user, $this->title ); $this->assertEquals( reset( $resultPatrol[0] ), reset( $result[0] ) ); - $this->setUserPerm( [ 'edituserjs', 'edituserjson', 'editusercss' ] ); - $result = $this->permissionManager + $this->overrideUserPermissions( $this->user, [ 'edituserjs', 'edituserjson', 'editusercss' ] ); + $result = MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'bogus', $this->user, $this->title ); $this->assertEquals( [ [ 'badaccess-group0' ] ], $result ); } @@ -777,16 +817,16 @@ class PermissionManagerTest extends MediaWikiLangTestCase { $this->setTitle( NS_MAIN ); $this->title->mRestrictionsLoaded = true; - $this->setUserPerm( "edit" ); + $this->overrideUserPermissions( $this->user, "edit" ); $this->title->mRestrictions = [ "bogus" => [ 'bogus', "sysop", "protect", "" ] ]; $this->assertEquals( [], - $this->permissionManager->getPermissionErrors( 'edit', - $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager() + ->getPermissionErrors( 'edit', $this->user, $this->title ) ); $this->assertEquals( true, - $this->permissionManager->userCan( 'edit', $this->user, $this->title, - PermissionManager::RIGOR_QUICK ) ); + MediaWikiServices::getInstance()->getPermissionManager() + ->userCan( 'edit', $this->user, $this->title, PermissionManager::RIGOR_QUICK ) ); $this->title->mRestrictions = [ "edit" => [ 'bogus', "sysop", "protect", "" ], "bogus" => [ 'bogus', "sysop", "protect", "" ] ]; @@ -795,81 +835,81 @@ class PermissionManagerTest extends MediaWikiLangTestCase { [ 'protectedpagetext', 'bogus', 'bogus' ], [ 'protectedpagetext', 'editprotected', 'bogus' ], [ 'protectedpagetext', 'protect', 'bogus' ] ], - $this->permissionManager->getPermissionErrors( 'bogus', - $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors( + 'bogus', $this->user, $this->title ) ); $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ], [ 'protectedpagetext', 'editprotected', 'edit' ], [ 'protectedpagetext', 'protect', 'edit' ] ], - $this->permissionManager->getPermissionErrors( 'edit', - $this->user, $this->title ) ); - $this->setUserPerm( "" ); + MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors( + 'edit', $this->user, $this->title ) ); + $this->overrideUserPermissions( $this->user ); $this->assertEquals( [ [ 'badaccess-group0' ], [ 'protectedpagetext', 'bogus', 'bogus' ], [ 'protectedpagetext', 'editprotected', 'bogus' ], [ 'protectedpagetext', 'protect', 'bogus' ] ], - $this->permissionManager->getPermissionErrors( 'bogus', - $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors( + 'bogus', $this->user, $this->title ) ); $this->assertEquals( [ [ 'badaccess-groups', "*, [[$prefix:Users|Users]]", 2 ], [ 'protectedpagetext', 'bogus', 'edit' ], [ 'protectedpagetext', 'editprotected', 'edit' ], [ 'protectedpagetext', 'protect', 'edit' ] ], - $this->permissionManager->getPermissionErrors( 'edit', - $this->user, $this->title ) ); - $this->setUserPerm( [ "edit", "editprotected" ] ); + MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors( + 'edit', $this->user, $this->title ) ); + $this->overrideUserPermissions( $this->user, [ "edit", "editprotected" ] ); $this->assertEquals( [ [ 'badaccess-group0' ], [ 'protectedpagetext', 'bogus', 'bogus' ], [ 'protectedpagetext', 'protect', 'bogus' ] ], - $this->permissionManager->getPermissionErrors( 'bogus', - $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors( + 'bogus', $this->user, $this->title ) ); $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ], [ 'protectedpagetext', 'protect', 'edit' ] ], - $this->permissionManager->getPermissionErrors( 'edit', - $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors( + 'edit', $this->user, $this->title ) ); $this->title->mCascadeRestriction = true; - $this->setUserPerm( "edit" ); + $this->overrideUserPermissions( $this->user, "edit" ); $this->assertEquals( false, - $this->permissionManager->userCan( 'bogus', $this->user, $this->title, - PermissionManager::RIGOR_QUICK ) ); + MediaWikiServices::getInstance()->getPermissionManager() + ->userCan( 'bogus', $this->user, $this->title, PermissionManager::RIGOR_QUICK ) ); $this->assertEquals( false, - $this->permissionManager->userCan( 'edit', $this->user, $this->title, - PermissionManager::RIGOR_QUICK ) ); + MediaWikiServices::getInstance()->getPermissionManager()->userCan( + 'edit', $this->user, $this->title, PermissionManager::RIGOR_QUICK ) ); $this->assertEquals( [ [ 'badaccess-group0' ], [ 'protectedpagetext', 'bogus', 'bogus' ], [ 'protectedpagetext', 'editprotected', 'bogus' ], [ 'protectedpagetext', 'protect', 'bogus' ] ], - $this->permissionManager->getPermissionErrors( 'bogus', - $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors( + 'bogus', $this->user, $this->title ) ); $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ], [ 'protectedpagetext', 'editprotected', 'edit' ], [ 'protectedpagetext', 'protect', 'edit' ] ], - $this->permissionManager->getPermissionErrors( 'edit', - $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors( + 'edit', $this->user, $this->title ) ); - $this->setUserPerm( [ "edit", "editprotected" ] ); + $this->overrideUserPermissions( $this->user, [ "edit", "editprotected" ] ); $this->assertEquals( false, - $this->permissionManager->userCan( 'bogus', $this->user, $this->title, - PermissionManager::RIGOR_QUICK ) ); + MediaWikiServices::getInstance()->getPermissionManager()->userCan( + 'bogus', $this->user, $this->title, PermissionManager::RIGOR_QUICK ) ); $this->assertEquals( false, - $this->permissionManager->userCan( 'edit', $this->user, $this->title, - PermissionManager::RIGOR_QUICK ) ); + MediaWikiServices::getInstance()->getPermissionManager()->userCan( + 'edit', $this->user, $this->title, PermissionManager::RIGOR_QUICK ) ); $this->assertEquals( [ [ 'badaccess-group0' ], [ 'protectedpagetext', 'bogus', 'bogus' ], [ 'protectedpagetext', 'protect', 'bogus' ], [ 'protectedpagetext', 'protect', 'bogus' ] ], - $this->permissionManager->getPermissionErrors( 'bogus', - $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors( + 'bogus', $this->user, $this->title ) ); $this->assertEquals( [ [ 'protectedpagetext', 'bogus', 'edit' ], [ 'protectedpagetext', 'protect', 'edit' ], [ 'protectedpagetext', 'protect', 'edit' ] ], - $this->permissionManager->getPermissionErrors( 'edit', - $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors( + 'edit', $this->user, $this->title ) ); } /** @@ -877,7 +917,7 @@ class PermissionManagerTest extends MediaWikiLangTestCase { */ public function testCascadingSourcesRestrictions() { $this->setTitle( NS_MAIN, "test page" ); - $this->setUserPerm( [ "edit", "bogus" ] ); + $this->overrideUserPermissions( $this->user, [ "edit", "bogus" ] ); $this->title->mCascadeSources = [ Title::makeTitle( NS_MAIN, "Bogus" ), @@ -888,17 +928,21 @@ class PermissionManagerTest extends MediaWikiLangTestCase { ]; $this->assertEquals( false, - $this->permissionManager->userCan( 'bogus', $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->userCan( + 'bogus', $this->user, $this->title ) ); $this->assertEquals( [ [ "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ], [ "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ], [ "cascadeprotected", 2, "* [[:Bogus]]\n* [[:UnBogus]]\n", 'bogus' ] ], - $this->permissionManager->getPermissionErrors( 'bogus', $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors( + 'bogus', $this->user, $this->title ) ); $this->assertEquals( true, - $this->permissionManager->userCan( 'edit', $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->userCan( + 'edit', $this->user, $this->title ) ); $this->assertEquals( [], - $this->permissionManager->getPermissionErrors( 'edit', $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors( + 'edit', $this->user, $this->title ) ); } /** @@ -907,7 +951,7 @@ class PermissionManagerTest extends MediaWikiLangTestCase { * @covers \MediaWiki\Permissions\PermissionManager::checkActionPermissions */ public function testActionPermissions() { - $this->setUserPerm( [ "createpage" ] ); + $this->overrideUserPermissions( $this->user, [ "createpage" ] ); $this->setTitle( NS_MAIN, "test page" ); $this->title->mTitleProtection['permission'] = ''; $this->title->mTitleProtection['user'] = $this->user->getId(); @@ -916,75 +960,85 @@ class PermissionManagerTest extends MediaWikiLangTestCase { $this->title->mCascadeRestriction = false; $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'create', $this->user, $this->title ) ); $this->assertEquals( false, - $this->permissionManager->userCan( 'create', $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->userCan( + 'create', $this->user, $this->title ) ); $this->title->mTitleProtection['permission'] = 'editprotected'; - $this->setUserPerm( [ 'createpage', 'protect' ] ); + $this->overrideUserPermissions( $this->user, [ 'createpage', 'protect' ] ); $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'create', $this->user, $this->title ) ); $this->assertEquals( false, - $this->permissionManager->userCan( 'create', $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->userCan( + 'create', $this->user, $this->title ) ); - $this->setUserPerm( [ 'createpage', 'editprotected' ] ); + $this->overrideUserPermissions( $this->user, [ 'createpage', 'editprotected' ] ); $this->assertEquals( [], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'create', $this->user, $this->title ) ); $this->assertEquals( true, - $this->permissionManager->userCan( 'create', $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->userCan( + 'create', $this->user, $this->title ) ); - $this->setUserPerm( [ 'createpage' ] ); + $this->overrideUserPermissions( $this->user, [ 'createpage' ] ); $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'create', $this->user, $this->title ) ); $this->assertEquals( false, - $this->permissionManager->userCan( 'create', $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->userCan( + 'create', $this->user, $this->title ) ); $this->setTitle( NS_MEDIA, "test page" ); - $this->setUserPerm( [ "move" ] ); + $this->overrideUserPermissions( $this->user, [ "move" ] ); $this->assertEquals( false, - $this->permissionManager->userCan( 'move', $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->userCan( + 'move', $this->user, $this->title ) ); $this->assertEquals( [ [ 'immobile-source-namespace', 'Media' ] ], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move', $this->user, $this->title ) ); $this->setTitle( NS_HELP, "test page" ); $this->assertEquals( [], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move', $this->user, $this->title ) ); $this->assertEquals( true, - $this->permissionManager->userCan( 'move', $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->userCan( + 'move', $this->user, $this->title ) ); $this->title->mInterwiki = "no"; $this->assertEquals( [ [ 'immobile-source-page' ] ], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move', $this->user, $this->title ) ); $this->assertEquals( false, - $this->permissionManager->userCan( 'move', $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->userCan( + 'move', $this->user, $this->title ) ); $this->setTitle( NS_MEDIA, "test page" ); $this->assertEquals( false, - $this->permissionManager->userCan( 'move-target', $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->userCan( + 'move-target', $this->user, $this->title ) ); $this->assertEquals( [ [ 'immobile-target-namespace', 'Media' ] ], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move-target', $this->user, $this->title ) ); $this->setTitle( NS_HELP, "test page" ); $this->assertEquals( [], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move-target', $this->user, $this->title ) ); $this->assertEquals( true, - $this->permissionManager->userCan( 'move-target', $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->userCan( + 'move-target', $this->user, $this->title ) ); $this->title->mInterwiki = "no"; $this->assertEquals( [ [ 'immobile-target-page' ] ], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move-target', $this->user, $this->title ) ); $this->assertEquals( false, - $this->permissionManager->userCan( 'move-target', $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->userCan( + 'move-target', $this->user, $this->title ) ); } /** @@ -997,10 +1051,7 @@ class PermissionManagerTest extends MediaWikiLangTestCase { 'wgBlockDisablesLogin' => false, ] ); - $this->overrideMwServices(); - $this->permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); - - $this->setUserPerm( [ + $this->overrideUserPermissions( $this->user, [ 'createpage', 'edit', 'move', @@ -1013,24 +1064,32 @@ class PermissionManagerTest extends MediaWikiLangTestCase { # $wgEmailConfirmToEdit only applies to 'edit' action $this->assertEquals( [], - $this->permissionManager->getPermissionErrors( 'move-target', - $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors( + 'move-target', $this->user, $this->title ) ); $this->assertContains( [ 'confirmedittext' ], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'edit', $this->user, $this->title ) ); $this->setMwGlobals( 'wgEmailConfirmToEdit', false ); - $this->overrideMwServices(); - $this->permissionManager = MediaWikiServices::getInstance()->getPermissionManager(); + $this->resetServices(); + $this->overrideUserPermissions( $this->user, [ + 'createpage', + 'edit', + 'move', + 'rollback', + 'patrol', + 'upload', + 'purge' + ] ); $this->assertNotContains( [ 'confirmedittext' ], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'edit', $this->user, $this->title ) ); # $wgEmailConfirmToEdit && !$user->isEmailConfirmed() && $action != 'createaccount' $this->assertEquals( [], - $this->permissionManager->getPermissionErrors( 'move-target', - $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors( + 'move-target', $this->user, $this->title ) ); global $wgLang; $prev = time(); @@ -1049,13 +1108,13 @@ class PermissionManagerTest extends MediaWikiLangTestCase { '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1', 'Useruser', null, 'infinite', '127.0.8.1', $wgLang->timeanddate( wfTimestamp( TS_MW, $prev ), true ) ] ], - $this->permissionManager->getPermissionErrors( 'move-target', - $this->user, $this->title ) ); + MediaWikiServices::getInstance()->getPermissionManager()->getPermissionErrors( + 'move-target', $this->user, $this->title ) ); - $this->assertEquals( false, $this->permissionManager + $this->assertEquals( false, MediaWikiServices::getInstance()->getPermissionManager() ->userCan( 'move-target', $this->user, $this->title ) ); // quickUserCan should ignore user blocks - $this->assertEquals( true, $this->permissionManager + $this->assertEquals( true, MediaWikiServices::getInstance()->getPermissionManager() ->userCan( 'move-target', $this->user, $this->title, PermissionManager::RIGOR_QUICK ) ); @@ -1074,7 +1133,7 @@ class PermissionManagerTest extends MediaWikiLangTestCase { '[[User:Useruser|Useruser]]', 'no reason given', '127.0.0.1', 'Useruser', null, '23:00, 31 December 1969', '127.0.8.1', $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move-target', $this->user, $this->title ) ); # $action != 'read' && $action != 'createaccount' && $user->isBlockedFrom( $this ) # $user->blockedFor() == '' @@ -1096,22 +1155,22 @@ class PermissionManagerTest extends MediaWikiLangTestCase { $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ]; $this->assertEquals( $errors, - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'edit', $this->user, $this->title ) ); $this->assertEquals( $errors, - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move-target', $this->user, $this->title ) ); $this->assertEquals( $errors, - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'rollback', $this->user, $this->title ) ); $this->assertEquals( $errors, - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'patrol', $this->user, $this->title ) ); $this->assertEquals( $errors, - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'upload', $this->user, $this->title ) ); $this->assertEquals( [], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'purge', $this->user, $this->title ) ); // partial block message test @@ -1126,22 +1185,22 @@ class PermissionManagerTest extends MediaWikiLangTestCase { ] ); $this->assertEquals( [], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'edit', $this->user, $this->title ) ); $this->assertEquals( [], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move-target', $this->user, $this->title ) ); $this->assertEquals( [], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'rollback', $this->user, $this->title ) ); $this->assertEquals( [], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'patrol', $this->user, $this->title ) ); $this->assertEquals( [], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'upload', $this->user, $this->title ) ); $this->assertEquals( [], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'purge', $this->user, $this->title ) ); $this->user->mBlock->setRestrictions( [ @@ -1154,22 +1213,22 @@ class PermissionManagerTest extends MediaWikiLangTestCase { $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ]; $this->assertEquals( $errors, - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'edit', $this->user, $this->title ) ); $this->assertEquals( $errors, - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'move-target', $this->user, $this->title ) ); $this->assertEquals( $errors, - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'rollback', $this->user, $this->title ) ); $this->assertEquals( $errors, - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'patrol', $this->user, $this->title ) ); $this->assertEquals( [], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'upload', $this->user, $this->title ) ); $this->assertEquals( [], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'purge', $this->user, $this->title ) ); // Test no block. @@ -1177,7 +1236,7 @@ class PermissionManagerTest extends MediaWikiLangTestCase { $this->user->mBlock = null; $this->assertEquals( [], - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'edit', $this->user, $this->title ) ); } @@ -1228,7 +1287,7 @@ class PermissionManagerTest extends MediaWikiLangTestCase { $wgLang->timeanddate( wfTimestamp( TS_MW, $now ), true ) ] ]; $this->assertEquals( $errors, - $this->permissionManager + MediaWikiServices::getInstance()->getPermissionManager() ->getPermissionErrors( 'tester', $this->user, $this->title ) ); } @@ -1243,7 +1302,7 @@ class PermissionManagerTest extends MediaWikiLangTestCase { //$this->assertSame( '', $user->blockedBy(), 'sanity check' ); //$this->assertSame( '', $user->blockedFor(), 'sanity check' ); //$this->assertFalse( (bool)$user->isHidden(), 'sanity check' ); - $this->assertFalse( $this->permissionManager + $this->assertFalse( MediaWikiServices::getInstance()->getPermissionManager() ->isBlockedFrom( $user, $ut ), 'sanity check' ); // Block the user @@ -1264,7 +1323,8 @@ class PermissionManagerTest extends MediaWikiLangTestCase { //$this->assertSame( $blocker->getName(), $user->blockedBy() ); //$this->assertSame( 'Because', $user->blockedFor() ); //$this->assertTrue( (bool)$user->isHidden() ); - $this->assertTrue( $this->permissionManager->isBlockedFrom( $user, $ut ) ); + $this->assertTrue( MediaWikiServices::getInstance()->getPermissionManager() + ->isBlockedFrom( $user, $ut ) ); // Unblock $block->delete(); @@ -1275,7 +1335,8 @@ class PermissionManagerTest extends MediaWikiLangTestCase { //$this->assertSame( '', $user->blockedBy() ); //$this->assertSame( '', $user->blockedFor() ); //$this->assertFalse( (bool)$user->isHidden() ); - $this->assertFalse( $this->permissionManager->isBlockedFrom( $user, $ut ) ); + $this->assertFalse( MediaWikiServices::getInstance()->getPermissionManager() + ->isBlockedFrom( $user, $ut ) ); } /** @@ -1325,7 +1386,8 @@ class PermissionManagerTest extends MediaWikiLangTestCase { $block->insert(); try { - $this->assertSame( $expect, $this->permissionManager->isBlockedFrom( $user, $title ) ); + $this->assertSame( $expect, MediaWikiServices::getInstance()->getPermissionManager() + ->isBlockedFrom( $user, $title ) ); } finally { $block->delete(); } @@ -1408,4 +1470,187 @@ class PermissionManagerTest extends MediaWikiLangTestCase { ]; } + /** + * @covers \MediaWiki\Permissions\PermissionManager::getUserPermissions + */ + public function testGetUserPermissions() { + $user = $this->getTestUser( [ 'unittesters' ] )->getUser(); + $rights = MediaWikiServices::getInstance()->getPermissionManager() + ->getUserPermissions( $user ); + $this->assertContains( 'runtest', $rights ); + $this->assertNotContains( 'writetest', $rights ); + $this->assertNotContains( 'modifytest', $rights ); + $this->assertNotContains( 'nukeworld', $rights ); + } + + /** + * @covers \MediaWiki\Permissions\PermissionManager::getUserPermissions + */ + public function testGetUserPermissionsHooks() { + $user = $this->getTestUser( [ 'unittesters', 'testwriters' ] )->getUser(); + $userWrapper = TestingAccessWrapper::newFromObject( $user ); + + $rights = MediaWikiServices::getInstance()->getPermissionManager() + ->getUserPermissions( $user ); + $this->assertContains( 'test', $rights, 'sanity check' ); + $this->assertContains( 'runtest', $rights, 'sanity check' ); + $this->assertContains( 'writetest', $rights, 'sanity check' ); + $this->assertNotContains( 'nukeworld', $rights, 'sanity check' ); + + // Add a hook manipluating the rights + $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'UserGetRights' => [ function ( $user, &$rights ) { + $rights[] = 'nukeworld'; + $rights = array_diff( $rights, [ 'writetest' ] ); + } ] ] ); + + $this->resetServices(); + $rights = MediaWikiServices::getInstance()->getPermissionManager() + ->getUserPermissions( $user ); + $this->assertContains( 'test', $rights ); + $this->assertContains( 'runtest', $rights ); + $this->assertNotContains( 'writetest', $rights ); + $this->assertContains( 'nukeworld', $rights ); + + // Add a Session that limits rights + $mock = $this->getMockBuilder( stdClass::class ) + ->setMethods( [ 'getAllowedUserRights', 'deregisterSession', 'getSessionId' ] ) + ->getMock(); + $mock->method( 'getAllowedUserRights' )->willReturn( [ 'test', 'writetest' ] ); + $mock->method( 'getSessionId' )->willReturn( + new SessionId( str_repeat( 'X', 32 ) ) + ); + $session = TestUtils::getDummySession( $mock ); + $mockRequest = $this->getMockBuilder( FauxRequest::class ) + ->setMethods( [ 'getSession' ] ) + ->getMock(); + $mockRequest->method( 'getSession' )->willReturn( $session ); + $userWrapper->mRequest = $mockRequest; + + $this->resetServices(); + $rights = MediaWikiServices::getInstance()->getPermissionManager() + ->getUserPermissions( $user ); + $this->assertContains( 'test', $rights ); + $this->assertNotContains( 'runtest', $rights ); + $this->assertNotContains( 'writetest', $rights ); + $this->assertNotContains( 'nukeworld', $rights ); + } + + /** + * @covers \MediaWiki\Permissions\PermissionManager::getGroupPermissions + */ + public function testGroupPermissions() { + $rights = MediaWikiServices::getInstance()->getPermissionManager() + ->getGroupPermissions( [ 'unittesters' ] ); + $this->assertContains( 'runtest', $rights ); + $this->assertNotContains( 'writetest', $rights ); + $this->assertNotContains( 'modifytest', $rights ); + $this->assertNotContains( 'nukeworld', $rights ); + + $rights = MediaWikiServices::getInstance()->getPermissionManager() + ->getGroupPermissions( [ 'unittesters', 'testwriters' ] ); + $this->assertContains( 'runtest', $rights ); + $this->assertContains( 'writetest', $rights ); + $this->assertContains( 'modifytest', $rights ); + $this->assertNotContains( 'nukeworld', $rights ); + } + + /** + * @covers \MediaWiki\Permissions\PermissionManager::getGroupPermissions + */ + public function testRevokePermissions() { + $rights = MediaWikiServices::getInstance()->getPermissionManager() + ->getGroupPermissions( [ 'unittesters', 'formertesters' ] ); + $this->assertNotContains( 'runtest', $rights ); + $this->assertNotContains( 'writetest', $rights ); + $this->assertNotContains( 'modifytest', $rights ); + $this->assertNotContains( 'nukeworld', $rights ); + } + + /** + * @dataProvider provideGetGroupsWithPermission + * @covers \MediaWiki\Permissions\PermissionManager::getGroupsWithPermission + */ + public function testGetGroupsWithPermission( $expected, $right ) { + $result = MediaWikiServices::getInstance()->getPermissionManager() + ->getGroupsWithPermission( $right ); + sort( $result ); + sort( $expected ); + + $this->assertEquals( $expected, $result, "Groups with permission $right" ); + } + + public static function provideGetGroupsWithPermission() { + return [ + [ + [ 'unittesters', 'testwriters' ], + 'test' + ], + [ + [ 'unittesters' ], + 'runtest' + ], + [ + [ 'testwriters' ], + 'writetest' + ], + [ + [ 'testwriters' ], + 'modifytest' + ], + ]; + } + + /** + * @covers \MediaWiki\Permissions\PermissionManager::userHasRight + */ + public function testUserHasRight() { + $result = MediaWikiServices::getInstance()->getPermissionManager()->userHasRight( + $this->getTestUser( 'unittesters' )->getUser(), + 'test' + ); + $this->assertTrue( $result ); + + $result = MediaWikiServices::getInstance()->getPermissionManager()->userHasRight( + $this->getTestUser( 'formertesters' )->getUser(), + 'runtest' + ); + $this->assertFalse( $result ); + + $result = MediaWikiServices::getInstance()->getPermissionManager()->userHasRight( + $this->getTestUser( 'formertesters' )->getUser(), + '' + ); + $this->assertTrue( $result ); + } + + /** + * @covers \MediaWiki\Permissions\PermissionManager::groupHasPermission + */ + public function testGroupHasPermission() { + $result = MediaWikiServices::getInstance()->getPermissionManager()->groupHasPermission( + 'unittesters', + 'test' + ); + $this->assertTrue( $result ); + + $result = MediaWikiServices::getInstance()->getPermissionManager()->groupHasPermission( + 'formertesters', + 'runtest' + ); + $this->assertFalse( $result ); + } + + /** + * @covers \MediaWiki\Permissions\PermissionManager::isEveryoneAllowed + */ + public function testIsEveryoneAllowed() { + $result = MediaWikiServices::getInstance()->getPermissionManager() + ->isEveryoneAllowed( 'editmyoptions' ); + $this->assertTrue( $result ); + + $result = MediaWikiServices::getInstance()->getPermissionManager() + ->isEveryoneAllowed( 'test' ); + $this->assertFalse( $result ); + } + } diff --git a/tests/phpunit/includes/Revision/RevisionRendererTest.php b/tests/phpunit/includes/Revision/RevisionRendererTest.php index d57625b510..d1418c28c8 100644 --- a/tests/phpunit/includes/Revision/RevisionRendererTest.php +++ b/tests/phpunit/includes/Revision/RevisionRendererTest.php @@ -6,7 +6,6 @@ use CommentStoreComment; use Content; use Language; use LogicException; -use MediaWiki\Permissions\PermissionManager; use MediaWiki\Revision\MutableRevisionRecord; use MediaWiki\Revision\MainSlotRoleHandler; use MediaWiki\Revision\RevisionRecord; @@ -20,7 +19,6 @@ use ParserOptions; use ParserOutput; use PHPUnit\Framework\MockObject\MockObject; use Title; -use User; use Wikimedia\Rdbms\IDatabase; use Wikimedia\Rdbms\ILoadBalancer; use WikitextContent; @@ -30,20 +28,6 @@ use WikitextContent; */ class RevisionRendererTest extends MediaWikiTestCase { - /** @var PermissionManager|\PHPUnit_Framework_MockObject_MockObject $permissionManagerMock */ - private $permissionManagerMock; - - protected function setUp() { - parent::setUp(); - - $this->permissionManagerMock = $this->createMock( PermissionManager::class ); - $this->overrideMwServices( null, [ - 'PermissionManager' => function (): PermissionManager { - return $this->permissionManagerMock; - } - ] ); - } - /** * @param int $articleId * @param int $revisionId @@ -88,13 +72,9 @@ class RevisionRendererTest extends MediaWikiTestCase { return $mock->getArticleID() === $other->getArticleID(); } ); - $this->permissionManagerMock->expects( $this->any() ) - ->method( 'userCan' ) - ->willReturnCallback( - function ( $perm, User $user ) { - return $user->isAllowed( $perm ); - } - ); + $mock->expects( $this->any() ) + ->method( 'getRestrictions' ) + ->willReturn( [] ); return $mock; } @@ -383,6 +363,7 @@ class RevisionRendererTest extends MediaWikiTestCase { $sysop = $this->getTestUser( [ 'sysop' ] )->getUser(); // privileged! $rr = $renderer->getRenderedRevision( $rev, $options, $sysop ); + $this->assertNotNull( $rr, 'getRenderedRevision' ); $this->assertTrue( $rr->isContentDeleted(), 'isContentDeleted' ); $this->assertSame( $rev, $rr->getRevision() ); diff --git a/tests/phpunit/includes/RevisionDbTestBase.php b/tests/phpunit/includes/RevisionDbTestBase.php index bbd034a30d..2d141e6ba6 100644 --- a/tests/phpunit/includes/RevisionDbTestBase.php +++ b/tests/phpunit/includes/RevisionDbTestBase.php @@ -1539,8 +1539,7 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase { public function testUserCanBitfield( $bitField, $field, $userGroups, $title, $expected ) { $title = Title::newFromText( $title ); - $this->setMwGlobals( - 'wgGroupPermissions', + $this->setGroupPermissions( [ 'sysop' => [ 'deletedtext' => true, @@ -1592,8 +1591,7 @@ abstract class RevisionDbTestBase extends MediaWikiTestCase { * @covers Revision::userCan */ public function testUserCan( $bitField, $field, $userGroups, $expected ) { - $this->setMwGlobals( - 'wgGroupPermissions', + $this->setGroupPermissions( [ 'sysop' => [ 'deletedtext' => true, diff --git a/tests/phpunit/includes/TemplateCategoriesTest.php b/tests/phpunit/includes/TemplateCategoriesTest.php index ebd8dbd3da..04addab4a6 100644 --- a/tests/phpunit/includes/TemplateCategoriesTest.php +++ b/tests/phpunit/includes/TemplateCategoriesTest.php @@ -15,7 +15,7 @@ class TemplateCategoriesTest extends MediaWikiLangTestCase { */ public function testTemplateCategories() { $user = new User(); - $user->mRights = [ 'createpage', 'edit', 'purge', 'delete' ]; + $this->overrideUserPermissions( $user, [ 'createpage', 'edit', 'purge', 'delete' ] ); $title = Title::newFromText( "Categorized from template" ); $page = WikiPage::factory( $title ); diff --git a/tests/phpunit/includes/TitlePermissionTest.php b/tests/phpunit/includes/TitlePermissionTest.php index e09546e7ee..150e2ed14a 100644 --- a/tests/phpunit/includes/TitlePermissionTest.php +++ b/tests/phpunit/includes/TitlePermissionTest.php @@ -72,17 +72,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->user = $this->userUser; } - $this->overrideMwServices(); - } - - protected function setUserPerm( $perm ) { - // Setting member variables is evil!!! - - if ( is_array( $perm ) ) { - $this->user->mRights = $perm; - } else { - $this->user->mRights = [ $perm ]; - } + $this->resetServices(); } protected function setTitle( $ns, $title = "Main_Page" ) { @@ -114,139 +104,139 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->setUser( 'anon' ); $this->setTitle( NS_TALK ); - $this->setUserPerm( "createtalk" ); + $this->overrideUserPermissions( $this->user, "createtalk" ); $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); $this->assertEquals( [], $res ); $this->setTitle( NS_TALK ); - $this->setUserPerm( "createpage" ); + $this->overrideUserPermissions( $this->user, "createpage" ); $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); $this->assertEquals( [ [ "nocreatetext" ] ], $res ); $this->setTitle( NS_TALK ); - $this->setUserPerm( "" ); + $this->overrideUserPermissions( $this->user, "" ); $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); $this->assertEquals( [ [ 'nocreatetext' ] ], $res ); $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createpage" ); + $this->overrideUserPermissions( $this->user, "createpage" ); $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); $this->assertEquals( [], $res ); $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createtalk" ); + $this->overrideUserPermissions( $this->user, "createtalk" ); $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); $this->assertEquals( [ [ 'nocreatetext' ] ], $res ); $this->setUser( $this->userName ); $this->setTitle( NS_TALK ); - $this->setUserPerm( "createtalk" ); + $this->overrideUserPermissions( $this->user, "createtalk" ); $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); $this->assertEquals( [], $res ); $this->setTitle( NS_TALK ); - $this->setUserPerm( "createpage" ); + $this->overrideUserPermissions( $this->user, "createpage" ); $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res ); $this->setTitle( NS_TALK ); - $this->setUserPerm( "" ); + $this->overrideUserPermissions( $this->user ); $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res ); $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createpage" ); + $this->overrideUserPermissions( $this->user, "createpage" ); $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); $this->assertEquals( [], $res ); $this->setTitle( NS_MAIN ); - $this->setUserPerm( "createtalk" ); + $this->overrideUserPermissions( $this->user, "createtalk" ); $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res ); $this->setTitle( NS_MAIN ); - $this->setUserPerm( "" ); + $this->overrideUserPermissions( $this->user ); $res = $this->title->getUserPermissionsErrors( 'create', $this->user ); $this->assertEquals( [ [ 'nocreate-loggedin' ] ], $res ); $this->setUser( 'anon' ); $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "" ); + $this->overrideUserPermissions( $this->user ); $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); $this->assertEquals( [ [ 'cant-move-user-page' ], [ 'movenologintext' ] ], $res ); $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "" ); + $this->overrideUserPermissions( $this->user ); $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); $this->assertEquals( [ [ 'movenologintext' ] ], $res ); $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "move-rootuserpages" ); + $this->overrideUserPermissions( $this->user, "move-rootuserpages" ); $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); $this->assertEquals( [ [ 'movenologintext' ] ], $res ); $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "move-rootuserpages" ); + $this->overrideUserPermissions( $this->user, "move-rootuserpages" ); $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); $this->assertEquals( [ [ 'movenologintext' ] ], $res ); $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "" ); + $this->overrideUserPermissions( $this->user, "" ); $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); $this->assertEquals( [ [ 'cant-move-user-page' ], [ 'movenologintext' ] ], $res ); $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "" ); + $this->overrideUserPermissions( $this->user, "" ); $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); $this->assertEquals( [ [ 'movenologintext' ] ], $res ); $this->setTitle( NS_USER, $this->userName . '' ); - $this->setUserPerm( "move-rootuserpages" ); + $this->overrideUserPermissions( $this->user, "move-rootuserpages" ); $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); $this->assertEquals( [ [ 'movenologintext' ] ], $res ); $this->setTitle( NS_USER, $this->userName . '/subpage' ); - $this->setUserPerm( "move-rootuserpages" ); + $this->overrideUserPermissions( $this->user, "move-rootuserpages" ); $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); $this->assertEquals( [ [ 'movenologintext' ] ], $res ); $this->setUser( $this->userName ); $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "" ); + $this->overrideUserPermissions( $this->user ); $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); $this->assertEquals( [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ], $res ); $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "movefile" ); + $this->overrideUserPermissions( $this->user, "movefile" ); $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); $this->assertEquals( [ [ 'movenotallowed' ] ], $res ); $this->setUser( 'anon' ); $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "" ); + $this->overrideUserPermissions( $this->user ); $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); $this->assertEquals( [ [ 'movenotallowedfile' ], [ 'movenologintext' ] ], $res ); $this->setTitle( NS_FILE, "img.png" ); - $this->setUserPerm( "movefile" ); + $this->overrideUserPermissions( $this->user, "movefile" ); $res = $this->title->getUserPermissionsErrors( 'move', $this->user ); $this->assertEquals( [ [ 'movenologintext' ] ], $res ); $this->setUser( $this->userName ); - $this->setUserPerm( "move" ); + $this->overrideUserPermissions( $this->user, "move" ); $this->runGroupPermissions( 'move', [ [ 'movenotallowedfile' ] ] ); - $this->setUserPerm( "" ); + $this->overrideUserPermissions( $this->user ); $this->runGroupPermissions( 'move', [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ] ); $this->setUser( 'anon' ); - $this->setUserPerm( "move" ); + $this->overrideUserPermissions( $this->user, "move" ); $this->runGroupPermissions( 'move', [ [ 'movenotallowedfile' ] ] ); - $this->setUserPerm( "" ); + $this->overrideUserPermissions( $this->user ); $this->runGroupPermissions( 'move', [ [ 'movenotallowedfile' ], [ 'movenotallowed' ] ], @@ -259,51 +249,51 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->setTitle( NS_MAIN ); $this->setUser( 'anon' ); - $this->setUserPerm( "move" ); + $this->overrideUserPermissions( $this->user, "move" ); $this->runGroupPermissions( 'move', [] ); - $this->setUserPerm( "" ); + $this->overrideUserPermissions( $this->user, "" ); $this->runGroupPermissions( 'move', [ [ 'movenotallowed' ] ], [ [ 'movenologintext' ] ] ); $this->setUser( $this->userName ); - $this->setUserPerm( "" ); + $this->overrideUserPermissions( $this->user, "" ); $this->runGroupPermissions( 'move', [ [ 'movenotallowed' ] ] ); - $this->setUserPerm( "move" ); + $this->overrideUserPermissions( $this->user, "move" ); $this->runGroupPermissions( 'move', [] ); $this->setUser( 'anon' ); - $this->setUserPerm( 'move' ); + $this->overrideUserPermissions( $this->user, 'move' ); $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); $this->assertEquals( [], $res ); - $this->setUserPerm( '' ); + $this->overrideUserPermissions( $this->user ); $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); $this->assertEquals( [ [ 'movenotallowed' ] ], $res ); } $this->setTitle( NS_USER ); $this->setUser( $this->userName ); - $this->setUserPerm( [ "move", "move-rootuserpages" ] ); + $this->overrideUserPermissions( $this->user, [ "move", "move-rootuserpages" ] ); $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); $this->assertEquals( [], $res ); - $this->setUserPerm( "move" ); + $this->overrideUserPermissions( $this->user, "move" ); $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); $this->assertEquals( [ [ 'cant-move-to-user-page' ] ], $res ); $this->setUser( 'anon' ); - $this->setUserPerm( [ "move", "move-rootuserpages" ] ); + $this->overrideUserPermissions( $this->user, [ "move", "move-rootuserpages" ] ); $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); $this->assertEquals( [], $res ); $this->setTitle( NS_USER, "User/subpage" ); - $this->setUserPerm( [ "move", "move-rootuserpages" ] ); + $this->overrideUserPermissions( $this->user, [ "move", "move-rootuserpages" ] ); $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); $this->assertEquals( [], $res ); - $this->setUserPerm( "move" ); + $this->overrideUserPermissions( $this->user, "move" ); $res = $this->title->getUserPermissionsErrors( 'move-target', $this->user ); $this->assertEquals( [], $res ); @@ -329,7 +319,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { ]; foreach ( [ "edit", "protect", "" ] as $action ) { - $this->setUserPerm( null ); + $this->overrideUserPermissions( $this->user ); $this->assertEquals( $check[$action][0], $this->title->getUserPermissionsErrors( $action, $this->user, true ) ); $this->assertEquals( $check[$action][0], @@ -341,15 +331,19 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $old = $wgGroupPermissions; $wgGroupPermissions = []; + $this->resetServices(); + $this->assertEquals( $check[$action][1], $this->title->getUserPermissionsErrors( $action, $this->user, true ) ); $this->assertEquals( $check[$action][1], $this->title->getUserPermissionsErrors( $action, $this->user, 'full' ) ); $this->assertEquals( $check[$action][1], $this->title->getUserPermissionsErrors( $action, $this->user, 'secure' ) ); + $wgGroupPermissions = $old; + $this->resetServices(); - $this->setUserPerm( $action ); + $this->overrideUserPermissions( $this->user, $action ); $this->assertEquals( $check[$action][2], $this->title->getUserPermissionsErrors( $action, $this->user, true ) ); $this->assertEquals( $check[$action][2], @@ -357,7 +351,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->assertEquals( $check[$action][2], $this->title->getUserPermissionsErrors( $action, $this->user, 'secure' ) ); - $this->setUserPerm( $action ); + $this->overrideUserPermissions( $this->user, $action ); $this->assertEquals( $check[$action][3], $this->title->userCan( $action, $this->user, true ) ); $this->assertEquals( $check[$action][3], @@ -373,23 +367,39 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $result2 = $result; } + // XXX: there could be a better way to handle this, but since we need to + // override PermissionManager service each time globals are changed + // and in the same time we need to keep user permissions overrides from the outside + // the best we can do inside this method is to save & restore faked user perms + + $userPermsOverrides = MediaWikiServices::getInstance()->getPermissionManager() + ->getUserPermissions( $this->user ); + $wgGroupPermissions['autoconfirmed']['move'] = false; $wgGroupPermissions['user']['move'] = false; + $this->resetServices(); + $this->overrideUserPermissions( $this->user, $userPermsOverrides ); $res = $this->title->getUserPermissionsErrors( $action, $this->user ); $this->assertEquals( $result, $res ); $wgGroupPermissions['autoconfirmed']['move'] = true; $wgGroupPermissions['user']['move'] = false; + $this->resetServices(); + $this->overrideUserPermissions( $this->user, $userPermsOverrides ); $res = $this->title->getUserPermissionsErrors( $action, $this->user ); $this->assertEquals( $result2, $res ); $wgGroupPermissions['autoconfirmed']['move'] = true; $wgGroupPermissions['user']['move'] = true; + $this->resetServices(); + $this->overrideUserPermissions( $this->user, $userPermsOverrides ); $res = $this->title->getUserPermissionsErrors( $action, $this->user ); $this->assertEquals( $result2, $res ); $wgGroupPermissions['autoconfirmed']['move'] = false; $wgGroupPermissions['user']['move'] = true; + $this->resetServices(); + $this->overrideUserPermissions( $this->user, $userPermsOverrides ); $res = $this->title->getUserPermissionsErrors( $action, $this->user ); $this->assertEquals( $result2, $res ); } @@ -409,42 +419,42 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); $this->setTitle( NS_MAIN ); - $this->setUserPerm( 'bogus' ); + $this->overrideUserPermissions( $this->user, 'bogus' ); $this->assertEquals( [], $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); $this->setTitle( NS_MAIN ); - $this->setUserPerm( '' ); + $this->overrideUserPermissions( $this->user ); $this->assertEquals( [ [ 'badaccess-group0' ] ], $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); $wgNamespaceProtection[NS_USER] = [ 'bogus' ]; $this->setTitle( NS_USER ); - $this->setUserPerm( '' ); + $this->overrideUserPermissions( $this->user ); $this->assertEquals( [ [ 'badaccess-group0' ], [ 'namespaceprotected', 'User', 'bogus' ] ], $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); $this->setTitle( NS_MEDIAWIKI ); - $this->setUserPerm( 'bogus' ); + $this->overrideUserPermissions( $this->user, 'bogus' ); $this->assertEquals( [ [ 'protectedinterface', 'bogus' ] ], $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); $this->setTitle( NS_MEDIAWIKI ); - $this->setUserPerm( 'bogus' ); + $this->overrideUserPermissions( $this->user, 'bogus' ); $this->assertEquals( [ [ 'protectedinterface', 'bogus' ] ], $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); $wgNamespaceProtection = null; - $this->setUserPerm( 'bogus' ); + $this->overrideUserPermissions( $this->user, 'bogus' ); $this->assertEquals( [], $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); $this->assertEquals( true, $this->title->userCan( 'bogus', $this->user ) ); - $this->setUserPerm( '' ); + $this->overrideUserPermissions( $this->user ); $this->assertEquals( [ [ 'badaccess-group0' ] ], $this->title->getUserPermissionsErrors( 'bogus', $this->user ) ); $this->assertEquals( false, @@ -645,39 +655,39 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $resultUserJs, $resultPatrol ) { - $this->setUserPerm( '' ); + $this->overrideUserPermissions( $this->user ); $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user ); $this->assertEquals( $resultNone, $result ); - $this->setUserPerm( 'editmyusercss' ); + $this->overrideUserPermissions( $this->user, 'editmyusercss' ); $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user ); $this->assertEquals( $resultMyCss, $result ); - $this->setUserPerm( 'editmyuserjson' ); + $this->overrideUserPermissions( $this->user, 'editmyuserjson' ); $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user ); $this->assertEquals( $resultMyJson, $result ); - $this->setUserPerm( 'editmyuserjs' ); + $this->overrideUserPermissions( $this->user, 'editmyuserjs' ); $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user ); $this->assertEquals( $resultMyJs, $result ); - $this->setUserPerm( 'editusercss' ); + $this->overrideUserPermissions( $this->user, 'editusercss' ); $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user ); $this->assertEquals( $resultUserCss, $result ); - $this->setUserPerm( 'edituserjson' ); + $this->overrideUserPermissions( $this->user, 'edituserjson' ); $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user ); $this->assertEquals( $resultUserJson, $result ); - $this->setUserPerm( 'edituserjs' ); + $this->overrideUserPermissions( $this->user, 'edituserjs' ); $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user ); $this->assertEquals( $resultUserJs, $result ); - $this->setUserPerm( '' ); + $this->overrideUserPermissions( $this->user ); $result = $this->title->getUserPermissionsErrors( 'patrol', $this->user ); $this->assertEquals( reset( $resultPatrol[0] ), reset( $result[0] ) ); - $this->setUserPerm( [ 'edituserjs', 'edituserjson', 'editusercss' ] ); + $this->overrideUserPermissions( $this->user, [ 'edituserjs', 'edituserjson', 'editusercss' ] ); $result = $this->title->getUserPermissionsErrors( 'bogus', $this->user ); $this->assertEquals( [ [ 'badaccess-group0' ] ], $result ); } @@ -697,7 +707,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->setTitle( NS_MAIN ); $this->title->mRestrictionsLoaded = true; - $this->setUserPerm( "edit" ); + $this->overrideUserPermissions( $this->user, "edit" ); $this->title->mRestrictions = [ "bogus" => [ 'bogus', "sysop", "protect", "" ] ]; $this->assertEquals( [], @@ -720,7 +730,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { [ 'protectedpagetext', 'protect', 'edit' ] ], $this->title->getUserPermissionsErrors( 'edit', $this->user ) ); - $this->setUserPerm( "" ); + $this->overrideUserPermissions( $this->user ); $this->assertEquals( [ [ 'badaccess-group0' ], [ 'protectedpagetext', 'bogus', 'bogus' ], [ 'protectedpagetext', 'editprotected', 'bogus' ], @@ -733,7 +743,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { [ 'protectedpagetext', 'protect', 'edit' ] ], $this->title->getUserPermissionsErrors( 'edit', $this->user ) ); - $this->setUserPerm( [ "edit", "editprotected" ] ); + $this->overrideUserPermissions( $this->user, [ "edit", "editprotected" ] ); $this->assertEquals( [ [ 'badaccess-group0' ], [ 'protectedpagetext', 'bogus', 'bogus' ], [ 'protectedpagetext', 'protect', 'bogus' ] ], @@ -746,7 +756,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->user ) ); $this->title->mCascadeRestriction = true; - $this->setUserPerm( "edit" ); + $this->overrideUserPermissions( $this->user, "edit" ); $this->assertEquals( false, $this->title->quickUserCan( 'bogus', $this->user ) ); $this->assertEquals( false, @@ -763,7 +773,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->title->getUserPermissionsErrors( 'edit', $this->user ) ); - $this->setUserPerm( [ "edit", "editprotected" ] ); + $this->overrideUserPermissions( $this->user, [ "edit", "editprotected" ] ); $this->assertEquals( false, $this->title->quickUserCan( 'bogus', $this->user ) ); $this->assertEquals( false, @@ -786,7 +796,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { */ public function testCascadingSourcesRestrictions() { $this->setTitle( NS_MAIN, "test page" ); - $this->setUserPerm( [ "edit", "bogus" ] ); + $this->overrideUserPermissions( $this->user, [ "edit", "bogus" ] ); $this->title->mCascadeSources = [ Title::makeTitle( NS_MAIN, "Bogus" ), @@ -816,7 +826,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { * @covers \MediaWiki\Permissions\PermissionManager::checkActionPermissions */ public function testActionPermissions() { - $this->setUserPerm( [ "createpage" ] ); + $this->overrideUserPermissions( $this->user, [ "createpage" ] ); $this->setTitle( NS_MAIN, "test page" ); $this->title->mTitleProtection['permission'] = ''; $this->title->mTitleProtection['user'] = $this->user->getId(); @@ -830,26 +840,26 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->title->userCan( 'create', $this->user ) ); $this->title->mTitleProtection['permission'] = 'editprotected'; - $this->setUserPerm( [ 'createpage', 'protect' ] ); + $this->overrideUserPermissions( $this->user, [ 'createpage', 'protect' ] ); $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ], $this->title->getUserPermissionsErrors( 'create', $this->user ) ); $this->assertEquals( false, $this->title->userCan( 'create', $this->user ) ); - $this->setUserPerm( [ 'createpage', 'editprotected' ] ); + $this->overrideUserPermissions( $this->user, [ 'createpage', 'editprotected' ] ); $this->assertEquals( [], $this->title->getUserPermissionsErrors( 'create', $this->user ) ); $this->assertEquals( true, $this->title->userCan( 'create', $this->user ) ); - $this->setUserPerm( [ 'createpage' ] ); + $this->overrideUserPermissions( $this->user, [ 'createpage' ] ); $this->assertEquals( [ [ 'titleprotected', 'Useruser', 'test' ] ], $this->title->getUserPermissionsErrors( 'create', $this->user ) ); $this->assertEquals( false, $this->title->userCan( 'create', $this->user ) ); $this->setTitle( NS_MEDIA, "test page" ); - $this->setUserPerm( [ "move" ] ); + $this->overrideUserPermissions( $this->user, [ "move" ] ); $this->assertEquals( false, $this->title->userCan( 'move', $this->user ) ); $this->assertEquals( [ [ 'immobile-source-namespace', 'Media' ] ], @@ -895,9 +905,12 @@ class TitlePermissionTest extends MediaWikiLangTestCase { 'wgEmailAuthentication' => true, 'wgBlockDisablesLogin' => false, ] ); - $this->overrideMwServices(); + $this->resetServices(); - $this->setUserPerm( [ 'createpage', 'edit', 'move', 'rollback', 'patrol', 'upload', 'purge' ] ); + $this->overrideUserPermissions( + $this->user, + [ 'createpage', 'edit', 'move', 'rollback', 'patrol', 'upload', 'purge' ] + ); $this->setTitle( NS_HELP, "test page" ); # $wgEmailConfirmToEdit only applies to 'edit' action @@ -907,7 +920,11 @@ class TitlePermissionTest extends MediaWikiLangTestCase { $this->title->getUserPermissionsErrors( 'edit', $this->user ) ); $this->setMwGlobals( 'wgEmailConfirmToEdit', false ); - $this->overrideMwServices(); + $this->resetServices(); + $this->overrideUserPermissions( + $this->user, + [ 'createpage', 'edit', 'move', 'rollback', 'patrol', 'upload', 'purge' ] + ); $this->assertNotContains( [ 'confirmedittext' ], $this->title->getUserPermissionsErrors( 'edit', $this->user ) ); @@ -1071,6 +1088,7 @@ class TitlePermissionTest extends MediaWikiLangTestCase { ], ], ] ); + $this->resetServices(); $now = time(); $this->user->mBlockedby = $this->user->getName(); diff --git a/tests/phpunit/includes/TitleTest.php b/tests/phpunit/includes/TitleTest.php index 529d9fb0dd..225a786b21 100644 --- a/tests/phpunit/includes/TitleTest.php +++ b/tests/phpunit/includes/TitleTest.php @@ -355,7 +355,7 @@ class TitleTest extends MediaWikiTestCase { // New anonymous user with no rights $user = new User; - $user->mRights = []; + $this->overrideUserPermissions( $user, [] ); $errors = $title->userCan( $action, $user ); if ( is_bool( $expected ) ) { diff --git a/tests/phpunit/includes/actions/ActionTest.php b/tests/phpunit/includes/actions/ActionTest.php index 5ad773681d..4d977cbf1e 100644 --- a/tests/phpunit/includes/actions/ActionTest.php +++ b/tests/phpunit/includes/actions/ActionTest.php @@ -190,14 +190,14 @@ class ActionTest extends MediaWikiTestCase { public function testCanExecute() { $user = $this->getTestUser()->getUser(); - $user->mRights = [ 'access' ]; + $this->overrideUserPermissions( $user, 'access' ); $action = Action::factory( 'access', $this->getPage(), $this->getContext() ); $this->assertNull( $action->canExecute( $user ) ); } public function testCanExecuteNoRight() { $user = $this->getTestUser()->getUser(); - $user->mRights = []; + $this->overrideUserPermissions( $user, [] ); $action = Action::factory( 'access', $this->getPage(), $this->getContext() ); try { @@ -209,7 +209,7 @@ class ActionTest extends MediaWikiTestCase { public function testCanExecuteRequiresUnblock() { $user = $this->getTestUser()->getUser(); - $user->mRights = []; + $this->overrideUserPermissions( $user, [] ); $page = $this->getExistingTestPage(); $action = Action::factory( 'unblock', $page, $this->getContext() ); diff --git a/tests/phpunit/includes/api/ApiBlockTest.php b/tests/phpunit/includes/api/ApiBlockTest.php index 43da9a95ba..b29d333cb2 100644 --- a/tests/phpunit/includes/api/ApiBlockTest.php +++ b/tests/phpunit/includes/api/ApiBlockTest.php @@ -150,6 +150,8 @@ class ApiBlockTest extends ApiTestCase { $this->setMwGlobals( 'wgRevokePermissions', [ 'user' => [ 'applychangetags' => true ] ] ); + $this->resetServices(); + $this->doBlock( [ 'tags' => 'custom tag' ] ); } @@ -160,6 +162,7 @@ class ApiBlockTest extends ApiTestCase { $this->mergeMwGlobalArrayValue( 'wgGroupPermissions', [ 'sysop' => $newPermissions ] ); + $this->resetServices(); $res = $this->doBlock( [ 'hidename' => '' ] ); $dbw = wfGetDB( DB_MASTER ); @@ -209,6 +212,8 @@ class ApiBlockTest extends ApiTestCase { $this->setMwGlobals( 'wgRevokePermissions', [ 'sysop' => [ 'blockemail' => true ] ] ); + $this->resetServices(); + $this->doBlock( [ 'noemail' => '' ] ); } diff --git a/tests/phpunit/includes/api/ApiDeleteTest.php b/tests/phpunit/includes/api/ApiDeleteTest.php index c68954c077..cc5dadaa93 100644 --- a/tests/phpunit/includes/api/ApiDeleteTest.php +++ b/tests/phpunit/includes/api/ApiDeleteTest.php @@ -143,6 +143,7 @@ class ApiDeleteTest extends ApiTestCase { ChangeTags::defineTag( 'custom tag' ); $this->setMwGlobals( 'wgRevokePermissions', [ 'user' => [ 'applychangetags' => true ] ] ); + $this->resetServices(); $this->editPage( $name, 'Some text' ); diff --git a/tests/phpunit/includes/api/ApiEditPageTest.php b/tests/phpunit/includes/api/ApiEditPageTest.php index d2762e0893..3badd2859a 100644 --- a/tests/phpunit/includes/api/ApiEditPageTest.php +++ b/tests/phpunit/includes/api/ApiEditPageTest.php @@ -39,6 +39,7 @@ class ApiEditPageTest extends ApiTestCase { $this->tablesUsed, [ 'change_tag', 'change_tag_def', 'logging' ] ); + $this->resetServices(); } public function testEdit() { @@ -1367,6 +1368,9 @@ class ApiEditPageTest extends ApiTestCase { ChangeTags::defineTag( 'custom tag' ); $this->setMwGlobals( 'wgRevokePermissions', [ 'user' => [ 'applychangetags' => true ] ] ); + // Supply services with updated globals + $this->resetServices(); + try { $this->doApiRequestWithToken( [ 'action' => 'edit', @@ -1545,6 +1549,8 @@ class ApiEditPageTest extends ApiTestCase { $this->setMwGlobals( 'wgRevokePermissions', [ 'user' => [ 'upload' => true ] ] ); + // Supply services with updated globals + $this->resetServices(); $this->doApiRequestWithToken( [ 'action' => 'edit', @@ -1560,6 +1566,8 @@ class ApiEditPageTest extends ApiTestCase { 'The content you supplied exceeds the article size limit of 1 kilobyte.' ); $this->setMwGlobals( 'wgMaxArticleSize', 1 ); + // Supply services with updated globals + $this->resetServices(); $text = str_repeat( '!', 1025 ); @@ -1577,6 +1585,8 @@ class ApiEditPageTest extends ApiTestCase { 'The action you have requested is limited to users in the group: ' ); $this->setMwGlobals( 'wgRevokePermissions', [ '*' => [ 'edit' => true ] ] ); + // Supply services with updated globals + $this->resetServices(); $this->doApiRequestWithToken( [ 'action' => 'edit', @@ -1593,6 +1603,8 @@ class ApiEditPageTest extends ApiTestCase { $this->setMwGlobals( 'wgRevokePermissions', [ 'user' => [ 'editcontentmodel' => true ] ] ); + // Supply services with updated globals + $this->resetServices(); $this->doApiRequestWithToken( [ 'action' => 'edit', diff --git a/tests/phpunit/includes/api/ApiMainTest.php b/tests/phpunit/includes/api/ApiMainTest.php index a5518a1252..580efcd933 100644 --- a/tests/phpunit/includes/api/ApiMainTest.php +++ b/tests/phpunit/includes/api/ApiMainTest.php @@ -141,6 +141,7 @@ class ApiMainTest extends ApiTestCase { public function testSetCacheModeUnrecognized() { $api = new ApiMain(); $api->setCacheMode( 'unrecognized' ); + $this->resetServices(); $this->assertSame( 'private', TestingAccessWrapper::newFromObject( $api )->mCacheMode, @@ -150,7 +151,6 @@ class ApiMainTest extends ApiTestCase { public function testSetCacheModePrivateWiki() { $this->setGroupPermissions( '*', 'read', false ); - $wrappedApi = TestingAccessWrapper::newFromObject( new ApiMain() ); $wrappedApi->setCacheMode( 'public' ); $this->assertSame( 'private', $wrappedApi->mCacheMode ); @@ -401,7 +401,7 @@ class ApiMainTest extends ApiTestCase { } else { $user = new User(); } - $user->mRights = $rights; + $this->overrideUserPermissions( $user, $rights ); try { $this->doApiRequest( [ 'action' => 'query', diff --git a/tests/phpunit/includes/api/ApiMoveTest.php b/tests/phpunit/includes/api/ApiMoveTest.php index d880923d3f..c98308cc88 100644 --- a/tests/phpunit/includes/api/ApiMoveTest.php +++ b/tests/phpunit/includes/api/ApiMoveTest.php @@ -294,6 +294,7 @@ class ApiMoveTest extends ApiTestCase { $name = ucfirst( __FUNCTION__ ); $this->mergeMwGlobalArrayValue( 'wgNamespacesWithSubpages', [ NS_MAIN => true ] ); + $this->resetServices(); $pages = [ $name, "$name/1", "$name/2", "Talk:$name", "Talk:$name/1", "Talk:$name/3" ]; $ids = []; @@ -379,7 +380,6 @@ class ApiMoveTest extends ApiTestCase { $name = ucfirst( __FUNCTION__ ); $this->setGroupPermissions( 'sysop', 'suppressredirect', false ); - $id = $this->createPage( $name ); $res = $this->doApiRequestWithToken( [ diff --git a/tests/phpunit/includes/api/ApiParseTest.php b/tests/phpunit/includes/api/ApiParseTest.php index 0011d7a2c8..a87160a1d8 100644 --- a/tests/phpunit/includes/api/ApiParseTest.php +++ b/tests/phpunit/includes/api/ApiParseTest.php @@ -121,7 +121,7 @@ class ApiParseTest extends ApiTestCase { $this->setMwGlobals( 'wgExtraInterlanguageLinkPrefixes', [ 'madeuplanguage' ] ); $this->tablesUsed[] = 'interwiki'; - $this->overrideMwServices(); + $this->resetServices(); } /** diff --git a/tests/phpunit/includes/api/ApiStashEditTest.php b/tests/phpunit/includes/api/ApiStashEditTest.php index 47a6d81d7a..ecb7e1ec41 100644 --- a/tests/phpunit/includes/api/ApiStashEditTest.php +++ b/tests/phpunit/includes/api/ApiStashEditTest.php @@ -307,6 +307,7 @@ class ApiStashEditTest extends ApiTestCase { // Nor does the original one if they become a bot $user->addGroup( 'bot' ); + MediaWikiServices::getInstance()->getPermissionManager()->invalidateUsersRightsCache(); $this->assertFalse( $this->doCheckCache( $user ), "We assume bots don't have cache entries" @@ -315,6 +316,7 @@ class ApiStashEditTest extends ApiTestCase { // But other groups are okay $user->removeGroup( 'bot' ); $user->addGroup( 'sysop' ); + MediaWikiServices::getInstance()->getPermissionManager()->invalidateUsersRightsCache(); $this->assertInstanceOf( stdClass::class, $this->doCheckCache( $user ) ); } diff --git a/tests/phpunit/includes/api/ApiUserrightsTest.php b/tests/phpunit/includes/api/ApiUserrightsTest.php index a1bafed78c..0d7ad0c502 100644 --- a/tests/phpunit/includes/api/ApiUserrightsTest.php +++ b/tests/phpunit/includes/api/ApiUserrightsTest.php @@ -1,6 +1,7 @@ mergeMwGlobalArrayValue( 'wgRemoveGroups', [ 'bureaucrat' => $remove ] ); } + + $this->resetServices(); } /** @@ -75,6 +78,7 @@ class ApiUserrightsTest extends ApiTestCase { $res = $this->doApiRequestWithToken( $params ); $user->clearInstanceCache(); + MediaWikiServices::getInstance()->getPermissionManager()->invalidateUsersRightsCache(); $this->assertSame( $expectedGroups, $user->getGroups() ); $this->assertArrayNotHasKey( 'warnings', $res[0] ); @@ -217,6 +221,7 @@ class ApiUserrightsTest extends ApiTestCase { ChangeTags::defineTag( 'custom tag' ); $this->setGroupPermissions( 'user', 'applychangetags', false ); + $this->resetServices(); $this->doFailedRightsChange( 'You do not have permission to apply change tags along with your changes.', diff --git a/tests/phpunit/includes/auth/AuthManagerTest.php b/tests/phpunit/includes/auth/AuthManagerTest.php index e6a1d3886c..fc6f688091 100644 --- a/tests/phpunit/includes/auth/AuthManagerTest.php +++ b/tests/phpunit/includes/auth/AuthManagerTest.php @@ -1446,6 +1446,7 @@ class AuthManagerTest extends \MediaWikiTestCase { ]; $block = new DatabaseBlock( $blockOptions ); $block->insert(); + $this->resetServices(); $status = $this->manager->checkAccountCreatePermissions( $user ); $this->assertFalse( $status->isOK() ); $this->assertTrue( $status->hasMessage( 'cantcreateaccount-text' ) ); @@ -1472,12 +1473,12 @@ class AuthManagerTest extends \MediaWikiTestCase { ], 'wgProxyWhitelist' => [], ] ); - $this->overrideMwServices(); + $this->resetServices(); $status = $this->manager->checkAccountCreatePermissions( new \User ); $this->assertFalse( $status->isOK() ); $this->assertTrue( $status->hasMessage( 'sorbs_create_account_reason' ) ); $this->setMwGlobals( 'wgProxyWhitelist', [ '127.0.0.1' ] ); - $this->overrideMwServices(); + $this->resetServices(); $status = $this->manager->checkAccountCreatePermissions( new \User ); $this->assertTrue( $status->isGood() ); } @@ -2365,6 +2366,8 @@ class AuthManagerTest extends \MediaWikiTestCase { $this->mergeMwGlobalArrayValue( 'wgObjectCaches', [ __METHOD__ => [ 'class' => 'HashBagOStuff' ] ] ); $this->setMwGlobals( [ 'wgMainCacheType' => __METHOD__ ] ); + // Supply services with updated globals + $this->resetServices(); // Set up lots of mocks... $mocks = []; diff --git a/tests/phpunit/includes/page/ArticleTablesTest.php b/tests/phpunit/includes/page/ArticleTablesTest.php index 34b25251c1..5c5ce5c292 100644 --- a/tests/phpunit/includes/page/ArticleTablesTest.php +++ b/tests/phpunit/includes/page/ArticleTablesTest.php @@ -4,6 +4,7 @@ * @group Database */ class ArticleTablesTest extends MediaWikiLangTestCase { + /** * Make sure that T16404 doesn't strike again. We don't want * templatelinks based on the user language when {{int:}} is used, only the @@ -16,7 +17,7 @@ class ArticleTablesTest extends MediaWikiLangTestCase { $title = Title::newFromText( 'T16404' ); $page = WikiPage::factory( $title ); $user = new User(); - $user->mRights = [ 'createpage', 'edit', 'purge' ]; + $this->overrideUserPermissions( $user, [ 'createpage', 'edit', 'purge' ] ); $this->setContentLang( 'es' ); $this->setUserLang( 'fr' ); diff --git a/tests/phpunit/includes/page/WikiPageDbTestBase.php b/tests/phpunit/includes/page/WikiPageDbTestBase.php index 3a3feeea11..ee6c227b60 100644 --- a/tests/phpunit/includes/page/WikiPageDbTestBase.php +++ b/tests/phpunit/includes/page/WikiPageDbTestBase.php @@ -1374,6 +1374,7 @@ more stuff // Now, try the rollback $admin->addGroup( 'sysop' ); // Make the test user a sysop + MediaWikiServices::getInstance()->getPermissionManager()->invalidateUsersRightsCache(); $token = $admin->getEditToken( 'rollback' ); $errors = $page->doRollback( $secondUser->getName(), diff --git a/tests/phpunit/includes/user/UserGroupMembershipTest.php b/tests/phpunit/includes/user/UserGroupMembershipTest.php index 4862747b4f..340a4c3106 100644 --- a/tests/phpunit/includes/user/UserGroupMembershipTest.php +++ b/tests/phpunit/includes/user/UserGroupMembershipTest.php @@ -46,6 +46,8 @@ class UserGroupMembershipTest extends MediaWikiTestCase { $this->userTester->addGroup( 'unittesters' ); $this->expiryTime = wfTimestamp( TS_MW, time() + 100500 ); $this->userTester->addGroup( 'testwriters', $this->expiryTime ); + + $this->resetServices(); } /** diff --git a/tests/phpunit/includes/user/UserTest.php b/tests/phpunit/includes/user/UserTest.php index 79c6e966af..5a978f93ba 100644 --- a/tests/phpunit/includes/user/UserTest.php +++ b/tests/phpunit/includes/user/UserTest.php @@ -129,12 +129,12 @@ class UserTest extends MediaWikiTestCase { $this->assertNotContains( 'nukeworld', $rights, 'sanity check' ); // Add a hook manipluating the rights - $this->mergeMwGlobalArrayValue( 'wgHooks', [ 'UserGetRights' => [ function ( $user, &$rights ) { + $this->setTemporaryHook( 'UserGetRights', function ( $user, &$rights ) { $rights[] = 'nukeworld'; $rights = array_diff( $rights, [ 'writetest' ] ); - } ] ] ); + } ); - $userWrapper->mRights = null; + $this->resetServices(); $rights = $user->getRights(); $this->assertContains( 'test', $rights ); $this->assertContains( 'runtest', $rights ); @@ -156,7 +156,7 @@ class UserTest extends MediaWikiTestCase { $mockRequest->method( 'getSession' )->willReturn( $session ); $userWrapper->mRequest = $mockRequest; - $userWrapper->mRights = null; + $this->resetServices(); $rights = $user->getRights(); $this->assertContains( 'test', $rights ); $this->assertNotContains( 'runtest', $rights ); @@ -928,9 +928,11 @@ class UserTest extends MediaWikiTestCase { $this->setMwGlobals( 'wgRateLimitsExcludedIPs', [] ); $noRateLimitUser = $this->getMockBuilder( User::class )->disableOriginalConstructor() - ->setMethods( [ 'getIP', 'getRights' ] )->getMock(); + ->setMethods( [ 'getIP', 'getId', 'getGroups' ] )->getMock(); $noRateLimitUser->expects( $this->any() )->method( 'getIP' )->willReturn( '1.2.3.4' ); - $noRateLimitUser->expects( $this->any() )->method( 'getRights' )->willReturn( [ 'noratelimit' ] ); + $noRateLimitUser->expects( $this->any() )->method( 'getId' )->willReturn( 0 ); + $noRateLimitUser->expects( $this->any() )->method( 'getGroups' )->willReturn( [] ); + $this->overrideUserPermissions( $noRateLimitUser, 'noratelimit' ); $this->assertFalse( $noRateLimitUser->isPingLimitable() ); } -- 2.20.1