Extension:NamespacePermissions

Introduction
NamespacePermissions is a Mediawiki extension which provides flexible access management for custom namespaces.

It uses separate permissions for each action (read,edit,create,move) on each custom namespace for granting access to the articles in those namespaces.

Author
Petr Andreev User:Oduvan

Installation and usage
 Copy to your MediaWiki folder. (For source, see below.)

Add the following line at the end of  (or at least after declaring your custom namespaces, i.e. after setting  ):

require_once( "extensions/NamespacePermissions.php" );

Optionally set up permissions for existing groups via (see Help:User rights).

Use Special:Userrights to assign groups (including groups provided by the extension) to users.



Permissions provided
where  - namespace number (e.g. ,  ). You can use these with the variable in  to set permissions on your extra namespaces for many users at once. See the example below.

Groups provided
e.g.,. These groups are for granting permission to one existing user at a time; the extension causes them to appear on the Special:Userrights page. The extension provides the above pair of groups for each extra namespace you defined in.
 * 1)   - full access to the namespace   (all permissions for the namespace granted)
 * 2)   - read-only access to the namespace   (only read permission granted)

Sample LocalSettings.php
$wgExtraNamespaces = array(100 => "Foo", 101 => "Foo_Talk"); // optional (example): allow registered users to view and edit articles in Foo $wgGroupPermissions[ 'user' ][ 'ns100_read' ] = true; $wgGroupPermissions[ 'user' ][ 'ns100_edit' ] = true; // end of optional require('extensions/NamespacePermissions.php');

Source of NamespacePermissions.php
 "Foo", 101 => "Foo_Talk"); * // optional (example): allow registered users to view and edit articles in Foo * $wgGroupPermissions[ 'user' ][ 'ns100_read' ] = true; * $wgGroupPermissions[ 'user' ][ 'ns100_edit' ] = true; * // end of optional * require('extensions/NamespacePermissions.php'); *  * Permissions provided: *  # ns{$num}_read *  # ns{$num}_edit *  # ns{$num}_create *  # ns{$num}_move * where {$num} - namespace number (e.g. ns100_read, ns101_create) * * Groups provided: *  # ns{$title}RW - full access to the namespace {$title} *  # ns{$title}RO - read-only access to the namespace {$title} *  e.g. nsFoo_talkRW, nsFooRO */ // permissions for autocreated groups should be set now, // before the User object for current user is instantiated namespacePermissionsCreateGroups; // other stuff should better be done via standard mechanism of running extensions $wgExtensionFunctions[] = "wfNamespacePermissions"; // create groups for each custom namespace function namespacePermissionsCreateGroups { global $wgExtraNamespaces, $wgGroupPermissions; foreach ( $wgExtraNamespaces as $num => $title ) { $wgGroupPermissions[ "ns{$title}RW" ][ "ns{$num}_edit" ] = true; $wgGroupPermissions[ "ns{$title}RW" ][ "ns{$num}_read" ] = true; $wgGroupPermissions[ "ns{$title}RW" ][ "ns{$num}_create" ] = true; $wgGroupPermissions[ "ns{$title}RW" ][ "ns{$num}_move" ] = true; $wgGroupPermissions[ "ns{$title}RO" ][ "ns{$num}_read" ] = true; } } function wfNamespacePermissions { global $wgHooks; // use the userCan hook to check permissions $wgHooks[ 'userCan' ][] = 'namespacePermissionsCheckNamespace'; } function namespacePermissionsCheckNamespace( $title, $user, $action, $result ) { if ( ( $ns = $title->getNamespace ) >= 100 ) { if ( ! $user->isAllowed("ns{$ns}_{$action}") ) { $result = false; return false; }    }      return null; } ?>

Security issues
Warning! There's some security issues with the extension:
 * Can we disable searches in a "hidden" namespace? Suggestion here.
 * Also, edits still show up in RecentChanges for regular users :-(.
 * Also, XML Export is available for regular users.
 * Also, Special:Allpages shows all pages, even in restricted namespaces.
 * Also, transcluding restricted page to open one can show the content (usage of in a authorised namespace gives complete content!)


 * Answer: Solutions, workarounds and ideas to these problems are in the discussion page.

Change 'view source' to 'edit' for namespaces editable by logged in users?
Is this possible? I want to deny a certain namespace edit rights only to not logged in users. So the 'view source' link is incongruous with Mediawiki's usual behavior of displaying an 'edit' link but then requiring login.

What about creating?
I've added a user to (and only to) the new groups. When this user saves new content it ends under namspace 0. How do I create content that goes into the 100 namespace?

Examples
The macro "define" should be used to create extra-namespaces in LocalSettings.php. e.g. define('NS_ADMIN', 100); define('NS_BLOG', 102);

namespace for all to read, but limited edit rights
$wgExtraNamespaces = array(100 => "NS1",	     101 => "NS1_Diskussion",		102 => "NS2",		103 => "NS2_Diskussion",		104 => "READ_ONLY",		105 => "READ_ONLY_Diskussion",	      );
 * 1) LocalSettings.php

