diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index 17ae9705..1a4887c3 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -31,6 +31,7 @@ namespace App\Controller; use App\Entity\Attachments\AttachmentType; use App\Entity\UserSystem\User; +use App\Form\Permissions\PermissionsType; use App\Form\UserAdminForm; use App\Form\UserSettingsType; use App\Services\EntityExporter; @@ -135,9 +136,18 @@ class UserController extends AdminPages\BaseAdminController $avatar = $packages->getUrl('/img/default_avatar.png'); } + //Show permissions to user + $builder = $this->createFormBuilder()->add('permissions',PermissionsType::class, [ + 'mapped' => false, + 'disabled' => true, + 'inherit' => true, + 'data' => $user + ]); + return $this->render('Users/user_info.html.twig', [ 'user' => $user, 'avatar' => $avatar, + 'form' => $builder->getForm()->createView() ]); } diff --git a/src/Form/Permissions/PermissionGroupType.php b/src/Form/Permissions/PermissionGroupType.php index 1cb9cd4a..992ef645 100644 --- a/src/Form/Permissions/PermissionGroupType.php +++ b/src/Form/Permissions/PermissionGroupType.php @@ -71,7 +71,8 @@ class PermissionGroupType extends AbstractType 'label' => $permission['label'] ?? $key, 'mapped' => false, 'data' => $builder->getData(), - 'disabled' => $options['disabled'] + 'disabled' => $options['disabled'], + 'inherit' => $options['inherit'] ]); } } @@ -84,6 +85,8 @@ class PermissionGroupType extends AbstractType return trim($options['name']); }); + $resolver->setDefault('inherit', false); + $resolver->setDefault('label', function (Options $options) { if (!empty($this->perm_structure['groups'][$options['group_name']]['label'])) { return $this->perm_structure['groups'][$options['group_name']]['label']; diff --git a/src/Form/Permissions/PermissionType.php b/src/Form/Permissions/PermissionType.php index c1d9e044..b82ea218 100644 --- a/src/Form/Permissions/PermissionType.php +++ b/src/Form/Permissions/PermissionType.php @@ -44,7 +44,7 @@ use Symfony\Component\Form\FormView; use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; -class PermissionType extends AbstractType implements DataMapperInterface +class PermissionType extends AbstractType { protected $resolver; protected $perm_structure; @@ -76,6 +76,7 @@ class PermissionType extends AbstractType implements DataMapperInterface }); $resolver->setDefaults([ + 'inherit' => false ]); } @@ -92,76 +93,11 @@ class PermissionType extends AbstractType implements DataMapperInterface ]); } - $builder->setDataMapper($this); + $builder->setDataMapper(new PermissionsMapper($this->resolver, $options['inherit'])); } public function buildView(FormView $view, FormInterface $form, array $options) { $view->vars['multi_checkbox'] = $options['multi_checkbox']; } - - /** - * Maps the view data of a compound form to its children. - * - * The method is responsible for calling {@link FormInterface::setData()} - * on the children of compound forms, defining their underlying model data. - * - * @param mixed $viewData View data of the compound form being initialized - * @param FormInterface[]|\Traversable $forms A list of {@link FormInterface} instances - * - * @throws Exception\UnexpectedTypeException if the type of the data parameter is not supported - */ - public function mapDataToForms($viewData, $forms) - { - foreach ($forms as $form) { - $value = $this->resolver->dontInherit( - $viewData, - $form->getParent()->getConfig()->getOption('perm_name'), - $form->getName() - ); - $form->setData($value); - } - } - - /** - * Maps the model data of a list of children forms into the view data of their parent. - * - * This is the internal cascade call of FormInterface::submit for compound forms, since they - * cannot be bound to any input nor the request as scalar, but their children may: - * - * $compoundForm->submit($arrayOfChildrenViewData) - * // inside: - * $childForm->submit($childViewData); - * // for each entry, do the same and/or reverse transform - * $this->dataMapper->mapFormsToData($compoundForm, $compoundInitialViewData) - * // then reverse transform - * - * When a simple form is submitted the following is happening: - * - * $simpleForm->submit($submittedViewData) - * // inside: - * $this->viewData = $submittedViewData - * // then reverse transform - * - * The model data can be an array or an object, so this second argument is always passed - * by reference. - * - * @param FormInterface[]|\Traversable $forms A list of {@link FormInterface} instances - * @param mixed $viewData The compound form's view data that get mapped - * its children model data - * - * @throws Exception\UnexpectedTypeException if the type of the data parameter is not supported - */ - public function mapFormsToData($forms, &$viewData) - { - foreach ($forms as $form) { - $value = $form->getData(); - $this->resolver->setPermission( - $viewData, - $form->getParent()->getConfig()->getOption('perm_name'), - $form->getName(), - $value - ); - } - } } \ No newline at end of file diff --git a/src/Form/Permissions/PermissionsMapper.php b/src/Form/Permissions/PermissionsMapper.php new file mode 100644 index 00000000..f9d91d8b --- /dev/null +++ b/src/Form/Permissions/PermissionsMapper.php @@ -0,0 +1,128 @@ +inherit = $inherit; + $this->resolver = $resolver; + } + + /** + * Maps the view data of a compound form to its children. + * + * The method is responsible for calling {@link FormInterface::setData()} + * on the children of compound forms, defining their underlying model data. + * + * @param mixed $viewData View data of the compound form being initialized + * @param FormInterface[]|\Traversable $forms A list of {@link FormInterface} instances + * + */ + public function mapDataToForms($viewData, $forms) + { + foreach ($forms as $form) { + if ($this->inherit) { + $value = $this->resolver->inherit( + $viewData, + $form->getParent()->getConfig()->getOption('perm_name'), + $form->getName() + ) ?? false; + } else { + $value = $this->resolver->dontInherit( + $viewData, + $form->getParent()->getConfig()->getOption('perm_name'), + $form->getName() + ); + } + $form->setData($value); + } + } + + /** + * Maps the model data of a list of children forms into the view data of their parent. + * + * This is the internal cascade call of FormInterface::submit for compound forms, since they + * cannot be bound to any input nor the request as scalar, but their children may: + * + * $compoundForm->submit($arrayOfChildrenViewData) + * // inside: + * $childForm->submit($childViewData); + * // for each entry, do the same and/or reverse transform + * $this->dataMapper->mapFormsToData($compoundForm, $compoundInitialViewData) + * // then reverse transform + * + * When a simple form is submitted the following is happening: + * + * $simpleForm->submit($submittedViewData) + * // inside: + * $this->viewData = $submittedViewData + * // then reverse transform + * + * The model data can be an array or an object, so this second argument is always passed + * by reference. + * + * @param FormInterface[]|\Traversable $forms A list of {@link FormInterface} instances + * @param mixed $viewData The compound form's view data that get mapped + * its children model data + * + */ + public function mapFormsToData($forms, &$viewData) + { + if ($this->inherit) { + throw new \RuntimeException('The permission type is readonly when it is showing read only data!'); + } + + foreach ($forms as $form) { + $value = $form->getData(); + $this->resolver->setPermission( + $viewData, + $form->getParent()->getConfig()->getOption('perm_name'), + $form->getName(), + $value + ); + } + } +} \ No newline at end of file diff --git a/src/Form/Permissions/PermissionsType.php b/src/Form/Permissions/PermissionsType.php index bb75f8e3..241442ba 100644 --- a/src/Form/Permissions/PermissionsType.php +++ b/src/Form/Permissions/PermissionsType.php @@ -62,7 +62,8 @@ class PermissionsType extends AbstractType return [new NoLockout()]; } return []; - } + }, + 'inherit' => false, ]); @@ -82,7 +83,8 @@ class PermissionsType extends AbstractType 'group_name' => $key, 'mapped' => false, 'data' => $builder->getData(), - 'disabled' => $options['disabled'] + 'disabled' => $options['disabled'], + 'inherit' => $options['inherit'] ]); } @@ -91,7 +93,8 @@ class PermissionsType extends AbstractType 'label' => 'perm.group.other', 'mapped' => false, 'data' => $builder->getData(), - 'disabled' => $options['disabled'] + 'disabled' => $options['disabled'], + 'inherit' => $options['inherit'] ]); } } \ No newline at end of file diff --git a/src/Security/Voter/UserVoter.php b/src/Security/Voter/UserVoter.php index 4b0e5ffa..2a57c391 100644 --- a/src/Security/Voter/UserVoter.php +++ b/src/Security/Voter/UserVoter.php @@ -78,7 +78,9 @@ class UserVoter extends ExtendedVoter } } //Else just check users permission: - return $this->resolver->inherit($user, 'users', $attribute) ?? false; + if ($this->resolver->isValidOperation('users', $attribute)) { + return $this->resolver->inherit($user, 'users', $attribute) ?? false; + } } return false; diff --git a/templates/Users/user_info.html.twig b/templates/Users/user_info.html.twig index 07262c01..8293bc18 100644 --- a/templates/Users/user_info.html.twig +++ b/templates/Users/user_info.html.twig @@ -29,7 +29,7 @@