Extension talk:Lockdown/LQT Archive 1

Difference to NamespacePermissions Extension ?
The meta:NamespacePermissions_Extension seems to fulfill the same purpose. Can you elaborate on the differences?

Well, basically, I found a lot of different extensions for more fine grained access restrictions, decided I didn't quite like any of them, and so I went ahead and wrote my own :) The main differences to NamespacePermissions_Extension seem to be:


 * NamespacePermissions only applies to custom namespaces (ID >= 100), Lockdown to any namespace
 * Lockdown also provides a mechanism for controlling access to individual pages in the Special pseudo-namespace.
 * NamespacePermissions only supports read, edit, create, and move, while Lockdown supports all permissions, including delete for example.
 * NamespacePermissions uses special permission names like $wgGroupPermissions[ 'user' ][ 'ns100_edit' ] = true; to manage permissions for individual namespaces; Lockdown uses $wgNamespacePermissionLockdown[100]['edit'] = array('user'), which I find cleaner.
 * NamespacePermissions uses special magic groups as a shortcut to granting or denying acces to a specific namespace - to grant a user full access to namespace 102, you would add it to the group ns102RW; Lockdown uses permission wildcards instead - to restrict all access to namespace 102 to members of group xxx, you would set $wgNamespacePermissionLockdown['102']['*'] = array('xxx');, which I like better.

In the process of writing the Lockdown extension, I also plugged some holes regarding read-permissions (the holes are still open in 1.9.x). NamespacePermissions would benefit from that too, of course. -- Duesentrieb ⇌ 23:14, 23 February 2007 (UTC)

Changes to Work on MediaWiki 1.8.2
I got this extensions working fine on MediaWiki 1.8.2 with one slight change. In includes/Title.php, add this function to the Title class:

function isSpecial( $page ) {	return (($this->getNsText == "Special") && ($this->getText == $page)); }

-- Adrianm 6 March 2007

Basic Namespace Security Fix
This fix improves the security of many of the Special pages by enforcing the namespace restrictions provided by the Lockdown extension. Specific fixes are also required for many of the Special pages, which are addressed below this section. Tested in MediaWiki 1.8.2 by Adrianm.

This fix relys on the fact that many (but not all) Sepcial pages use the $wgContLang->getNamespaces function located in languages/Language.php to obtain their list of available namespaces. No namespace checking is performed by this function in the default MediaWiki install, and it doesn't call the hook used by the Lockdown extension. So, we add a step to the getNamespaces function which filters out restricted namespaces whenever the array is retrieved. Since a lot of MediaWiki classes use this function, a small change code in this function fixes bugs in a lot of places.

The solution involves two steps. Firstly, add the following two functions to Lockdown.php:

