mlanthaler: Added the possibility to define "deny permissions". See http://www.silverstripe.com/google-summer-of-code-forum/flat/3679?showPost=4105 for more details.

ischommer: merged with ability to provide comma-separated codes, cleaned up some code-formatting
(merged from branches/gsoc)


git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@42077 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2007-09-16 14:58:27 +00:00
parent e286068cc9
commit 4f87512d73

View File

@ -1,20 +1,47 @@
<?php <?php
class Permission extends DataObject { class Permission extends DataObject {
// the (1) after Type specifies the DB default value which is needed for
// upgrades from older SilverStripe versions
static $db = array( static $db = array(
"Code" => "Varchar", "Code" => "Varchar",
"Arg" => "Int", "Arg" => "Int",
"Type" => "Int(1)"
); );
static $has_one = array( static $has_one = array(
"Group" => "Group", "Group" => "Group"
); );
static $indexes = array( static $indexes = array(
"Code" => true, "Code" => true
);
static $defaults = array(
"Type" => 1
); );
/** /**
* Permissions declared as belonging to the system. This is used to provide * This is the value to use for the "Type" field if a permission should be
* permission matrices. * granted.
*/
const GRANT_PERMISSION = 1;
/**
* This is the value to use for the "Type" field if a permission should be
* denied.
*/
const DENY_PERMISSION = -1;
/**
* This is the value to use for the "Type" field if a permission should be
* inherited.
*/
const INHERIT_PERMISSION = 0;
/**
* Method to globally disable "strict" checking, which means a permission
* will be granted if the key does not exist at all.
*
* @var bool
*/ */
static $declared_permissions = null; static $declared_permissions = null;
@ -131,9 +158,12 @@ class Permission extends DataObject {
$permission = DB::query(" $permission = DB::query("
SELECT ID SELECT ID
FROM Permission FROM Permission
WHERE (Code IN ($SQL_codeList $adminFilter) WHERE (
Code IN ($SQL_codeList $adminFilter)
AND Type = " . self::GRANT_PERMISSION . "
AND GroupID IN ($groupCSV) AND GroupID IN ($groupCSV)
$argClause $argClause
)
")->value(); ")->value();
if($permission) if($permission)
@ -142,8 +172,15 @@ class Permission extends DataObject {
// Strict checking disabled? // Strict checking disabled?
if(!self::$strict_checking || !$strict) { if(!self::$strict_checking || !$strict) {
if(!DB::query("SELECT COUNT(*) FROM Permission " . $hasPermission = DB::query("
"WHERE (Code IN '$code')'")->value()) { SELECT COUNT(*)
FROM Permission
WHERE (
(Code IN '$code')'
AND (Type = " . self::GRANT_PERMISSION . ")
)
")->value();
if(!$hasPermission) {
return true; return true;
} }
} }
@ -210,6 +247,41 @@ class Permission extends DataObject {
$perm = new Permission(); $perm = new Permission();
$perm->GroupID = $groupID; $perm->GroupID = $groupID;
$perm->Code = $code; $perm->Code = $code;
$perm->Type = self::GRANT_PERMISSION;
// Arg component
switch($arg) {
case "any":
break;
case "all":
$perm->Arg = -1;
default:
if(is_numeric($arg)) {
$perm->Arg = $arg;
} else {
use_error("Permission::checkMember: bad arg '$arg'",
E_USER_ERROR);
}
}
$perm->write();
return $perm;
}
/**
* Deny the given permission code/arg to the given group
*
* @param int $groupID The ID of the group
* @param string $code The permission code
* @param string Optional: The permission argument (e.g. a page ID).
* @returns Permission Returns the new permission object.
*/
public static function deny($groupID, $code, $arg = "any") {
$perm = new Permission();
$perm->GroupID = $groupID;
$perm->Code = $code;
$perm->Type = self::DENY_PERMISSION;
// Arg component // Arg component
switch($arg) { switch($arg) {
@ -275,14 +347,16 @@ class Permission extends DataObject {
public static function get_members_by_permission($code) { public static function get_members_by_permission($code) {
$groupIDs = array(); $groupIDs = array();
if(is_array($code)) $SQL_filter = "Permission.Code IN ('" . implode("','", Convert::raw2sql($code)) . "')"; $SQL_codeList = (is_array($code)) ? implode("','", Convert::raw2sql($code)) : Convert::raw2sql($code);
else $SQL_filter = "Permission.Code = '" . Convert::raw2sql($code) . "'";
$SQL_filter = "Permission.Code IN ('" . $SQL_codeList . "') " .
"AND Permission.Type = " . self::GRANT_PERMISSION;
$toplevelGroups = DataObject::get( $toplevelGroups = DataObject::get(
'Group', 'Group',
$SQL_filter, // filter $SQL_filter, // filter
null, // limit null, // limit
"LEFT JOIN `Permission` ON `Group`.`ID` = `Permission`.`GroupID`" // join "LEFT JOIN `Permission` ON `Group`.`ID` = `Permission`.`GroupID`"
); );
if(!$toplevelGroups) if(!$toplevelGroups)
return false; return false;