Extension talk:NamespacePermissions

Requesting clarification and finding errors
Hello all,


 * All I wanted is to do the followings:
 * Disable any anonymous access altogether
 * "Logged in" users have "READONLY" access and even can't use Talk pages.
 * Create bunch of custom namespaces (e.g. MyNS1, MyNS2, etc.)
 * Use NameSpacePermission Extension to make it automatically create groups (nsMyNS1RW, nsMyNS1RO, nsMyNS2RW, nsMyNS2RO, etc.)
 * As soon as I add a user into one of the groups (e.g. Add user1 to nsMyNS1RW), I expect that user1 can create/Manage any article start with "MyNS1:" (e.g. MyNS1:Test Page, MyNS1:The Page can be only accessible by the users in nsMyNS1RW or nsMyNS1RO group)

 // Create Custom Namespaces $wgExtraNamespaces[1001] = "MyNS1"; $wgExtraNamespaces[1002] = "MyNS1_Talk"; $wgExtraNamespaces[2001] = "MyNS1"; $wgExtraNamespaces[2002] = "MyNS1_Talk";
 * I simply placed NamespacePermissions.php under .\extensions folder.
 * Updated the localsettings as following:

// Overriding Implicit group for all visitors $wgGroupPermissions['*'   ]['createaccount']   = false; //prevents new registrations from anonymous users //$wgGroupPermissions['*'   ]['read']            = false; // Optional depending on the security requirement $wgGroupPermissions['*'   ]['edit']            = false; $wgGroupPermissions['*'   ]['createpage']      = false; $wgGroupPermissions['*'   ]['createtalk']      = false;

// Double overriding on Commandline mode if ($wgCommandLineMode) { $wgGroupPermissions['*']['read'] = true; }

$wgWhitelistRead = array( "Main Page", "Special:Userlogin", "-", "MediaWiki:Monobook.css", "*Support*" );
 * 1) Pages anonymous (not-logged-in) users may see

$wgDisableAnonTalk = true; # no discussion pages for anonyous users

// Overriding Implicit group for all logged-in accounts READONLY. $wgGroupPermissions['user' ]['move']           = false; $wgGroupPermissions['user' ]['read']           = true; // <-- $wgGroupPermissions['user' ]['edit']           = false; $wgGroupPermissions['user' ]['createpage']     = false; $wgGroupPermissions['user' ]['createtalk']     = false; $wgGroupPermissions['user' ]['upload']         = true; $wgGroupPermissions['user' ]['reupload']       = true; $wgGroupPermissions['user' ]['reupload-shared'] = true; $wgGroupPermissions['user' ]['minoredit']      = false;

// The following need to be defined after $wgExtraNamespaces require_once( "extensions/NamespacePermissions.php" ); 


 * With these settings, somehow user1 is simply treated as just "user" and have readonly for everything including MyNS1 even though user1 is on nsMyNS1RW group.
 * Can you tell me what is wrong with this?

Thanks in advance.

Ypae 04:24, 7 February 2007 (UTC)

Problem "Cannot modify header information..."
This facility looks like just what I need, but I followed the instructions and my main page was then besmirched with lots of errors along the lines of:

Warning: Cannot modify header information - headers already sent by (output started at /reuters/radt/local/MediaWiki/mediawiki-1.6.7/extensions/NamespacePermissions.php:59) in /reuters/radt/local/MediaWiki/mediawiki-1.6.7/includes/OutputPage.php on line 412

I'll try to contact the originators to see what this means - I'm pretty new to this stuff and don't speak PHP (yet)!

Andthepharaohs 14:54, 20 July 2006 (UTC)

eof
Line 59 seems to be the last line of the file. Please check that the symbols "?>" (PHP closing "brace") are the last symbols of the file. If they are not (one space or a linefeed is bad enough) the extra symbols will go to the output, and setting the headers afterwards will fail.

Oduvan 12:25, 21 July 2006 (UTC)

dawald
What a great plugin, exaclty what I was looking for. Unfortunatly it doesn't seem to work. I get the following error message: "Warning: call_user_func: First argument is expected to be a valid callback in /wiki/includes/Setup.php on line 327" I'm using Verion 1.6.7 without other extensions.

fixed
you found an interesting bug/feature of MediaWiki - thank you! (it seems that the object for the current user get created before the extension functions are called).

please copy the source from the content page again. it should work now.

Oduvan 15:39, 21 July 2006 (UTC)

