mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
ENHANCEMENT Allowing PermissionCheckboxSetField to inspect multiple group records for existing permissions (from r99584)
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/branches/2.4@99658 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
a179e144cb
commit
41b91d4a39
@ -35,20 +35,6 @@ class Group extends DataObject {
|
|||||||
"Hierarchy",
|
"Hierarchy",
|
||||||
);
|
);
|
||||||
|
|
||||||
function getAllParents() {
|
|
||||||
$doSet = new DataObjectSet();
|
|
||||||
|
|
||||||
$parentID = $this->ParentID;
|
|
||||||
|
|
||||||
while($parentID) {
|
|
||||||
$parent = DataObject::get_by_id('Group', $parentID);
|
|
||||||
$doSet->push($parent);
|
|
||||||
$parentID = $parent->ParentID;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $doSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getAllChildren() {
|
function getAllChildren() {
|
||||||
$doSet = new DataObjectSet();
|
$doSet = new DataObjectSet();
|
||||||
|
|
||||||
@ -123,7 +109,7 @@ class Group extends DataObject {
|
|||||||
$fields->removeFieldFromTab('Root', 'Permissions');
|
$fields->removeFieldFromTab('Root', 'Permissions');
|
||||||
$fields->removeFieldFromTab('Root', 'IP Addresses');
|
$fields->removeFieldFromTab('Root', 'IP Addresses');
|
||||||
} else {
|
} else {
|
||||||
// $parentGroups = $this->getAllParents();
|
// $parentGroups = $this->getAncestors();
|
||||||
// if ($parentGroups) {
|
// if ($parentGroups) {
|
||||||
// foreach ($parentGroups as $parent) {
|
// foreach ($parentGroups as $parent) {
|
||||||
// if ($parent->Permissions()->Count()) {
|
// if ($parent->Permissions()->Count()) {
|
||||||
@ -148,7 +134,7 @@ class Group extends DataObject {
|
|||||||
$roleData = Permission::check('ADMIN') ? DataObject::get('PermissionRole') : DataObject::get('PermissionRole', 'OnlyAdminCanApply = 0');
|
$roleData = Permission::check('ADMIN') ? DataObject::get('PermissionRole') : DataObject::get('PermissionRole', 'OnlyAdminCanApply = 0');
|
||||||
$fields->addFieldToTab('Root.' . _t('SecurityAdmin.ROLES', 'Roles'), new CheckboxSetField('Roles', 'Roles', $roleData));
|
$fields->addFieldToTab('Root.' . _t('SecurityAdmin.ROLES', 'Roles'), new CheckboxSetField('Roles', 'Roles', $roleData));
|
||||||
|
|
||||||
// $parentGroups = $this->getAllParents();
|
// $parentGroups = $this->getAncestors();
|
||||||
// if ($parentGroups) {
|
// if ($parentGroups) {
|
||||||
// foreach ($parentGroups as $parent) {
|
// foreach ($parentGroups as $parent) {
|
||||||
// if ($parent->Roles()->Count()) {
|
// if ($parent->Roles()->Count()) {
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
class PermissionCheckboxSetField extends CheckboxSetField {
|
* Shows a categorized list of available permissions (through {@link Permission::get_codes()}).
|
||||||
|
* Permissions which are assigned to a given {@link Group} record
|
||||||
|
* (either directly, inherited from parent groups, or through a {@link PermissionRole})
|
||||||
|
* will be checked automatically. All checkboxes for "inherited" permissions will be readonly.
|
||||||
|
*
|
||||||
|
* @package sapphire
|
||||||
|
* @subpackage security
|
||||||
|
*/
|
||||||
|
class PermissionCheckboxSetField extends FormField {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Array Filter certain permission codes from the output.
|
* @var Array Filter certain permission codes from the output.
|
||||||
@ -8,11 +16,41 @@ class PermissionCheckboxSetField extends CheckboxSetField {
|
|||||||
*/
|
*/
|
||||||
protected $hiddenPermissions = array();
|
protected $hiddenPermissions = array();
|
||||||
|
|
||||||
function __construct($name, $title, $managedClass, $filterField, $record = null) {
|
/**
|
||||||
|
* @var DataObjectSet
|
||||||
|
*/
|
||||||
|
protected $groups = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array Array Nested array in same notation as {@link CheckboxSetField}.
|
||||||
|
*/
|
||||||
|
protected $source = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param String $name
|
||||||
|
* @param String $title
|
||||||
|
* @param String $managedClass
|
||||||
|
* @param String $filterField
|
||||||
|
* @param Group|DataObjectSet $groups One or more {@link Group} records used to determine permission checkboxes.
|
||||||
|
* Caution: saveInto() can only be used with a single group, all inherited permissions will be marked readonly.
|
||||||
|
* Setting multiple groups only makes sense in a readonly context. (Optional)
|
||||||
|
*/
|
||||||
|
function __construct($name, $title, $managedClass, $filterField, $groups = null) {
|
||||||
$this->filterField = $filterField;
|
$this->filterField = $filterField;
|
||||||
$this->managedClass = $managedClass;
|
$this->managedClass = $managedClass;
|
||||||
$this->record = $record;
|
|
||||||
parent::__construct($name, $title, Permission::get_codes(true));
|
if(is_a($groups, 'DataObjectSet')) {
|
||||||
|
$this->groups = $groups;
|
||||||
|
} elseif(is_a($groups, 'Group')) {
|
||||||
|
$this->groups = new DataObjectSet($groups);
|
||||||
|
} elseif($groups) {
|
||||||
|
throw new InvalidArgumentException('$group should be either a Group record, or a DataObjectSet of Group records');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all available codes in the system as a categorized nested array
|
||||||
|
$this->source = Permission::get_codes(true);
|
||||||
|
|
||||||
|
parent::__construct($name, $title);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,19 +70,58 @@ class PermissionCheckboxSetField extends CheckboxSetField {
|
|||||||
function Field() {
|
function Field() {
|
||||||
Requirements::css(SAPPHIRE_DIR . '/css/CheckboxSetField.css');
|
Requirements::css(SAPPHIRE_DIR . '/css/CheckboxSetField.css');
|
||||||
|
|
||||||
$source = $this->source;
|
// Get existing values from the form record (assuming the formfield name is a join field on the record)
|
||||||
$values = array();
|
$uninheritedCodes = array();
|
||||||
|
|
||||||
// Get values from the join, if available
|
|
||||||
if(is_object($this->form)) {
|
if(is_object($this->form)) {
|
||||||
$record = $this->form->getRecord();
|
$record = $this->form->getRecord();
|
||||||
if ($record && $record->hasMethod($this->name)) {
|
if ($record && $record->hasMethod($this->name)) {
|
||||||
$funcName = $this->name;
|
$funcName = $this->name;
|
||||||
$join = $record->$funcName();
|
$join = $record->$funcName();
|
||||||
|
if($join) foreach($join as $joinItem) {
|
||||||
|
$uninheritedCodes[$joinItem->Code] = $joinItem->Code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if($join) {
|
// Get all 'inherited' codes not directly assigned to the group (which is stored in $values)
|
||||||
foreach($join as $joinItem) {
|
$inheritedCodes = array();
|
||||||
$values[] = $joinItem->Code;
|
if($this->groups) foreach($this->groups as $group) {
|
||||||
|
// Get all uninherited permissions
|
||||||
|
foreach($group->Permissions() as $permission) {
|
||||||
|
$uninheritedCodes[$permission->Code] = $permission->Code;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get all permissions from roles
|
||||||
|
if ($group->Roles()->Count()) {
|
||||||
|
foreach($group->Roles() as $role) {
|
||||||
|
foreach($role->Codes() as $code) {
|
||||||
|
if (!isset($inheritedCodes[$code->Code])) $inheritedCodes[$code->Code] = array();
|
||||||
|
// TODO i18n
|
||||||
|
$inheritedCodes[$code->Code][] = 'from role '.$role->Title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get from parent groups
|
||||||
|
$parentGroups = $group->getAncestors();
|
||||||
|
if ($parentGroups) {
|
||||||
|
foreach ($parentGroups as $parent) {
|
||||||
|
if (!$parent->Roles()->Count()) continue;
|
||||||
|
foreach($parent->Roles() as $role) {
|
||||||
|
if ($role->Codes()) {
|
||||||
|
foreach($role->Codes() as $code) {
|
||||||
|
if (!isset($inheritedCodes[$code->Code])) $inheritedCodes[$code->Code] = array();
|
||||||
|
// TODO i18n
|
||||||
|
$inheritedCodes[$code->Code][] = 'role '.$role->Title.' on group '.$parent->Title;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($parent->Permissions()->Count()) {
|
||||||
|
foreach($parent->Permissions() as $permission) {
|
||||||
|
if (!isset($inheritedCodes[$permission->Code])) $inheritedCodes[$permission->Code] = array();
|
||||||
|
// TODO i18n
|
||||||
|
$inheritedCodes[$permission->Code][] = 'group '.$parent->Title;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,65 +129,32 @@ class PermissionCheckboxSetField extends CheckboxSetField {
|
|||||||
|
|
||||||
$odd = 0;
|
$odd = 0;
|
||||||
$options = '';
|
$options = '';
|
||||||
|
if($this->source) {
|
||||||
$inheritedItems = array();
|
// loop through all available categorized permissions and see if they're assigned for the given groups
|
||||||
if ($this->record) {
|
foreach($this->source as $categoryName => $permissions) {
|
||||||
if ($this->record->Roles()->Count()) {
|
|
||||||
foreach($this->record->Roles() as $role) {
|
|
||||||
foreach($role->Codes() as $code) {
|
|
||||||
if (!isset($inheritedItems[$code->Code])) $inheritedItems[$code->Code] = array();
|
|
||||||
$inheritedItems[$code->Code][] = 'from role '.$role->Title;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$parentGroups = $this->record->getAllParents();
|
|
||||||
if ($parentGroups) {
|
|
||||||
foreach ($parentGroups as $parent) {
|
|
||||||
if ($parent->Roles()->Count()) {
|
|
||||||
foreach($parent->Roles() as $role) {
|
|
||||||
if ($role->Codes()) {
|
|
||||||
foreach($role->Codes() as $code) {
|
|
||||||
if (!isset($inheritedItems[$code->Code])) $inheritedItems[$code->Code] = array();
|
|
||||||
$inheritedItems[$code->Code][] = 'role '.$role->Title.' on group '.$parent->Title;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($parent->Permissions()->Count()) {
|
|
||||||
foreach($parent->Permissions() as $permission) {
|
|
||||||
if (!isset($inheritedItems[$permission->Code])) $inheritedItems[$permission->Code] = array();
|
|
||||||
$inheritedItems[$permission->Code][] = 'group '.$parent->Title;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if($source) {
|
|
||||||
foreach($source as $categoryName => $permissions) {
|
|
||||||
$options .= "<li><h5>$categoryName</h5></li>";
|
$options .= "<li><h5>$categoryName</h5></li>";
|
||||||
foreach($permissions as $code => $permission) {
|
foreach($permissions as $code => $permission) {
|
||||||
if(in_array($code, $this->hiddenPermissions)) continue;
|
if(in_array($code, $this->hiddenPermissions)) continue;
|
||||||
$key = $code;
|
|
||||||
$value = $permission['name'];
|
$value = $permission['name'];
|
||||||
|
|
||||||
$odd = ($odd + 1) % 2;
|
$odd = ($odd + 1) % 2;
|
||||||
$extraClass = $odd ? 'odd' : 'even';
|
$extraClass = $odd ? 'odd' : 'even';
|
||||||
$extraClass .= ' val' . str_replace(' ', '', $key);
|
$extraClass .= ' val' . str_replace(' ', '', $code);
|
||||||
$itemID = $this->id() . '_' . ereg_replace('[^a-zA-Z0-9]+', '', $key);
|
$itemID = $this->id() . '_' . ereg_replace('[^a-zA-Z0-9]+', '', $code);
|
||||||
$checked = $disabled = $inheritMessage = '';
|
$checked = $disabled = $inheritMessage = '';
|
||||||
|
$checked = in_array($code, $uninheritedCodes) ? ' checked="checked"' : '';
|
||||||
$checked = in_array($key, $values) ? ' checked="checked"' : '';
|
|
||||||
|
|
||||||
$title = $permission['help'] ? 'title="' . htmlentities($permission['help']) . '" ' : '';
|
$title = $permission['help'] ? 'title="' . htmlentities($permission['help']) . '" ' : '';
|
||||||
|
|
||||||
if (isset($inheritedItems[$code])) {
|
if (isset($inheritedCodes[$code])) {
|
||||||
|
// disable inherited codes, as any saving logic would be too complicate to express in this interface
|
||||||
$disabled = ' disabled="true"';
|
$disabled = ' disabled="true"';
|
||||||
$inheritMessage = ' inherited from '.join(', ', $inheritedItems[$code]).'';
|
// TODO i18n
|
||||||
|
$inheritMessage = ' inherited from ' . join(', ', $inheritedCodes[$code]) . '';
|
||||||
$options .= "<li class=\"$extraClass\"><label {$title}for=\"$itemID\">$value is $inheritMessage</label></li>\n";
|
$options .= "<li class=\"$extraClass\"><label {$title}for=\"$itemID\">$value is $inheritMessage</label></li>\n";
|
||||||
} else {
|
} else {
|
||||||
$options .= "<li class=\"$extraClass\"><input id=\"$itemID\"$disabled name=\"$this->name[$key]\" type=\"checkbox\" value=\"$key\"$checked class=\"checkbox\" /> <label {$title}for=\"$itemID\">$value$inheritMessage</label></li>\n";
|
// uninherited (and hence editable) code checkbox
|
||||||
|
$options .= "<li class=\"$extraClass\"><input id=\"$itemID\"$disabled name=\"$this->name[$code]\" type=\"checkbox\" value=\"$code\"$checked class=\"checkbox\" /> <label {$title}for=\"$itemID\">$value$inheritMessage</label></li>\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user