Implementing user levels management. This is only a very basic interface and several...
authorAntoine Musso <hashar@users.mediawiki.org>
Sun, 24 Oct 2004 19:14:48 +0000 (19:14 +0000)
committerAntoine Musso <hashar@users.mediawiki.org>
Sun, 24 Oct 2004 19:14:48 +0000 (19:14 +0000)
29 files changed:
includes/Article.php
includes/DefaultSettings.php
includes/DifferenceEngine.php
includes/ImagePage.php
includes/LogPage.php
includes/SearchEngine.php
includes/Skin.php
includes/SkinPHPTal.php
includes/SpecialAsksql.php
includes/SpecialBlockip.php
includes/SpecialContributions.php
includes/SpecialDebug.php
includes/SpecialIpblocklist.php
includes/SpecialLockdb.php
includes/SpecialMakesysop.php
includes/SpecialNewpages.php
includes/SpecialPage.php
includes/SpecialSpecialpages.php
includes/SpecialUnlockdb.php
includes/SpecialUserlevels.php
includes/Title.php
includes/User.php
index.php
languages/Language.php
maintenance/archives/patch-userlevels-defaultgroups.sql [new file with mode: 0644]
maintenance/parserTests.txt
maintenance/postgresql/pg_tables.sql
skins/CologneBlue.php
skins/Standard.php