All Pages
While the pages themselves seem to be protected with this extension, what is the possibility that the entries in the special page "All Pages" be hidden unless the user is signed in with a login that allows access to the protected namespace? Otherwise, the number and names of pages within a protected namespace are available.

12.223.26.3 21:28, 22 July 2006 (UTC)
 * There's also a lot of other pages that can show article names. See Hidden pages for details. Ilya Voyager 11:17, 8 October 2006 (UTC)

Security Issue: How to Prevent Public Searching
When using NamespacePermissions Extension it is possible for every user to include the protected namespaces when searching. For every page hit the wiki will show (possibly secret) text from protected pages.

I will describe how to patch the system, in order to make searching in protected namespaces only possible for users in the provided (protected) groups.

The Special:Search page first make a list of all searchable namespaces and then remove those not included in the user's preferences or in the "power search" settings.

The approach was to reduce the list of all searchable namespaces and not include protected namespaces for users that have no permission.

Version
Use with care. No guarantee. Please try, test and give feedback.
 * Current patch version: 1.1 (27 July 2006)
 * Tested and works with: MediaWiki 1.7.1
 * Author: Andershhh

Change file SearchEngine.php
You will have to change a few lines in the file includes/SearchEngine.php, start at row 159. A few more lines are included for orientation.

It should be noted that changes to any files other than LocalSettings.php might need to be overwritten when upgrading to a newer mediawiki version. --Umassthrower

SearchEngine.php (old)
/**        * Make a list of searchable namespaces and their canonical names. * @return array * @access public */       function searchableNamespaces { global $wgContLang; $arr = array; foreach( $wgContLang->getNamespaces as $ns => $name ) { if( $ns >= NS_MAIN ) { $arr[$ns] = $name; }               }                return $arr; }

SearchEngine.php (new)
/**        * Make a list of searchable namespaces and their canonical names. * Updated 07/27/2006 by andershhh: Check user user rights and * only return those namespaces the user has permission to. * @return array * @access public */       function searchableNamespaces { global $wgContLang, $wgUser; $arr = array; foreach( $wgContLang->getNamespaces as $ns => $name ) { if( $ns >= NS_MAIN ) { $userAllowed = $wgUser->isAllowed("ns{$ns}_read"); $groupExists = in_array("ns{$name}RO", $wgUser->getAllGroups); if ( $userAllowed || !$groupExists ) { $arr[$ns] = $name; }                       }                }                return $arr; }

Sample LocalSettings.php
// Extra namespaces, that should be protected $wgExtraNamespaces = array(100 => "Brf", 101 => "Brf_Talk"); // Include extension. require('extensions/NamespacePermissions.php'); // Extra namespaces, that should not be protected. $wgExtraNamespaces[102] = "Tmp"; // Allow subpages $wgNamespacesWithSubpages[100] = true; // Make namespaces searchable by default $wgNamespacesToBeSearchedDefault[NS_PROJECT] = 1; $wgNamespacesToBeSearchedDefault[100] = 1; $wgNamespacesToBeSearchedDefault[102] = 1;

The order of the first three variables are important.

Andershhh 14:18, 27 July 2006 (UTC)

Patch for SpecialRecentchanges.php
This patch for SpecialRecentchanges.php hides the recent changes comments from users without reading permissions

global $wgExtraNamespaces; ... foreach ( $wgExtraNamespaces as $num => $title ) { if (!($wgUser->isAllowed("ns".$num."_read"))) { $hidem .= ' AND rc_namespace!='.$num; } } ...
 * 1) Namespace filtering

Patch for SpecialAllpages.php
This patch for SpecialAllpages.php dumps the user to the (Main) namespace if they attempt to access one which they don't have access to.

In function "wfSpecialAllpages" in "includes/SpecialAllpages.php", put the following code at the top of the function, replacing everything down to (and including) the $namespace = 0; line. --71.224.196.239 09:11, 9 February 2007 (UTC)

global $wgRequest, $wgOut, $wgContLang, $wgUser; # GET values $from = $wgRequest->getVal( 'from' ); $namespace = $wgRequest->getInt( 'namespace' ); $namespaces = $wgContLang->getNamespaces; $indexPage = new SpecialAllpages; $userAllowed = $wgUser->isAllowed("ns{$namespace}_read"); $groupExists = in_array("ns{$namespaces[$namespace]}RO", $wgUser->getAllGroups); if( !in_array($namespace, array_keys($namespaces)) || (!$userAllowed && $groupExists)) $namespace = 0;