/* Checks whether the given namespace is visible to the user who is logged in. function namespaceIsVisible($ns) {	global $wgNamespacePermissionLockdown, $wgUser;
 * @author Adrian Mikula
 * @return Boolean

$groups = @$wgNamespacePermissionLockdown[$ns]['read']; if (!$groups) $groups = @$wgNamespacePermissionLockdown['*']['read']; if (!$groups) $groups = @$wgNamespacePermissionLockdown[$ns]['*']; if (!$groups) return true;

$ugroups = $wgUser->getEffectiveGroups; $match = array_intersect($ugroups, $groups); if ($match) return true; return false; }

/* Removes hidden namespaces from an array of namespaces. function filterHiddenNamespaces($namespaces) {	foreach ( $namespaces as $ns => $name ) {		if (!namespaceIsVisible($ns)) {			unset($namespaces[$ns]); }	}	return $namespaces; }
 * @author Adrian Mikula
 * @return array

And secondly, modify the following function in Language.php

function getNamespaces { $this->load; return $this->namespaceNames; }

To look like this:

function getNamespaces { $this->load; return filterHiddenNamespaces($this->namespaceNames); }

Now, special pages which have dropdown combos (eg. Special:Allpages) or checkboxes (eg. Special:Search) listing namespaces won't display namespaces which are restricted using $wgNamespacePermissionLockdown</tt>. Please note that many Special pages have additional security flaws that also need to be fixed. -- Adrianm 7 March 2007

Default Namespace Fix
The purpose of this fix is to provide a secure way for Special pages to determine which namespace should be selected by default. Currently, most of the Special pages select the Main namespace by default, which is fine unless you wish to restrict access to the Main namespace. This fix assumes that the Basic Namespace Security Fix (above) has been performed.

Add the following to Lockdown.php</tt>.

/* Cycles through the namespaces in a specific order, and returns the function getDefaultNamespace {	$nsOrder = array(NS_MAIN, NS_CUSTOM_1, NS_CUSTOM_2, NS_HELP);
 * first namespace which the user has access to.

foreach ($nsOrder as $ns) {		if (namespaceIsVisible($ns)) return $ns; }	return -100; }

Change the namespaces to reflect the namespaces on your wiki, in order of preference. Then call this function whenever a Special page has to select a default namespace (ie. where you find $namespace = 0;</tt>). -- Adrianm 7 March 2007

fix for search results
To disable search results in namespaces the user can not read, the file specialsearch.php needs to be adjusted.

within function showMatches: while( $result = $matches->next ) { if ( ( $result->getTitle != NULL ) && ( $result->getTitle->userCanRead ) ) { $out .= $this->showHit( $result, $terms ); }		}

fix if Main namespace is restricted
It fixes a security flaw where searches are performed on the Main namespace by default if no namespace was supplied to the search page. This fix is only neccessary if you need to restrict access to the Main page. This fix assumes that the Basic Namespace Security and the Default Namespace fixes (above) have been performed.

We need to fix a line of code in includes/SearchMySQL.php</tt> which searches the Main namespace by default if no namespace was specified. Find the following function:

function queryNamespaces { $namespaces = implode( ',', $this->namespaces ); if ($namespaces == '') { $namespaces = '0'; }	return 'AND page_namespace IN (' . $namespaces . ')'; }

And change the line $namespaces = '0';</tt> to obtain a default namespace using getDefaultNamespace</tt>. Now, you should not be able to search the Main namespace if you don't check any other namespace boxes.

-- Adrianm 7 March 2007

Fix for Special:Allpages
This fixes a security flaw where pages from the the Main namespace are displayed on Special:Allpages when you first load the page. This fix is only neccessary if you need to restrict access to the Main page. This fix assumes that the Basic Namespace Security and the Default Namespace fixes (above) have been performed.

We need to fix a line of code in includes/SpecialAllpages.php</tt> which lists pages in the Main namespace by default if no namespace was specified. Find the following lines inside the function wfSpecialAllpages</tt>:

if (!in_array($namespace, array_keys($namespaces))) $namespace = 0;

And change the line $namespace = 0;</tt> to obtain a default namespace using getDefaultNamespace</tt>. Now, you should not be able to list pages from the Main namespace when you load Special:Allpages.

-- Adrianm 7 March 2007

Questions/Support
How does the new $wgNamespaceProtection fit into working with this extension?


 * $wgNamespaceProtection only handles edit permission, afaik. Don't use it if you use the Lockdown extension, that would be confusing... -- Duesentrieb ⇌ 23:57, 10 April 2007 (UTC)

Lockdown does not respect $wgWhitelistRead. I think it should.


 * Hm, I didn't test this, but Lockdown does nothing to bypass $wgWhitelistRead. It uses the generic UserCan hook - if that bypasses $wgWhitelistRead, that would be a bug I guss. Can you provide more details about what you are trying to do, and how? -- Duesentrieb ⇌ 23:55, 5 May 2007 (UTC)


 * In Title.php, in the function userCanRead, Mediawiki code looks at wgWhiteListRead only after wfRunHooks is called. I hope that explains why that happens. Let me now go on to what I am doing. In my setup (without using Lockdown), I blocked a namespace and allowed access to a single page in that namespace. I modified $wgWhitelistRead and userCanRead to do what I wanted. Now, I am using Lockdown, and blocked that namespace using $wgNamespacePermissionLockdown. Naturally, the page I wanted visible, is blocked as well. Thinking about it now, I don't know if it is Lockdown's job to support this. But, that is the issue.


 * Ah, now I understand. You want wgWhiteListRead to take preference over Lockdown - I thought you mean Lockdown undid the restrictions imposed by wgWhiteListRead. Hm, yea, sounds reasonable. I'll look into it. Maybe the whitelist check should go first... or maybe Lockdown should explicitely check wgWhiteListRead. -- Duesentrieb ⇌ 13:15, 6 May 2007 (UTC)


 * I just copied the code that checks for wgWhiteListRead from Title.php to the start of lockdownUserCan.

Fixed in 21946 -- Duesentrieb ⇌ 22:20, 6 May 2007 (UTC)


 * I think the code needs to set $result = true;
 * Not really - it returns true, which means "go on as usual". This in turn causes Title::userCan to look at wgWhiteListRead again and return true if appropriate. Setting $result to true would lead to the same result, I'm not completely sure which is the Right Thing to do: my way says "Lockdown does not apply to pages that are whitelisted", while setting $result to true would mean "Lockdown allows access to whitelisted pages". Since Lockdown is not designed to allow access, but to restrict it, returning true seems to be consistent. A quick test worked fine for me. -- Duesentrieb ⇌ 10:17, 7 May 2007 (UTC)