-
-
Notifications
You must be signed in to change notification settings - Fork 485
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
new RolesMatrixType to display available actions per admin as matrix (#…
…1005) Role permissions can now be displayed in a matrix view using the Sonata\UserBundle\Form\Type\RolesMatrixType
- Loading branch information
1 parent
cfd6e7e
commit 3ede651
Showing
26 changed files
with
1,833 additions
and
3 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,3 +13,4 @@ User Bundle | |
reference/two_step_validation | ||
reference/api | ||
reference/user_impersonation | ||
reference/roles_matrix |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
Roles Matrix | ||
============ | ||
|
||
The ``Sonata\UserBundle\Form\Type\RolesMatrixType`` was built to show all | ||
roles in a matrix view. | ||
|
||
|
||
.. figure:: ../images/roles_matrix.png | ||
:align: center | ||
:alt: Role matrix | ||
:width: 700px | ||
|
||
Every admin has defined default roles like: | ||
|
||
- EDIT | ||
- LIST | ||
- CREATE | ||
- VIEW | ||
- DELETE | ||
- EXPORT | ||
- ALL | ||
|
||
The roles matrix consists of two parts: | ||
|
||
1. one that shows the matrix with each admin and their permissions. | ||
2. another that shows the custom roles which are configured in | ||
``security.yml`` and lists them as checkboxes (and shows their | ||
inherited roles). | ||
|
||
.. note:: | ||
|
||
The user can just use roles which he is granted. | ||
|
||
How to exclude an admin | ||
----------------------- | ||
|
||
You can set the ``show_in_roles_matrix`` option to ``false``, like this: | ||
|
||
.. configuration-block:: | ||
|
||
.. code-block:: yaml | ||
# config/services.yaml | ||
services: | ||
app.admin.post: | ||
class: App\Admin\PostAdmin | ||
tags: | ||
- name: sonata.admin | ||
manager_type: orm | ||
label: "Post" | ||
show_in_roles_matrix: false | ||
arguments: | ||
- ~ | ||
- App\Entity\Post | ||
- ~ | ||
public: true |
37 changes: 37 additions & 0 deletions
37
src/DependencyInjection/Compiler/RolesMatrixCompilerPass.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Sonata Project package. | ||
* | ||
* (c) Thomas Rabaix <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Sonata\UserBundle\DependencyInjection\Compiler; | ||
|
||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; | ||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
|
||
/** | ||
* @author Christian Gripp <[email protected]> | ||
* @author Cengizhan Çalışkan <[email protected]> | ||
* @author Silas Joisten <[email protected]> | ||
*/ | ||
final class RolesMatrixCompilerPass implements CompilerPassInterface | ||
{ | ||
public function process(ContainerBuilder $container): void | ||
{ | ||
foreach ($container->findTaggedServiceIds('sonata.admin') as $name => $items) { | ||
foreach ($items as $item) { | ||
if (($item['show_in_roles_matrix'] ?? true) === false) { | ||
$container->getDefinition('sonata.user.admin_roles_builder') | ||
->addMethodCall('addExcludeAdmin', [$name]); | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
/* | ||
* This file is part of the Sonata Project package. | ||
* | ||
* (c) Thomas Rabaix <[email protected]> | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace Sonata\UserBundle\Form\Type; | ||
|
||
use Sonata\UserBundle\Security\RolesBuilder\ExpandableRolesBuilderInterface; | ||
use Symfony\Component\Form\AbstractType; | ||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; | ||
use Symfony\Component\Form\FormTypeInterface; | ||
use Symfony\Component\OptionsResolver\Options; | ||
use Symfony\Component\OptionsResolver\OptionsResolver; | ||
|
||
/** | ||
* @author Silas Joisten <[email protected]> | ||
*/ | ||
final class RolesMatrixType extends AbstractType | ||
{ | ||
/** | ||
* @var ExpandableRolesBuilderInterface | ||
*/ | ||
private $rolesBuilder; | ||
|
||
public function __construct(ExpandableRolesBuilderInterface $rolesBuilder) | ||
{ | ||
$this->rolesBuilder = $rolesBuilder; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function configureOptions(OptionsResolver $resolver): void | ||
{ | ||
$resolver->setDefaults([ | ||
'expanded' => true, | ||
'choices' => function (Options $options, $parentChoices): array { | ||
if (!empty($parentChoices)) { | ||
return []; | ||
} | ||
|
||
$roles = $this->rolesBuilder->getRoles( | ||
$options['choice_translation_domain'], | ||
$options['expanded'] | ||
); | ||
$roles = array_keys($roles); | ||
|
||
return array_combine($roles, $roles); | ||
}, | ||
'choice_translation_domain' => function (Options $options, $value): ?string { | ||
// if choice_translation_domain is true, then it's the same as translation_domain | ||
if (true === $value) { | ||
$value = $options['translation_domain']; | ||
} | ||
if (null === $value) { | ||
// no translation domain yet, try to ask sonata admin | ||
$admin = null; | ||
if (isset($options['sonata_admin'])) { | ||
$admin = $options['sonata_admin']; | ||
} | ||
if (null === $admin && isset($options['sonata_field_description'])) { | ||
$admin = $options['sonata_field_description']->getAdmin(); | ||
} | ||
if (null !== $admin) { | ||
$value = $admin->getTranslationDomain(); | ||
} | ||
} | ||
|
||
return $value; | ||
}, | ||
|
||
'data_class' => null, | ||
]); | ||
|
||
// Symfony 2.8 BC | ||
if (method_exists(FormTypeInterface::class, 'setDefaultOptions')) { | ||
$resolver->setDefault('choices_as_values', true); | ||
} | ||
} | ||
|
||
public function getParent(): string | ||
{ | ||
return ChoiceType::class; | ||
} | ||
|
||
public function getBlockPrefix(): string | ||
{ | ||
return 'sonata_roles_matrix'; | ||
} | ||
|
||
public function getName(): string | ||
{ | ||
return $this->getBlockPrefix(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,12 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> | ||
<services> | ||
<service id="sonata.user.twig.global" class="Sonata\UserBundle\Twig\GlobalVariables"> | ||
<service id="sonata.user.twig.global" class="Sonata\UserBundle\Twig\GlobalVariables" public="false"> | ||
<argument type="service" id="service_container"/> | ||
</service> | ||
<service id="sonata.user.roles_matrix_extension" class="Sonata\UserBundle\Twig\RolesMatrixExtension" public="false"> | ||
<argument type="service" id="sonata.user.matrix_roles_builder"/> | ||
<tag name="twig.extension"/> | ||
</service> | ||
</services> | ||
</container> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
{# | ||
This file is part of the Sonata package. | ||
(c) Thomas Rabaix <[email protected]> | ||
For the full copyright and license information, please view the LICENSE | ||
file that was distributed with this source code. | ||
#} | ||
<table class="table table-condensed"> | ||
<thead> | ||
<tr> | ||
<th></th> | ||
{% for label in permission_labels|sort %} | ||
<th> {{ label }} </th> | ||
{% endfor %} | ||
</tr> | ||
</thead> | ||
<tbody> | ||
{% for admin_label, roles in grouped_roles %} | ||
<tr> | ||
<th>{{ admin_label }}</th> | ||
{% for role, attributes in roles|sort %} | ||
<td> | ||
{{ form_widget(attributes.form, { label: false }) }} | ||
{% if not attributes.is_granted %} | ||
<script> | ||
$('input[value="{{ role }}"]').iCheck('disable'); | ||
$('form').on('submit', function() { | ||
$('input[value="{{ role }}"]').iCheck('enable'); | ||
}); | ||
</script> | ||
{% endif %} | ||
</td> | ||
{% endfor %} | ||
</tr> | ||
{% endfor %} | ||
</tbody> | ||
</table> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{# | ||
This file is part of the Sonata package. | ||
(c) Thomas Rabaix <[email protected]> | ||
For the full copyright and license information, please view the LICENSE | ||
file that was distributed with this source code. | ||
#} | ||
{% for role, attributes in roles|sort %} | ||
<li>{{ form_widget(attributes.form, {label: attributes.role_translated, value: attributes.role}) }}</li> | ||
{% if not attributes.is_granted %} | ||
<script> | ||
$('input[value="{{ role }}"]').iCheck('disable'); | ||
$('form').on('submit', function() { | ||
$('input[value="{{ role }}"]').iCheck('enable'); | ||
}); | ||
</script> | ||
{% endif %} | ||
{% endfor %} |
Oops, something went wrong.