mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
406 lines
12 KiB
PHP
Executable File
406 lines
12 KiB
PHP
Executable File
<?php
|
|
|
|
namespace SilverStripe\Admin;
|
|
|
|
|
|
use SilverStripe\Security\Security;
|
|
use SilverStripe\Security\Member;
|
|
use SilverStripe\Security\Group;
|
|
use SilverStripe\Security\Permission;
|
|
use SilverStripe\Security\PermissionRole;
|
|
use SilverStripe\Security\PermissionProvider;
|
|
use Requirements;
|
|
use GridField;
|
|
use GridFieldConfig_RecordEditor;
|
|
use GridFieldButtonRow;
|
|
use GridFieldExportButton;
|
|
use Convert;
|
|
use FieldList;
|
|
use TabSet;
|
|
use Tab;
|
|
use LiteralField;
|
|
use HiddenField;
|
|
use HeaderField;
|
|
use Form;
|
|
use ArrayData;
|
|
use Deprecation;
|
|
use Config;
|
|
|
|
|
|
/**
|
|
* Security section of the CMS
|
|
*
|
|
* @package framework
|
|
* @subpackage admin
|
|
*/
|
|
class SecurityAdmin extends LeftAndMain implements PermissionProvider {
|
|
|
|
private static $url_segment = 'security';
|
|
|
|
private static $url_rule = '/$Action/$ID/$OtherID';
|
|
|
|
private static $menu_title = 'Security';
|
|
|
|
private static $tree_class = 'SilverStripe\\Security\\Group';
|
|
|
|
private static $subitem_class = 'SilverStripe\\Security\\Member';
|
|
|
|
private static $allowed_actions = array(
|
|
'EditForm',
|
|
'MemberImportForm',
|
|
'memberimport',
|
|
'GroupImportForm',
|
|
'groupimport',
|
|
'groups',
|
|
'users',
|
|
'roles'
|
|
);
|
|
|
|
protected function init() {
|
|
parent::init();
|
|
Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/client/dist/js/SecurityAdmin.js');
|
|
}
|
|
|
|
/**
|
|
* Shortcut action for setting the correct active tab.
|
|
*
|
|
* @param SS_HTTPRequest $request
|
|
* @return SS_HTTPResponse
|
|
*/
|
|
public function users($request) {
|
|
return $this->index($request);
|
|
}
|
|
|
|
/**
|
|
* Shortcut action for setting the correct active tab.
|
|
*
|
|
* @param SS_HTTPRequest $request
|
|
* @return SS_HTTPResponse
|
|
*/
|
|
public function groups($request) {
|
|
return $this->index($request);
|
|
}
|
|
|
|
/**
|
|
* Shortcut action for setting the correct active tab.
|
|
*
|
|
* @param SS_HTTPRequest $request
|
|
* @return SS_HTTPResponse
|
|
*/
|
|
public function roles($request) {
|
|
return $this->index($request);
|
|
}
|
|
|
|
public function getEditForm($id = null, $fields = null) {
|
|
// TODO Duplicate record fetching (see parent implementation)
|
|
if(!$id) $id = $this->currentPageID();
|
|
$form = parent::getEditForm($id);
|
|
|
|
// TODO Duplicate record fetching (see parent implementation)
|
|
$record = $this->getRecord($id);
|
|
|
|
if($record && !$record->canView()) {
|
|
return Security::permissionFailure($this);
|
|
}
|
|
|
|
$memberList = GridField::create(
|
|
'Members',
|
|
false,
|
|
Member::get(),
|
|
$memberListConfig = GridFieldConfig_RecordEditor::create()
|
|
->addComponent(new GridFieldButtonRow('after'))
|
|
->addComponent(new GridFieldExportButton('buttons-after-left'))
|
|
)->addExtraClass("members_grid");
|
|
|
|
if($record && method_exists($record, 'getValidator')) {
|
|
$validator = $record->getValidator();
|
|
} else {
|
|
$validator = Member::singleton()->getValidator();
|
|
}
|
|
|
|
$memberListConfig
|
|
->getComponentByType('GridFieldDetailForm')
|
|
->setValidator($validator);
|
|
|
|
$groupList = GridField::create(
|
|
'Groups',
|
|
false,
|
|
Group::get(),
|
|
GridFieldConfig_RecordEditor::create()
|
|
);
|
|
$columns = $groupList->getConfig()->getComponentByType('GridFieldDataColumns');
|
|
$columns->setDisplayFields(array(
|
|
'Breadcrumbs' => singleton('SilverStripe\\Security\\Group')->fieldLabel('Title')
|
|
));
|
|
$columns->setFieldFormatting(array(
|
|
'Breadcrumbs' => function($val, $item) {
|
|
return Convert::raw2xml($item->getBreadcrumbs(' > '));
|
|
}
|
|
));
|
|
|
|
$fields = new FieldList(
|
|
$root = new TabSet(
|
|
'Root',
|
|
$usersTab = new Tab('Users', _t('SecurityAdmin.Users', 'Users'),
|
|
|
|
new LiteralField('MembersCautionText',
|
|
sprintf('<div class="alert alert-warning" role="alert">%s</div>',
|
|
_t(
|
|
'SecurityAdmin.MemberListCaution',
|
|
'Caution: Removing members from this list will remove them from all groups and the database'
|
|
)
|
|
)
|
|
),
|
|
$memberList
|
|
),
|
|
$groupsTab = new Tab('Groups', singleton('SilverStripe\\Security\\Group')->i18n_plural_name(),
|
|
$groupList
|
|
)
|
|
),
|
|
// necessary for tree node selection in LeftAndMain.EditForm.js
|
|
new HiddenField('ID', false, 0)
|
|
);
|
|
|
|
// Add import capabilities. Limit to admin since the import logic can affect assigned permissions
|
|
if(Permission::check('ADMIN')) {
|
|
$fields->addFieldsToTab('Root.Users', array(
|
|
new HeaderField(_t('SecurityAdmin.IMPORTUSERS', 'Import users'), 3),
|
|
new LiteralField(
|
|
'MemberImportFormIframe',
|
|
sprintf(
|
|
'<iframe src="%s" id="MemberImportFormIframe" width="100%%" height="250px" frameBorder="0">'
|
|
. '</iframe>',
|
|
$this->Link('memberimport')
|
|
)
|
|
)
|
|
));
|
|
$fields->addFieldsToTab('Root.Groups', array(
|
|
new HeaderField(_t('SecurityAdmin.IMPORTGROUPS', 'Import groups'), 3),
|
|
new LiteralField(
|
|
'GroupImportFormIframe',
|
|
sprintf(
|
|
'<iframe src="%s" id="GroupImportFormIframe" width="100%%" height="250px" frameBorder="0">'
|
|
. '</iframe>',
|
|
$this->Link('groupimport')
|
|
)
|
|
)
|
|
));
|
|
}
|
|
|
|
// Tab nav in CMS is rendered through separate template
|
|
$root->setTemplate('CMSTabSet');
|
|
|
|
// Add roles editing interface
|
|
if(Permission::check('APPLY_ROLES')) {
|
|
$rolesField = GridField::create('Roles',
|
|
false,
|
|
PermissionRole::get(),
|
|
GridFieldConfig_RecordEditor::create()
|
|
);
|
|
|
|
$rolesTab = $fields->findOrMakeTab('Root.Roles', _t('SecurityAdmin.TABROLES', 'Roles'));
|
|
$rolesTab->push($rolesField);
|
|
}
|
|
|
|
$actionParam = $this->getRequest()->param('Action');
|
|
if($actionParam == 'groups') {
|
|
$groupsTab->addExtraClass('ui-state-active');
|
|
} elseif($actionParam == 'users') {
|
|
$usersTab->addExtraClass('ui-state-active');
|
|
} elseif($actionParam == 'roles') {
|
|
$rolesTab->addExtraClass('ui-state-active');
|
|
}
|
|
|
|
$actions = new FieldList();
|
|
|
|
$form = Form::create(
|
|
$this,
|
|
'EditForm',
|
|
$fields,
|
|
$actions
|
|
)->setHTMLID('Form_EditForm');
|
|
$form->addExtraClass('cms-edit-form');
|
|
$form->setTemplate($this->getTemplatesWithSuffix('_EditForm'));
|
|
// Tab nav in CMS is rendered through separate template
|
|
if($form->Fields()->hasTabset()) {
|
|
$form->Fields()->findOrMakeTab('Root')->setTemplate('CMSTabSet');
|
|
}
|
|
$form->addExtraClass('center ss-tabset cms-tabset ' . $this->BaseCSSClasses());
|
|
$form->setAttribute('data-pjax-fragment', 'CurrentForm');
|
|
|
|
$this->extend('updateEditForm', $form);
|
|
|
|
return $form;
|
|
}
|
|
|
|
public function memberimport() {
|
|
Requirements::clear();
|
|
Requirements::css(FRAMEWORK_ADMIN_DIR . '/client/dist/styles/bundle.css');
|
|
Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
|
|
Requirements::javascript(FRAMEWORK_DIR . '/thirdparty/jquery-entwine/dist/jquery.entwine-dist.js');
|
|
Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/client/dist/js/MemberImportForm.js');
|
|
return $this->renderWith('BlankPage', array(
|
|
'Form' => $this->MemberImportForm()->forTemplate(),
|
|
'Content' => ' '
|
|
));
|
|
}
|
|
|
|
/**
|
|
* @see SecurityAdmin_MemberImportForm
|
|
*
|
|
* @return Form
|
|
*/
|
|
public function MemberImportForm() {
|
|
if(!Permission::check('ADMIN')) return false;
|
|
|
|
$group = $this->currentPage();
|
|
$form = new MemberImportForm(
|
|
$this,
|
|
'SilverStripe\\Admin\\MemberImportForm'
|
|
);
|
|
$form->setGroup($group);
|
|
|
|
return $form;
|
|
}
|
|
|
|
public function groupimport() {
|
|
Requirements::clear();
|
|
Requirements::css(FRAMEWORK_ADMIN_DIR . '/client/dist/styles/bundle.css');
|
|
Requirements::javascript(THIRDPARTY_DIR . '/jquery/jquery.js');
|
|
Requirements::javascript(FRAMEWORK_DIR . '/thirdparty/jquery-entwine/dist/jquery.entwine-dist.js');
|
|
Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/client/dist/js/MemberImportForm.js');
|
|
return $this->renderWith('BlankPage', array(
|
|
'Content' => ' ',
|
|
'Form' => $this->GroupImportForm()->forTemplate()
|
|
));
|
|
}
|
|
|
|
/**
|
|
* @see SecurityAdmin_MemberImportForm
|
|
*
|
|
* @return Form
|
|
*/
|
|
public function GroupImportForm() {
|
|
if(!Permission::check('ADMIN')) return false;
|
|
|
|
$form = new GroupImportForm(
|
|
$this,
|
|
'SilverStripe\\Admin\\GroupImportForm'
|
|
);
|
|
|
|
return $form;
|
|
}
|
|
|
|
/**
|
|
* Disable GridFieldDetailForm backlinks for this view, as its
|
|
*/
|
|
public function Backlink() {
|
|
return false;
|
|
}
|
|
|
|
public function Breadcrumbs($unlinked = false) {
|
|
$crumbs = parent::Breadcrumbs($unlinked);
|
|
|
|
// Name root breadcrumb based on which record is edited,
|
|
// which can only be determined by looking for the fieldname of the GridField.
|
|
// Note: Titles should be same titles as tabs in RootForm().
|
|
$params = $this->getRequest()->allParams();
|
|
if(isset($params['FieldName'])) {
|
|
// TODO FieldName param gets overwritten by nested GridFields,
|
|
// so shows "Members" rather than "Groups" for the following URL:
|
|
// admin/security/EditForm/field/Groups/item/2/ItemEditForm/field/Members/item/1/edit
|
|
$firstCrumb = $crumbs->shift();
|
|
if($params['FieldName'] == 'Groups') {
|
|
$crumbs->unshift(new ArrayData(array(
|
|
'Title' => singleton('SilverStripe\\Security\\Group')->i18n_plural_name(),
|
|
'Link' => $this->Link('groups')
|
|
)));
|
|
} elseif($params['FieldName'] == 'Users') {
|
|
$crumbs->unshift(new ArrayData(array(
|
|
'Title' => _t('SecurityAdmin.Users', 'Users'),
|
|
'Link' => $this->Link('users')
|
|
)));
|
|
} elseif($params['FieldName'] == 'Roles') {
|
|
$crumbs->unshift(new ArrayData(array(
|
|
'Title' => _t('SecurityAdmin.TABROLES', 'Roles'),
|
|
'Link' => $this->Link('roles')
|
|
)));
|
|
}
|
|
$crumbs->unshift($firstCrumb);
|
|
}
|
|
|
|
return $crumbs;
|
|
}
|
|
|
|
public function providePermissions() {
|
|
$title = $this->menu_title();
|
|
return array(
|
|
"CMS_ACCESS_SecurityAdmin" => array(
|
|
'name' => _t('CMSMain.ACCESS', "Access to '{title}' section", array('title' => $title)),
|
|
'category' => _t('Permission.CMS_ACCESS_CATEGORY', 'CMS Access'),
|
|
'help' => _t(
|
|
'SecurityAdmin.ACCESS_HELP',
|
|
'Allow viewing, adding and editing users, as well as assigning permissions and roles to them.'
|
|
)
|
|
),
|
|
'EDIT_PERMISSIONS' => array(
|
|
'name' => _t('SecurityAdmin.EDITPERMISSIONS', 'Manage permissions for groups'),
|
|
'category' => _t('Permissions.PERMISSIONS_CATEGORY', 'Roles and access permissions'),
|
|
'help' => _t('SecurityAdmin.EDITPERMISSIONS_HELP',
|
|
'Ability to edit Permissions and IP Addresses for a group.'
|
|
. ' Requires the "Access to \'Security\' section" permission.'),
|
|
'sort' => 0
|
|
),
|
|
'APPLY_ROLES' => array(
|
|
'name' => _t('SecurityAdmin.APPLY_ROLES', 'Apply roles to groups'),
|
|
'category' => _t('Permissions.PERMISSIONS_CATEGORY', 'Roles and access permissions'),
|
|
'help' => _t('SecurityAdmin.APPLY_ROLES_HELP', 'Ability to edit the roles assigned to a group.'
|
|
. ' Requires the "Access to \'Users\' section" permission.'),
|
|
'sort' => 0
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* The permissions represented in the $codes will not appearing in the form
|
|
* containing {@link PermissionCheckboxSetField} so as not to be checked / unchecked.
|
|
*
|
|
* @deprecated 4.0 Use "Permission.hidden_permissions" config setting instead
|
|
* @param $codes String|Array
|
|
*/
|
|
public static function add_hidden_permission($codes){
|
|
if(is_string($codes)) $codes = array($codes);
|
|
Deprecation::notice('4.0', 'Use "Permission.hidden_permissions" config setting instead');
|
|
Config::inst()->update('SilverStripe\\Security\\Permission', 'hidden_permissions', $codes);
|
|
}
|
|
|
|
/**
|
|
* @deprecated 4.0 Use "Permission.hidden_permissions" config setting instead
|
|
* @param $codes String|Array
|
|
*/
|
|
public static function remove_hidden_permission($codes){
|
|
if(is_string($codes)) $codes = array($codes);
|
|
Deprecation::notice('4.0', 'Use "Permission.hidden_permissions" config setting instead');
|
|
Config::inst()->remove('SilverStripe\\Security\\Permission', 'hidden_permissions', $codes);
|
|
}
|
|
|
|
/**
|
|
* @deprecated 4.0 Use "Permission.hidden_permissions" config setting instead
|
|
* @return Array
|
|
*/
|
|
public static function get_hidden_permissions(){
|
|
Deprecation::notice('4.0', 'Use "Permission.hidden_permissions" config setting instead');
|
|
Config::inst()->get('SilverStripe\\Security\\Permission', 'hidden_permissions', Config::FIRST_SET);
|
|
}
|
|
|
|
/**
|
|
* Clear all permissions previously hidden with {@link add_hidden_permission}
|
|
*
|
|
* @deprecated 4.0 Use "Permission.hidden_permissions" config setting instead
|
|
*/
|
|
public static function clear_hidden_permissions(){
|
|
Deprecation::notice('4.0', 'Use "Permission.hidden_permissions" config setting instead');
|
|
Config::inst()->remove('SilverStripe\\Security\\Permission', 'hidden_permissions', Config::anything());
|
|
}
|
|
}
|