Extension:NamespacePermissions

From MediaWiki.org

Jump to: navigation, search
If you need per-page or partial page access restrictions, you are advised to install an appropriate content management package. MediaWiki was not written to provide per-page access restrictions, and almost all hacks or patches promising to add them will likely have flaws somewhere, which could lead to exposure of confidential data. We are not responsible for anything being leaked, leading to loss of funds or one's job.
For further details, see Security issues with authorization extensions


Manual on MediaWiki Extensions
List of MediaWiki Extensions
NamespacePermissions

Release status: unknown

Implementation User rights
Description provides flexible access management for custom namespaces
Author(s) Petr Andreev
Download see below
Hooks used

userCan

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.

Contents

[edit] Installation and usage

  1. Copy NamespacePermissions.php to your MediaWiki extensions folder. (For source, see below.)
  2. Add the following line at the end of LocalSettings.php (or at least after declaring your custom namespaces, i.e. after setting $wgExtraNamespaces):
    require_once( "extensions/NamespacePermissions.php" );
    
  3. Optionally set up permissions for existing groups via $wgGroupPermissions (see Help:User rights).
  4. Use Special:Userrights to assign groups (including groups provided by the extension) to users.

[edit] Permissions provided

  1. ns{$num}_read
  2. ns{$num}_edit
  3. ns{$num}_create
  4. ns{$num}_move

where {$num} - namespace number (e.g. ns100_read, ns101_create). You can use these with the $wgGroupPermissions variable in LocalSettings.php to set permissions on your extra namespaces for many users at once. See the example below.

[edit] Groups provided

  1. ns{$title}RW - full access to the namespace {$title} (all permissions for the namespace granted)
  2. ns{$title}RO - read-only access to the namespace {$title} (only read permission granted)

e.g. nsFoo_talkRW, nsFooRO. 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 $wgExtraNamespaces.

[edit] 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');

[edit] Source of NamespacePermissions.php

<?php
 /* NamespacePermissions - MediaWiki extension
  * 
  * provides separate permissions for each action (read,edit,create,move) 
  * on articles in custom namespaces for fine access management
  *
  * Author: Petr Andreev
  *
  * Sample usage:3
  *
  * $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');
  * 
  * 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 true;
 }
 
 /**
 * Add extension information to Special:Version
 */
 $wgExtensionCredits['other'][] = array(
        'name' => 'NamespacePermissions',
        'version' => '',
        'author' => 'Petr Andreev',
        'description' => 'flexible access management for custom namespaces',
        'url' => 'http://www.mediawiki.org/wiki/Extension:NamespacePermissions'
        );

[edit] Pitfalls

Warning
  • By default there is a limitation concerning the length of the title for a namespace, see Discussion.


[edit] Questions

[edit] 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 {{:Forbidden_Namespace:Secret_page}} in a authorised namespace gives complete content!)
Answer: Solutions, workarounds and ideas to these problems are in the discussion page.

[edit] 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.

[edit] 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?

[edit] Examples

The macro "define()" should be used to create extra-namespaces in LocalSettings.php. e.g.

define('NS_ADMIN', 100);
define('NS_BLOG', 102);

[edit] Namespace for all to read, but limited edit rights

#LocalSettings.php
$wgExtraNamespaces =
        array(100 => "NS1",
              101 => "NS1_Diskussion",
              102 => "NS2",
              103 => "NS2_Diskussion",
              104 => "READ_ONLY",
              105 => "READ_ONLY_Diskussion",
              );
 
$wgGroupPermissions[ '*' ][ 'ns104_read' ] = true;
require('extensions/NamespacePermissions.php');
 
#include READ_ONLY in default search
$wgNamespacesToBeSearchedDefault = array(
        NS_MAIN           => true,
        NS_HELP           => true,
        NS_TEMPLATE       => true,
        NS_CATEGORY       => true,
        104               => true,
);

[edit] 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:
      1. Users with logins click here to see ABC pages
      2. 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:

[edit] LocalSettings.php

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

