Extension:CategoryPermissions

From MediaWiki.org

Jump to: navigation, search
If you need per-page or partial page access restrictions, you are advised to install an appropriate content management package. MediaWiki was not written to provide per-page access restrictions, and almost all hacks or patches promising to add them will likely have flaws somewhere, which could lead to exposure of confidential data. We are not responsible for anything being leaked, leading to loss of funds or one's job.
For further details, see Security issues with authorization extensions


Manual on MediaWiki Extensions
List of MediaWiki Extensions
CategoryPermissions

Release status: beta

Implementation User rights
Description User permissions restrictions based on page categories
Author(s) Matthew Vernon
Version 0.31 (2007-05-25)
MediaWiki Tested on 1.7.1
Download no link
Hooks used

userCan

Contents

[edit] What can this extension do?

Extends permissions checking by allowing group access to pages that have specific categories. This extension utilizes the usercan hook, however standard permissions checks are still performed. Use this extension at your own risk. Any security scheme based on userCan will not prevent page content from being displayed in search results![1]

[edit] Changes

  • 0.31 - Changed line 49 per anonymous note #PHP undefined constant
  • 0.3 - No longer bypasses standard permissions except when denying access. Previous version was working around a problem that was outside the extension in my server configuration.

[edit] Usage

See Installation


[edit] Installation

  • Copy the code shown in the Code section below to extensions/CategoryPermissions.php
    • I will try to provide a file for download also
  • Make changes to LocalSettings.php as shown below

[edit] Changes to LocalSettings.php

require_once("$IP/extensions/CategoryPermissions.php");
$wgGroupDefaultAllow=true; //set to true to allow everyone access to pages without a category
$wgCategoryExclusive=array("Category:cat_name","Category:cat2_name");//deny access to these categories for anyone not in the group
$wgGroupPermissions['group_name']['Category:categoryname_read']=true;
$wgGroupPermissions['group_name']['Category:categoryname_edit']=true;
$wgGroupPermissions['group_name']['Category:categoryname_move']=true;
$wgGroupPermissions['group_name']['Category:categoryname_create']=true;
$wgGroupPermissions['group_name']['*_read']=true; //allow access to all categories


The permissions are checked as follows:

  1. Each category in the list is checked for permissions
    1. If a category is in the array $wgCategoryExclusive and the user does not have permissions, access is immediately rejected
    2. If the user has permissions for any category and has not been rejected by an exclusive category, they are granted access
  2. If global access (*_read, etc) is set for this user, then access is granted
  3. If the page has no categories, $wgGroupDefaultAllow is is used to grant or deny access
  4. Access is denied ... but we should never get to this step

[edit] Code

<?php
/*
 * Custom Permissions Scheme using Categories
 * based on Extension:NamespacePermissions by Petr Andreev
 *
 * Provides separate permissions for each action (read,edit,create,move) based
 * on category tags on pages.
 *
 * Author: Matthew Vernon
 * Additional Contributions by Carsten Zimmermann
 *
 * Licensed under GPL - use,change,enjoy
 *
 * Usage:
 *
 * require_once('extensions/CategoryPermissions.php');
 * $wgCategoryExclusive=array("Category:cat_name","Category:cat2_name");//deny acces to these categories for anyone not in the group
 * $wgGroupAlwaysAllow=''; //set a group name to ALWAYS allow access to this group
 * $wgGroupDefaultAllow=true; //set to true to allow everyone access to pages without a category
 *
 *
 * //add groups to category permissions by:
 * $wgGroupPermissions['group_name']['Category:categoryname_read']=true;
 * $wgGroupPermissions['group_name']['Category:categoryname_edit']=true;
 * $wgGroupPermissions['group_name']['Category:categoryname_move']=true;
 * $wgGroupPermissions['group_name']['Category:categoryname_create']=true;
 *
 * //allow access to all groups like this
 * $wgGroupPermissions['group_name']['*_read']=true;
 */
 
 
//set up hook
$wgExtensionFunctions[] = "wfCategoryPermissions";
 
function wfCategoryPermissions()
{
  global $wgHooks;
 
  // use the userCan hook to check permissions
  $wgHooks[ 'userCan' ][] = 'checkCategoryPermissions';
}
 
 
//register extension
$wgExtensionCredits['parserhook'][] = array( 'name'=>'CategoryPermissions', 'author'=>'Matthew Vernon', 'url'=>'http://www.mediawiki.org/wiki/Extension:CategoryPermissions');
 
 
//turn on debug messages by changing to 1 or true ... is there a better way to do this?
define("__debug_permissions",0);
 
function checkCategoryPermissions( $title, $user, $action, $result )
{
  global $wgGroupDefaultAllow, $wgGroupPermissions, $wgCategoryExclusive;
 
  $user_allowed=false;
 
  //get categories for this page
  $parentCategories=$title->getParentCategories();
 
  //scan list of categories, if any
  if(is_array($parentCategories))
  {
 
    foreach( $parentCategories as $category=>$dd)
    {
      if( $user->isAllowed("{$category}_{$action}") )
      {
        if(__debug_permissions)wfDebug("checkCategoryPermissions:{$category}_{$action} allowed on {$title->mPrefixedText} to {$user->mName}\n");
          $user_allowed=true;
      }
      else
      {
        if(in_array($category,$wgCategoryExclusive))
        { //if category is in $wgCategoryExclusive then deny anyone who doesn't have explicit access
          if(__debug_permissions)wfDebug("checkCategoryPermissions:{$category}_{$action} DENIED on {$title->mPrefixedText} to {$user->mName} : Exlcusive Category\n");
          $result=false;
          return false;
        }
      }
    }//foreach( $parentCategories as $category=>$dd)
  }//if($parentCategories)
 
  //if we are here, then no exclusive categories have rejected us
  if($user_allowed==true)
  {    return null;  }
 
 
  //always allow groups with *_read etc. regardless of categories
  if( $user->isAllowed("*_{$action}") )
  {
    if(__debug_permissions)wfDebug("checkCategoryPermissions:{$action} allowed on {$title->mPrefixedText} to {$user->mName} : AlwaysAllow\n");
    return null;
  }
 
 
  if(!($parentCategories))
  {
    //handle special case of no categories
    //default action is based on wgGroupDefaultAllow
    if($wgGroupDefaultAllow)
    {
      if(__debug_permissions)wfDebug("checkCategoryPermissions:{$action} allowed on {$title->mPrefixedText} to {$user->mName} : No Categories\n");
      return null;
    }
    else
    {
      if(__debug_permissions)wfDebug("checkCategoryPermissions:{$action} DENIED on {$title->mPrefixedText} to {$user->mName} : No Categories\n");
      $result=false;
      return false;
    }
  }
 
  //default action=deny
  if(__debug_permissions)wfDebug("checkCategoryPermissions:{$action} DENIED on {$title->mPrefixedText} to {$user->mName}\n");
  $result=false;
  return false;
}
 
?>

[edit] Notes

  1. According to Security issues with authorization extensions this has been addressed in MW 1.10, rev:21821: The search page no longer shows excerpts from pages that are not readable (but it still lists the titles)
  • In order to make this extension compatible with version 1.10.0 and up, replace all instances of return null; with return true;. Read more about this: Manual:Hooks/userCan.
Personal tools