index 8047430..fdb9d46 100644 (file)
@@ -885,7 +885,7 @@ class Article {
                # If we have been passed an &rcid= parameter, we want to give the user a
                # chance to mark this new article as patrolled.
                if ( $wgUseRCPatrol && !is_null ( $rcid ) && $rcid != 0 && $wgUser->getID() != 0 &&
-                    ( $wgUser->isSysop() || !$wgOnlySysopsCanPatrol ) )
+                    ( $wgUser->isAllowed('patrol') || !$wgOnlySysopsCanPatrol ) )
                {
                        $wgOut->addHTML( wfMsg ( 'markaspatrolledlink',
                                $sk->makeKnownLinkObj ( $this->mTitle, wfMsg ( 'markaspatrolledtext' ),
@@ -1284,7 +1284,7 @@ class Article {
                        $wgOut->loginToUse();
                        return;
                }
-               if ( $wgOnlySysopsCanPatrol && !$wgUser->isSysop() )
+               if ( $wgOnlySysopsCanPatrol && !$wgUser->isAllowed('patrol') )
                {
                        $wgOut->sysopRequired();
                        return;
@@ -1355,7 +1355,7 @@ class Article {
        function protect( $limit = 'sysop' ) {
                global $wgUser, $wgOut, $wgRequest;
 
-               if ( ! $wgUser->isSysop() ) {
+               if ( ! $wgUser->isAllowed('protect') ) {
                        $wgOut->sysopRequired();
                        return;
                }
@@ -1482,7 +1482,7 @@ class Article {
                # This code desperately needs to be totally rewritten
 
                # Check permissions
-               if ( ( ! $wgUser->isSysop() ) ) {
+               if ( ( ! $wgUser->isAllowed('delete') ) ) {
                        $wgOut->sysopRequired();
                        return;
                }
@@ -1790,7 +1790,7 @@ class Article {
                global $wgUser, $wgOut, $wgRequest;
                $fname = 'Article::rollback';
 
-               if ( ! $wgUser->isSysop() ) {
+               if ( ! $wgUser->isAllowed('rollback') ) {
                        $wgOut->sysopRequired();
                        return;
                }
index 093a375..06b7b3a 100644 (file)
@@ -807,6 +807,14 @@ $wgBrowserBlackList = array(
 # $wgLocaltimezone = 'Europe/Sweden';
 # $wgLocaltimezone = 'CET';
 
+# User level management
+# The number is the database id of a group you want users to be attached by
+# default. A better interface should be coded [av]
+$wgAnonGroupId = 1;
+$wgLoggedInGroupId = 2;
+
+$wgWhitelistRead = array ( ':Accueil', ':Main_Page');
+
 } else {
        die();
 }
index e1cfa32..09c9a80 100644 (file)
@@ -109,14 +109,14 @@ class DifferenceEngine {
                        'target=' . urlencode($this->mOldUser) );
                $newContribs = $sk->makeKnownLinkObj( Title::makeTitle( NS_SPECIAL, 'Contributions' ), $contribs,
                        'target=' . urlencode($this->mNewUser) );
-               if ( !$this->mNewid && $wgUser->isSysop() ) {
+               if ( !$this->mNewid && $wgUser->isAllowed('rollback') ) {
                        $rollback = '&nbsp;&nbsp;&nbsp;<strong>[' . $sk->makeKnownLinkObj( $wgTitle, wfMsg( 'rollbacklink' ),
                                'action=rollback&from=' . urlencode($this->mNewUser) ) . ']</strong>';
                } else {
                        $rollback = '';
                }
                if ( $wgUseRCPatrol && $this->mRcidMarkPatrolled != 0 && $wgUser->getID() != 0 &&
-                    ( $wgUser->isSysop() || !$wgOnlySysopsCanPatrol ) )
+                    ( $wgUser->isAllowed('rollback') || !$wgOnlySysopsCanPatrol ) )
                {
                        $patrol = ' [' . $sk->makeKnownLinkObj( $wgTitle, wfMsg( 'markaspatrolleddiff' ),
                                "action=markpatrolled&rcid={$this->mRcidMarkPatrolled}" ) . ']';
index e251b93..1a3b938 100644 (file)
@@ -159,7 +159,7 @@ class ImagePage extends Article {
                
                # Only sysops can delete images. Previously ordinary users could delete 
                # old revisions, but this is no longer the case.
-               if ( !$wgUser->isSysop() ) {
+               if ( !$wgUser->isAllowed('delete') ) {
                        $wgOut->sysopRequired();
                        return;
                }
index 1923048..68b73b2 100644 (file)
@@ -162,7 +162,13 @@ class LogPage {
                        return "$action $titleLink";
                }
        }
-       
+
+       /**
+        * Add a log entry
+        * @param string $action one of 'block', 'protect', 'rights', 'delete', 'upload'
+        * @param &$target
+        * @param string $comment Description associated
+        */
        function addEntry( $action, &$target, $comment ) {
                global $wgLang, $wgUser;
                
index 295b0be..58b8cf2 100644 (file)
@@ -1,5 +1,10 @@
 <?php
+/**
+ * Contain a class for special pages
+ * @package MediaWiki
+ */
 
+/** */
 class SearchEngine {
        var $limit = 10;
        var $offset = 0;
@@ -193,6 +198,7 @@ class SearchEngine {
        
 }
 
+/** */
 class SearchEngineDummy {
        function search( $term ) {
                return null;
@@ -200,4 +206,4 @@ class SearchEngineDummy {
 }
 
 
-?>
\ No newline at end of file
+?>
index 06bc505..16615f6 100644 (file)
@@ -294,7 +294,7 @@ class Skin {
                }
                else $a = array( 'bgcolor' => '#FFFFFF' );
                if($wgOut->isArticle() && $wgUser->getOption('editondblclick') &&
-                 (!$wgTitle->isProtected() || $wgUser->isSysop()) ) {
+                 (!$wgTitle->isProtected() || $wgUser->isAllowed('protect')) ) {
                        $t = wfMsg( 'editthispage' );
                        $oid = $red = '';
                        if ( !empty($redirect) && $redirect == 'no' ) {
@@ -597,7 +597,7 @@ class Skin {
 
        function getUndeleteLink() {
                global $wgUser, $wgTitle, $wgContLang, $action;
-               if( $wgUser->isSysop() &&
+               if( $wgUser->isAllowed('rollback') &&
                        (($wgTitle->getArticleId() == 0) || ($action == "history")) &&
                        ($n = $wgTitle->isDeleted() ) ) {
                        return wfMsg( 'thisisdeleted',
@@ -800,10 +800,11 @@ class Skin {
                                        }
                                }
                        }
-                       if ( $wgUser->isSysop() && $wgTitle->getArticleId() ) {
-                               $s .= "\n<br />" . $this->deleteThisPage() .
-                               $sep . $this->protectThisPage() .
-                               $sep . $this->moveThisPage();
+                       if ( $wgTitle->getArticleId() ) {
+                               $s .= "\n<br />";
+                               if($wgUser->isAllowed('delete')) { $s .= $this->deleteThisPage(); }
+                               if($wgUser->isAllowed('protect')) { $s .= $sep . $this->protectThisPage(); }
+                               if($wgUser->isAllowed('move')) { $s .= $sep . $this->moveThisPage(); }
                        }
                        $s .= "<br />\n" . $this->otherLanguages();
                }
@@ -1020,7 +1021,7 @@ class Skin {
                global $wgUser, $wgOut, $wgTitle, $wgRequest;
 
                $diff = $wgRequest->getVal( 'diff' );
-               if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
+               if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isAllowed('delete') ) {
                        $n = $wgTitle->getPrefixedText();
                        $t = wfMsg( 'deletethispage' );
 
@@ -1035,7 +1036,7 @@ class Skin {
                global $wgUser, $wgOut, $wgTitle, $wgRequest;
 
                $diff = $wgRequest->getVal( 'diff' );
-               if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isSysop() ) {
+               if ( $wgTitle->getArticleId() && ( ! $diff ) && $wgUser->isAllowed('protect') ) {
                        $n = $wgTitle->getPrefixedText();
 
                        if ( $wgTitle->isProtected() ) {
@@ -2220,7 +2221,7 @@ class Skin {
                                $diffLink = wfMsg( 'diff' );
                        } else {
                                if ( $wgUseRCPatrol && $rc_patrolled == 0 && $wgUser->getID() != 0 &&
-                                    ( $wgUser->isSysop() || !$wgOnlySysopsCanPatrol ) )
+                                    ( $wgUser->isAllowed('protect') || !$wgOnlySysopsCanPatrol ) )
                                        $rcidparam = "&rcid={$rc_id}";
                                else
                                        $rcidparam = "";
@@ -2242,7 +2243,7 @@ class Skin {
                        # If it's a new article, there is no diff link, but if it hasn't been
                        # patrolled yet, we need to give users a way to do so
                        if ( $wgUseRCPatrol && $rc_type == RC_NEW && $rc_patrolled == 0 &&
-                            $wgUser->getID() != 0 && ( $wgUser->isSysop() || !$wgOnlySysopsCanPatrol ) )
+                            $wgUser->getID() != 0 && ( $wgUser->isAllowed('patrol') || !$wgOnlySysopsCanPatrol ) )
                                $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '', "rcid={$rc_id}" );
                        else
                                $articleLink = $this->makeKnownLinkObj( $rc->getTitle(), '' );
@@ -2277,7 +2278,7 @@ class Skin {
                }
                # Block link
                $blockLink='';
-               if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
+               if ( ( 0 == $rc_user ) && $wgUser->isAllowed('block') ) {
                        $blockLink = $this->makeKnownLink( $wgContLang->specialPage(
                          'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
 
@@ -2379,7 +2380,7 @@ class Skin {
                $userTalkLink= $this->makeLink($utns . ':'.$rc_user_text, $talkname );
 
                global $wgDisableAnonTalk;
-               if ( ( 0 == $rc_user ) && $wgUser->isSysop() ) {
+               if ( ( 0 == $rc_user ) && $wgUser->isAllowed('block') ) {
                        $blockLink = $this->makeKnownLink( $wgContLang->specialPage(
                          'Blockip' ), wfMsg( 'blocklink' ), 'ip='.$rc_user_text );
                        if( $wgDisableAnonTalk )
@@ -2498,7 +2499,7 @@ class Skin {
                if ( $iscur ) {
                        $url = Image::wfImageUrl( $img );
                        $rlink = $cur;
-                       if ( $wgUser->isSysop() ) {
+                       if ( $wgUser->isAllowed('delete') ) {
                                $link = $wgTitle->escapeLocalURL( 'image=' . $wgTitle->getPartialURL() .
                                  '&action=delete' );
                                $style = $this->getInternalLinkAttributes( $link, $delall );
index f986ae4..9a68314 100644 (file)
@@ -208,7 +208,6 @@ class SkinPHPTal extends Skin {
                $tpl->set( "watch", $wgTitle->userIsWatching() ? "unwatch" : "watch" );
                $tpl->set( "protect", count($wgTitle->getRestrictions()) ? "unprotect" : "protect" );
                $tpl->set( "helppage", wfMsg('helppage'));
-               $tpl->set( "sysop", $wgUser->isSysop() );
                */
                $tpl->set( 'searchaction', $this->escapeSearchLink() );
                $tpl->setRef( 'stylepath', $wgStylePath );
@@ -474,9 +473,10 @@ class SkinPHPTal extends Skin {
                                        'href' => $this->makeUrl($this->thispage, 'action=rollback'),
                                        'ttip' => wfMsg('tooltip-rollback'),
                                        'akey' => wfMsg('accesskey-rollback'));
-                               }*/
+                               }
+                               */
 
-                               if($wgUser->isSysop()){
+                               if($wgUser->isAllowed('protect')){
                                        if(!$wgTitle->isProtected()){
                                                $content_actions['protect'] = array(
                                                        'class' => ($action == 'protect') ? 'selected' : false,
@@ -491,6 +491,8 @@ class SkinPHPTal extends Skin {
                                                        'href' => $this->makeUrl($this->thispage, 'action=unprotect')
                                                );
                                        }
+                               }
+                               if($wgUser->isAllowed('delete')){
                                        $content_actions['delete'] = array(
                                                'class' => ($action == 'delete') ? 'selected' : false,
                                                'text' => wfMsg('delete'),
@@ -507,7 +509,7 @@ class SkinPHPTal extends Skin {
                                }
                        } else {
                                //article doesn't exist or is deleted
-                               if($wgUser->isSysop()){
+                               if($wgUser->isAllowed('delete')){
                                        if( $n = $wgTitle->isDeleted() ) {
                                                $content_actions['undelete'] = array(
                                                        'class' => false,
index 666030b..f48eedc 100644 (file)
@@ -20,7 +20,7 @@ function wfSpecialAsksql() {
                $wgOut->errorpage( "nosuchspecialpage", "nospecialpagetext" );
                return;
        }
-       if( !$wgUser->isSysop() ) {
+       if( !$wgUser->isAllowed('asksql') ) {
                $wgOut->sysopRequired();
                return;
        }
index 34fde40..f3e1534 100644 (file)
@@ -12,7 +12,7 @@
 function wfSpecialBlockip() {
        global $wgUser, $wgOut, $wgRequest;
 
-       if ( ! $wgUser->isSysop() ) {
+       if ( ! $wgUser->isAllowed('block') ) {
                $wgOut->sysopRequired();
                return;
        }
index 9a97865..4b41a75 100644 (file)
@@ -198,8 +198,8 @@ function ucListEdit( $sk, $ns, $t, $ts, $topmark, $comment, $isminor, $isnew, $t
                } else {
                        $difftext .= wfMsg('newarticle');
                }
-               $sysop = $wgUser->isSysop();
-               if($sysop ) {
+               
+               if( $wgUser->isAllowed('rollback') ) {
                        $extraRollback = $wgRequest->getBool( 'bot' ) ? '&bot=1' : '';
                        # $target = $wgRequest->getText( 'target' );
                        $topmarktext .= ' ['. $sk->makeKnownLink( $page,
index b628128..cc82c0a 100644 (file)
@@ -11,7 +11,7 @@
 function wfSpecialDebug() {
        global $wgUser, $wgOut;
 
-       if ( ! $wgUser->isDeveloper() ) {
+       if ( ! $wgUser->isAllowed('siteadmin') ) {
                $wgOut->developerRequired();
                return;
        }
index 87d9e39..71f8ec1 100644 (file)
@@ -21,7 +21,7 @@ function wfSpecialIpblocklist() {
                $msg = wfMsg( "ipusuccess", htmlspecialchars( $ip ) );
                $ipu->showList( $msg );
        } else if ( "submit" == $action && $wgRequest->wasPosted() ) {
-               if ( ! $wgUser->isSysop() ) {
+               if ( ! $wgUser->isAllowed('block') ) {
                        $wgOut->sysopRequired();
                        return;
                }
@@ -161,7 +161,7 @@ function wfAddRow( $block, $tag ) {
                $wgOut->addHTML( " ({$clink})" );
        }
 
-       if ( $wgUser->isSysop() ) {
+       if ( $wgUser->isAllowed('block') ) {
                $titleObj = Title::makeTitle( NS_SPECIAL, "Ipblocklist" );
                $ublink = "<a href=\"" . 
                  $titleObj->escapeLocalURL( "action=unblock&ip=" . urlencode( $addr ) ) . "\">" .
index bbc8e7e..1635aa4 100644 (file)
@@ -12,7 +12,7 @@ function wfSpecialLockdb()
 {
        global $wgUser, $wgOut, $wgRequest;
 
-       if ( ! $wgUser->isDeveloper() ) {
+       if ( ! $wgUser->isAllowed('siteadmin') ) {
                $wgOut->developerRequired();
                return;
        }
index ef3d0f2..57eb11b 100644 (file)
@@ -1,10 +1,14 @@
 <?php
 /**
- *
+ * File is replaced by SpecialUserlevels. It is kept here for migration purposes
  * @package MediaWiki
  * @subpackage SpecialPage
+ * @deprecated
  */
 
+wfDebugDieBacktrace('Use SpecialUserlevels instead !!'); // [av]
+
+
 /**
  *
  */
@@ -20,7 +24,7 @@ function wfSpecialMakesysop() {
                $wgOut->errorpage( "movenologin", "movenologintext" );
                return;
        }
-       if (! $wgUser->isBureaucrat() && ! $wgUser->isDeveloper() ){
+       if (! $wgUser->isAllowed('userrights') ) {
                $wgOut->errorpage( "bureaucrattitle", "bureaucrattext" );
                return;
        }
index 33a4a00..123ab1d 100644 (file)
@@ -30,7 +30,7 @@ class NewPagesPage extends QueryPage {
        function getSQL() {
                global $wgUser, $wgOnlySysopsCanPatrol, $wgUseRCPatrol;
                $usepatrol = ( $wgUseRCPatrol && $wgUser->getID() != 0 &&
-                              ( $wgUser->isSysop() || !$wgOnlySysopsCanPatrol ) ) ? 1 : 0;
+                              ( $wgUser->isAllowed('patrol') || !$wgOnlySysopsCanPatrol ) ) ? 1 : 0;
                $dbr =& wfGetDB( DB_SLAVE );
                extract( $dbr->tableNames( 'recentchanges', 'cur' ) );
 
@@ -74,7 +74,7 @@ class NewPagesPage extends QueryPage {
                # mark the article as patrolled if it isn't already
                if ( $wgUseRCPatrol && !is_null ( $result->usepatrol ) && $result->usepatrol &&
                     $result->patrolled == 0 && $wgUser->getID() != 0 &&
-                    ( $wgUser->isSysop() || !$wgOnlySysopsCanPatrol ) )
+                    ( $wgUser->isAllowed('patrol') || !$wgOnlySysopsCanPatrol ) )
                        $link = $skin->makeKnownLink( $result->title, '', "rcid={$result->rcid}" );
                else
                        $link = $skin->makeKnownLink( $result->title, '' );
index 767b2c7..8a299e5 100644 (file)
@@ -27,7 +27,7 @@ $wgSpecialPages = array(
        'BrokenRedirects'       => new UnlistedSpecialPage ( 'BrokenRedirects' ),
        'Disambiguations'       => new UnlistedSpecialPage ( 'Disambiguations' ),
        
-       'Userlogin'         => new SpecialPage( 'Userlogin' ),
+       'Userlogin'         => new SpecialPage( 'Userlogin', 'createaccount' ),
        'Userlogout'        => new UnlistedSpecialPage( 'Userlogout' ),
        'Preferences'       => new SpecialPage( 'Preferences' ),
        'Watchlist'         => new SpecialPage( 'Watchlist' ),
@@ -80,17 +80,18 @@ $wgSpecialPages = array_merge($wgSpecialPages, array (
        'Allmessages'   => new SpecialPage( 'Allmessages' ),
        'Search'                => new UnlistedSpecialPage( 'Search' ),
        'Log'           => new SpecialPage( 'Log' ),
-       'Blockip'               => new SpecialPage( 'Blockip', 'sysop' ),
-       'Asksql'                => new SpecialPage( 'Asksql', 'sysop' ),
-       'Undelete'              => new SpecialPage( 'Undelete', 'sysop' ),
-       'Makesysop'             => new SpecialPage( 'Makesysop', 'sysop' ),
+       'Blockip'               => new SpecialPage( 'Blockip', 'block' ),
+       'Asksql'                => new SpecialPage( 'Asksql', 'asksql' ),
+       'Undelete'              => new SpecialPage( 'Undelete', 'delete' ),
+       // Makesysop is obsolete, replaced by Special:Userlevels [av]
+       # 'Makesysop'           => new SpecialPage( 'Makesysop', 'userrights' ),
 
 # Special:Import is half-written
 #      "Import"                => new SpecialPage( "Import", "sysop" ),
-       'Lockdb'                => new SpecialPage( 'Lockdb', 'developer' ),
-       'Unlockdb'              => new SpecialPage( 'Unlockdb', 'developer' ),
-       'Sitesettings'  => new SpecialPage( 'Sitesettings', 'sysop' ),
-       'Userlevels'    => new SpecialPage( 'Userlevels', 'sysop' ),
+       'Lockdb'                => new SpecialPage( 'Lockdb', 'siteadmin' ),
+       'Unlockdb'              => new SpecialPage( 'Unlockdb', 'siteadmin' ),
+       'Sitesettings'  => new SpecialPage( 'Sitesettings', 'siteadmin' ),
+       'Userlevels'    => new SpecialPage( 'Userlevels', 'userrights' ),
 ));
 
 /**
index 041a22f..bc59328 100644 (file)
@@ -9,7 +9,7 @@
  *
  */
 function wfSpecialSpecialpages() {
-       global $wgLang, $wgOut, $wgUser;
+       global $wgLang, $wgOut, $wgUser, $wgAvailableRights;
        
        $wgOut->setRobotpolicy( 'index,nofollow' );
        $sk = $wgUser->getSkin();       
@@ -17,6 +17,24 @@ function wfSpecialSpecialpages() {
        # Get listable pages
        $pages = SpecialPage::getPages();
 
+       /** pages available to all */
+       wfSpecialSpecialpages_gen($pages[''],'spheading',$sk);
+
+       /** show pages splitted by user rights */
+       foreach($wgAvailableRights as $right) {
+               /** only show pages a user can access */
+               if( $wgUser->isAllowed($right) ) {
+                       /** some rights might not have any special page associated */
+                       if(isset($pages[$right])) {
+                       wfSpecialSpecialpages_gen($pages[$right], $right.'pheading', $sk);
+                       }
+               }
+       
+       }
+
+/** FIXME : spheading, sysopspheading, developerspheading need to be removed
+from language files [av] */
+/**
        # all users special pages
        wfSpecialSpecialpages_gen($pages[''],'spheading',$sk);
 
@@ -30,6 +48,7 @@ function wfSpecialSpecialpages() {
                wfSpecialSpecialpages_gen($pages['developer'],'developerspheading',$sk);
 
        }
+*/
 }
 
 /**
index f2d056e..fa674d7 100644 (file)
@@ -11,7 +11,7 @@
 function wfSpecialUnlockdb() {
        global $wgUser, $wgOut, $wgRequest;
 
-       if ( ! $wgUser->isDeveloper() ) {
+       if ( ! $wgUser->isAllowed('siteadmin') ) {
                $wgOut->developerRequired();
                return;
        }
index f7f68b3..ef71033 100644 (file)
@@ -11,7 +11,8 @@ require_once('Group.php');
 /** Entry point */
 function wfSpecialUserlevels($par=null) {
        global $wgRequest;
-//     print_r($_POST);
+       # Debug statement
+       // print_r($_POST);
        $form = new UserlevelsForm($wgRequest);
        $form->execute();
 }
@@ -54,7 +55,8 @@ class UserlevelsForm extends HTMLForm {
                        if($this->mRequest->getCheck('savegroup')) {
                                $this->saveGroup($this->mRequest->getVal('editgroup-name'),
                                                 $this->mRequest->getVal('editgroup-oldname'),
-                                                $this->mRequest->getVal('editgroup-description'));
+                                                $this->mRequest->getVal('editgroup-description'),
+                                                                $this->mRequest->getVal('editgroup-getrights'));
                        
                        } elseif($this->mRequest->getCheck('saveusergroups')) {
                                $this->saveUserGroups($this->mRequest->getVal('user-editname'),
@@ -70,9 +72,10 @@ class UserlevelsForm extends HTMLForm {
         * @param string $newname Group name.
         * @param string $oldname Old (current) group name.
         * @param string $description Group description.
-        * @todo FIXME : doesnt validate anything.
+        *
+        * @todo FIXME : doesnt validate anything. Log is incorrect.
         */
-       function saveGroup($newname, $oldname, $description) {
+       function saveGroup($newname, $oldname, $description, $rights) {
                $newame = trim($newname);
        
                if($oldname == '') {
@@ -86,7 +89,13 @@ class UserlevelsForm extends HTMLForm {
                // save stuff
                $g->setName($newname);
                $g->setDescription($description);
+               if(isset($rights)) { $g->setRights( implode(',',$rights) ); }
+               
                $g->save();
+
+               $log = new LogPage( 'rights' );
+               $log->addEntry( 'rights', Title::makeTitle( NS_SPECIAL, $g->getName()) , ' '.$g->getRights() );
+
        }
 
        /**
@@ -96,6 +105,8 @@ class UserlevelsForm extends HTMLForm {
         * @param string $username Username to apply changes to.
         * @param array $removegroup id of groups to be removed.
         * @param array $addgroup id of groups to be added.
+        *
+        * @todo Log groupname instead of group id.
         */
        function saveUserGroups($username,$removegroup,$addgroup) {
                $u = User::NewFromName($username);
@@ -112,12 +123,22 @@ class UserlevelsForm extends HTMLForm {
                $u->setID( $id );
 
                $groups = $u->getGroups();
+               $logcomment = ' ';
                // remove then add groups               
-               if(isset($removegroup)) { $groups = array_diff($groups, $removegroup); }
-               if(isset($addgroup)) { $groups = array_merge($groups, $addgroup); }
+               if(isset($removegroup)) {
+                       $groups = array_diff($groups, $removegroup);
+                       $logcomment .= implode( ' -', $removegroup);
+                       }
+               if(isset($addgroup)) {
+                       $groups = array_merge($groups, $addgroup);
+                       $logcomment .= implode( ' +', $addgroup );
+                       }
                // save groups in user object and database
                $u->setGroups($groups);
                $u->saveSettings();
+
+               $log = new LogPage( 'rights' );
+               $log->addEntry( 'rights', Title::makeTitle( NS_USER, $u->getName() ), $logcomment );
        }
 
        /**
@@ -143,7 +164,7 @@ class UserlevelsForm extends HTMLForm {
                                $this->textbox( 'user-editname' ) .
                                '<input type="submit" name="ssearchuser" value="'.wfMsg('editusergroup').'">'
                ));
-               $wgOut->addHTML( "</form>" );
+               $wgOut->addHTML( '</form>' );
        }
 
        /**
@@ -152,28 +173,33 @@ class UserlevelsForm extends HTMLForm {
         */
        function editGroupForm($groupID = 0) {
                global $wgOut;
-               
+
                if($this->mRequest->getVal('seditgroup')) {
                // fetch data if we edit a group
                        $g = Group::newFromID($groupID);
-                       $gName = $g->getName();
-                       $gDescription = $g->getDescription();
                        $fieldname = 'editgroup';
                } else {
                // default datas when we add a group
-                       $gName = '';
-                       $gDescription = '';
+                       $g = new group();
                        $fieldname = 'addgroup';
                }
 
+               $gName = $g->getName();
+               $gDescription = $g->getDescription();
+
+
                $wgOut->addHTML( "<form name=\"editGroup\" action=\"$this->action\" method=\"post\">".
                                '<input type="hidden" name="editgroup-oldname" value="'.$gName.'">');
                $wgOut->addHTML( $this->fieldset( $fieldname,
                        $this->textbox( 'editgroup-name', $gName ) .
                        $this->textareabox( 'editgroup-description', $gDescription ) .
+                       '<br /><table border="0" align="center"><tr><td>'.
+                       $this->HTMLSelectRights($g->getRights()).
+                       '</td></table>'.                        
                        '<input type="submit" name="savegroup" value="'.wfMsg('savegroup').'">'
                        ));
-               $wgOut->addHTML( "</form>" );
+
+               $wgOut->addHTML( "</form>\n" );
        }
 
        /**
@@ -201,7 +227,7 @@ class UserlevelsForm extends HTMLForm {
                                                 '<input type="hidden" name="user-editname" value="'.$username.'">');
                $wgOut->addHTML( $this->fieldset( 'editusergroup',
                        wfMsg('editing', $this->mRequest->getVal('user-editname')).'.<br />' .
-                       '<table border="0"><tr><td>'.
+                       '<table border="0" align="center"><tr><td>'.
                        $this->HTMLSelectGroups('groupsmember', $groups,true,6).
                        '</td><td>'.
                        $this->HTMLSelectGroups('groupsavailable', $groups,true,6,true).
@@ -209,7 +235,7 @@ class UserlevelsForm extends HTMLForm {
                        '<p>'.wfMsg('userlevels-groupshelp').'</p>'.
                        '<input type="submit" name="saveusergroups" value="'.wfMsg('saveusergroups').'">'
                        ));
-               $wgOut->addHTML( "</form>" );
+               $wgOut->addHTML( "</form>\n" );
        }
 
 
@@ -243,10 +269,25 @@ class UserlevelsForm extends HTMLForm {
                                $out .= 'value="'.$g->group_id.'">'.$g->group_name.'</option>';
                        }
                }
-                       
                $out .= '</select>';
                return $out;
        }
-
+       
+       function HTMLSelectRights($selected='') {
+               global $wgAvailableRights;
+               $out = '<select name="editgroup-getrights[]" multiple>';
+               $groupRights = explode(',',$selected);
+               
+               foreach($wgAvailableRights as $right) {
+               
+                       // check box when right exist
+                       if(in_array($right, $groupRights)) { $selected = 'selected'; }
+                       else { $selected = ''; }
+                                               
+                       $out .= '<option  '.$selected.' value="'.$right.'">'.$right.'</option>';
+               }
+               $out .= '</fieldset>';
+               return $out;
+       }
 }
 ?>
index c8ece2a..4b29f11 100644 (file)
@@ -755,13 +755,13 @@ class Title {
        function userCanEdit() {
                global $wgUser;
                if ( -1 == $this->mNamespace ) { return false; }
-               if ( NS_MEDIAWIKI == $this->mNamespace && !$wgUser->isSysop() ) { return false; }
+               if ( NS_MEDIAWIKI == $this->mNamespace && !$wgUser->isAllowed('editinterface') ) { return false; }
                # if ( 0 == $this->getArticleID() ) { return false; }
                if ( $this->mDbkeyform == '_' ) { return false; }
                # protect global styles and js
                if ( NS_MEDIAWIKI == $this->mNamespace 
                     && preg_match("/\\.(css|js)$/", $this->mTextform )
-                    && !$wgUser->isSysop() )
+                    && !$wgUser->isAllowed('editinterface') )
                { return false; }
                //if ( $this->isCssJsSubpage() and !$this->userCanEditCssJsSubpage() ) { return false; }
                # protect css/js subpages of user pages
@@ -769,10 +769,11 @@ class Title {
                # XXX: Find a way to work around the php bug that prevents using $this->userCanEditCssJsSubpage() from working
                if( Namespace::getUser() == $this->mNamespace
                        and preg_match("/\\.(css|js)$/", $this->mTextform )
-                       and !$wgUser->isSysop()
+                       and !$wgUser->isAllowed('editinterface')
                        and !preg_match('/^'.preg_quote($wgUser->getName(), '/').'\//', $this->mTextform) )
                { return false; }
                $ur = $wgUser->getRights();
+
                foreach ( $this->getRestrictions() as $r ) {
                        if ( '' != $r && ( ! in_array( $r, $ur ) ) ) {
                                return false;
@@ -790,15 +791,25 @@ class Title {
                global $wgUser;
                global $wgWhitelistRead;
                
-               if( 0 != $wgUser->getID() ) return true;
-               if( !is_array( $wgWhitelistRead ) ) return true;
-               
-               $name = $this->getPrefixedText();
-               if( in_array( $name, $wgWhitelistRead ) ) return true;
-               
-               # Compatibility with old settings
-               if( $this->getNamespace() == NS_MAIN ) {
-                       if( in_array( ':' . $name, $wgWhitelistRead ) ) return true;
+               if($wgUser->isAllowed('read')) {
+                       return true;
+               } else {
+                       $name = $this->getPrefixedText();
+
+                       /** user can create an account */
+                       if($wgUser->isAllowed('createaccount')
+                          && $name == 'Special:Userlogin') { return true; }
+                        else { 
+                        echo $name;
+                        print_r($wgUser->getRights());
+                        }
+
+                       /** some pages are explicitly allowed */
+                       if( in_array( $name, $wgWhitelistRead ) ) return true;
+                       # Compatibility with old settings
+                       if( $this->getNamespace() == NS_MAIN ) {
+                               if( in_array( ':' . $name, $wgWhitelistRead ) ) return true;
+                       }
                }
                return false;
        }
@@ -837,7 +848,7 @@ class Title {
         */
        function userCanEditCssJsSubpage() {
                global $wgUser;
-               return ( $wgUser->isSysop() or preg_match('/^'.preg_quote($wgUser->getName(), '/').'\//', $this->mTextform) );
+               return ( $wgUser->isAllowed('editinterface') or preg_match('/^'.preg_quote($wgUser->getName(), '/').'\//', $this->mTextform) );
        }
 
        /**
index 162cb29..7f0bce7 100644 (file)
@@ -9,6 +9,7 @@
  *
  */
 require_once( 'WatchedItem.php' );
+require_once( 'Group.php' );
 
 # Number of characters in user_token field
 define( 'USER_TOKEN_LENGTH', 32 );
@@ -326,16 +327,21 @@ class User {
         * Load a user from the database
         */
        function loadFromDatabase() {
-               global $wgCommandLineMode;
+               global $wgCommandLineMode, $wgAnonGroupId, $wgLoggedInGroupId;
                $fname = "User::loadFromDatabase";
                if ( $this->mDataLoaded || $wgCommandLineMode ) {
                        return;
                }
-               
+
                # Paranoia
                $this->mId = IntVal( $this->mId );
 
+               /** Anonymous user */
                if(!$this->mId) {
+                       /** Get rights */
+                       $anong = Group::newFromId($wgAnonGroupId);
+                       $anong->loadFromDatabase();
+                       $this->mRights = explode(',', $anong->getRights());
                        $this->mDataLoaded = true;
                        return;
                } # the following stuff is for non-anonymous users only
@@ -354,16 +360,28 @@ class User {
                        $this->decodeOptions( $s->user_options );
                        $this->mTouched = wfTimestamp(TS_MW,$s->user_touched);
                        $this->mToken = $s->user_token;
-                       
-                       $this->mRights = explode( ",", strtolower( 
-                               $dbr->selectField( 'user_rights', 'ur_rights', array( 'ur_user' => $this->mId ) )
-                       ) );
-                       
+
                        // Get groups id
                        $res = $dbr->select( 'user_groups', array( 'ug_group' ), array( 'ug_user' => $this->mId ) );
+
                        while($group = $dbr->fetchRow($res)) {
                                $this->mGroups[] = $group[0];
                        }
+
+                       // add the default group for logged in user
+                       $this->mGroups[] = $wgLoggedInGroupId;
+
+                       $this->mRights = array();
+                       // now we merge groups rights to get this user rights
+                       foreach($this->mGroups as $aGroupId) {
+                               $g = Group::newFromId($aGroupId);
+                               $g->loadFromDatabase();
+                               $this->mRights = array_merge($this->mRights, explode(',', $g->getRights()));
+                       }
+                       
+                       // array merge duplicate rights which are part of several groups
+                       $this->mRights = array_unique($this->mRights);
+                       
                        $dbr->freeResult($res);
                }
 
@@ -557,29 +575,46 @@ class User {
                $this->invalidateCache();
        }
 
+       /**
+        * Check if a user is sysop
+        * Die with backtrace. Use User:isAllowed() instead.
+        * @deprecated
+        */
        function isSysop() {
+       /**
                $this->loadFromDatabase();
                if ( 0 == $this->mId ) { return false; }
 
                return in_array( 'sysop', $this->mRights );
+       */
+       wfDebugDieBacktrace("User::isSysop() is deprecated. Use User::isAllowed() instead");
        }
 
+       /** @deprecated */
        function isDeveloper() {
+       /**
                $this->loadFromDatabase();
                if ( 0 == $this->mId ) { return false; }
 
                return in_array( 'developer', $this->mRights );
+       */
+       wfDebugDieBacktrace("User::isDeveloper() is deprecated. Use User::isAllowed() instead");
        }
 
+       /** @deprecated */
        function isBureaucrat() {
+       /**
                $this->loadFromDatabase();
                if ( 0 == $this->mId ) { return false; }
 
                return in_array( 'bureaucrat', $this->mRights );
+       */
+       wfDebugDieBacktrace("User::isBureaucrat() is deprecated. Use User::isAllowed() instead");
        }
 
        /**
         * Whether the user is a bot
+        * @todo need to be migrated to the new user level management sytem
         */
        function isBot() {
                $this->loadFromDatabase();
@@ -590,6 +625,16 @@ class User {
                return in_array( 'bot', $this->mRights );
        }
 
+       /**
+        * Check if user is allowed to access a feature / make an action
+        * @param string $action Action to be checked (see $wgAvailableRights in Defines.php for possible actions).
+        * @return boolean True: action is allowed, False: action should not be allowed
+        */
+       function isAllowed($action='') {
+               $this->loadFromDatabase();
+               return in_array( $action , $this->mRights );
+       }
+
        /**
         * Load a skin if it doesn't exist or return it
         * @todo FIXME : need to check the old failback system [AV]
@@ -775,6 +820,7 @@ class User {
                
                // delete old groups
                $dbw->delete( 'user_groups', array( 'ug_user' => $this->mId), $fname);
+               
                // save new ones
                foreach ($this->mGroups as $group) {
                        $dbw->replace( 'user_groups',
@@ -827,8 +873,8 @@ class User {
                $this->mId = $dbw->insertId();
                $dbw->insert( 'user_rights',
                        array(
-                               'ur_user' => $this->mId,
-                               'ur_rights' => implode( ',', $this->mRights )
+                               'ur_user_id' => $this->mId,
+                               'ur_user_rights' => implode( ',', $this->mRights )
                        ), $fname
                );
                
index e4d71b5..1386b26 100644 (file)
--- a/index.php
+++ b/index.php
@@ -50,6 +50,9 @@ if ( "" == $title && "delete" != $action ) {
 }
 wfProfileOut( "main-misc-setup" );
 
+# Debug statement for user levels
+// print_r($wgUser);
+
 # If the user is not logged in, the Namespace:title of the article must be in
 # the Read array in order for the user to see it. (We have to check here to
 # catch special pages etc. We check again in Article::view())
index 0255244..3627658 100644 (file)
@@ -1030,8 +1030,17 @@ That comes to '''$5''' average edits per page, and '''$6''' views per edit.",
 'listadmins'   => 'Admins list',
 'specialpages' => 'Special pages',
 'spheading'            => 'Special pages for all users',
+'asksqlpheading' => 'asksql level',
+'blockpheading' => 'block level',
+'createaccountpheading' => 'createaccount level',
+'deletepheading' => 'delete level',
+'userrightspheading' => 'userrights level',
+'siteadminpheading' => 'siteadmin level',
+
+/** obsoletes
 'sysopspheading' => 'For sysop use only',
 'developerspheading' => 'For developer use only',
+*/
 'protectpage'  => 'Protect page',
 'recentchangeslinked' => 'Related changes',
 'rclsub'               => "(to pages linked from \"$1\")",
diff --git a/maintenance/archives/patch-userlevels-defaultgroups.sql b/maintenance/archives/patch-userlevels-defaultgroups.sql
new file mode 100644 (file)
index 0000000..1b4eca1
--- /dev/null
@@ -0,0 +1,10 @@
+--
+-- Provide default groups
+-- Should probably be inserted when someone create a new database
+--
+
+INSERT INTO `group` VALUES (1,'Anonymous','Anonymous users','read,edit,createaccount');
+INSERT INTO `group` VALUES (2,'Loggedin','General logged in users','read,edit,move,upload');
+INSERT INTO `group` VALUES (3,'Sysops','Operators of this site','read,edit,move,delete,undelete,protect,block,upload,asksql,rollback,patrol,editinterface');
+INSERT INTO `group` VALUES (4,'Bureaucrat','The bureaucrat group is able to make sysops for example. They have no other rights.','read,edit,move,delete,undelete,protect,block,userrights,createaccount,upload,asksql,rollback,patrol,editinterface,siteadmin');
+
index 96dd225..904be04 100644 (file)
@@ -1774,4 +1774,3 @@ more tables
 math
 character entities
 and much more
-
index c928889..27a89ac 100644 (file)
@@ -281,7 +281,7 @@ CREATE TABLE "group" (
 
 -- Relation table between user and groups
 CREATE TABLE user_groups (
-       user_id integer NOT NULL,
-       group_id integer NOT NULL,
+       ug_user integer NOT NULL,
+       ug_group integer NOT NULL,
        PRIMARY KEY  (user_id,group_id)
 );
index 665f5d7..7b709cf 100644 (file)
@@ -185,11 +185,13 @@ class SkinCologneBlue extends Skin {
                        if ( 0 != $wgUser->getID() ) {
                                $s .= $sep . $this->moveThisPage();
                        }
-                       if ( $wgUser->isSysop() ) {
+                       if ( $wgUser->isAllowed('delete') ) {
                                $dtp = $this->deleteThisPage();
                                if ( "" != $dtp ) {
                                        $s .= $sep . $dtp;
                                }
+                       }
+                       if ( $wgUser->isAllowed('protect') ) {
                                $ptp = $this->protectThisPage();
                                if ( "" != $ptp ) {
                                        $s .= $sep . $ptp;
index 67d82e1..6c71c66 100644 (file)
@@ -227,7 +227,7 @@ class SkinStandard extends Skin {
                                if ( $wgTitle->userCanEdit() )
                                        $s .= $sep . $this->moveThisPage();
                        }
-                       if ( $wgUser->isSysop() and $articleExists ) {
+                       if ( $wgUser->isAllowed('delete') and $articleExists ) {
                                $s .= $sep . $this->deleteThisPage() .
                                $sep . $this->protectThisPage();
                        }