# custom namespaces: 8700sql and sim manuals, "public" for external pages.
$wgExtraNamespaces =
        array(100 => "Custom1",
              101 => "Custom1_talk",
              102 => "Custom2",
              103 => "Custom2_talk",
              104 => "Public",
              105 => "Public_talk"
              );
 
$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 );
 
 
 
### ====================================== PERMISSIONS ###
 
# no one can create accounts except for SYS OP users
$wgGroupPermissions['*']['createaccount'] = false;
 
# custom1 namespace
$wgGroupPermissions[ '*' ][ 'ns100_read' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns100_edit' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns100_create' ] = true;
 
# custom1 talk namespace
$wgGroupPermissions[ '*' ][ 'ns101_read' ] = true;
$wgGroupPermissions[ '*' ][ 'ns101_edit' ] = true;
$wgGroupPermissions[ '*' ][ 'ns101_create' ] = true;
 
# custom2 namespace
$wgGroupPermissions[ '*' ][ 'ns102_read' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns102_edit' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns102_create' ] = true;
 
# custom2 talk namespace
$wgGroupPermissions[ '*' ][ 'ns103_read' ] = true;
$wgGroupPermissions[ '*' ][ 'ns103_edit' ] = true;
$wgGroupPermissions[ '*' ][ 'ns103_create' ] = true;
 
# Public namespace ### everyone can read, only users can edit/create
$wgGroupPermissions[ '*' ][ 'ns104_read' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns104_edit' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns104_create' ] = true;
 
# Public talk namespace ### everyone can read/edit/create
$wgGroupPermissions[ '*' ][ 'ns105_read' ] = true;
$wgGroupPermissions[ '*' ][ 'ns105_edit' ] = true;
$wgGroupPermissions[ '*' ][ 'ns105_create' ] = true;
 
# special pages
$wgGroupPermissions[ '*' ][ 'ns-1_read' ] = true;
$wgGroupPermissions[ '*' ][ 'ns-1_edit' ] = true;
$wgGroupPermissions[ '*' ][ 'ns-1_create' ] = true;
 
# regular pages
$wgGroupPermissions[ 'user' ][ 'ns0_read' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns0_edit' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns0_create' ] = true;
$wgGroupPermissions[ 'bureaucrat' ][ 'ns0_move' ] = true;
 
# regular talk pages
$wgGroupPermissions[ 'user' ][ 'ns1_read' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns1_edit' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns1_create' ] = true;
 
# user pages
$wgGroupPermissions[ 'user' ][ 'ns2_read' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns2_edit' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns2_create' ] = true;
 
# images
$wgGroupPermissions[ 'user' ][ 'ns6_read' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns6_edit' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns6_create' ] = true;
 
# mediawiki pages
$wgGroupPermissions[ 'bureaucrat' ][ 'ns8_read' ] = true;
$wgGroupPermissions[ 'bureaucrat' ][ 'ns8_edit' ] = true;
$wgGroupPermissions[ 'bureaucrat' ][ 'ns8_create' ] = true;
 
# templates
$wgGroupPermissions[ 'user' ][ 'ns10_read' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns10_edit' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns10_create' ] = true;
 
# help
$wgGroupPermissions[ 'user' ][ 'ns12_read' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns12_edit' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns12_create' ] = true;
 
# categories
$wgGroupPermissions[ 'user' ][ 'ns14_read' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns14_edit' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns14_create' ] = true;
 
require_once( "extensions/NamespacePermissions.php" );

[edit] 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;
}

--Axelseaa 19:49, 14 January 2008 (UTC)The example above does not allow the user to logout - keep that in mind if you are going to try this at home. Another easy solution would be to check for namespaces equal to or greater than 0. That would leave the special pages alone.

[edit] 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.

[edit] 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;
 }

[edit] See also

If you use MediaWiki 1.10 or above, you want to look at Extension:Lockdown. While it does the same thing, it is safer.

Personal tools