Patch for SpecialWhatlinkshere.php
Adapted from the above patch for SpecialRecentchanges.php --69.145.178.105 03:09, 14 October 2006 (UTC)

global $wgUser; global $wgExtraNamespaces; ... // Make the query $plConds = array( ... ); $tlConds = array( ... ); foreach ( $wgExtraNamespaces as $num => $title ) { if (!($wgUser->isAllowed("ns".$num."_read"))) { $plConds[] = 'page_namespace!='.$num; $tlConds[] = 'page_namespace!='.$num; } } ...

The above patch is inserted into the showIndirectLinks call, if it wasn't apparent. It prevents pages from a restricted namespace from showing up on other page's "What links here" pages.

The following patch can be inserted just after (or instead) of the above one and blocks access to the "What links here" page for users who don't have access to the page itself. (Note that I only did very limited testing on this) --71.224.196.239 08:08, 9 February 2007 (UTC)

if (!($wgUser->isAllowed("ns".$target->getNamespace."_read")) &&     ($target->getNamespace >= 100)) { return; }

Patch for all namespace dropdown menus
This patch fixes all the dropdown menus that contain namespaces, including that of the Special:Allpages page.

In "includes/XML.php", find the function "namespaceSelector" and replace $s = "\n\n"; $arr = $wgContLang->getFormattedNamespaces; if( !is_null($allnamespaces) ) { $arr = array($allnamespaces => wfMsg('namespacesall')) + $arr; } foreach ($arr as $index => $name) { if ($index < NS_MAIN) continue;

$name = $index !== 0 ? $name : wfMsg('blanknamespace');

with $s = "\n\n"; $arr = $wgContLang->getNamespaces; if( !is_null($allnamespaces) ) { $arr = array($allnamespaces => wfMsg('namespacesall')) + $arr; } foreach ($arr as $index => $name) { if ($index < NS_MAIN) continue; $userAllowed = $wgUser->isAllowed("ns{$index}_read"); $groupExists = in_array("ns{$name}RO", $wgUser->getAllGroups); if ( !$userAllowed && $groupExists ) { continue; } 	$name = $index !== 0 ? strtr($name, '_', ' ') : wfMsg('blanknamespace');

You also need to replace the first line of the function with global $wgContLang, $wgUser; So far, it seems to work just fine for me. I will note, though that this fix doesn't prevent the user from manually entering the hidden namespace ID into the URL. See the Patch for SpecialRecentchanges.php and the Patch for SpecialAllpages.php sections for fixes for the rest of the page. --71.224.196.239 09:03, 9 February 2007 (UTC)

Re Preventing public searching and hiding changes
If it comes to making a patch, a more global solution would be using Title::userCan method (which runs userCan hooks) rather than filtering the list of namespaces.

Having hacked SpecialRecentchanges.php and SearchEngine.php - do you think it will work?

It is a better solution because there can be other means to protect pages from being viewed, may be individually (I am about to implement such a system now) - in which case pages have to be handled separately.

Oduvan 20:29, 29 July 2006 (UTC)

Transcluding
Apart from the search problem, there is another flaw : if a page name is known, there one can use in a authorised namespace and simply get the content this way.

to prevent or at least reduce this problem, there would be need that the special:allpages hides the page list in this namespace for all not-in-the-required-group-to-view users.

DarkoNeko 20:02, 13 August 2006 (UTC)


 * To completely avoid this problem you can forbid transclusion of pages in custom namespaces.
 * In Parser.php, look for the following code (it starts at line 2642 in ver. 1.6.6; line 2829 in 1.7.1):

$articleContent = $this->fetchTemplate( $title ); if ( $articleContent !== false ) { $found = true; $text = $articleContent; $replaceHeadings = true; }
 * and add the following right below it:

if ( $title->getNamespace >= 100 ) { $found = true; $text = $linestart. wfMsg( 'templatenotincluded' ); }
 * 1) Don't allow inclusion from custom namespaces
 * --Oscar 6 23:55, 29 August 2006 (UTC)


 * I have improved the trick. Now transclusions are allowed in the same namespace, but forbidden between namespaces. I.e. you can transclude an article from namespace A into an article from namespace A, but can't into an article from namespace B. However, you can define a namespace (or list of namespaces), articles from which are allowed to be transcluded everywhere.

global $wgNamespacesAllowedForTransclusion; if ( ($title->getNamespace >= 100) && ($title->getNamespace != $this->mTitle->getNamespace) &&     (!$wgNamespacesAllowedForTransclusion[$title->getNamespace]) ) { $found = true; $text = $linestart. wfMsg( 'templatenotincluded' ); }


 * As you can see, you define a list of allowed-to-be-transcluded-namespaces using $wgNamespacesAllowedForTransclusion variable (in LocalSettings.php). Example:

$wgNamespacesAllowedForTransclusion[100] = 1;
 * So, it works exactly like $wgNamespacesToBeSearchedDefault variable.
 * Enjoy.
 * --Oscar 6 22:07, 8 November 2006 (UTC)

Length of Namespace limitation
I found that the plugin doesn't work with namespaces that are longer than 12 characters. Is this a limitation of the extension or wikimedia itself?

The group name would get truncated in the userlist if the ns*group*RW or ns*group*RO names are longer than 16 characters.

--Thelastguardian 03:10, 17 August 2006 (UTC)


 * I've stumbled upon the very same problem. I've dug through tons of code just to find out that it was database limitation: turns out, the ug_group field in the user_groups table has char(16) type, meaning it can't contain more than 16 characters. I changed it to char(128) and it worked like a miracle. Phew.


 * --Oscar 6 16:28, 25 August 2006 (UTC)


 * I find it strange that this is just to be found in the discussion page. I was lucky to find it quickly but it should be on the content page. I will put this under "Pitfalls".


 * --141.41.37.95 11:33, 25 September 2006 (UTC)


 * For those of you that would prefer not to have to research how to implement Oscar's fix, here it is:

alter table mw_user_groups modify ug_group CHAR(128);
 * Incidentally, I also find it strange that this is where I had to find this information.
 * --dustin 12/01/2006

Version Info
I added the following lines to your  file to show up the extension-info on Special:Version:

$wgExtensionCredits['other'][] = array(   "name" => "NamespacePermissions",     "author" => "Petr Andreev",     "url" => "http://meta.wikimedia.org/wiki/NamespacePermissions_Extension",    "description" => "Permission set per Namespace"  );

right after

$wgExtensionFunctions[] = "wfNamespacePermissions"; It would be nice to have it in standard source code :-)

