Jump to content

Extension:NamespacePermissions

From mediawiki.org
Revision as of 17:17, 8 November 2006 by 63.163.61.3 (talk) (Examples)

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 NamespacePermissions.php to "extensions" folder. (source see below)
  • Add a line require_once( "extensions/NamespacePermissions.php" ); at the end of "LocalSettings.php" (or at least after declaring your custom namespaces, i.e. after setting $wgExtraNamespaces).
  • Optionally set up permissions for existing groups via $wgGroupPermissions (see Help:User rights)
  • Use Special:Userrights to assign groups (including groups provided by the extension, see below) to users

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)

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


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

<?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:
 *
 * $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 null;
}
?>

Pitfalls

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


Questions

Security issues

Warning! There's some security issues with the externsion:

  • Can we disable searches in a "hidden" namespace?
  • 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.

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. Hvor do I create content that goes into the 100 namespace?

Examples

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,
);

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:

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;

// Implicit group for all visitors
#$wgGroupPermissions['*'    ]['read']            = false;
#$wgGroupPermissions['*'    ]['edit']            = false; # actually, this is overridden by title.php - namespace 104 cannot be edited, all others can
#$wgGroupPermissions['*'    ]['createpage']      = false;
#$wgGroupPermissions['*'    ]['createtalk']      = true;
#$wgGroupPermissions['*'    ]['talk']            = true;

# 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;

# regular pages
$wgGroupPermissions[ 'user' ][ 'ns0_read' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns0_edit' ] = true;
$wgGroupPermissions[ 'user' ][ 'ns0_create' ] = true;


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;
}