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

Reply via email to