Star

Security Issue: XML Export
It looks that XML Export module doesn't respect user rights of this extension. So you SHOULD either turn off XML Export or write a patch to Export.php like one above. Ilya Voyager 11:05, 8 October 2006 (UTC)

Change the following in SpecialExport.php: $exporter->pageByName( $page ); to: $title = Title::newFromText( $page ); if ($title->userCanRead) { $exporter->pageByName( $page ); } --Cmreigrut 23:04, 23 January 2007 (UTC)

Problem: Writeable namespace for anonymous user
In my setup, anonymous users have the edit right set to false. I wanted to create a namespace with edit rights for anonymous users and added $wgGroupPermissions['*']['ns100_edit'] = true; to LocalSettings.php. That doesn't seem to work. Maybe the global edit = false configuration overrides the namespace-specific setting? Do I have to set edit = false for every single (default) namespace to work around this? 147.142.207.95 14:04, 24 October 2006 (UTC)
 * It does. See my fix below for interacting with the talkright extension. It's possible that it's not just talkright that messes it up... --71.224.196.239 04:48, 14 February 2007 (UTC)

Formatting changes to installation instructions
I reformatted the Installation and usage instructions, hopefully with no content changes. Using an HTML list instead of a wiki list allows the code line example to appear more readably, and to maintain list item numbering around the code line example (which will not work with a wiki list). I also added links to the various filename, variable name, and page name references, to help me as I learn this material. I hope others find this format change useful. Teratornis 01:28, 14 November 2006 (UTC)

Error: Warning: Invalid argument supplied for foreach in ..../extensions/NamespacePermissions.php on line 40
Hi,

On installing the NamespacePermissions.php script "vanilla", without first defining any extra namespaces, the following error occurs:

Warning: Invalid argument supplied for foreach in (path)/extensions/NamespacePermissions.php on line 40

This is quite trivial to avoid, and for completeness, you might want to include this in your script:

if($wgExtraNamespaces <> "") { 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; }   }

(my additions emboldened in the above)

Regards, Steve


 * I wrote a slightly different workaround, posted below:

if ( $wgExtraNamespaces == NULL ) {}

