Page MenuHomeWickedGov Phorge

SpecialGlobalGroupPermissions.php
No OneTemporary

Size
23 KB
Referenced Files
None
Subscribers
None

SpecialGlobalGroupPermissions.php

<?php
# This file is part of MediaWiki.
# MediaWiki is free software: you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License
# as published by the Free Software Foundation.
# MediaWiki is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
namespace MediaWiki\Extension\CentralAuth\Special;
use Exception;
use InvalidArgumentException;
use LogEventsList;
use LogPage;
use ManualLogEntry;
use MediaWiki\Extension\CentralAuth\CentralAuthDatabaseManager;
use MediaWiki\Extension\CentralAuth\GlobalGroup\GlobalGroupLookup;
use MediaWiki\Extension\CentralAuth\User\CentralAuthUser;
use MediaWiki\Extension\CentralAuth\WikiSet;
use MediaWiki\Html\Html;
use MediaWiki\Output\OutputPage;
use MediaWiki\Permissions\PermissionManager;
use MediaWiki\SpecialPage\SpecialPage;
use MediaWiki\Status\Status;
use MediaWiki\Title\Title;
use MediaWiki\User\User;
use MediaWiki\User\UserGroupMembership;
use MediaWiki\Xml\Xml;
use MediaWiki\Xml\XmlSelect;
/**
* Special page to allow managing global groups
* Prototype for a similar system in core.
*
* @file
* @ingroup Extensions
*/
class SpecialGlobalGroupPermissions extends SpecialPage {
private PermissionManager $permissionManager;
private CentralAuthDatabaseManager $databaseManager;
private GlobalGroupLookup $globalGroupLookup;
public function __construct(
PermissionManager $permissionManager,
CentralAuthDatabaseManager $databaseManager,
GlobalGroupLookup $globalGroupLookup
) {
parent::__construct( 'GlobalGroupPermissions' );
$this->permissionManager = $permissionManager;
$this->databaseManager = $databaseManager;
$this->globalGroupLookup = $globalGroupLookup;
}
public function doesWrites() {
return true;
}
/**
* @param User $user
* @return bool
*/
public function userCanEdit( $user ) {
$globalUser = CentralAuthUser::getInstance( $user );
# Should be a global user
if ( !$globalUser->exists() || !$globalUser->isAttached() ) {
return false;
}
return $user->isAllowed( 'globalgrouppermissions' );
}
/** @inheritDoc */
public function execute( $subpage ) {
$this->addHelpLink( 'Extension:CentralAuth' );
if ( !$this->userCanExecute( $this->getUser() ) ) {
$this->displayRestrictionError();
}
$this->getOutput()->setPageTitleMsg( $this->msg( 'globalgrouppermissions' ) );
$this->getOutput()->addModuleStyles( 'ext.centralauth.misc.styles' );
$this->getOutput()->setRobotPolicy( "noindex,nofollow" );
$this->getOutput()->setArticleRelated( false );
$this->getOutput()->disableClientCache();
if ( $subpage == '' ) {
$subpage = $this->getRequest()->getVal( 'wpGroup' );
}
if (
$subpage != ''
&& $this->getUser()->matchEditToken( $this->getRequest()->getVal( 'wpEditToken' ) )
&& $this->getRequest()->wasPosted()
) {
$this->doSubmit( $subpage );
} elseif ( $subpage != '' ) {
$this->buildGroupView( $subpage );
} else {
$this->buildMainView();
}
}
private function buildMainView() {
$out = $this->getOutput();
$groups = $this->globalGroupLookup->getDefinedGroups();
if ( count( $groups ) ) {
$out->addHTML(
$this->msg( 'centralauth-globalgroupperms-groups-intro' )->parseAsBlock()
. $this->getGlobalGroupsTable( $groups )
);
} else {
$out->addWikiMsg( 'centralauth-globalgroupperms-nogroups' );
}
if ( $this->userCanEdit( $this->getUser() ) ) {
// "Create a group" prompt
// @todo Move this out of main view to a separate page
$html = Xml::fieldset( $this->msg( 'centralauth-newgroup-legend' )->text() );
$html .= $this->msg( 'centralauth-newgroup-intro' )->parseAsBlock();
$html .= Xml::openElement( 'form', [
'method' => 'post',
'action' => $this->getConfig()->get( 'Script' ),
'name' => 'centralauth-globalgroups-newgroup'
] );
$html .= Html::hidden( 'title', $this->getPageTitle()->getPrefixedText() );
$fields = [ 'centralauth-globalgroupperms-newgroupname' => Xml::input( 'wpGroup' ) ];
$html .= Xml::buildForm( $fields, 'centralauth-globalgroupperms-creategroup-submit' );
$html .= Xml::closeElement( 'form' );
$html .= Xml::closeElement( 'fieldset' );
$out->addHTML( $html );
}
}
/**
* @param array $groups
* @return string HTML for the group permissions table
*/
protected function getGlobalGroupsTable( $groups ) {
$table = Html::openElement( 'table',
[ 'class' => 'mw-centralauth-groups-table wikitable' ] );
// Header stuff
$table .= Html::openElement( 'tr' );
$table .= Html::element( 'th', [],
$this->msg( 'centralauth-globalgroupperms-group' )->text()
);
$table .= Html::element( 'th', [],
$this->msg( 'centralauth-globalgroupperms-rights' )->text()
);
$table .= Html::closeElement( 'tr' );
foreach ( $groups as $groupName ) {
$groupInfo = $this->getGroupInfo( $groupName );
$wikiset = $groupInfo['wikiset'];
$table .= Html::openElement( 'tr' );
// Column with group name, links and local disabled status
$table .= Html::openElement( 'td' );
$table .= $this->getOutput()->parseInlineAsInterface(
UserGroupMembership::getLinkWiki( $groupName, $this->getContext() ) ) . '<br />';
$groupWithParentheses = $this->msg( 'parentheses' )->params( $groupName )->escaped();
$table .= Html::openElement( 'code' );
$table .= $groupWithParentheses;
$table .= Html::closeElement( 'code' ) . Html::element( 'br' );
$linkRenderer = $this->getLinkRenderer();
$links = [
$linkRenderer->makeKnownLink(
$this->getPageTitle( $groupName ),
$this->msg( 'centralauth-globalgroupperms-management' )->text()
),
$linkRenderer->makeKnownLink(
SpecialPage::getTitleFor( 'GlobalUsers', $groupName ),
$this->msg( 'centralauth-globalgroupperms-group-listmembers' )->text()
),
];
$table .= $this->msg( 'parentheses' )
->rawParams( $this->getLanguage()->pipeList( $links ) )->escaped();
if ( $wikiset !== null && !$wikiset['enabledHere'] ) {
$table .= '<br /><small>';
$table .= $this->msg( 'centralauth-globalgroupperms-group-disabled' )->escaped() .
'</small>';
}
$table .= Html::closeElement( 'td' );
// Column for wikiset info and group rights list
$table .= Html::openElement( 'td' );
if ( $wikiset === null ) {
$table .= $this->msg( 'centralauth-globalgroupperms-wikiset-none' )->escaped();
} else {
$table .= $this->msg( 'centralauth-globalgroupperms-group-wikiset' )
->rawParams(
$linkRenderer->makeKnownLink(
SpecialPage::getTitleFor( 'WikiSets', $wikiset['id'] ),
$wikiset['name']
)
)->escaped();
}
$table .= '<hr />';
$rightsList = '';
foreach ( $groupInfo['rights'] as $right ) {
$rightsList .= Html::rawElement( 'li', [], $this->formatRight( $right ) );
}
$table .= '<ul>' . $rightsList . '</ul>';
$table .= Html::closeElement( 'td' );
$table .= Html::closeElement( 'tr' );
}
$table .= Html::closeElement( 'table' );
return $table;
}
/**
* @param string $group The group's name
* @return array
* - rights: string The list of rights assigned to the group
* - wikiset: array|null Either array with id, name, enabledHere or
* null if the group is not associated to any wikiset
* @throws Exception
*/
protected function getGroupInfo( $group ) {
$info = [ 'rights' => $this->getAssignedRights( $group ) ];
$wikiset = WikiSet::getWikiSetForGroup( $group );
if ( $wikiset !== 0 ) {
$wikiset = WikiSet::newFromID( $wikiset );
if ( !$wikiset ) {
throw new InvalidArgumentException( "__METHOD__: $group with unknown wikiset." );
}
$info['wikiset'] = [
'id' => $wikiset->getId(),
'name' => $wikiset->getName(),
'enabledHere' => $wikiset->inSet(),
];
} else {
$info['wikiset'] = null;
}
return $info;
}
/**
* @param string $group
*/
private function buildGroupView( $group ) {
$editable = $this->userCanEdit( $this->getUser() );
$assignedRights = $this->getAssignedRights( $group );
$this->getOutput()->addBacklinkSubtitle( $this->getPageTitle() );
if ( !$assignedRights ) {
// if the group doesn't exist and the user can not manage the global groups,
// an error message should be shown instead of the permission list box.
if ( !$editable ) {
$this->getOutput()->wrapWikiMsg( '<div class="error">$1</div>',
[ 'centralauth-editgroup-nonexistent', $group ] );
$this->showLogFragment( $group, $this->getOutput() );
return;
}
$nameValidationResult = $this->validateGroupName( $group );
if ( !$nameValidationResult->isGood() ) {
$this->getOutput()->wrapWikiMsg( '<div class="error">$1</div>',
$nameValidationResult->getMessage() );
$this->showLogFragment( $group, $this->getOutput() );
return;
}
}
$fieldsetClass = $editable
? 'mw-centralauth-editgroup'
: 'mw-centralauth-editgroup-readonly';
$html = Xml::fieldset(
$this->msg( 'centralauth-editgroup-fieldset', $group )->text(),
false,
[ 'class' => $fieldsetClass ]
);
if ( $editable ) {
$html .= Xml::openElement( 'form', [
'method' => 'post',
'action' => $this->getPageTitle( $group )->getLocalUrl(),
'name' => 'centralauth-globalgroups-newgroup'
] );
$html .= Html::hidden( 'wpGroup', $group );
$html .= Html::hidden( 'wpEditToken', $this->getUser()->getEditToken() );
}
$fields = [];
if ( $editable ) {
$fields['centralauth-editgroup-name'] = Xml::input( 'wpGlobalGroupName', 50, $group );
} else {
$fields['centralauth-editgroup-name'] = htmlspecialchars( $group );
}
$lang = $this->getLanguage();
if ( $this->getContext()->getAuthority()->isAllowed( 'editinterface' ) ) {
# Show edit link only to user with the editinterface right
$fields['centralauth-editgroup-display'] = $this->msg(
'centralauth-editgroup-display-edit',
$group,
$lang->getGroupName( $group )
)->parse();
$fields['centralauth-editgroup-member'] = $this->msg(
'centralauth-editgroup-member-edit',
$group,
$lang->getGroupMemberName( $group, '#' )
)->parse();
} else {
$fields['centralauth-editgroup-display'] =
htmlspecialchars( $lang->getGroupName( $group ) );
$fields['centralauth-editgroup-member'] =
htmlspecialchars( $lang->getGroupMemberName( $group, '#' ) );
}
$fields['centralauth-editgroup-members'] = $this->msg(
'centralauth-editgroup-members-link',
$group,
$lang->getGroupMemberName( $group, '#' )
)->parse();
$fields['centralauth-editgroup-restrictions'] = $this->buildWikiSetSelector( $group );
$fields['centralauth-editgroup-perms'] = $this->buildCheckboxes( $group );
if ( $editable ) {
$fields['centralauth-editgroup-reason'] = Xml::input( 'wpReason', 60 );
}
$html .= Xml::buildForm( $fields, $editable ? 'centralauth-editgroup-submit' : null );
if ( $editable ) {
$html .= Xml::closeElement( 'form' );
}
$html .= Xml::closeElement( 'fieldset' );
$this->getOutput()->addHTML( $html );
$this->showLogFragment( $group, $this->getOutput() );
}
/**
* @param string $group
* @return string
*/
private function buildWikiSetSelector( $group ) {
$sets = WikiSet::getAllWikiSets();
$default = WikiSet::getWikiSetForGroup( $group );
if ( !$this->userCanEdit( $this->getUser() ) ) {
$set = WikiSet::newFromID( $default );
if ( $set ) {
return $this->getLinkRenderer()->makeLink(
SpecialPage::getTitleFor( 'WikiSets', (string)$set->getId() ),
$set->getName()
);
} else {
return $this->msg( 'centralauth-editgroup-nowikiset' )->parse();
}
}
$select = new XmlSelect( 'set', 'wikiset', (string)$default );
$select->addOption( $this->msg( 'centralauth-editgroup-noset' )->text(), '0' );
foreach ( $sets as $set ) {
$select->addOption( $set->getName(), (string)$set->getID() );
}
$editlink = $this->msg( 'centralauth-editgroup-editsets' )->parse();
return $select->getHTML() . "&#160;{$editlink}";
}
/**
* @param string $group
* @return string
*/
private function buildCheckboxes( $group ) {
$editable = $this->userCanEdit( $this->getUser() );
$assignedRights = $this->getAssignedRights( $group );
$checkboxes = [];
$attribs = [];
if ( !$editable ) {
$attribs['disabled'] = 'disabled';
}
$rights = array_unique(
array_merge(
$this->permissionManager->getAllPermissions(),
$assignedRights
)
);
sort( $rights );
foreach ( $rights as $right ) {
// Build a checkbox
$checked = in_array( $right, $assignedRights );
$desc = $this->formatRight( $right );
$checkbox = Xml::check( "wpRightAssigned-$right", $checked,
array_merge( $attribs, [ 'id' => "wpRightAssigned-$right" ] ) );
$label = Xml::tags( 'label', [ 'for' => "wpRightAssigned-$right" ],
$desc );
$liClass = $checked
? 'mw-centralauth-editgroup-checked'
: 'mw-centralauth-editgroup-unchecked';
$checkboxes[] = Html::rawElement(
'li', [ 'class' => $liClass ], "$checkbox&#160;$label" );
}
$count = count( $checkboxes );
$html = Html::openElement( 'div', [ 'class' => 'mw-centralauth-rights' ] )
. '<ul>';
foreach ( $checkboxes as $cb ) {
$html .= $cb;
}
$html .= '</ul>'
. Html::closeElement( 'div' );
return $html;
}
/**
* Given a user right name, return HTML with the description
* of the right and it's name for displaying to the user
* @param string $right
* @return string escaped html
*/
protected function formatRight( $right ) {
return $this->msg( 'listgrouprights-right-display' )
->params( User::getRightDescription( $right ) )
->rawParams( Html::element(
'span',
[ 'class' => 'mw-listgrouprights-right-name' ],
$right
) )
->parse();
}
/**
* @param string $group
* @return string[]
*/
private function getAssignedRights( $group ) {
return $this->globalGroupLookup->getRightsForGroup( $group );
}
/**
* @param string $group
*/
private function doSubmit( $group ) {
// It is important to check userCanEdit, as otherwise an
// unauthorized user could manually construct a POST request.
if ( !$this->userCanEdit( $this->getUser() ) ) {
return;
}
$reason = $this->getRequest()->getVal( 'wpReason', '' );
// Current name of the group
// XXX This is a horrible hack. We should not use Title for normalization. We need to prefix
// the group name so that the first letter doesn't get uppercased.
$group = Title::newFromText( "A/$group" );
if ( !$group ) {
$this->getOutput()->addWikiMsg( 'centralauth-editgroup-invalid-name' );
return;
}
$group = ltrim( substr( $group->getDBkey(), 2 ), '_' );
// (Potentially) New name of the group
$newname = $this->getRequest()->getVal( 'wpGlobalGroupName', $group );
$newname = Title::newFromText( "A/$newname" );
if ( !$newname ) {
$this->getOutput()->addWikiMsg( 'centralauth-editgroup-invalid-name' );
return;
}
$newname = ltrim( substr( $newname->getDBkey(), 2 ), '_' );
// all new group names should be lowercase: check all new and changed group names (T202095)
if (
!in_array( $group, $this->globalGroupLookup->getDefinedGroups( DB_PRIMARY ) )
|| ( $group !== $newname )
) {
$nameValidationResult = $this->validateGroupName( $newname );
if ( !$nameValidationResult->isGood() ) {
$this->getOutput()->wrapWikiMsg( '<div class="error">$1</div>',
$nameValidationResult->getMessage() );
return;
}
}
// Calculate permission changes already! We'll only save any changes
// here after processing a possible group rename, but want to add
// validation logic before that.
$addRights = [];
$removeRights = [];
$oldRights = $this->getAssignedRights( $group );
$allRights = array_unique(
array_merge(
$this->permissionManager->getAllPermissions(),
$oldRights
)
);
foreach ( $allRights as $right ) {
$alreadyAssigned = in_array( $right, $oldRights );
$checked = $this->getRequest()->getCheck( "wpRightAssigned-$right" );
if ( !$alreadyAssigned && $checked ) {
$addRights[] = $right;
} elseif ( $alreadyAssigned && !$checked ) {
$removeRights[] = $right;
}
}
// Disallow deleting existing groups with members in them
if (
count( $oldRights ) !== 0
&& count( $addRights ) === 0
&& count( $removeRights ) === count( $oldRights )
) {
$dbr = $this->databaseManager->getCentralReplicaDB();
$memberCount = $dbr->newSelectQueryBuilder()
->select( 'gug_group' )
->from( 'global_user_groups' )
->where( [ 'gug_group' => $group ] )
->caller( __METHOD__ )
->fetchRow();
if ( $memberCount ) {
$this->getOutput()->addWikiMsg( 'centralauth-editgroup-delete-removemembers' );
return;
}
}
// Check if we need to rename the group
if ( $group != $newname ) {
if ( in_array( $newname, $this->globalGroupLookup->getDefinedGroups( DB_PRIMARY ) ) ) {
$this->getOutput()->addWikiMsg( 'centralauth-editgroup-rename-taken', $newname );
return;
}
$dbw = $this->databaseManager->getCentralPrimaryDB();
$updates = [
'global_group_permissions' => 'ggp_group',
'global_group_restrictions' => 'ggr_group',
'global_user_groups' => 'gug_group'
];
foreach ( $updates as $table => $field ) {
$dbw->newUpdateQueryBuilder()
->update( $table )
->set( [ $field => $newname ] )
->where( [ $field => $group ] )
->caller( __METHOD__ )
->execute();
}
$this->addRenameLog( $group, $newname, $reason );
// The rest of the changes here will be performed on the "new" group
$group = $newname;
}
// Assign the rights.
if ( count( $addRights ) > 0 ) {
$this->grantRightsToGroup( $group, $addRights );
}
if ( count( $removeRights ) > 0 ) {
$this->revokeRightsFromGroup( $group, $removeRights );
}
// Log it
if ( !( count( $addRights ) == 0 && count( $removeRights ) == 0 ) ) {
$this->addPermissionLog( $group, $addRights, $removeRights, $reason );
}
// Change set
$current = WikiSet::getWikiSetForGroup( $group );
$new = $this->getRequest()->getInt( 'set' );
if ( $current != $new ) {
$this->setRestrictions( $group, $new );
$this->addWikiSetLog( $group, $current, $new, $reason );
}
$this->invalidateRightsCache( $group );
// Display success
$this->getOutput()->setSubTitle( $this->msg( 'centralauth-editgroup-success' ) );
$this->getOutput()->addWikiMsg( 'centralauth-editgroup-success-text', $group );
}
/**
* @param string $group
* @param string[] $rights
*/
private function revokeRightsFromGroup( $group, $rights ) {
$dbw = $this->databaseManager->getCentralPrimaryDB();
# Delete from the DB
$dbw->newDeleteQueryBuilder()
->deleteFrom( 'global_group_permissions' )
->where( [ 'ggp_group' => $group, 'ggp_permission' => $rights ] )
->caller( __METHOD__ )
->execute();
}
/**
* @param string $group
* @param string[]|string $rights
*/
private function grantRightsToGroup( $group, $rights ) {
$dbw = $this->databaseManager->getCentralPrimaryDB();
if ( !is_array( $rights ) ) {
$rights = [ $rights ];
}
$insertRows = [];
foreach ( $rights as $right ) {
$insertRows[] = [ 'ggp_group' => $group, 'ggp_permission' => $right ];
}
# Replace into the DB
$dbw->newReplaceQueryBuilder()
->replaceInto( 'global_group_permissions' )
->uniqueIndexFields( [ 'ggp_group', 'ggp_permission' ] )
->rows( $insertRows )
->caller( __METHOD__ )
->execute();
}
/**
* @param string $group
* @param OutputPage $output
*/
protected function showLogFragment( $group, $output ) {
$title = SpecialPage::getTitleFor( 'GlobalUsers', $group );
$logPage = new LogPage( 'gblrights' );
$output->addHTML( Xml::element( 'h2', null, $logPage->getName()->text() . "\n" ) );
LogEventsList::showLogExtract( $output, 'gblrights', $title->getPrefixedText() );
}
/**
* Log permission changes
*
* @param string $group
* @param string[] $addRights
* @param string[] $removeRights
* @param string $reason
*/
private function addPermissionLog( $group, $addRights, $removeRights, $reason ) {
$entry = new ManualLogEntry( 'gblrights', 'groupprms2' );
$entry->setTarget( SpecialPage::getTitleFor( 'GlobalUsers', $group ) );
$entry->setPerformer( $this->getUser() );
$entry->setComment( $reason );
$entry->setParameters( [
'addRights' => $addRights,
'removeRights' => $removeRights,
] );
$logid = $entry->insert();
$entry->publish( $logid );
}
/**
* Log the renaming of a global group
*
* @param string $oldName
* @param string $newName
* @param string $reason
*/
private function addRenameLog( $oldName, $newName, $reason ) {
$entry = new ManualLogEntry( 'gblrights', 'grouprename' );
// This has to point to 'Special:GlobalUsers so that self::showLogFragment can find it
$entry->setTarget( SpecialPage::getTitleFor( 'GlobalUsers', $newName ) );
$entry->setPerformer( $this->getUser() );
$entry->setComment( $reason );
$entry->setParameters( [
'newName' => $newName,
'oldName' => $oldName,
] );
$logid = $entry->insert();
$entry->publish( $logid );
}
/**
* Log wikiset changes
*
* @param string $group
* @param int $old
* @param int $new
* @param string $reason
*/
private function addWikiSetLog( $group, $old, $new, $reason ) {
$entry = new ManualLogEntry( 'gblrights', 'groupprms3' );
$entry->setTarget( SpecialPage::getTitleFor( 'GlobalUsers', $group ) );
$entry->setPerformer( $this->getUser() );
$entry->setComment( $reason );
$params = [];
$mapping = [
'old' => [ 4, $old ],
'new' => [ 5, $new ],
];
foreach ( $mapping as $param => [ $id, $set ] ) {
$name = $this->getWikiSetName( $set );
if ( $name !== null ) {
$params["$id::$param"] = $name;
} else {
$params["$id:msg:$param"] = 'centralauth-editgroup-noset';
}
}
$entry->setParameters( $params );
$logid = $entry->insert();
$entry->publish( $logid );
}
/**
* @param string $group
* @param int $set
* @return bool
*/
private function setRestrictions( $group, $set ) {
$dbw = $this->databaseManager->getCentralPrimaryDB();
if ( $set == 0 ) {
$dbw->newDeleteQueryBuilder()
->deleteFrom( 'global_group_restrictions' )
->where( [ 'ggr_group' => $group ] )
->caller( __METHOD__ )
->execute();
} else {
$dbw->newReplaceQueryBuilder()
->replaceInto( 'global_group_restrictions' )
->uniqueIndexFields( 'ggr_group' )
->row( [ 'ggr_group' => $group, 'ggr_set' => $set, ] )
->caller( __METHOD__ )
->execute();
}
return (bool)$dbw->affectedRows();
}
/**
* @param string|int $id
* @return string|null
*/
private function getWikiSetName( $id ) {
$wikiset = WikiSet::newFromID( $id );
if ( $wikiset !== null ) {
return $wikiset->getName();
}
return null;
}
/**
* @param string $group
*/
private function invalidateRightsCache( $group ) {
// Figure out all the users in this group.
// Use the primary database over here as this could go horribly wrong with newly created or just
// renamed groups
$dbr = $this->databaseManager->getCentralPrimaryDB();
$res = $dbr->newSelectQueryBuilder()
->select( 'gu_name' )
->from( 'globaluser' )
->join( 'global_user_groups', null, 'gu_id=gug_user' )
->where( [ 'gug_group' => $group ] )
->caller( __METHOD__ )
->fetchFieldValues();
// Invalidate their rights cache.
foreach ( $res as $name ) {
// Use READ_LATEST for paranoia, though the DB isn't used in this method
$cu = CentralAuthUser::getPrimaryInstanceByName( $name );
$cu->quickInvalidateCache();
}
}
/** @inheritDoc */
protected function getGroupName() {
return 'users';
}
private function validateGroupName( string $name ): Status {
// all new group names should be lowercase (T202095)
if ( $name !== strtolower( $name ) ) {
return Status::newFatal( 'centralauth-editgroup-invalid-name-lowercase' );
}
return Status::newGood();
}
}

File Metadata

Mime Type
text/x-php
Expires
Sat, May 16, 18:21 (7 h, 16 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
4f/19/8d5ad49e068be316c3df6aa652ac
Default Alt Text
SpecialGlobalGroupPermissions.php (23 KB)

Event Timeline