Every permission included in managechangetags is really harmless and can be reverted
in short time, except of the permission to irriversibly delete tags. That's why
this should be excluded in an additional permission that other wikis can restrict
deletechangetags more than other tag management actions.
Bug: T133811
Change-Id: Ieb9199f2c6997316ae3468ff5a92b2d2456c012f
# $wgGroupPermissions['sysop']['upload_by_url'] = true;
$wgGroupPermissions['sysop']['mergehistory'] = true;
$wgGroupPermissions['sysop']['managechangetags'] = true;
+$wgGroupPermissions['sysop']['deletechangetags'] = true;
// Permission to change users' group assignments
$wgGroupPermissions['bureaucrat']['userrights'] = true;
$params = $this->extractRequestParams();
// make sure the user is allowed
- if ( !$this->getUser()->isAllowed( 'managechangetags' ) ) {
- $this->dieUsage( "You don't have permission to manage change tags", 'permissiondenied' );
+ if ( $params['operation'] !== 'delete'
+ && !$this->getUser()->isAllowed( 'managechangetags' )
+ ) {
+ $this->dieUsage( "You don't have permission to manage change tags",
+ 'permissiondenied' );
+ } elseif ( !$this->getUser()->isAllowed( 'deletechangetags' ) ) {
+ $this->dieUsage( "You don't have permission to delete change tags",
+ 'permissiondenied' );
}
$result = $this->getResult();
$tagUsage = self::tagUsageStatistics();
if ( !is_null( $user ) ) {
- if ( !$user->isAllowed( 'managechangetags' ) ) {
- return Status::newFatal( 'tags-manage-no-permission' );
+ if ( !$user->isAllowed( 'deletechangetags' ) ) {
+ return Status::newFatal( 'tags-delete-no-permission' );
} elseif ( $user->isBlocked() ) {
return Status::newFatal( 'tags-manage-blocked' );
}
$user = $this->getUser();
$userCanManage = $user->isAllowed( 'managechangetags' );
+ $userCanDelete = $user->isAllowed( 'deletechangetags' );
$userCanEditInterface = $user->isAllowed( 'editinterface' );
// Show form to create a tag
// Insert tags that have been applied at least once
foreach ( $tagStats as $tag => $hitcount ) {
- $html .= $this->doTagRow( $tag, $hitcount, $userCanManage, $userCanEditInterface );
+ $html .= $this->doTagRow( $tag, $hitcount, $userCanManage,
+ $userCanDelete, $userCanEditInterface );
}
// Insert tags defined somewhere but never applied
foreach ( $definedTags as $tag ) {
if ( !isset( $tagStats[$tag] ) ) {
- $html .= $this->doTagRow( $tag, 0, $userCanManage, $userCanEditInterface );
+ $html .= $this->doTagRow( $tag, 0, $userCanManage, $userCanDelete, $userCanEditInterface );
}
}
) );
}
- function doTagRow( $tag, $hitcount, $showActions, $showEditLinks ) {
+ function doTagRow( $tag, $hitcount, $showManageActions, $showDeleteActions, $showEditLinks ) {
$newRow = '';
$newRow .= Xml::tags( 'td', null, Xml::element( 'code', null, $tag ) );
$newRow .= Xml::tags( 'td', [ 'data-sort-value' => $hitcount ], $hitcountLabel );
// actions
- if ( $showActions ) { // we've already checked that the user had the requisite userright
- $actionLinks = [];
+ $actionLinks = [];
- // delete
- if ( ChangeTags::canDeleteTag( $tag )->isOK() ) {
- $actionLinks[] = Linker::linkKnown( $this->getPageTitle( 'delete' ),
- $this->msg( 'tags-delete' )->escaped(),
- [],
- [ 'tag' => $tag ] );
- }
+ // delete
+ if ( $showDeleteActions && ChangeTags::canDeleteTag( $tag )->isOK() ) {
+ $actionLinks[] = Linker::linkKnown( $this->getPageTitle( 'delete' ),
+ $this->msg( 'tags-delete' )->escaped(),
+ [],
+ [ 'tag' => $tag ] );
+ }
+
+ if ( $showManageActions ) { // we've already checked that the user had the requisite userright
// activate
if ( ChangeTags::canActivateTag( $tag )->isOK() ) {
protected function showDeleteTagForm( $tag ) {
$user = $this->getUser();
- if ( !$user->isAllowed( 'managechangetags' ) ) {
- throw new PermissionsError( 'managechangetags' );
+ if ( !$user->isAllowed( 'deletechangetags' ) ) {
+ throw new PermissionsError( 'deletechangetags' );
}
$out = $this->getOutput();
'createpage',
'createtalk',
'delete',
+ 'deletechangetags',
'deletedhistory',
'deletedtext',
'deletelogentry',
"right-override-export-depth": "Export pages including linked pages up to a depth of 5",
"right-sendemail": "Send email to other users",
"right-passwordreset": "View password reset emails",
- "right-managechangetags": "Create and delete [[Special:Tags|tags]] from the database",
+ "right-managechangetags": "Create and (de)activate [[Special:Tags|tags]]",
"right-applychangetags": "Apply [[Special:Tags|tags]] along with one's changes",
"right-changetags": "Add and remove arbitrary [[Special:Tags|tags]] on individual revisions and log entries",
+ "right-deletechangetags": "Delete [[Special:Tags|tags]] from the database",
"grant-generic": "\"$1\" rights bundle",
"grant-group-page-interaction": "Interact with pages",
"grant-group-file-interaction": "Interact with media",
"action-viewmyprivateinfo": "view your private information",
"action-editmyprivateinfo": "edit your private information",
"action-editcontentmodel": "edit the content model of a page",
- "action-managechangetags": "create and delete tags from the database",
+ "action-managechangetags": "create and (de)activate tags",
"action-applychangetags": "apply tags along with your changes",
"action-changetags": "add and remove arbitrary tags on individual revisions and log entries",
+ "action-deletechangetags": "delete tags from the database",
"nchanges": "$1 {{PLURAL:$1|change|changes}}",
"enhancedrc-since-last-visit": "$1 {{PLURAL:$1|since last visit}}",
"enhancedrc-history": "history",
"tags-delete-not-found": "The tag \"$1\" does not exist.",
"tags-delete-too-many-uses": "The tag \"$1\" is applied to more than $2 {{PLURAL:$2|revision|revisions}}, which means it cannot be deleted.",
"tags-delete-warnings-after-delete": "The tag \"$1\" was deleted, but the following {{PLURAL:$2|warning was|warnings were}} encountered:",
+ "tags-delete-no-permission": "You do not have permission to delete change tags.",
"tags-activate-title": "Activate tag",
"tags-activate-question": "You are about to activate the tag \"$1\".",
"tags-activate-reason": "Reason:",
"right-managechangetags": "{{doc-right|managechangetags}}",
"right-applychangetags": "{{doc-right|applychangetags}}",
"right-changetags": "{{doc-right|changetags}}",
+ "right-deletechangetags": "{{doc-right|deletechangetags}}",
"grant-generic": "Used if the grant name is not defined. Parameters:\n* $1 - grant name\n\nDefined grants (grant name refers: blockusers, createeditmovepage, ...):\n* {{msg-mw|grant-checkuser}}\n* {{msg-mw|grant-blockusers}}\n* {{msg-mw|grant-createaccount}}\n* {{msg-mw|grant-createeditmovepage}}\n* {{msg-mw|grant-delete}}\n* {{msg-mw|grant-editinterface}}\n* {{msg-mw|grant-editmycssjs}}\n* {{msg-mw|grant-editmyoptions}}\n* {{msg-mw|grant-editmywatchlist}}\n* {{msg-mw|grant-editpage}}\n* {{msg-mw|grant-editprotected}}\n* {{msg-mw|grant-highvolume}}\n* {{msg-mw|grant-oversight}}\n* {{msg-mw|grant-patrol}}\n* {{msg-mw|grant-protect}}\n* {{msg-mw|grant-rollback}}\n* {{msg-mw|grant-sendemail}}\n* {{msg-mw|grant-uploadeditmovefile}}\n* {{msg-mw|grant-uploadfile}}\n* {{msg-mw|grant-basic}}\n* {{msg-mw|grant-viewdeleted}}\n* {{msg-mw|grant-viewmywatchlist}}",
"grant-group-page-interaction": "{{Related|grant-group}}",
"grant-group-file-interaction": "{{Related|grant-group}}",
"action-managechangetags": "{{doc-action|managechangetags}}",
"action-applychangetags": "{{doc-action|applychangetags}}",
"action-changetags": "{{doc-action|changetags}}",
+ "action-deletechangetags": "{{doc-action|deletechangetags}}",
"nchanges": "Appears on enhanced watchlist and recent changes when page has more than one change on given date, linking to a diff of the changes.\n\nParameters:\n* $1 - the number of changes on that day (2 or more)\nThree messages are shown side-by-side: ({{msg-mw|Nchanges}} | {{msg-mw|Enhancedrc-since-last-visit}} | {{msg-mw|Enhancedrc-history}}).",
"enhancedrc-since-last-visit": "Appears on enhanced watchlist and recent changes when page has more than one change on given date and at least one that the user hasn't seen yet, linking to a diff of the unviewed changes.\n\nParameters:\n* $1 - the number of unviewed changes (1 or more)\nThree messages are shown side-by-side: ({{msg-mw|nchanges}} | {{msg-mw|enhancedrc-since-last-visit}} | {{msg-mw|enhancedrc-history}}).",
"enhancedrc-history": "Appears on enhanced watchlist and recent changes when page has more than one change on given date, linking to its history.\n\nThis is the same as {{msg-mw|hist}}, but not abbreviated.\n\nThree messages are shown side-by-side: ({{msg-mw|nchanges}} | {{msg-mw|enhancedrc-since-last-visit}} | {{msg-mw|enhancedrc-history}}).\n{{Identical|History}}",
"tags-delete-not-found": "Error message on [[Special:Tags]]",
"tags-delete-too-many-uses": "Error message on [[Special:Tags]]",
"tags-delete-warnings-after-delete": "Warning shown after deleting a tag.\n\nParameters:\n* $1 - the code name of the tag that was deleted\n* $2 - the number of warnings",
+ "tags-delete-no-permission": "Error message on [[Special:Tags]]",
"tags-activate-title": "The title of a page used to activate a tag. For more information on tags see [[mw:Manual:Tags|MediaWiki]].",
"tags-activate-question": "An explanation to tell users what they are about to do.\n\nParameters:\n* $1 - the code name of the tag that is about to be activated",
"tags-activate-reason": "{{Identical|Reason}}",