$wgGroupPermissions[ '*' ][ 'ns104_read' ] = true; require('extensions/NamespacePermissions.php');

$wgNamespacesToBeSearchedDefault = array(	NS_MAIN          => true,	NS_HELP           => true,	NS_TEMPLATE       => true,	NS_CATEGORY       => true,	104               => true, );
 * 1) include READ_ONLY in default search

Further Configuration
The NamespacePermissions Extension works great for me, but I wanted to restrict all namespaces, not just the custom ones. I want to create this setup:
 * No one can read "main" pages unless logged in
 * Remember, need to give access to the "Main Page" and to "Special:Userlogin"
 * The "Main Page" on my wiki has two links:
 * Users with logins click here to see ABC pages
 * Users without logins click here to see XYZ pages
 * All users can read 100, 102, 104
 * Only logged-un users can edit/create 100, 102, 104
 * All users can read/edit/create 101, 103, 105 ("talk" namespaces for 100, 102, 104)

So here's what I did:

LocalSettings.php
In LocalSettings.php, I create the namespaces and give permissions:

$wgExtraNamespaces = array(100 => "Custom1",	     101 => "Custom1_talk",	      102 => "Custom2",	      103 => "Custom2_talk",	      104 => "Public",	      105 => "Public_talk"	      );
 * 1) custom namespaces: 8700sql and sim manuals, "public" for external pages.

$wgNamespacesToBeSearchedDefault = array( -1 => 0, NS_MAIN => 1, NS_USER => 1, NS_USER_TALK => 1, NS_PROJECT_TALK => 0, NS_IMAGE_TALK => 0,   NS_IMAGE_TALK => 0, NS_TEMPLATE_TALK => 0, NS_HELP_TALK => 0,   NS_CATEGORY_TALK => 1,   100 => 1, 101 => 1,  102 => 1, 103 => 1,  104 => 1, 105 => 1 );


 * 1) ====================================== PERMISSIONS ###

$wgGroupPermissions['*']['createaccount'] = false;
 * 1) no one can create accounts except for SYS OP users

$wgGroupPermissions[ '*' ][ 'ns100_read' ] = true; $wgGroupPermissions[ 'user' ][ 'ns100_edit' ] = true; $wgGroupPermissions[ 'user' ][ 'ns100_create' ] = true;
 * 1) custom1 namespace

$wgGroupPermissions[ '*' ][ 'ns101_read' ] = true; $wgGroupPermissions[ '*' ][ 'ns101_edit' ] = true; $wgGroupPermissions[ '*' ][ 'ns101_create' ] = true;
 * 1) custom1 talk namespace

$wgGroupPermissions[ '*' ][ 'ns102_read' ] = true; $wgGroupPermissions[ 'user' ][ 'ns102_edit' ] = true; $wgGroupPermissions[ 'user' ][ 'ns102_create' ] = true;
 * 1) custom2 namespace

$wgGroupPermissions[ '*' ][ 'ns103_read' ] = true; $wgGroupPermissions[ '*' ][ 'ns103_edit' ] = true; $wgGroupPermissions[ '*' ][ 'ns103_create' ] = true;
 * 1) custom2 talk namespace

$wgGroupPermissions[ '*' ][ 'ns104_read' ] = true; $wgGroupPermissions[ 'user' ][ 'ns104_edit' ] = true; $wgGroupPermissions[ 'user' ][ 'ns104_create' ] = true;
 * 1) Public namespace ### everyone can read, only users can edit/create

$wgGroupPermissions[ '*' ][ 'ns105_read' ] = true; $wgGroupPermissions[ '*' ][ 'ns105_edit' ] = true; $wgGroupPermissions[ '*' ][ 'ns105_create' ] = true;
 * 1) Public talk namespace ### everyone can read/edit/create

