Extension:DisallowAccessOnCategory

From MediaWiki.org
Jump to: navigation, search
MediaWiki extensions manual - list
Crystal Clear action run.png
DisallowAccessOnCategory

Release status: beta

Implementation User rights
Description Restrict Access to pages based on their category
Author(s) User:Mati
Last version 0.1 (2009-07-29 (fix tested with 1.15.1))
MediaWiki 1.9.0
License No license specified
Download No link
no readme or changelog so far
Parameters

none

Added rights

GPL

Check usage and version matrix; stats

Contents

Introduction[edit]

This Extension was created out of a desire to make it possible to restrict access to a set of pages quickly. For now, in its initial version, the extension itself is only 25 lines long, but I plan on adding a little more functionality later.

Warning: This extension was specifically developed for our internal wiki. Some of the features came more as a side-effect and are not very well tested (read: not at all). The basic functionality works though. Please feel free to post suggestions and bugreports to the DiscussionPage.

Features[edit]

When properly configured any page that belongs to the category "Protected" is only viewable by users that belong to a certain group. It is thus very easy for everyone (even users not in that group!) to restrict access quickly and easily.

Note that a user cannot gain additional privileges with this extension. If, for example, an anonymous user has no read-access in the first place, he won't be able to gain it either.

Please read about security issues with authorization extensions. It may be a good Idea to have an extra page for checking security, so this is done here.

Configuration[edit]

First you have to download DisallowAccessOnCategory.php.tar.gz, unpack it into the extensions directory of your MediaWiki-Installation and require-once it in your LocalSettings.php, like this:

require_once ("$IP/extensions/DisallowAccessOnCategory.php");

To allow access to a group you have to set the "protected" value of that group to true. In our wiki we define a special group called "protected_group" where only certain users are added to as needed. This is equivalent to a whitelist-based approach on page-access:

#define rights of "protected_group"
$wgGroupPermissions['protected_group']['read'] = true;
$wgGroupPermissions['protected_group']['edit'] = true;
$wgGroupPermissions['protected_group']['createpage'] = true;
$wgGroupPermissions['protected_group']['createtalk'] = true;
$wgGroupPermissions['protected_group']['minoredit'] = true;
# allow protected_group to use the pages of the "Protected" Category
$wgGroupPermissions['protected_group']['protected'] = true;

This way it is of course easy to, for example, only restrict write-access to these users and still allow everyone to read it.

Of course it would also be easy to allow access only to registered users:

$wgGroupPermissions['user']['protected'] = true;

or

 $wgGroupPermissions['*']['your category'] = false;     /* <-- prevents anonymous users from seeing the pages */
 $wgGroupPermissions['user']['your category'] = false;  /* <-- prevents logged in users from seeing the pages */

RecentChanges patch[edit]

Not really part of this extension, but noteworthy none the less. We didn't want the pages to appear in RecentChanges, also the RSS Feed still displayed changes to restricted pages to everyone. We solved this problem by patching SpecialRecentchanges.php with this patch. This is only tested with MediaWiki 1.9.0, but should be easy to apply to other versions of MediaWiki as well. Here is the code of the patch:

--- SpecialRecentchanges.php.old        2007-02-20 17:00:24.000000000 +0100
+++ SpecialRecentchanges.php    2007-02-22 14:58:02.000000000 +0100
@@ -171,7 +171,23 @@
        $rows = array();
        $batch = new LinkBatch;
        while( $row = $dbr->fetchObject( $res ) ){
-               $rows[] = $row;
+               $nt = Title::newFromText ( $row->rc_title , $row->rc_namespace ) ;
+               $id = $nt->getArticleID() ;
+
+               /* Patch for the DissallowAccessOnCategory Extension:
+                * The following snippet excludes Articles from RecentChanges
+                * if the user is not allowed to view its contents
+                */
+               global $wgContLang;
+               $categories = $nt->getParentCategories();
+               $categoryNSText = $wgContLang->getNSText ( NS_CATEGORY );
+               if ( gettype($categories) == "array" && array_key_exists("$categoryNSText:Protected", $categories) ) {
+                       global $wgUser;
+                       if ( ! ( $wgUser->isAllowed("$action") && $wgUser->isAllowed('protected') ) )
+                               continue;
+               }
+
+               $rows[] = $row; 
                if ( !$feedFormat ) {
                        // User page link
                        $title = Title::makeTitleSafe( NS_USER, $row->rc_user_text );
@@ -286,6 +302,17 @@
        foreach ( $rows AS $k => $r ) {
                $nt = Title::newFromText ( $r->rc_title , $r->rc_namespace ) ;
                $id = $nt->getArticleID() ;
+
+               /* patch for the DisallowAccessOnCategory extension:
+                * same as above, but this function is only called if 
+                * $wgAllowCategorizedRecentChanges is set to true
+                */
+               global $wgContLang;
+               $categories = $nt->getParentCategories();
+               $categoryNSText = $wgContLang->getNSText ( NS_CATEGORY );
+               if ( gettype($categories) == "array" && array_key_exists("$categoryNSText:Protected", $categories) )
+                       continue;
+
                if ( $id == 0 ) continue ; # Page might have been deleted...
                if ( !in_array ( $id , $articles ) ) {
                        $articles[] = $id ;

I'm not entirely sure if this is the best possible approach but it works. Unfortunately RecentChanges Page doesn't provide any hooks yet.

TODO[edit]

There are some thing to to for the next version::

  • Restrict search/RSS results for protected pages (without patch if possible)
  • the use of multiple accesscontrol-tags for use in templates
  • the additional use of single users
  • the accesscontrol-tag has to be on the first line of the wikitext to work correctly, that has to be fixed

Bugs[edit]

  • Under MediaWiki 1.8.2: If you add a subpage to the Protected category, its parent-page is also protected. This is caused by the function getParentCategories in Title.php that, in 1.8.2, also returns the Categories of its subpages. I don't know a way around this problem, unfortunately.

Fix for recent MediaWiki versions[edit]

<?php
 
 
//set up hook
$wgExtensionFunctions[] = "wfDisallowReadOnCategory";
 
function wfDisallowReadOnCategory()
{
  global $wgHooks;
 
  // use the userCan hook to check permissions
  $wgHooks[ 'userCan' ][] = 'DisallowReadOnCategory';
}
 
 
/** DisallowReadOnCategory
 * @param $titlePage TitlePage
 * @param $user wgUser
 * @param $action string
 * @param $result boolean
 */
function DisallowReadOnCategory ( $titlePage, $user, $action, $result )
{
        global $wgContLang; 
 
        $categoryNSText = $wgContLang->getNSText ( NS_CATEGORY );
        $categories = $titlePage->getParentCategories(); 
        if ( is_array( $categories ) && array_key_exists("$categoryNSText:Protected", $categories) )
        {
          if ( $user->isAllowed("$action") && $user->isAllowed('protected') ) 
            $result = true;
          else
            $result = false;
          return false;
        }
        return true;
}
 
?>