Umherirrender has uploaded a new change for review.
https://gerrit.wikimedia.org/r/154452
Change subject: Add 'editsitejs' and 'editsitecss' user rights
......................................................................
Add 'editsitejs' and 'editsitecss' user rights
The new user rights are now needed to edit mediawiki pages like
MediaWiki:Common.js or MediaWiki:Common.css.
The sysop group has these rights by default.
The 'editinterface' right is still needed, because namespace protections
are strict to the full namespace. In the praxis this seems okay, because
often messages also effected, when adjust css or js.
Added a warning, when editing site js or css.
The new user rights allows to create a new user group which is allow
to edit site js and css and to remove the user rights from all sysops.
It is also possible to create a new user group and use
$wgRevokePermissions to disable edit of site/js for
users of that new group.
Change-Id: I6ad49037464c0bea8a6ee4a7866ff820168795fb
---
M RELEASE-NOTES-1.24
M includes/DefaultSettings.php
M includes/EditPage.php
M includes/Title.php
M includes/User.php
M languages/i18n/en.json
M languages/i18n/qqq.json
M tests/phpunit/includes/TitlePermissionTest.php
8 files changed, 134 insertions(+), 28 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core
refs/changes/52/154452/1
diff --git a/RELEASE-NOTES-1.24 b/RELEASE-NOTES-1.24
index 30d59ba..6ab9027 100644
--- a/RELEASE-NOTES-1.24
+++ b/RELEASE-NOTES-1.24
@@ -57,6 +57,8 @@
there is a maintenance script wrapOldPassword.php that can wrap all
passwords in
PBKDF2 (or the hashing algorithm of your choice) if you don't want to wait
for your
users to log in.
+* New rights 'editsitejs' and 'editsitecss' restrict edit of site wide css and
js,
+ e.g. MediaWiki:Common.js. They have been added by default to the sysop user
group.
=== New features in 1.24 ===
* Added a new hook, "WhatLinksHereProps", to allow extensions to annotate
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index cf00701..4c53720 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -4491,6 +4491,8 @@
$wgGroupPermissions['sysop']['deletedtext'] = true;
$wgGroupPermissions['sysop']['undelete'] = true;
$wgGroupPermissions['sysop']['editinterface'] = true;
+$wgGroupPermissions['sysop']['editsitecss'] = true;
+$wgGroupPermissions['sysop']['editsitejs'] = true;
$wgGroupPermissions['sysop']['editusercss'] = true;
$wgGroupPermissions['sysop']['edituserjs'] = true;
$wgGroupPermissions['sysop']['import'] = true;
diff --git a/includes/EditPage.php b/includes/EditPage.php
index 145eae2..e65476f 100644
--- a/includes/EditPage.php
+++ b/includes/EditPage.php
@@ -2100,8 +2100,17 @@
$namespace = $this->mTitle->getNamespace();
if ( $namespace == NS_MEDIAWIKI ) {
- # Show a warning if editing an interface message
- $wgOut->wrapWikiMsg( "<div
class='mw-editinginterface'>\n$1\n</div>", 'editinginterface' );
+ # Show a warning if editing an site css or js page
+ if ( $this->mTitle->isCssOrJsPage() ) { // Runs a hook
+ if ( $this->mTitle->hasContentModel(
CONTENT_MODEL_CSS ) ) {
+ $wgOut->wrapWikiMsg( "<div
class='mw-editingsitecss'>\n$1\n</div>", 'editingsitecss' );
+ } elseif ( $this->mTitle->hasContentModel(
CONTENT_MODEL_JAVASCRIPT ) ) {
+ $wgOut->wrapWikiMsg( "<div
class='mw-editingsitejs'>\n$1\n</div>", 'editingsitejs' );
+ }
+ } else {
+ # Show a warning if editing an interface message
+ $wgOut->wrapWikiMsg( "<div
class='mw-editinginterface'>\n$1\n</div>", 'editinginterface' );
+ }
} elseif ( $namespace == NS_FILE ) {
# Show a hint to shared repo
$file = wfFindFile( $this->mTitle );
diff --git a/includes/Title.php b/includes/Title.php
index a1b2352..87fca5d 100644
--- a/includes/Title.php
+++ b/includes/Title.php
@@ -2093,21 +2093,31 @@
* @return array List of errors
*/
private function checkCSSandJSPermissions( $action, $user, $errors,
$doExpensiveQueries, $short ) {
- # Protect css/js subpages of user pages
- # XXX: this might be better using restrictions
- # XXX: right 'editusercssjs' is deprecated, for backward
compatibility only
- if ( $action != 'patrol' && !$user->isAllowed( 'editusercssjs'
) ) {
- if ( preg_match( '/^' . preg_quote( $user->getName(),
'/' ) . '\//', $this->mTextform ) ) {
- if ( $this->isCssSubpage() &&
!$user->isAllowedAny( 'editmyusercss', 'editusercss' ) ) {
- $errors[] = array(
'mycustomcssprotected' );
- } elseif ( $this->isJsSubpage() &&
!$user->isAllowedAny( 'editmyuserjs', 'edituserjs' ) ) {
- $errors[] = array(
'mycustomjsprotected' );
+ if ( $action != 'patrol' ) {
+ # Protect css/js subpages of user pages
+ # XXX: this might be better using restrictions
+ # XXX: right 'editusercssjs' is deprecated, for
backward compatibility only
+ if ( !$user->isAllowed( 'editusercssjs' ) ) {
+ if ( preg_match( '/^' . preg_quote(
$user->getName(), '/' ) . '\//', $this->mTextform ) ) {
+ if ( $this->isCssSubpage() &&
!$user->isAllowedAny( 'editmyusercss', 'editusercss' ) ) {
+ $errors[] = array(
'mycustomcssprotected' );
+ } elseif ( $this->isJsSubpage() &&
!$user->isAllowedAny( 'editmyuserjs', 'edituserjs' ) ) {
+ $errors[] = array(
'mycustomjsprotected' );
+ }
+ } else {
+ if ( $this->isCssSubpage() &&
!$user->isAllowed( 'editusercss' ) ) {
+ $errors[] = array(
'customcssprotected' );
+ } elseif ( $this->isJsSubpage() &&
!$user->isAllowed( 'edituserjs' ) ) {
+ $errors[] = array(
'customjsprotected' );
+ }
}
- } else {
- if ( $this->isCssSubpage() &&
!$user->isAllowed( 'editusercss' ) ) {
- $errors[] = array( 'customcssprotected'
);
- } elseif ( $this->isJsSubpage() &&
!$user->isAllowed( 'edituserjs' ) ) {
- $errors[] = array( 'customjsprotected'
);
+ }
+ // Protect site css/js - maybe also protected by
namespace protection: editinterface
+ if ( $this->isCssOrJsPage() ) { // Runs a hook
+ if ( $this->hasContentModel( CONTENT_MODEL_CSS
) && !$user->isAllowed( 'editsitecss' ) ) {
+ $errors[] = array( 'sitecssprotected' );
+ } elseif ( $this->hasContentModel(
CONTENT_MODEL_JAVASCRIPT ) && !$user->isAllowed( 'editsitejs' ) ) {
+ $errors[] = array( 'sitejsprotected' );
}
}
}
diff --git a/includes/User.php b/includes/User.php
index 7e846ad..d586900 100644
--- a/includes/User.php
+++ b/includes/User.php
@@ -120,6 +120,8 @@
'editmyuserjs',
'editmywatchlist',
'editsemiprotected',
+ 'editsitecss',
+ 'editsitejs',
'editusercssjs', #deprecated
'editusercss',
'edituserjs',
diff --git a/languages/i18n/en.json b/languages/i18n/en.json
index a43a742..d7926de 100644
--- a/languages/i18n/en.json
+++ b/languages/i18n/en.json
@@ -346,6 +346,10 @@
"viewyourtext": "You can view and copy the source of <strong>your
edits</strong> to this page:",
"protectedinterface": "This page provides interface text for the
software on this wiki, and is protected to prevent abuse.\nTo add or change
translations for all wikis, please use [//translatewiki.net/
translatewiki.net], the MediaWiki localisation project.",
"editinginterface": "<strong>Warning:</strong> You are editing a page
that is used to provide interface text for the software.\nChanges to this page
will affect the appearance of the user interface for other users on this
wiki.\nTo add or change translations for all wikis, please use
[//translatewiki.net/ translatewiki.net], the MediaWiki localisation project.",
+ "editingsitecss": "<strong>Warning:</strong> You are editing site wide
CSS.\nChanges to this page will affect the appearance of the user interface for
other users on this wiki.",
+ "editingsitejs": "<strong>Warning:</strong> You are editing site wide
JavaScript.\nChanges to this page will affect the appearance of the user
interface for other users on this wiki.",
+ "sitecssprotected": "You do not have permission to edit this CSS page
because it contains site wide CSS.",
+ "sitejsprotected": "You do not have permission to edit this JavaScript
page because it contains site wide JavaScript.",
"cascadeprotected": "This page has been protected from editing because
it is included in the following {{PLURAL:$1|page, which is|pages, which are}}
protected with the \"cascading\" option turned on:\n$2",
"namespaceprotected": "You do not have permission to edit pages in the
<strong>$1</strong> namespace.",
"customcssprotected": "You do not have permission to edit this CSS page
because it contains another user's personal settings.",
@@ -1105,6 +1109,8 @@
"right-editprotected": "Edit pages protected as
\"{{int:protect-level-sysop}}\"",
"right-editsemiprotected": "Edit pages protected as
\"{{int:protect-level-autoconfirmed}}\"",
"right-editinterface": "Edit the user interface",
+ "right-editsitecss": "Edit site CSS files",
+ "right-editsitejs": "Edit site JavaScript files",
"right-editusercssjs": "Edit other users' CSS and JavaScript files",
"right-editusercss": "Edit other users' CSS files",
"right-edituserjs": "Edit other users' JavaScript files",
diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json
index e135277..bd40a31 100644
--- a/languages/i18n/qqq.json
+++ b/languages/i18n/qqq.json
@@ -508,6 +508,10 @@
"viewyourtext": "Same as {{msg-mw|viewsourcetext}} but when showing the
text submitted by the user, this happens e.g. when the user was blocked while
he is editing the page",
"protectedinterface": "Message shown if a user without the
\"editinterface\" right tries to edit a page in the MediaWiki namespace.\n\nSee
also {{msg-mw|editinginterface}}.",
"editinginterface": "A message shown when editing pages in the
namespace MediaWiki:.\n\nSee also {{msg-mw|protectedinterface}}.",
+ "editingsitecss": "A message shown when editing CSS pages in the
namespace MediaWiki:.",
+ "editingsitejs": "A message shown when editing JavaScript pages in the
namespace MediaWiki:.",
+ "sitecssprotected": "Used as error message.",
+ "sitejsprotected": "Used as error message.",
"cascadeprotected": "Parameters:\n* $1 - number of cascade-protected
pages, used for PLURAL\n* $2 - list of cascade-protected pages",
"namespaceprotected": "Parameters:\n* $1 - namespace name",
"customcssprotected": "Used as error message.",
@@ -1267,6 +1271,8 @@
"right-editprotected": "{{doc-right|editprotected}}\nRefers to
{{msg-mw|Protect-level-sysop}}.\n\nSee also:\n*
{{msg-mw|Right-editsemiprotected}}",
"right-editsemiprotected": "{{doc-right|editsemiprotected}}\nRefers to
{{msg-mw|Protect-level-autoconfirmed}}.\n\nSee also:\n*
{{msg-mw|Right-editprotected}}",
"right-editinterface": "{{doc-right|editinterface}}",
+ "right-editsitecss": "{{doc-right|editsitecss}}",
+ "right-editsitejs": "{{doc-right|editsitejs}}",
"right-editusercssjs": "{{doc-right|editusercssjs}}",
"right-editusercss": "{{doc-right|editusercss}}\nSee also:\n*
{{msg-mw|Right-editmyusercss}}",
"right-edituserjs": "{{doc-right|edituserjs}}\nSee also:\n*
{{msg-mw|Right-editmyuserjs}}",
diff --git a/tests/phpunit/includes/TitlePermissionTest.php
b/tests/phpunit/includes/TitlePermissionTest.php
index 988a4a4..4208f90 100644
--- a/tests/phpunit/includes/TitlePermissionTest.php
+++ b/tests/phpunit/includes/TitlePermissionTest.php
@@ -444,7 +444,11 @@
array( array( 'badaccess-group0' ), array(
'mycustomjsprotected' ) ),
array( array( 'badaccess-group0' ) ),
array( array( 'badaccess-group0' ), array(
'mycustomjsprotected' ) ),
- array( array( 'badaccess-group0' ) )
+ array( array( 'badaccess-group0' ) ),
+ array( array( 'badaccess-group0' ) ),
+ array( array( 'badaccess-group0' ) ),
+ array( array( 'badaccess-group0' ), array(
'mycustomjsprotected' ) ),
+ array( array( 'badaccess-group0' ), array(
'mycustomjsprotected' ) )
);
$this->setTitle( NS_USER, $this->userName . '/test.css' );
@@ -453,6 +457,10 @@
array( array( 'badaccess-group0' ) ),
array( array( 'badaccess-group0' ), array(
'mycustomcssprotected' ) ),
array( array( 'badaccess-group0' ) ),
+ array( array( 'badaccess-group0' ), array(
'mycustomcssprotected' ) ),
+ array( array( 'badaccess-group0' ) ),
+ array( array( 'badaccess-group0' ) ),
+ array( array( 'badaccess-group0' ), array(
'mycustomcssprotected' ) ),
array( array( 'badaccess-group0' ), array(
'mycustomcssprotected' ) )
);
@@ -462,7 +470,11 @@
array( array( 'badaccess-group0' ), array(
'customjsprotected' ) ),
array( array( 'badaccess-group0' ), array(
'customjsprotected' ) ),
array( array( 'badaccess-group0' ), array(
'customjsprotected' ) ),
- array( array( 'badaccess-group0' ) )
+ array( array( 'badaccess-group0' ) ),
+ array( array( 'badaccess-group0' ) ),
+ array( array( 'badaccess-group0' ) ),
+ array( array( 'badaccess-group0' ), array(
'customjsprotected' ) ),
+ array( array( 'badaccess-group0' ), array(
'customjsprotected' ) )
);
$this->setTitle( NS_USER, $this->altUserName . '/test.css' );
@@ -471,6 +483,10 @@
array( array( 'badaccess-group0' ), array(
'customcssprotected' ) ),
array( array( 'badaccess-group0' ), array(
'customcssprotected' ) ),
array( array( 'badaccess-group0' ) ),
+ array( array( 'badaccess-group0' ), array(
'customcssprotected' ) ),
+ array( array( 'badaccess-group0' ) ),
+ array( array( 'badaccess-group0' ) ),
+ array( array( 'badaccess-group0' ), array(
'customcssprotected' ) ),
array( array( 'badaccess-group0' ), array(
'customcssprotected' ) )
);
@@ -480,45 +496,98 @@
array( array( 'badaccess-group0' ) ),
array( array( 'badaccess-group0' ) ),
array( array( 'badaccess-group0' ) ),
+ array( array( 'badaccess-group0' ) ),
+ array( array( 'badaccess-group0' ) ),
+ array( array( 'badaccess-group0' ) ),
+ array( array( 'badaccess-group0' ) ),
+ array( array( 'badaccess-group0' ) )
+ );
+
+ $this->setTitle( NS_MEDIAWIKI, 'Common.js' );
+ $this->runCSSandJSPermissions(
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ), array( 'sitejsprotected' ) ),
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ), array( 'sitejsprotected' ) ),
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ), array( 'sitejsprotected' ) ),
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ), array( 'sitejsprotected' ) ),
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ), array( 'sitejsprotected' ) ),
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ), array( 'sitejsprotected' ) ),
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ), array( 'sitejsprotected' ) ),
+ array( array( 'badaccess-group0' ), array(
'sitejsprotected' ) ),
+ array( array( 'badaccess-group0' ) )
+ );
+
+ $this->setTitle( NS_MEDIAWIKI, 'Common.css' );
+ $this->runCSSandJSPermissions(
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ), array( 'sitecssprotected' ) ),
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ), array( 'sitecssprotected' ) ),
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ), array( 'sitecssprotected' ) ),
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ), array( 'sitecssprotected' ) ),
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ), array( 'sitecssprotected' ) ),
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ), array( 'sitecssprotected' ) ),
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ), array( 'sitecssprotected' ) ),
+ array( array( 'badaccess-group0' ) ),
+ array( array( 'badaccess-group0' ), array(
'sitecssprotected' ) )
+ );
+
+ $this->setTitle( NS_MEDIAWIKI, 'tempo' );
+ $this->runCSSandJSPermissions(
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ) ),
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ) ),
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ) ),
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ) ),
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ) ),
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ) ),
+ array( array( 'badaccess-group0' ), array(
'protectedinterface' ) ),
+ array( array( 'badaccess-group0' ) ),
array( array( 'badaccess-group0' ) )
);
}
- protected function runCSSandJSPermissions( $result0, $result1,
$result2, $result3, $result4 ) {
+ protected function runCSSandJSPermissions( $result0, $result1,
$result2, $result3, $result4, $result5, $result6, $result7, $result8 ) {
$this->setUserPerm( '' );
$this->assertEquals( $result0,
$this->title->getUserPermissionsErrors( 'bogus',
- $this->user ) );
+ $this->user ), 'No user rights set' );
$this->setUserPerm( 'editmyusercss' );
$this->assertEquals( $result1,
$this->title->getUserPermissionsErrors( 'bogus',
- $this->user ) );
+ $this->user ), 'editmyusercss right set' );
$this->setUserPerm( 'editmyuserjs' );
$this->assertEquals( $result2,
$this->title->getUserPermissionsErrors( 'bogus',
- $this->user ) );
+ $this->user ), 'editmyuserjs right set' );
$this->setUserPerm( 'editusercss' );
$this->assertEquals( $result3,
$this->title->getUserPermissionsErrors( 'bogus',
- $this->user ) );
+ $this->user ), 'editusercss right set' );
$this->setUserPerm( 'edituserjs' );
$this->assertEquals( $result4,
$this->title->getUserPermissionsErrors( 'bogus',
- $this->user ) );
+ $this->user ), 'edituserjs right set' );
$this->setUserPerm( 'editusercssjs' );
- $this->assertEquals( array( array( 'badaccess-group0' ) ),
+ $this->assertEquals( $result5,
$this->title->getUserPermissionsErrors( 'bogus',
- $this->user ) );
+ $this->user ), 'editusercssjs right set' );
$this->setUserPerm( array( 'edituserjs', 'editusercss' ) );
- $this->assertEquals( array( array( 'badaccess-group0' ) ),
+ $this->assertEquals( $result6,
$this->title->getUserPermissionsErrors( 'bogus',
- $this->user ) );
+ $this->user ), 'edituserjs and editusercss
rights set' );
+
+ $this->setUserPerm( array( 'editinterface', 'editsitecss' ) );
+ $this->assertEquals( $result7,
+ $this->title->getUserPermissionsErrors( 'bogus',
+ $this->user ), 'editinterface and editsitecss
rights set' );
+
+ $this->setUserPerm( array( 'editinterface', 'editsitejs' ) );
+ $this->assertEquals( $result8,
+ $this->title->getUserPermissionsErrors( 'bogus',
+ $this->user ), 'editinterface and editsitejs
rights set' );
}
/**
--
To view, visit https://gerrit.wikimedia.org/r/154452
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6ad49037464c0bea8a6ee4a7866ff820168795fb
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Umherirrender <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits