Extension talk:CategoryPermissions

Please add comments or suggestions

Special pages (well.. namespaces)
Hey there. A category-bases permission system is just what I need, so I am trying to get this one working on my Mediawiki installation (now if only I could find out its version, but think it's 1.6'ish). I use the proposed default rule to deny for all categories in CustomPermission.php. Unfortunately, it doesn't allow anonymous users to access the "meta-namespace" (sorry for lacking the appropriate term here) even though $wgGroupDefaultAllow == true. The start page for example doesn't have a category (at least none that I can see) and neither has the login page, amongst others. So, I cannot even log on to alter my access level. Does this work as expected? --Carp 08:39, 20 April 2007 (UTC)
 * Got a running version - I changed quite a bit, so I'm posting a diff instead of editing the code on the main site. It had nothing to do with namespace, instead I found that a few variables and properties where never checked. I'm running it on a production site now. Seems to work smoothly. Thanks for your work! --Carp 13:03, 20 April 2007 (UTC)


 * Deleted buggy diff -> didn't work with more than category, see below --Carp 11:28, 22 April 2007 (UTC)

Thanks for posting your version. I have made several changes to the code that I am currently running and have not had time to update the page. I will look through your version and update the page sometime this week ... and I suppose i should create an account so I can watch the talk page.

Working version
Hey again. Forget the diff I submitted the other day. I found out that it didn't work on a page that was listed in more than one category, hence I rewrote the entire block that checks for parentCategories. Another LocalSettings.php variable can be set to set default allow / deny to categories that haven't been explicitly denied in the LocalSettings.php file. --- CustomPermissions.php.old	Sat Apr 21 17:39:56 2007 +++ CustomPermissions.php	Sat Apr 21 17:39:27 2007 @@ -11,73 +11,87 @@ * Usage: * * require_once('extensions/CategoryPermissions.php'); - * =''; //set a group name to ALWAYS allow access to this group - * =true; //set to true to allow everyone access to pages without a category + * $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 + * $wgGroupDefaultAllowCategory=true; //set to true to allow everyone access to pages with a category that is not explicitly restricted * *  * //add groups to category permissions by: - * ['group_name']['Category:categoryname_read']=true; - * ['group_name']['Category:categoryname_edit']=true; - * ['group_name']['Category:categoryname_move']=true; - * ['group_name']['Category:categoryname_create']=true; + * $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; */ //set up hook -[] = "wfCategoryPermissions"; +$wgExtensionFunctions[] = "wfCategoryPermissions"; function wfCategoryPermissions { - global ; + global $wgHooks; // use the userCan hook to check permissions - [ 'userCan' ][] = 'checkCategoryPermissions'; + $wgHooks[ 'userCan' ][] = 'checkCategoryPermissions'; } -function checkCategoryPermissions { - global, , ; - +function checkCategoryPermissions( $title, $user, $action, $result ) { + global $wgGroupAlwaysAllow, $wgGroupDefaultAllow, $wgGroupPermissions, $wgGroupDefaultAllowCategory; //get categories for this page - =->getParentCategories; + $parentCategories=$title->getParentCategories; //always allow wgGroupAlwaysAllow group - if(in_array(,->mGroups)) + if(in_array($wgGroupAlwaysAllow,$user->mGroups)) { -   wfDebug("checkCategoryPermissions:{} allowed on {->mPrefixedText} to {->mName} : AlwaysAllow\n"); -    = true; +   wfDebug("checkCategoryPermissions:{$action} allowed on {$title->mPrefixedText} to {$user->mName} : AlwaysAllow\n"); +   $result = true; return null; }  //scan list of categories, if any - if{ -   foreach(  as =>){ - -      = ->isAllowed("{}_{}"); -     if{ -       wfDebug("checkCategoryPermissions:{}_{} allowed on {->mPrefixedText} to {->mName}\n"); -       if(->isAnon){ -         =true; -         return true; -       } -        else{ -         return null; -       } +  if(is_array($parentCategories)) { +   if ($user->isAnon or sizeof($user->mGroups) == 0) { +     $groups = array( '*' ); +   } +    else { +     $groups = $user->mGroups; +   } +    // Defaults to deny acces unless category is $wgGroupDefaultAllowCategory is true +   $allowed_in_category = isset($wgGroupDefaultAllowCategory) ? $wgGroupDefaultAllowCategory : false; +   // Search permissions for groups (or '*') and store result for each +   // group the user is in +    foreach ($groups as $group) { +     // Iterate through all of the article's categories +     foreach( $parentCategories as $category=>$dd){ +	if (isset($wgGroupPermissions["$group"]["{$category}_{$action}"])) { +         // if there's one false in the chain, access is not granted ... +	  // which is exactly what we want. +         $allowed_in_category = $allowed_in_category && $wgGroupPermissions["$group"]["{$category}_{$action}"]; +	}      }     } +    if ($allowed_in_category) { +     wfDebug("checkCategoryPermissions:{$category}_{$action} allowed on {$title->mPrefixedText} to {$user->mName}\n"); +   } +    else { +     wfDebug("checkCategoryPermissions:{$category}_{$action} DENIED on {$title->mPrefixedText} to {$user->mName}\n"); +   } +    $result = $allowed_in_category; +   return $result; } + // No categories found -> grant access based on $wgGroupDefaultAllow else { -   wfDebug("checkCategoryPermissions:{} DENIED on {->mPrefixedText} to {->mName} : No Categories\n"); -   =false; -   return false; +   wfDebug("checkCategoryPermissions:{$action} allowed on {$title->mPrefixedText} to {$user->mName} : No Categories\n"); +   $result= $wgGroupDefaultAllow; +   return $result; }  //default action=deny - wfDebug("checkCategoryPermissions:{} DENIED on {->mPrefixedText} to {->mName}\n"); - =false; - return false; + wfDebug("checkCategoryPermissions:{$action} DENIED on {$title->mPrefixedText} to {$user->mName}\n"); + $result=false; + return $result; } -

And here's is the entire new file: <?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 * * Usage: * * require_once('extensions/CategoryPermissions.php'); * $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 * $wgGroupDefaultAllowCategory=true; //set to true to allow everyone access to pages with a category that is not explicitly restricted * * * //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; */

//set up hook $wgExtensionFunctions[] = "wfCategoryPermissions";

function wfCategoryPermissions { global $wgHooks;

// use the userCan hook to check permissions $wgHooks[ 'userCan' ][] = 'checkCategoryPermissions';

}

function checkCategoryPermissions( $title, $user, $action, $result ) { global $wgGroupAlwaysAllow, $wgGroupDefaultAllow, $wgGroupPermissions, $wgGroupDefaultAllowCategory;

//get categories for this page $parentCategories=$title->getParentCategories;

//always allow wgGroupAlwaysAllow group if(in_array($wgGroupAlwaysAllow,$user->mGroups)) {   wfDebug("checkCategoryPermissions:{$action} allowed on {$title->mPrefixedText} to {$user->mName} : AlwaysAllow\n"); $result = true; return null; }

//scan list of categories, if any if(is_array($parentCategories)) { if ($user->isAnon or sizeof($user->mGroups) == 0) { $groups = array( '*' ); }   else { $groups = $user->mGroups; }   // Defaults to deny acces unless category is $wgGroupDefaultAllowCategory is true $allowed_in_category = isset($wgGroupDefaultAllowCategory) ? $wgGroupDefaultAllowCategory : false; // Search permissions for groups (or '*') and store result for each // group the user is in   foreach ($groups as $group) { // Iterate through all of the article's categories foreach( $parentCategories as $category=>$dd){ if (isset($wgGroupPermissions["$group"]["{$category}_{$action}"])) { // if there's one false in the chain, access is not granted ... // which is exactly what we want. $allowed_in_category = $allowed_in_category && $wgGroupPermissions["$group"]["{$category}_{$action}"]; }     }    }    if ($allowed_in_category) { wfDebug("checkCategoryPermissions:{$category}_{$action} allowed on {$title->mPrefixedText} to {$user->mName}\n"); }   else { wfDebug("checkCategoryPermissions:{$category}_{$action} DENIED on {$title->mPrefixedText} to {$user->mName}\n"); }   $result = $allowed_in_category; return $result; } // No categories found -> grant access based on $wgGroupDefaultAllow else { wfDebug("checkCategoryPermissions:{$action} allowed on {$title->mPrefixedText} to {$user->mName} : No Categories\n"); $result= $wgGroupDefaultAllow; return $result; }

//default action=deny wfDebug("checkCategoryPermissions:{$action} DENIED on {$title->mPrefixedText} to {$user->mName}\n"); $result=false; return $result; }

Sorry for the long page now, but I can't upload arbitrary files here (which is probably a Good Thing).--Carp 11:43, 22 April 2007 (UTC)

Licensing
Maybe I only didn't see it ... but I think you didn't mention a licence for your original file. I hope I was allowed to modify and / or use it at all ;) . If your CustomPermissions isn't GPL'ed, I put my modified file under a BSD Licence - in which case I'd be happy if you could list me, Carsten Zimmermann somewhere should you decide to incorporate the code. But I am really not that concerned ;) Cheers, --Carp 11:47, 22 April 2007 (UTC)

This is my first foray into posting code, so I don't know all the semantics of licensing or documentation requirements yet. Everything I post is GPL ... I suppose I should add it to the file. As far as adding names, my philosophy is that if you contribute your name can be included. --Sunergos 18:48, 22 April 2007 (UTC)