mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Make a hierarchy in roles
This is more understandable for users.
This commit is contained in:
parent
b6d1f05e00
commit
0e5ab47474
@ -108,6 +108,8 @@ class PermissionsGroupController extends Controller
|
||||
|
||||
$translatableStringHelper = $this->get('chill.main.helper.translatable_string');
|
||||
$roleScopes = $permissionsGroup->getRoleScopes()->toArray();
|
||||
|
||||
// sort $roleScopes by name
|
||||
usort($roleScopes,
|
||||
function(RoleScope $a, RoleScope $b) use ($translatableStringHelper) {
|
||||
if ($a->getScope() === NULL) {
|
||||
@ -122,10 +124,21 @@ class PermissionsGroupController extends Controller
|
||||
$translatableStringHelper->localize($b->getScope()->getName())
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
// sort role scope by title
|
||||
/* @var $roleProvider \Chill\MainBundle\Security\RoleProvider */
|
||||
$roleProvider = $this->get('chill.main.role_provider');
|
||||
$roleScopesSorted = array();
|
||||
foreach($roleScopes as $roleScope) {
|
||||
/* @var $roleScope RoleScope */
|
||||
$title = $roleProvider->getRoleTitle($roleScope->getRole());
|
||||
$roleScopesSorted[$title][] = $roleScope;
|
||||
}
|
||||
ksort($roleScopesSorted);
|
||||
|
||||
return $this->render('ChillMainBundle:PermissionsGroup:show.html.twig', array(
|
||||
'entity' => $permissionsGroup,
|
||||
'role_scopes' => $roleScopes,
|
||||
'role_scopes_sorted' => $roleScopesSorted,
|
||||
'expanded_roles' => $this->getExpandedRoles($roleScopes)
|
||||
));
|
||||
}
|
||||
@ -171,6 +184,7 @@ class PermissionsGroupController extends Controller
|
||||
throw $this->createNotFoundException('Unable to find PermissionsGroup entity.');
|
||||
}
|
||||
|
||||
// create all the forms
|
||||
$editForm = $this->createEditForm($permissionsGroup);
|
||||
|
||||
$deleteRoleScopesForm = array();
|
||||
@ -180,9 +194,21 @@ class PermissionsGroupController extends Controller
|
||||
}
|
||||
|
||||
$addRoleScopesForm = $this->createAddRoleScopeForm($permissionsGroup);
|
||||
|
||||
// sort role scope by title
|
||||
/* @var $roleProvider \Chill\MainBundle\Security\RoleProvider */
|
||||
$roleProvider = $this->get('chill.main.role_provider');
|
||||
$roleScopesSorted = array();
|
||||
foreach($permissionsGroup->getRoleScopes()->toArray() as $roleScope) {
|
||||
/* @var $roleScope RoleScope */
|
||||
$title = $roleProvider->getRoleTitle($roleScope->getRole());
|
||||
$roleScopesSorted[$title][] = $roleScope;
|
||||
}
|
||||
ksort($roleScopesSorted);
|
||||
|
||||
return $this->render('ChillMainBundle:PermissionsGroup:edit.html.twig', array(
|
||||
'entity' => $permissionsGroup,
|
||||
'role_scopes_sorted' => $roleScopesSorted,
|
||||
'edit_form' => $editForm->createView(),
|
||||
'expanded_roles' => $this->getExpandedRoles($permissionsGroup->getRoleScopes()->toArray()),
|
||||
'delete_role_scopes_form' => array_map( function($form) {
|
||||
|
@ -56,12 +56,20 @@ class ComposedRoleScopeType extends AbstractType
|
||||
*/
|
||||
private $translatableStringHelper;
|
||||
|
||||
public function __construct(TranslatableStringHelper $translatableStringHelper,
|
||||
RoleProvider $roleProvider)
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var RoleProvider
|
||||
*/
|
||||
private $roleProvider;
|
||||
|
||||
public function __construct(
|
||||
TranslatableStringHelper $translatableStringHelper,
|
||||
RoleProvider $roleProvider
|
||||
) {
|
||||
$this->roles = $roleProvider->getRoles();
|
||||
$this->rolesWithoutScope = $roleProvider->getRolesWithoutScopes();
|
||||
$this->translatableStringHelper = $translatableStringHelper;
|
||||
$this->roleProvider = $roleProvider;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
@ -86,6 +94,9 @@ class ComposedRoleScopeType extends AbstractType
|
||||
} else {
|
||||
return array('data-has-scope' => '1');
|
||||
}
|
||||
},
|
||||
'group_by' => function($role, $key, $index) {
|
||||
return $this->roleProvider->getRoleTitle($role);
|
||||
}
|
||||
))
|
||||
->add('scope', 'entity', array(
|
||||
|
@ -15,6 +15,10 @@
|
||||
<h2>{{ 'Grant those permissions'|trans }} :</h2>
|
||||
|
||||
{%- if entity.getRoleScopes|length > 0 -%}
|
||||
{% for title, role_scopes in role_scopes_sorted %}
|
||||
|
||||
<h3>{{ title|default("Unclassified")|trans }}</h3>
|
||||
|
||||
<table class="striped rounded">
|
||||
<thead>
|
||||
<tr>
|
||||
@ -25,7 +29,7 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{% for role_scope in entity.getRoleScopes %}
|
||||
{% for role_scope in role_scopes %}
|
||||
<tr>
|
||||
<td>
|
||||
<span class="role_scope role">{{ role_scope.role|trans }}</span>
|
||||
@ -53,6 +57,7 @@
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endfor %}
|
||||
|
||||
{%- else -%}
|
||||
<p>{{ 'This group does not provide any permission'|trans }}</p>
|
||||
@ -64,15 +69,24 @@
|
||||
{{ form_errors(add_role_scopes_form) }}
|
||||
{{ form_row(add_role_scopes_form.composed_role_scope.role) }}
|
||||
{{ form_row(add_role_scopes_form.composed_role_scope.scope) }}
|
||||
{{ form_row(add_role_scopes_form.submit, { 'attr' : { 'class': 'sc-button green' } } ) }}
|
||||
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
{{ form_row(add_role_scopes_form.submit, { 'attr' : { 'class': 'sc-button bt-create' } } ) }}
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ path('admin_permissionsgroup_show', { 'id': entity.id }) }}" class="sc-button bt-see">{{ 'Cancel'|trans }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ path('admin_permissionsgroup') }}" class="sc-button bt-cancel">
|
||||
{{ 'Back to the list'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
{{ form_end(add_role_scopes_form) }}
|
||||
|
||||
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ path('admin_permissionsgroup') }}">
|
||||
{{ 'Back to the list'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{% endblock %}
|
||||
|
@ -17,12 +17,12 @@
|
||||
<tr>
|
||||
<td><a href="{{ path('admin_permissionsgroup_show', { 'id': entity.id }) }}">{{ entity.name }}</a></td>
|
||||
<td>
|
||||
<ul>
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ path('admin_permissionsgroup_show', { 'id': entity.id }) }}">{{ 'show'|trans }}</a>
|
||||
<a href="{{ path('admin_permissionsgroup_show', { 'id': entity.id }) }}" class="sc-button bt-see">{{ 'See'|trans }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ path('admin_permissionsgroup_edit', { 'id': entity.id }) }}">{{ 'edit'|trans }}</a>
|
||||
<a href="{{ path('admin_permissionsgroup_edit', { 'id': entity.id }) }}" class="sc-button bt-edit">{{ 'Edit'|trans }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
@ -31,9 +31,9 @@
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<ul>
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ path('admin_permissionsgroup_new') }}">
|
||||
<a href="{{ path('admin_permissionsgroup_new') }}" class="sc-button bt-create">
|
||||
{{ 'Create a new permissions group'| trans }}
|
||||
</a>
|
||||
</li>
|
||||
|
@ -13,9 +13,11 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
{% if role_scopes|length > 0 %}
|
||||
{% if role_scopes_sorted|length > 0 %}
|
||||
<h2>{{ 'Grant those permissions'|trans }} :</h2>
|
||||
|
||||
|
||||
{% for title, role_scopes in role_scopes_sorted %}
|
||||
<h3>{{ title|default('Unclassified')|trans }}</h3>
|
||||
<table class="striped rounded">
|
||||
<thead>
|
||||
<tr>
|
||||
@ -24,6 +26,7 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{% for role_scope in role_scopes %}
|
||||
<tr>
|
||||
<td>
|
||||
@ -43,6 +46,7 @@
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endfor %}
|
||||
|
||||
{% else %}
|
||||
|
||||
@ -51,16 +55,18 @@
|
||||
{{ 'add permissions'|trans|capitalize }}</a></p>
|
||||
{% endif %}
|
||||
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
<a href="{{ path('admin_permissionsgroup') }}">
|
||||
{{ 'Back to the list'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ path('admin_permissionsgroup_edit', { 'id': entity.id }) }}">
|
||||
{{ 'Edit'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="record_actions">
|
||||
|
||||
<li>
|
||||
<a href="{{ path('admin_permissionsgroup_edit', { 'id': entity.id }) }}" class="sc-button bt-edit">
|
||||
{{ 'Edit'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ path('admin_permissionsgroup') }}" class="sc-button bt-cancel">
|
||||
{{ 'Back to the list'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
42
Security/ProvideRoleHierarchyInterface.php
Normal file
42
Security/ProvideRoleHierarchyInterface.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2017 Champs Libres Cooperative <info@champs-libres.coop>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
namespace Chill\MainBundle\Security;
|
||||
|
||||
/**
|
||||
* Give a hierarchy for the role.
|
||||
*
|
||||
* This hierarchy allow to sort roles, which is useful in UI
|
||||
*
|
||||
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||
*/
|
||||
interface ProvideRoleHierarchyInterface extends ProvideRoleInterface
|
||||
{
|
||||
/**
|
||||
* Return an array of roles, where keys are the hierarchy, and values
|
||||
* an array of roles.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```
|
||||
* [ 'Title' => [ 'CHILL_FOO_SEE', 'CHILL_FOO_UPDATE' ] ]
|
||||
* ```
|
||||
*
|
||||
* @return array where keys are the hierarchy, and values an array of roles: `[ 'title' => [ 'CHILL_FOO_SEE', 'CHILL_FOO_UPDATE' ] ]`
|
||||
*/
|
||||
public function getRolesWithHierarchy();
|
||||
}
|
@ -32,6 +32,16 @@ class RoleProvider
|
||||
*/
|
||||
private $providers = array();
|
||||
|
||||
/**
|
||||
* an array where keys are the role, and value is the title
|
||||
* for the given role.
|
||||
*
|
||||
* Null when not initialized.
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
private $rolesTitlesCache = null;
|
||||
|
||||
/**
|
||||
* Add a role provider
|
||||
*
|
||||
@ -75,4 +85,52 @@ class RoleProvider
|
||||
return $roles;
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize the array for caching role and titles
|
||||
*
|
||||
*/
|
||||
private function initializeRolesTitlesCache()
|
||||
{
|
||||
// break if already initialized
|
||||
if ($this->rolesTitlesCache !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->providers as $provider) {
|
||||
if ($provider instanceof ProvideRoleHierarchyInterface) {
|
||||
foreach ($provider->getRolesWithHierarchy() as $title => $roles) {
|
||||
foreach($roles as $role) {
|
||||
$this->rolesTitlesCache[$role] = $title;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($provider->getRoles() !== null) {
|
||||
$this->rolesTitlesCache = \array_merge(
|
||||
$this->rolesTitlesCache,
|
||||
\array_fill_keys($provider->getRoles(), null)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title for each role.
|
||||
*
|
||||
* @param string $role
|
||||
* @return string the title of the role
|
||||
*/
|
||||
public function getRoleTitle($role)
|
||||
{
|
||||
$this->initializeRolesTitlesCache();
|
||||
|
||||
if (! \array_key_exists($role, $this->rolesTitlesCache)) {
|
||||
// this case might happens when the role is not described in
|
||||
// `getRolesWithHierarchy`
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->rolesTitlesCache[$role];
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user