-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Permissions on users logic #39
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,27 +17,34 @@ | |
use CleverAge\UiProcessBundle\Admin\Field\EnumField; | ||
use CleverAge\UiProcessBundle\Entity\ProcessExecution; | ||
use CleverAge\UiProcessBundle\Repository\ProcessExecutionRepository; | ||
use Doctrine\ORM\QueryBuilder; | ||
use EasyCorp\Bundle\EasyAdminBundle\Collection\FieldCollection; | ||
use EasyCorp\Bundle\EasyAdminBundle\Collection\FilterCollection; | ||
use EasyCorp\Bundle\EasyAdminBundle\Config\Action; | ||
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; | ||
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; | ||
use EasyCorp\Bundle\EasyAdminBundle\Config\Filters; | ||
use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext; | ||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController; | ||
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto; | ||
use EasyCorp\Bundle\EasyAdminBundle\Dto\SearchDto; | ||
use EasyCorp\Bundle\EasyAdminBundle\Field\ArrayField; | ||
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField; | ||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField; | ||
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; | ||
use Symfony\Component\HttpFoundation\RedirectResponse; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; | ||
use Symfony\Component\Security\Core\Role\RoleHierarchy; | ||
use Symfony\Component\Security\Http\Attribute\IsGranted; | ||
|
||
#[IsGranted('ROLE_USER')] | ||
#[IsGranted('ROLE_ADMIN')] | ||
class ProcessExecutionCrudController extends AbstractCrudController | ||
{ | ||
public function __construct( | ||
private readonly ProcessExecutionRepository $processExecutionRepository, | ||
private readonly string $logDirectory, | ||
private readonly RoleHierarchy $roleHierarchy, | ||
) { | ||
} | ||
|
||
|
@@ -153,4 +160,22 @@ private function getLogFilePath(ProcessExecution $processExecution): string | |
\DIRECTORY_SEPARATOR.$processExecution->logFilename | ||
; | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Modification du query builder de la page de listing de l'execution des process pour ne pas afficher les rôles sur lesquels l'user connecté n'a pas le role ROLE_PROCESS_VIEW#{process.code} |
||
public function createIndexQueryBuilder( | ||
SearchDto $searchDto, | ||
EntityDto $entityDto, | ||
FieldCollection $fields, | ||
FilterCollection $filters, | ||
): QueryBuilder { | ||
$roles = $this->roleHierarchy->getReachableRoleNames($this->getUser()?->getRoles() ?? []); | ||
$qb = parent::createIndexQueryBuilder($searchDto, $entityDto, $fields, $filters); | ||
$qb->andWhere( | ||
$qb->expr()->in( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Si l'user a accès a ROLE_PROCESS_VIEW alors ne pas faire le filtrage. |
||
(string) $qb->expr()->concat($qb->expr()->literal('ROLE_PROCESS_VIEW#'), 'entity.code'), | ||
':roles' | ||
) | ||
)->setParameter('roles', $roles); | ||
|
||
return $qb; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,7 @@ | |
|
||
namespace CleverAge\UiProcessBundle\Controller\Admin; | ||
|
||
use CleverAge\ProcessBundle\Registry\ProcessConfigurationRegistry; | ||
use CleverAge\UiProcessBundle\Entity\User; | ||
use EasyCorp\Bundle\EasyAdminBundle\Config\Action; | ||
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; | ||
|
@@ -30,20 +31,31 @@ | |
use Symfony\Component\Form\Extension\Core\Type\RepeatedType; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Component\PasswordHasher\Hasher\Pbkdf2PasswordHasher; | ||
use Symfony\Component\Routing\Generator\UrlGenerator; | ||
use Symfony\Component\Security\Http\Attribute\IsGranted; | ||
use Symfony\Contracts\Translation\TranslatorInterface; | ||
|
||
#[IsGranted('ROLE_USER')] | ||
#[IsGranted('ROLE_SUPER_ADMIN')] | ||
class UserCrudController extends AbstractCrudController | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A voir si on fait une gestion des groupes via une admin ou juste via le security.yaml role_hierarchy. |
||
{ | ||
/** @param array<string, string> $roles */ | ||
public function __construct(private readonly array $roles) | ||
{ | ||
/** @param array<string, array<string, string>|string> $roles */ | ||
public function __construct( | ||
private array $roles, | ||
private readonly ProcessConfigurationRegistry $processConfigurationRegistry, | ||
private readonly TranslatorInterface $translator, | ||
) { | ||
foreach ($this->processConfigurationRegistry->getProcessConfigurations() as $config) { | ||
$this->roles[$config->getCode()] = [ | ||
$this->translator->trans('View process').' '.$config->getCode() => 'ROLE_PROCESS_VIEW#'.$config->getCode(), | ||
$this->translator->trans('Execute process').' '.$config->getCode() => 'ROLE_PROCESS_EXECUTE#'.$config->getCode(), | ||
]; | ||
} | ||
} | ||
|
||
public function configureCrud(Crud $crud): Crud | ||
{ | ||
$crud->showEntityActionsInlined(); | ||
$crud->setEntityPermission('ROLE_ADMIN'); | ||
$crud->setEntityPermission('ROLE_SUPER_ADMIN'); | ||
|
||
return $crud; | ||
} | ||
|
@@ -79,7 +91,7 @@ public function configureFields(string $pageName): iterable | |
yield FormField::addTab('Roles')->setIcon('fa fa-theater-masks'); | ||
yield ChoiceField::new('roles', false) | ||
->setChoices($this->roles) | ||
->setFormTypeOptions(['multiple' => true, 'expanded' => true]); | ||
->setFormTypeOptions(['multiple' => true, 'expanded' => false]); | ||
yield FormField::addTab('Intl.')->setIcon('fa fa-flag'); | ||
yield TimezoneField::new('timezone'); | ||
yield LocaleField::new('locale'); | ||
|
@@ -95,7 +107,8 @@ public function configureActions(Actions $actions): Actions | |
->addCssClass('text-warning'))->update(Crud::PAGE_INDEX, Action::DELETE, fn (Action $action) => $action->setIcon('fa fa-trash-o') | ||
->setLabel(false) | ||
->addCssClass(''))->update(Crud::PAGE_INDEX, Action::BATCH_DELETE, fn (Action $action) => $action->setLabel('Delete') | ||
->addCssClass(''))->add(Crud::PAGE_EDIT, Action::new('generateToken')->linkToCrudAction('generateToken')); | ||
->addCssClass(''))->add(Crud::PAGE_EDIT, Action::new('generateToken')->linkToCrudAction('generateToken')) | ||
->add(Crud::PAGE_INDEX, Action::new('ConnectAs')->linkToUrl(fn (User $user) => $this->generateUrl('process', ['_switch_user' => $user->getEmail()], UrlGenerator::ABSOLUTE_URL))->setLabel(false)->setIcon('fa-solid fa-right-to-bracket'))->setPermission('ConnectAs', 'ROLE_SUPER_ADMIN'); | ||
} | ||
|
||
public function generateToken(AdminContext $adminContext, AdminUrlGenerator $adminUrlGenerator): Response | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of the CleverAge/UiProcessBundle package. | ||
* | ||
* Copyright (c) Clever-Age | ||
* | ||
* For the full copyright and license information, please view the LICENSE | ||
* file that was distributed with this source code. | ||
*/ | ||
|
||
namespace CleverAge\UiProcessBundle\DependencyInjection\CompilerPass; | ||
|
||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; | ||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
|
||
class SecurityRolesCompilerPass implements CompilerPassInterface | ||
{ | ||
public function process(ContainerBuilder $container) | ||
{ | ||
if ($container->hasDefinition('security.role_hierarchy')) { | ||
// For each configured process, add ROLE_PROCESS_VIEW#<code> and ROLE_PROCESS_EXECUTE#<code> under ROLE_SUPER_ADMIN role | ||
$pbExtCfg = $container->getExtensionConfig('clever_age_process'); | ||
$processCodes = array_keys(array_merge(...array_column($pbExtCfg, 'configurations'))); | ||
$processRoles = array_merge(...array_map(fn ($code) => ['ROLE_PROCESS_VIEW#'.$code, 'ROLE_PROCESS_EXECUTE#'.$code], $processCodes)); | ||
$roleHierarchy = $container->getParameter('security.role_hierarchy.roles'); | ||
if (\is_array($roleHierarchy)) { | ||
$roleHierarchy['ROLE_SUPER_ADMIN'] = array_merge($roleHierarchy['ROLE_SUPER_ADMIN'] ?? [], $processRoles); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rajouter 2 niveaux ROLE_PROCESS_VIEW et ROLE_PROCESS_EXECUTE qui contiennent leurs enfants respectifs. Du coup ROLE_SUPER_ADMIN, contient [ROLE_PROCESS_VIEW, ROLE_PROCESS_EXECUTE]. Ajouter un bout de doc expliquant qu'il suffit de mettre un role_hierarchy: ROLE_ADMIN: [ROLE_PROCESS_VIEW, ROLE_PROCESS_EXECUTE] si on a pas besoin de cette protection. |
||
$container->setParameter('security.role_hierarchy.roles', $roleHierarchy); | ||
$container->getDefinition('security.role_hierarchy')->replaceArgument(0, $roleHierarchy); | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Modification du query builder de la page de listing des logs pour ne pas afficher les rôles sur lesquels l'user connecté n'a pas le role ROLE_PROCESS_VIEW#{process.code}