diff --git a/src/Controller/PermissionController.php b/src/Controller/PermissionController.php
index e7566710..d08c7f38 100644
--- a/src/Controller/PermissionController.php
+++ b/src/Controller/PermissionController.php
@@ -16,6 +16,7 @@ use App\Event\PermissionSectionsEvent;
use App\Event\PermissionsEvent;
use App\Form\RoleType;
use App\Model\PermissionSection;
+use App\Repository\Query\UserQuery;
use App\Repository\RoleRepository;
use App\Repository\UserRepository;
use App\Security\RolePermissionManager;
@@ -46,7 +47,7 @@ final class PermissionController extends AbstractController
#[Route(path: '', name: 'admin_user_permissions', methods: ['GET', 'POST'])]
#[IsGranted('role_permissions')]
- public function permissions(EventDispatcherInterface $dispatcher, CsrfTokenManagerInterface $csrfTokenManager, RoleService $roleService): Response
+ public function permissions(EventDispatcherInterface $dispatcher, CsrfTokenManagerInterface $csrfTokenManager, RoleService $roleService, UserRepository $userRepository): Response
{
$all = $this->roleRepository->findAll();
$existing = [];
@@ -151,7 +152,10 @@ final class PermissionController extends AbstractController
$page->setHelp('permissions.html');
$page->setActionName('user_permissions');
+ $users = $userRepository->getUsersForQuery(new UserQuery());
+
return $this->render('permission/permissions.html.twig', [
+ 'users' => $users,
'page_setup' => $page,
'token' => $csrfTokenManager->refreshToken(self::TOKEN_NAME)->getValue(),
'roles' => array_values($roles),
diff --git a/src/Entity/Role.php b/src/Entity/Role.php
index d2c3224d..eaa9403c 100644
--- a/src/Entity/Role.php
+++ b/src/Entity/Role.php
@@ -46,4 +46,9 @@ class Role
return $this;
}
+
+ public function isUser(): bool
+ {
+ return $this->name === User::ROLE_USER;
+ }
}
diff --git a/src/Form/RoleType.php b/src/Form/RoleType.php
index c27c31d7..9b552857 100644
--- a/src/Form/RoleType.php
+++ b/src/Form/RoleType.php
@@ -34,22 +34,43 @@ final class RoleType extends AbstractType
]
]);
+ $replacer = function ($roleName): ?string {
+ if ($roleName === null) {
+ return null;
+ }
+
+ if (\is_string($roleName)) {
+ $roleName = preg_replace('/[^a-zA-Z_]/', '_', $roleName);
+ $roleName = preg_replace('/_+/', '_', $roleName ?? '');
+ $roleName = ltrim($roleName ?? '', '_');
+ $roleName = rtrim($roleName, '_');
+ $roleName = strtoupper($roleName);
+ }
+
+ return $roleName;
+ };
+
// help the user to figure out the allowed name
$builder->get('name')->addViewTransformer(
new CallbackTransformer(
- function ($roleName) {
- if (\is_string($roleName)) {
- $roleName = str_replace(' ', '_', $roleName);
- $roleName = str_replace('-', '_', $roleName);
- }
-
- return $roleName;
+ function ($roleName) use ($replacer) {
+ return $replacer($roleName);
},
function ($roleName) {
return $roleName;
}
)
);
+ $builder->get('name')->addModelTransformer(
+ new CallbackTransformer(
+ function ($roleName) {
+ return $roleName;
+ },
+ function ($roleName) use ($replacer) {
+ return $replacer($roleName);
+ }
+ )
+ );
}
public function configureOptions(OptionsResolver $resolver): void
diff --git a/templates/permission/permissions.html.twig b/templates/permission/permissions.html.twig
index bfce0618..3ba77fac 100644
--- a/templates/permission/permissions.html.twig
+++ b/templates/permission/permissions.html.twig
@@ -9,6 +9,7 @@
'name': 'alwaysVisible',
} %}
{% set canEditPermissions = is_granted('role_permissions') %}
+
{% for role in roles %}
{% set class = 'alwaysVisible text-center' %}
{% if role.name == 'ROLE_SUPER_ADMIN' %}
@@ -16,17 +17,48 @@
{% elseif role.name == 'ROLE_USER' %}
{% set class = class ~ ' bg-green-lt' %}
{% endif %}
- {% set options = {'class': class} %}
- {% if canEditPermissions and (role.name not in system_roles) %}
- {% set widget %}
-
{{ icon('trash') }}
- {% endset %}
- {% set options = options|merge({'html_after': widget}) %}
+ {% set columns = columns|merge({(role.name): {'class': class}}) %}
+ {% set roleUsers = [] %}
+ {% for user in users %}
+ {% if user.hasRole(role.getName()) %}
+ {% set roleUsers = roleUsers|merge([user]) %}
+ {% endif %}
+ {% endfor %}
+
+ {% if not role.isUser() %}
+
+
+
+
+
+ {{ role.getName()|trans }}
+ {% if canEditPermissions and (role.name not in system_roles) %}
+
+ {{ icon('trash') }}
+ {% endif %}
+
+
+
+
+
+ {% for user in roleUsers %}
+ {{ widgets.user_avatar(user, user.displayName, 'avatar-rounded avatar-xs') }}
+ {% endfor %}
+
+
+
+
+
{% endif %}
- {% set columns = columns|merge({
- (role.name): options,
- }) %}
{% endfor %}
+
+
{% set tableName = 'user_admin_permissions' %}
diff --git a/tests/Controller/PermissionControllerTest.php b/tests/Controller/PermissionControllerTest.php
index 32efd721..8b543742 100644
--- a/tests/Controller/PermissionControllerTest.php
+++ b/tests/Controller/PermissionControllerTest.php
@@ -19,17 +19,17 @@ use App\Entity\User;
*/
class PermissionControllerTest extends ControllerBaseTest
{
- public function testIsSecure()
+ public function testIsSecure(): void
{
$this->assertUrlIsSecured('/admin/permissions');
}
- public function testIsSecureForRole()
+ public function testIsSecureForRole(): void
{
$this->assertUrlIsSecuredForRole(User::ROLE_ADMIN, '/admin/permissions');
}
- public function testPermissions()
+ public function testPermissions(): void
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN);
$this->assertAccessIsGranted($client, '/admin/permissions');
@@ -52,17 +52,17 @@ class PermissionControllerTest extends ControllerBaseTest
self::assertStringContainsString('', $content);
}
- public function testCreateRoleIsSecured()
+ public function testCreateRoleIsSecured(): void
{
$this->assertUrlIsSecured('/admin/permissions/roles/create');
}
- public function testCreateRoleIsSecuredForRole()
+ public function testCreateRoleIsSecuredForRole(): void
{
$this->assertUrlIsSecuredForRole(User::ROLE_ADMIN, '/admin/permissions');
}
- public function testCreateRole()
+ public function testCreateRole(): void
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN);
$this->assertAccessIsGranted($client, '/admin/permissions/roles/create');
@@ -79,17 +79,17 @@ class PermissionControllerTest extends ControllerBaseTest
$this->assertTableHeader($content);
}
- public function testDeleteRoleIsSecured()
+ public function testDeleteRoleIsSecured(): void
{
$this->assertUrlIsSecured('/admin/permissions/roles/1/delete/sdfsdfsdfsd');
}
- public function testDeleteRoleIsSecuredForRole()
+ public function testDeleteRoleIsSecuredForRole(): void
{
$this->assertUrlIsSecuredForRole(User::ROLE_ADMIN, '/admin/permissions');
}
- public function testDeleteRole()
+ public function testDeleteRole(): void
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN);
$this->assertAccessIsGranted($client, '/admin/permissions/roles/create');
@@ -132,7 +132,7 @@ class PermissionControllerTest extends ControllerBaseTest
$this->assertEquals(['ROLE_TEAMLEAD', 'ROLE_SUPER_ADMIN', 'TEST_ROLE', 'ROLE_USER'], $user->getRoles());
$this->request($client, '/admin/permissions');
- $node = $client->getCrawler()->filter('table.dataTable thead th a.confirmation-link');
+ $node = $client->getCrawler()->filter('div.card .card-title a.confirmation-link');
self::assertEquals(1, $node->count());
$this->request($client, $node->attr('href'));
@@ -148,17 +148,17 @@ class PermissionControllerTest extends ControllerBaseTest
$this->assertEquals(['ROLE_TEAMLEAD', 'ROLE_SUPER_ADMIN', 'ROLE_USER'], $user->getRoles());
}
- public function testSavePermissionIsSecured()
+ public function testSavePermissionIsSecured(): void
{
$this->assertUrlIsSecured('/admin/permissions/roles/1/view_user/1/asdfasdf', 'POST');
}
- public function testSavePermissionIsSecuredForRole()
+ public function testSavePermissionIsSecuredForRole(): void
{
$this->assertUrlIsSecuredForRole(User::ROLE_ADMIN, '/admin/permissions');
}
- public function testSavePermission()
+ public function testSavePermission(): void
{
$client = $this->getClientForAuthenticatedUser(User::ROLE_SUPER_ADMIN);
$this->assertAccessIsGranted($client, '/admin/permissions/roles/create');
diff --git a/tests/Entity/RoleTest.php b/tests/Entity/RoleTest.php
index d8462ad3..66b9f014 100644
--- a/tests/Entity/RoleTest.php
+++ b/tests/Entity/RoleTest.php
@@ -22,6 +22,7 @@ class RoleTest extends TestCase
$sut = new Role();
self::assertNull($sut->getId());
self::assertNull($sut->getName());
+ self::assertFalse($sut->isUser());
}
public function testSetterAndGetter(): void
@@ -30,8 +31,13 @@ class RoleTest extends TestCase
$sut->setName('foo');
self::assertEquals('FOO', $sut->getName());
+ self::assertFalse($sut->isUser());
$sut->setName('BAR');
self::assertEquals('BAR', $sut->getName());
+ self::assertFalse($sut->isUser());
+
+ $sut->setName('ROLE_USER');
+ self::assertTrue($sut->isUser());
}
}
diff --git a/tests/phpstan.neon b/tests/phpstan.neon
index 02bcd497..68afa73e 100644
--- a/tests/phpstan.neon
+++ b/tests/phpstan.neon
@@ -2572,66 +2572,6 @@ parameters:
count: 1
path: Controller/PermissionControllerTest.php
- -
- message: "#^Method App\\\\Tests\\\\Controller\\\\PermissionControllerTest\\:\\:testCreateRole\\(\\) has no return type specified\\.$#"
- count: 1
- path: Controller/PermissionControllerTest.php
-
- -
- message: "#^Method App\\\\Tests\\\\Controller\\\\PermissionControllerTest\\:\\:testCreateRoleIsSecured\\(\\) has no return type specified\\.$#"
- count: 1
- path: Controller/PermissionControllerTest.php
-
- -
- message: "#^Method App\\\\Tests\\\\Controller\\\\PermissionControllerTest\\:\\:testCreateRoleIsSecuredForRole\\(\\) has no return type specified\\.$#"
- count: 1
- path: Controller/PermissionControllerTest.php
-
- -
- message: "#^Method App\\\\Tests\\\\Controller\\\\PermissionControllerTest\\:\\:testDeleteRole\\(\\) has no return type specified\\.$#"
- count: 1
- path: Controller/PermissionControllerTest.php
-
- -
- message: "#^Method App\\\\Tests\\\\Controller\\\\PermissionControllerTest\\:\\:testDeleteRoleIsSecured\\(\\) has no return type specified\\.$#"
- count: 1
- path: Controller/PermissionControllerTest.php
-
- -
- message: "#^Method App\\\\Tests\\\\Controller\\\\PermissionControllerTest\\:\\:testDeleteRoleIsSecuredForRole\\(\\) has no return type specified\\.$#"
- count: 1
- path: Controller/PermissionControllerTest.php
-
- -
- message: "#^Method App\\\\Tests\\\\Controller\\\\PermissionControllerTest\\:\\:testIsSecure\\(\\) has no return type specified\\.$#"
- count: 1
- path: Controller/PermissionControllerTest.php
-
- -
- message: "#^Method App\\\\Tests\\\\Controller\\\\PermissionControllerTest\\:\\:testIsSecureForRole\\(\\) has no return type specified\\.$#"
- count: 1
- path: Controller/PermissionControllerTest.php
-
- -
- message: "#^Method App\\\\Tests\\\\Controller\\\\PermissionControllerTest\\:\\:testPermissions\\(\\) has no return type specified\\.$#"
- count: 1
- path: Controller/PermissionControllerTest.php
-
- -
- message: "#^Method App\\\\Tests\\\\Controller\\\\PermissionControllerTest\\:\\:testSavePermission\\(\\) has no return type specified\\.$#"
- count: 1
- path: Controller/PermissionControllerTest.php
-
- -
- message: "#^Method App\\\\Tests\\\\Controller\\\\PermissionControllerTest\\:\\:testSavePermissionIsSecured\\(\\) has no return type specified\\.$#"
- count: 1
- path: Controller/PermissionControllerTest.php
-
- -
- message: "#^Method App\\\\Tests\\\\Controller\\\\PermissionControllerTest\\:\\:testSavePermissionIsSecuredForRole\\(\\) has no return type specified\\.$#"
- count: 1
- path: Controller/PermissionControllerTest.php
-
-
message: "#^Parameter \\#1 \\$content of method App\\\\Tests\\\\Controller\\\\PermissionControllerTest\\:\\:assertTableHeader\\(\\) expects string, string\\|false given\\.$#"
count: 2
|