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)
 * Sounds reasonable. You are right.

If I apply the Basic Namespace Security Fix on Language.php, the Namespace filtering affects also normal Links. A Link like MyNameSpace:Something is only displayed as :Something if I don't have the Right to read the Namespace. curry

Feature Requests
Is it possible to protect pictures or other uploaded files with lockdown in any way as well?--Makar 17:35, 20 August 2007 (UTC)


 * Makar, I wrote an extension to this extension also extending img_auth but it required extensive patching to run. Right now it only runs on 1.9.3 and 1.10.0.  but I'm using it extensively on several wikis.  The concept is this (where [ns] is your protected namespace ):
 * SpecialUpload into [ns]:[yourfile.jpg]
 * Reference as Image:[ns]:[yourfile.jpg] or Media:[ns]:[yourfile.jpg]


 * For example, given the protected namespace 'TEST', you would upload into TEST:Somefile.jpg and access as [[Image:TEST:Somefile.jpg]]


 * This enhancement was submitted as a bugfix, but given a wontfix status by the MediaWiki powers that be. The alternative is to use the new file classes, which I think are available in the new release 1.11.  If this is the case, I will spend the next couple of weeks trying to extend the classes instead of using this awkward syntax.  Wish me luck and I'll post here if successful.


 * If you want to try this out, go to NS Test Wiki and self-register. I'll grant access for testing to Testing Namespace-Based Protection.


 * If you need (or want) these patches, you can download them, but they are only available for MW 1.9.3 and 10.0.0:


 * Image NS Protection (Windows Zip)
 * Image NS Protection (TAR)
 * --jdpond 23:55, 5 September 2007 (UTC)


 * jdpond, thx for your respond. I will take a closer look on your work.--84.161.204.169 13:46, 9 September 2007 (UTC) (makar)

Possible to restrict 'delete'
Hi I tried successfully to restrict the following rights on custom namespaces


 * read
 * edit
 * move
 * createpage

I did not succeed with 'delete'.

Is this not forseen in the extension or am I doing something wrong?
 * I havn't tried, and don't have much time for this right now.
 * gnerally, the extension implements logic for the userCan check. If the deletion mechanism doesn't use userCan to dertermine if the user can delete, i would consider that a bug in the core code. Which I should then probably fix :)
 * I'll look into this soonish. Please remind me if I should forget. -- Duesentrieb ⇌ 08:57, 7 September 2007 (UTC)


 * Update: I have looked into the code, and it seems that Lockdown will not work for the delete permission (or protect, or patrol, etc). The reason is this: there are per-page permissions (checked using userCan), and global permissions (checked using isAllowed). Lockdown hooks into userCan, and thus only covers per-page permissions. However, several permissions that do conceptually apply to pages (like delete) are still treated as global permissions by mediawiki, and are thus not accessible to the Lockdown extension. I might change this in the MediaWiki core, but not before 1.12. -- Duesentrieb ⇌ 08:44, 10 September 2007 (UTC)

Allowing restriction to all but a few special pages
By Viybel 13:16, 18 September 2007 (UTC)

At present, if you want to restrict all but a few special pages, you need to specify a long list of $wgSpecialPageLockdown, because $wgNamespacePermissionLockdown[NS_SPECIAL] is skipped by the script.

To make it work, you just need to modifify a few lines in Lockdown.php:

Replace : else { $groups = @$wgNamespacePermissionLockdown[$ns][$action]; if (!$groups) $groups = @$wgNamespacePermissionLockdown['*'][$action]; if (!$groups) $groups = @$wgNamespacePermissionLockdown[$ns]['*']; }

by

if (!$groups) $groups = @$wgNamespacePermissionLockdown[$ns][$action]; if (!$groups) $groups = @$wgNamespacePermissionLockdown['*'][$action]; if (!$groups) $groups = @$wgNamespacePermissionLockdown[$ns]['*'];

So now you can use:

$wgSpecialPageLockdown['Search'] = array('*'); $wgSpecialPageLockdown['Userlogin'] = array('*'); $wgSpecialPageLockdown['Userlogout'] = array('*'); $wgNamespacePermissionLockdown[NS_SPECIAL]['read'] = array('sysop');

or even quicker:

$wgWhitelistRead = array("Special:Userlogin","Special:Userlogout", "Special:Search"); $wgNamespacePermissionLockdown[NS_SPECIAL]['read'] = array('sysop');

It would be nice if Duesentrieb could include this in the next release. Viybel 13:16, 18 September 2007 (UTC)