else { 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; }   }
 * Thanks, ^demon

Problem: The function namespacePermissionsCheckNamespace is never called
I have the installed the extension in our Wiki (1.5.x), but it seems that the function namespacePermissionsCheckNamespace is never called. Does this extension work in MediaWiki 1.5.x?

Error message patch in OutputPage.php
Great extension! However, I have noticed that the error message you get for users that don't have read access to a secured namespace, so I patched OutputPage.php to fix it. Currently, you get a message like The action you have requested is limited to users in one of the groups "*", "user". (even though those users obviously don't have access. This was written against 1.8.1, and assumes (as does the extension) that namespaces over 100 are going to have limited access.

For the correct groups, change: function loginToUse { global $wgUser, $wgTitle, $wgContLang;

if( $wgUser->isLoggedIn ) { $this->permissionRequired( 'read' ); return; } ... to: function loginToUse { global $wgUser, $wgTitle, $wgContLang;

if( $wgUser->isLoggedIn ) { if ( ( $ns = $wgTitle->getNamespace ) >= 100 ) { $this->permissionRequired("ns{$ns}_read"); } else { $this->permissionRequired( 'read' ); }       return; } ... --Cmreigrut 19:42, 23 January 2007 (UTC)

Security Issue: Special Pages
I've been working with the extension and all of the above patches thus far, but it would seem that all of these are simply fingers in the dike: many (if not all) of the special pages would have to be modified as well, as they all generally display information.

I'm starting to think that this really needs to be rolled into MediaWiki itself. Thoughts? --Cmreigrut 23:10, 23 January 2007 (UTC)

Where is the mod file?
After I installed mw 1.6.7 I went through the entire procedure to add the wgExtraNamespaces mod. I cannot find that file again. Would someone please direct me to the file? Or is it now necessary to grab the modified code from the body of the article? Thanks much. --JayEdgar 01:02, 31 January 2007 (UTC)

Compatability with talkright
For whatever reason, this extension appears to conflict with the Talkright extension. If you have both installed, and have $wgGroupPermissions['user']['edit'] = false; $wgGroupPermissions['user']['talk'] = true; $wgGroupPermissions['user']['ns100_read'] = true; $wgGroupPermissions['user']['ns100_edit'] = true; $wgGroupPermissions['user']['ns100_create'] = true; $wgGroupPermissions['user']['ns100_move'] = true; in your LocalSettings.php, users will be unable to actually edit anything in namespace 100. It's also possible that this is simply an effect of blocking user editing in general while permitting it on a given namespace - I haven't tested that.

To correct this, modify the NamespacePermissions.php file as follows: In function wfNamespacePermissions add $wgHooks[ 'AlternateEdit' ][] = 'namespaceEdit'; after $wgHooks[ 'userCan' ][] = 'namespacePermissionsCheckNamespace';

At the end of the file, (just before the ?> line) add: function namespaceEdit(&$editPage) { global $wgOut, $wgUser, $wgRequest, $wgTitle; if ((($ns = $wgTitle->getNamespace) >= 100) && $wgUser->isAllowed("ns{$ns}_edit")) { array_push($wgUser->mRights, 'edit'); }   return true; } --71.224.196.239 04:47, 14 February 2007 (UTC)

This extension is being used at an academic institution
I modified this extension slightly:
 * 1) Turned user defaults to false
 * 2) I also have the extension extend the modification of permissions for the following standard namespaces (in function namespacePermissionsCheckNamespace):
 * 3) MAIN
 * 4) TALK
 * 5) PROJECT
 * 6) MEDIAWIKI

Here are the modifications.

This allows the sysop to overwrite the defaults in some of the standard areas also. It has been up since August 2006 and so far has worked well. The "student" may edit only the course pages (ns >= 100) they are in and the default namespaces not named above (USER, IMAGE, TEMPLATE, HELP, CATAGORY). I have included my  modifications and I have also written a script which reads in a list of users and adds them to the database with an appropriate group. I welcome comments. Steve Weppner, Eckerd College--198.187.213.50 17:31, 19 February 2007 (UTC)

Categorization Problem: Pages in restricted namespaces are listed
After using the NamespacePermissions Extension apply Specialpages patches, I still had a small problem. If I categorize the pages within the restricted namespaces, anonymous users can see pages name listed in its category page. I think include/CategoryPage.php should be patched too. Need help in this issue.--Ikhnaton2 06:39, 10 March 2007 (UTC)