$wgGroupPermissions[ '*' ][ 'ns-1_read' ] = true; $wgGroupPermissions[ '*' ][ 'ns-1_edit' ] = true; $wgGroupPermissions[ '*' ][ 'ns-1_create' ] = true;
 * 1) special pages

$wgGroupPermissions[ 'user' ][ 'ns0_read' ] = true; $wgGroupPermissions[ 'user' ][ 'ns0_edit' ] = true; $wgGroupPermissions[ 'user' ][ 'ns0_create' ] = true; $wgGroupPermissions[ 'bureaucrat' ][ 'ns0_move' ] = true;
 * 1) regular pages

$wgGroupPermissions[ 'user' ][ 'ns1_read' ] = true; $wgGroupPermissions[ 'user' ][ 'ns1_edit' ] = true; $wgGroupPermissions[ 'user' ][ 'ns1_create' ] = true;
 * 1) regular talk pages

$wgGroupPermissions[ 'user' ][ 'ns2_read' ] = true; $wgGroupPermissions[ 'user' ][ 'ns2_edit' ] = true; $wgGroupPermissions[ 'user' ][ 'ns2_create' ] = true;
 * 1) user pages

$wgGroupPermissions[ 'user' ][ 'ns6_read' ] = true; $wgGroupPermissions[ 'user' ][ 'ns6_edit' ] = true; $wgGroupPermissions[ 'user' ][ 'ns6_create' ] = true;
 * 1) images

$wgGroupPermissions[ 'bureaucrat' ][ 'ns8_read' ] = true; $wgGroupPermissions[ 'bureaucrat' ][ 'ns8_edit' ] = true; $wgGroupPermissions[ 'bureaucrat' ][ 'ns8_create' ] = true;
 * 1) mediawiki pages

$wgGroupPermissions[ 'user' ][ 'ns10_read' ] = true; $wgGroupPermissions[ 'user' ][ 'ns10_edit' ] = true; $wgGroupPermissions[ 'user' ][ 'ns10_create' ] = true;
 * 1) templates

$wgGroupPermissions[ 'user' ][ 'ns12_read' ] = true; $wgGroupPermissions[ 'user' ][ 'ns12_edit' ] = true; $wgGroupPermissions[ 'user' ][ 'ns12_create' ] = true;
 * 1) help

$wgGroupPermissions[ 'user' ][ 'ns14_read' ] = true; $wgGroupPermissions[ 'user' ][ 'ns14_edit' ] = true; $wgGroupPermissions[ 'user' ][ 'ns14_create' ] = true;
 * 1) categories

require_once( "extensions/NamespacePermissions.php" );

NameSpacePermissions.php
I changed the namespacePermissionsCheckNamespace function. If the title is "Main Page" or "Special:Userlogin", allow them to see it. Otherwise, check the namespace permissions. Note that the -2 variable was changed from the original 100 variable because I want to perform the check on all namespaces, not just 100+.

function namespacePermissionsCheckNamespace( $title, $user, $action, $result ) { if ( $title->getPrefixedText == "Main Page" || $title->getPrefixedText == "Special:Userlogin" ) { return null; }

if ( ( $ns = $title->getNamespace ) >= -2 ) { if ( ! $user->isAllowed("ns{$ns}_{$action}") ) { $result = false; return false; }   	}

return null; }

SpecialSearch.php
To avoid nonpermitted searches in hidden namespaces i've had tuned the powerSearch function in SpecialSearch.php in an quick and dirty way:

function powerSearch( &$request ) { global $wgUser; $arr = array; foreach( SearchEngine::searchableNamespaces as $ns => $name ) { if( $request->getCheck( 'ns'. $ns ) ) { if ( $ns >= 100 ) { if ( $wgUser->isAllowed("ns{$ns}_read") ) { $arr[] = $ns; }                               } else { $arr[] = $ns; }                       }                }                return $arr; }

Sorry for the bad style.

Check $wgWhitelistRead
I changed the function namespacePermissionsCheckNamespace to check the $wgWhitelistRead Array.

function namespacePermissionsCheckNamespace( $title, $user, $action, $result ) {    # bh edited global $wgWhitelistRead; if ( in_array($title->getPrefixedText, $wgWhitelistRead) ) {       if( $action == "read" ) {               $result = true; return true; }    }     # end bh edited if ( ( $ns = $title->getNamespace ) >= -2 ) #bh Edited: -2 statt 100 {         if ( ! $user->isAllowed("ns{$ns}_{$action}") ) {           $result = false; return false; }   }     return null; }