diff --git a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php index 06489010c..25dd3fedd 100644 --- a/src/Bundle/ChillActivityBundle/Controller/ActivityController.php +++ b/src/Bundle/ChillActivityBundle/Controller/ActivityController.php @@ -24,6 +24,7 @@ use Chill\MainBundle\Entity\UserJob; use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Repository\LocationRepository; use Chill\MainBundle\Repository\UserRepositoryInterface; +use Chill\MainBundle\Security\ChillSecurity; use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; use Chill\MainBundle\Templating\Listing\FilterOrderHelper; use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactoryInterface; @@ -67,6 +68,7 @@ final class ActivityController extends AbstractController private readonly FilterOrderHelperFactoryInterface $filterOrderHelperFactory, private readonly TranslatableStringHelperInterface $translatableStringHelper, private readonly PaginatorFactory $paginatorFactory, + private readonly ChillSecurity $security ) {} /** @@ -384,7 +386,7 @@ final class ActivityController extends AbstractController } $entity = new Activity(); - $entity->setUser($this->getUser()); + $entity->setUser($this->security->getUser()); if ($person instanceof Person) { $entity->setPerson($person); @@ -399,7 +401,7 @@ final class ActivityController extends AbstractController $entity->setDate(new \DateTime('now')); if ($request->query->has('activityData')) { - $activityData = $request->query->get('activityData'); + $activityData = $request->query->all('activityData'); if (\array_key_exists('durationTime', $activityData) && $activityType->getDurationTimeVisible() > 0) { $durationTimeInMinutes = $activityData['durationTime']; @@ -452,7 +454,7 @@ final class ActivityController extends AbstractController if (\array_key_exists('comment', $activityData) && $activityType->getCommentVisible() > 0) { $comment = new CommentEmbeddable(); $comment->setComment($activityData['comment']); - $comment->setUserId($this->getUser()->getid()); + $comment->setUserId($this->security->getUser()->getId()); $comment->setDate(new \DateTime('now')); $entity->setComment($comment); } @@ -513,7 +515,7 @@ final class ActivityController extends AbstractController $activity_array = $this->serializer->normalize($entity, 'json', ['groups' => 'read']); - $defaultLocation = $this->getUser()->getCurrentLocation(); + $defaultLocation = $this->security->getUser()->getCurrentLocation(); return $this->render($view, [ 'person' => $person, @@ -568,7 +570,7 @@ final class ActivityController extends AbstractController 'person' => $person, 'accompanyingCourse' => $accompanyingPeriod, 'data' => $data, - 'activityData' => $request->query->get('activityData', []), + 'activityData' => $request->query->all('activityData'), ]); } diff --git a/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivity.php b/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivity.php index b205384e6..a547ab21e 100644 --- a/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivity.php +++ b/src/Bundle/ChillActivityBundle/DataFixtures/ORM/LoadActivity.php @@ -64,7 +64,7 @@ class LoadActivity extends AbstractFixture implements OrderedFixtureInterface ->setPerson($person) ->setDate($this->faker->dateTimeThisYear()) ->setDurationTime($this->faker->dateTime(36000)) - ->setType($this->getRandomActivityType()) + ->setActivityType($this->getRandomActivityType()) ->setScope($this->getRandomScope()); // ->setAttendee($this->faker->boolean()) diff --git a/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityController.php b/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityController.php index c29a5a6dc..e0d553327 100644 --- a/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityController.php +++ b/src/Bundle/ChillAsideActivityBundle/src/Controller/AsideActivityController.php @@ -15,19 +15,25 @@ use Chill\AsideActivityBundle\Entity\AsideActivity; use Chill\AsideActivityBundle\Repository\AsideActivityCategoryRepository; use Chill\MainBundle\CRUD\Controller\CRUDController; use Chill\MainBundle\Pagination\PaginatorInterface; +use Chill\MainBundle\Security\ChillSecurity; use Chill\MainBundle\Templating\Listing\FilterOrderHelper; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; final class AsideActivityController extends CRUDController { - public function __construct(private readonly AsideActivityCategoryRepository $categoryRepository) {} + public function __construct(private readonly AsideActivityCategoryRepository $categoryRepository, private readonly ChillSecurity $security) {} public function createEntity(string $action, Request $request): object { + if (!$this->security->isGranted('ROLE_USER')) { + throw new AccessDeniedHttpException(); + } + $asideActivity = new AsideActivity(); - $asideActivity->setAgent($this->getUser()); - $asideActivity->setLocation($this->getUser()->getCurrentLocation()); + $asideActivity->setAgent($this->security->getUser()); + $asideActivity->setLocation($this->security->getUser()->getCurrentLocation()); $duration = $request->query->get('duration', '300'); $duration = \DateTime::createFromFormat('U', $duration); diff --git a/src/Bundle/ChillCalendarBundle/Event/ListenToActivityCreate.php b/src/Bundle/ChillCalendarBundle/Event/ListenToActivityCreate.php index 82c76eea4..79629bfbb 100644 --- a/src/Bundle/ChillCalendarBundle/Event/ListenToActivityCreate.php +++ b/src/Bundle/ChillCalendarBundle/Event/ListenToActivityCreate.php @@ -29,7 +29,7 @@ class ListenToActivityCreate } if ($request->query->has('activityData')) { - $activityData = $request->query->get('activityData'); + $activityData = $request->query->all('activityData'); if (\array_key_exists('calendarId', $activityData)) { $calendarId = $activityData['calendarId']; diff --git a/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php b/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php index c9e1873b2..5f8d99f7c 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php +++ b/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php @@ -20,6 +20,7 @@ use Chill\DocGeneratorBundle\Service\Generator\GeneratorInterface; use Chill\DocGeneratorBundle\Service\Messenger\RequestGenerationMessage; use Chill\DocStoreBundle\Entity\StoredObject; use Chill\MainBundle\Pagination\PaginatorFactory; +use Chill\MainBundle\Security\ChillSecurity; use Chill\MainBundle\Serializer\Model\Collection; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -37,7 +38,15 @@ use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; final class DocGeneratorTemplateController extends AbstractController { - public function __construct(private readonly ContextManager $contextManager, private readonly DocGeneratorTemplateRepository $docGeneratorTemplateRepository, private readonly GeneratorInterface $generator, private readonly MessageBusInterface $messageBus, private readonly PaginatorFactory $paginatorFactory, private readonly EntityManagerInterface $entityManager) {} + public function __construct( + private readonly ContextManager $contextManager, + private readonly DocGeneratorTemplateRepository $docGeneratorTemplateRepository, + private readonly GeneratorInterface $generator, + private readonly MessageBusInterface $messageBus, + private readonly PaginatorFactory $paginatorFactory, + private readonly EntityManagerInterface $entityManager, + private readonly ChillSecurity $security + ) {} /** * @Route( @@ -217,7 +226,7 @@ final class DocGeneratorTemplateController extends AbstractController : []; // if is test, render the data or generate the doc - if ($isTest && isset($form) && $form['show_data']->getData()) { + if ($isTest && isset($form) && true === $form['show_data']->getData()) { return $this->render('@ChillDocGenerator/Generator/debug_value.html.twig', [ 'datas' => json_encode($context->getData($template, $entity, $contextGenerationData), \JSON_PRETTY_PRINT), ]); @@ -265,7 +274,7 @@ final class DocGeneratorTemplateController extends AbstractController $this->messageBus->dispatch( new RequestGenerationMessage( - $this->getUser(), + $this->security->getUser(), $template, $entityId, $storedObject, diff --git a/src/Bundle/ChillMainBundle/Controller/AbsenceController.php b/src/Bundle/ChillMainBundle/Controller/AbsenceController.php index 809b7b901..8664dbde5 100644 --- a/src/Bundle/ChillMainBundle/Controller/AbsenceController.php +++ b/src/Bundle/ChillMainBundle/Controller/AbsenceController.php @@ -12,12 +12,15 @@ declare(strict_types=1); namespace Chill\MainBundle\Controller; use Chill\MainBundle\Form\AbsenceType; +use Chill\MainBundle\Security\ChillSecurity; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; class AbsenceController extends AbstractController { + public function __construct(private readonly ChillSecurity $security) {} + /** * @Route( * "/{_locale}/absence", @@ -27,7 +30,7 @@ class AbsenceController extends AbstractController */ public function setAbsence(Request $request) { - $user = $this->getUser(); + $user = $this->security->getUser(); $form = $this->createForm(AbsenceType::class, $user); $form->handleRequest($request); @@ -54,7 +57,7 @@ class AbsenceController extends AbstractController */ public function unsetAbsence(Request $request) { - $user = $this->getUser(); + $user = $this->security->getUser(); $user->setAbsenceStart(null); $em = $this->getDoctrine()->getManager(); diff --git a/src/Bundle/ChillMainBundle/Controller/NotificationController.php b/src/Bundle/ChillMainBundle/Controller/NotificationController.php index 4131ba714..37b715ebd 100644 --- a/src/Bundle/ChillMainBundle/Controller/NotificationController.php +++ b/src/Bundle/ChillMainBundle/Controller/NotificationController.php @@ -13,7 +13,6 @@ namespace Chill\MainBundle\Controller; use Chill\MainBundle\Entity\Notification; use Chill\MainBundle\Entity\NotificationComment; -use Chill\MainBundle\Entity\User; use Chill\MainBundle\Form\NotificationCommentType; use Chill\MainBundle\Form\NotificationType; use Chill\MainBundle\Notification\Exception\NotificationHandlerNotFound; @@ -22,6 +21,7 @@ use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Repository\NotificationRepository; use Chill\MainBundle\Repository\UserRepository; use Chill\MainBundle\Security\Authorization\NotificationVoter; +use Chill\MainBundle\Security\ChillSecurity; use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -32,7 +32,6 @@ use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Routing\Annotation\Route; -use Symfony\Component\Security\Core\Security; use Symfony\Contracts\Translation\TranslatorInterface; use function in_array; @@ -41,7 +40,7 @@ use function in_array; */ class NotificationController extends AbstractController { - public function __construct(private readonly EntityManagerInterface $em, private readonly LoggerInterface $chillLogger, private readonly LoggerInterface $logger, private readonly Security $security, private readonly NotificationRepository $notificationRepository, private readonly NotificationHandlerManager $notificationHandlerManager, private readonly PaginatorFactory $paginatorFactory, private readonly TranslatorInterface $translator, private readonly UserRepository $userRepository) {} + public function __construct(private readonly EntityManagerInterface $em, private readonly LoggerInterface $chillLogger, private readonly LoggerInterface $logger, private readonly ChillSecurity $security, private readonly NotificationRepository $notificationRepository, private readonly NotificationHandlerManager $notificationHandlerManager, private readonly PaginatorFactory $paginatorFactory, private readonly TranslatorInterface $translator, private readonly UserRepository $userRepository) {} /** * @Route("/create", name="chill_main_notification_create") @@ -50,10 +49,6 @@ class NotificationController extends AbstractController { $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); - if (!$this->security->getUser() instanceof User) { - throw new AccessDeniedHttpException('You must be authenticated and a user to create a notification'); - } - if (!$request->query->has('entityClass')) { throw new BadRequestHttpException('Missing entityClass parameter'); } @@ -68,13 +63,13 @@ class NotificationController extends AbstractController ->setRelatedEntityId($request->query->getInt('entityId')) ->setSender($this->security->getUser()); - if ($request->query->has('tos')) { - foreach ($request->query->get('tos') as $toId) { - if (null === $to = $this->userRepository->find($toId)) { - throw new NotFoundHttpException("user with id {$toId} is not found"); - } - $notification->addAddressee($to); + $tos = $request->query->all('tos'); + + foreach ($tos as $toId) { + if (null === $to = $this->userRepository->find($toId)) { + throw new NotFoundHttpException("user with id {$toId} is not found"); } + $notification->addAddressee($to); } try { @@ -144,10 +139,6 @@ class NotificationController extends AbstractController { $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); - if (!$this->security->getUser() instanceof User) { - throw new AccessDeniedHttpException('You must be authenticated and a user to create a notification'); - } - foreach (['accessKey'/* , 'email' */] as $param) { if (!$request->query->has($param)) { throw new BadRequestHttpException("Missing {$param} parameter"); @@ -308,8 +299,8 @@ class NotificationController extends AbstractController ]); // we mark the notification as read after having computed the response - if ($this->getUser() instanceof User && !$notification->isReadBy($this->getUser())) { - $notification->markAsReadBy($this->getUser()); + if (!$notification->isReadBy($this->security->getUser())) { + $notification->markAsReadBy($this->security->getUser()); $this->em->flush(); } diff --git a/src/Bundle/ChillMainBundle/Controller/PasswordController.php b/src/Bundle/ChillMainBundle/Controller/PasswordController.php index 04ec22977..c6815f2cf 100644 --- a/src/Bundle/ChillMainBundle/Controller/PasswordController.php +++ b/src/Bundle/ChillMainBundle/Controller/PasswordController.php @@ -13,6 +13,7 @@ namespace Chill\MainBundle\Controller; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Form\UserPasswordType; +use Chill\MainBundle\Security\ChillSecurity; use Chill\MainBundle\Security\PasswordRecover\PasswordRecoverEvent; use Chill\MainBundle\Security\PasswordRecover\PasswordRecoverVoter; use Chill\MainBundle\Security\PasswordRecover\RecoverPasswordHelper; @@ -24,6 +25,7 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; use Symfony\Component\Validator\Constraints\Callback; @@ -33,56 +35,12 @@ use Symfony\Contracts\Translation\TranslatorInterface; /** * Class PasswordController. */ -class PasswordController extends AbstractController +final class PasswordController extends AbstractController { - /** - * @var LoggerInterface - */ - protected $chillLogger; - - /** - * @var EventDispatcherInterface - */ - protected $eventDispatcher; - - /** - * @var UserPasswordEncoderInterface - */ - protected $passwordEncoder; - - /** - * @var RecoverPasswordHelper - */ - protected $recoverPasswordHelper; - - /** - * @var TokenManager - */ - protected $tokenManager; - - /** - * @var TranslatorInterface - */ - protected $translator; - /** * PasswordController constructor. */ - public function __construct( - LoggerInterface $chillLogger, - UserPasswordEncoderInterface $passwordEncoder, - RecoverPasswordHelper $recoverPasswordHelper, - TokenManager $tokenManager, - TranslatorInterface $translator, - EventDispatcherInterface $eventDispatcher - ) { - $this->chillLogger = $chillLogger; - $this->passwordEncoder = $passwordEncoder; - $this->translator = $translator; - $this->tokenManager = $tokenManager; - $this->recoverPasswordHelper = $recoverPasswordHelper; - $this->eventDispatcher = $eventDispatcher; - } + public function __construct(private readonly LoggerInterface $chillLogger, private readonly UserPasswordEncoderInterface $passwordEncoder, private readonly RecoverPasswordHelper $recoverPasswordHelper, private readonly TokenManager $tokenManager, private readonly TranslatorInterface $translator, private readonly EventDispatcherInterface $eventDispatcher, private readonly ChillSecurity $security) {} /** * @return Response @@ -250,8 +208,11 @@ class PasswordController extends AbstractController */ public function UserPasswordAction(Request $request) { + if (!$this->security->isGranted('ROLE_USER')) { + throw new AccessDeniedHttpException(); + } // get authentified user - $user = $this->getUser(); + $user = $this->security->getUser(); // create a form for password_encoder $form = $this->passwordForm($user); @@ -269,7 +230,7 @@ class PasswordController extends AbstractController 'update password for an user', [ 'method' => $request->getMethod(), - 'user' => $user->getUsername(), + 'user' => $user->getUserIdentifier(), ] ); diff --git a/src/Bundle/ChillMainBundle/Controller/SearchController.php b/src/Bundle/ChillMainBundle/Controller/SearchController.php index 6324561cc..e81e3d9dc 100644 --- a/src/Bundle/ChillMainBundle/Controller/SearchController.php +++ b/src/Bundle/ChillMainBundle/Controller/SearchController.php @@ -199,7 +199,7 @@ class SearchController extends AbstractController { // TODO this is an incomplete implementation $query = $request->query->get('q', ''); - $types = $request->query->get('type', []); + $types = $request->query->all('type'); if (0 === \count($types)) { throw new BadRequestHttpException('The request must contains at one type'); diff --git a/src/Bundle/ChillMainBundle/Controller/UserApiController.php b/src/Bundle/ChillMainBundle/Controller/UserApiController.php index 6809d3289..ae764c9d2 100644 --- a/src/Bundle/ChillMainBundle/Controller/UserApiController.php +++ b/src/Bundle/ChillMainBundle/Controller/UserApiController.php @@ -13,13 +13,17 @@ namespace Chill\MainBundle\Controller; use Chill\MainBundle\CRUD\Controller\ApiController; use Chill\MainBundle\Pagination\PaginatorInterface; +use Chill\MainBundle\Security\ChillSecurity; use Doctrine\ORM\QueryBuilder; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\Routing\Annotation\Route; class UserApiController extends ApiController { + public function __construct(private readonly ChillSecurity $security) {} + /** * @Route( * "/api/1.0/main/user-current-location.{_format}", @@ -31,8 +35,12 @@ class UserApiController extends ApiController */ public function currentLocation(mixed $_format): JsonResponse { + if (!$this->isGranted('ROLE_USER')) { + throw new AccessDeniedHttpException(); + } + return $this->json( - $this->getUser()->getCurrentLocation(), + $this->security->getUser()->getCurrentLocation(), JsonResponse::HTTP_OK, [], ['groups' => ['read']] diff --git a/src/Bundle/ChillMainBundle/Controller/UserController.php b/src/Bundle/ChillMainBundle/Controller/UserController.php index 1a25c4ad4..8e0e8ad1b 100644 --- a/src/Bundle/ChillMainBundle/Controller/UserController.php +++ b/src/Bundle/ChillMainBundle/Controller/UserController.php @@ -20,6 +20,7 @@ use Chill\MainBundle\Form\UserPasswordType; use Chill\MainBundle\Form\UserType; use Chill\MainBundle\Pagination\PaginatorInterface; use Chill\MainBundle\Repository\UserRepository; +use Chill\MainBundle\Security\ChillSecurity; use Chill\MainBundle\Templating\Listing\FilterOrderHelper; use Psr\Log\LoggerInterface; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; @@ -38,7 +39,15 @@ class UserController extends CRUDController { final public const FORM_GROUP_CENTER_COMPOSED = 'composed_groupcenter'; - public function __construct(private readonly LoggerInterface $logger, private readonly ValidatorInterface $validator, private readonly UserPasswordEncoderInterface $passwordEncoder, private readonly UserRepository $userRepository, protected ParameterBagInterface $parameterBag, private readonly TranslatorInterface $translator) {} + public function __construct( + private readonly LoggerInterface $logger, + private readonly ValidatorInterface $validator, + private readonly UserPasswordEncoderInterface $passwordEncoder, + private readonly UserRepository $userRepository, + protected ParameterBagInterface $parameterBag, + private readonly TranslatorInterface $translator, + private readonly ChillSecurity $security + ) {} /** * @Route("/{_locale}/admin/main/user/{uid}/add_link_groupcenter", @@ -197,7 +206,7 @@ class UserController extends CRUDController */ public function editCurrentLocationAction(Request $request) { - $user = $this->getUser(); + $user = $this->security->getUser(); $form = $this->createForm(UserCurrentLocationType::class, $user) ->add('submit', SubmitType::class, ['label' => 'Save']) ->handleRequest($request); diff --git a/src/Bundle/ChillMainBundle/Controller/UserProfileController.php b/src/Bundle/ChillMainBundle/Controller/UserProfileController.php index 52aba1a48..0867bf2cd 100644 --- a/src/Bundle/ChillMainBundle/Controller/UserProfileController.php +++ b/src/Bundle/ChillMainBundle/Controller/UserProfileController.php @@ -12,18 +12,21 @@ declare(strict_types=1); namespace Chill\MainBundle\Controller; use Chill\MainBundle\Form\UserPhonenumberType; +use Chill\MainBundle\Security\ChillSecurity; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Component\Routing\Annotation\Route; -class UserProfileController extends AbstractController +final class UserProfileController extends AbstractController { public function __construct( private readonly TranslatorInterface $translator, + private readonly ChillSecurity $security, ) {} /** @@ -33,7 +36,11 @@ class UserProfileController extends AbstractController */ public function __invoke(Request $request) { - $user = $this->getUser(); + if (!$this->security->isGranted('ROLE_USER')) { + throw new AccessDeniedHttpException(); + } + + $user = $this->security->getUser(); $editForm = $this->createPhonenumberEditForm($user); $editForm->handleRequest($request); diff --git a/src/Bundle/ChillMainBundle/Controller/WorkflowController.php b/src/Bundle/ChillMainBundle/Controller/WorkflowController.php index b641ed46a..1e93d6f49 100644 --- a/src/Bundle/ChillMainBundle/Controller/WorkflowController.php +++ b/src/Bundle/ChillMainBundle/Controller/WorkflowController.php @@ -20,6 +20,7 @@ use Chill\MainBundle\Form\WorkflowStepType; use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository; use Chill\MainBundle\Security\Authorization\EntityWorkflowVoter; +use Chill\MainBundle\Security\ChillSecurity; use Chill\MainBundle\Workflow\EntityWorkflowManager; use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -27,10 +28,9 @@ use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Routing\Annotation\Route; -use Symfony\Component\Security\Core\Exception\AccessDeniedException; -use Symfony\Component\Security\Core\Security; use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Component\Workflow\Registry; use Symfony\Component\Workflow\TransitionBlocker; @@ -38,7 +38,7 @@ use Symfony\Contracts\Translation\TranslatorInterface; class WorkflowController extends AbstractController { - public function __construct(private readonly EntityWorkflowManager $entityWorkflowManager, private readonly EntityWorkflowRepository $entityWorkflowRepository, private readonly ValidatorInterface $validator, private readonly PaginatorFactory $paginatorFactory, private readonly Registry $registry, private readonly EntityManagerInterface $entityManager, private readonly TranslatorInterface $translator, private readonly Security $security) {} + public function __construct(private readonly EntityWorkflowManager $entityWorkflowManager, private readonly EntityWorkflowRepository $entityWorkflowRepository, private readonly ValidatorInterface $validator, private readonly PaginatorFactory $paginatorFactory, private readonly Registry $registry, private readonly EntityManagerInterface $entityManager, private readonly TranslatorInterface $translator, private readonly ChillSecurity $security) {} /** * @Route("/{_locale}/main/workflow/create", name="chill_main_workflow_create") @@ -62,7 +62,7 @@ class WorkflowController extends AbstractController ->setRelatedEntityClass($request->query->get('entityClass')) ->setRelatedEntityId($request->query->getInt('entityId')) ->setWorkflowName($request->query->get('workflow')) - ->addSubscriberToFinal($this->getUser()); + ->addSubscriberToFinal($this->security->getUser()); $errors = $this->validator->validate($entityWorkflow, null, ['creation']); @@ -123,17 +123,17 @@ class WorkflowController extends AbstractController } if (!$this->getUser() instanceof User) { - throw new AccessDeniedException('Not a valid user'); + throw new AccessDeniedHttpException('Not a valid user'); } if ($entityWorkflowStep->getAccessKey() !== $accessKey) { - throw new AccessDeniedException('Access key is invalid'); + throw new AccessDeniedHttpException('Access key is invalid'); } if (!$entityWorkflowStep->isWaitingForTransition()) { $this->addFlash('error', $this->translator->trans('workflow.Steps is not waiting for transition. Maybe someone apply the transition before you ?')); } else { - $entityWorkflowStep->addDestUserByAccessKey($this->getUser()); + $entityWorkflowStep->addDestUserByAccessKey($this->security->getUser()); $this->entityManager->flush(); $this->addFlash('success', $this->translator->trans('workflow.You get access to this step')); } @@ -150,11 +150,11 @@ class WorkflowController extends AbstractController { $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); - $total = $this->entityWorkflowRepository->countByPreviousTransitionned($this->getUser()); + $total = $this->entityWorkflowRepository->countByPreviousTransitionned($this->security->getUser()); $paginator = $this->paginatorFactory->create($total); $workflows = $this->entityWorkflowRepository->findByPreviousTransitionned( - $this->getUser(), + $this->security->getUser(), ['createdAt' => 'DESC'], $paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber() @@ -180,11 +180,11 @@ class WorkflowController extends AbstractController { $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); - $total = $this->entityWorkflowRepository->countByPreviousDestWithoutReaction($this->getUser()); + $total = $this->entityWorkflowRepository->countByPreviousDestWithoutReaction($this->security->getUser()); $paginator = $this->paginatorFactory->create($total); $workflows = $this->entityWorkflowRepository->findByPreviousDestWithoutReaction( - $this->getUser(), + $this->security->getUser(), ['createdAt' => 'DESC'], $paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber() @@ -208,11 +208,11 @@ class WorkflowController extends AbstractController { $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); - $total = $this->entityWorkflowRepository->countByDest($this->getUser()); + $total = $this->entityWorkflowRepository->countByDest($this->security->getUser()); $paginator = $this->paginatorFactory->create($total); $workflows = $this->entityWorkflowRepository->findByCc( - $this->getUser(), + $this->security->getUser(), ['createdAt' => 'DESC'], $paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber() @@ -235,11 +235,11 @@ class WorkflowController extends AbstractController { $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); - $total = $this->entityWorkflowRepository->countByDest($this->getUser()); + $total = $this->entityWorkflowRepository->countByDest($this->security->getUser()); $paginator = $this->paginatorFactory->create($total); $workflows = $this->entityWorkflowRepository->findByDest( - $this->getUser(), + $this->security->getUser(), ['createdAt' => 'DESC'], $paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber() @@ -262,11 +262,11 @@ class WorkflowController extends AbstractController { $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); - $total = $this->entityWorkflowRepository->countBySubscriber($this->getUser()); + $total = $this->entityWorkflowRepository->countBySubscriber($this->security->getUser()); $paginator = $this->paginatorFactory->create($total); $workflows = $this->entityWorkflowRepository->findBySubscriber( - $this->getUser(), + $this->security->getUser(), ['createdAt' => 'DESC'], $paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber() diff --git a/src/Bundle/ChillMainBundle/Entity/User.php b/src/Bundle/ChillMainBundle/Entity/User.php index fe1489337..d0debee73 100644 --- a/src/Bundle/ChillMainBundle/Entity/User.php +++ b/src/Bundle/ChillMainBundle/Entity/User.php @@ -364,6 +364,11 @@ class User implements UserInterface, \Stringable, PasswordAuthenticatedUserInter return $this->username; } + public function getUserIdentifier(): string + { + return $this->username; + } + /** * @return string */ diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php index af4da0bae..870f07cb4 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseController.php @@ -12,32 +12,41 @@ declare(strict_types=1); namespace Chill\PersonBundle\Controller; use Chill\ActivityBundle\Entity\Activity; +use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Form\AccompanyingCourseType; use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository; +use Chill\PersonBundle\Repository\PersonRepository; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; +use Chill\PersonBundle\Security\Authorization\PersonVoter; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\Routing\Annotation\Route; -use Symfony\Component\Serializer\SerializerInterface; +use Symfony\Component\Security\Core\Security; use Symfony\Component\Validator\ConstraintViolationInterface; use Symfony\Component\Validator\ConstraintViolationListInterface; use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Component\Workflow\Registry; -use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\Translation\TranslatorInterface; /** * Class AccompanyingCourseController. */ -class AccompanyingCourseController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController +final class AccompanyingCourseController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController { - public function __construct(protected SerializerInterface $serializer, protected EventDispatcherInterface $dispatcher, protected ValidatorInterface $validator, private readonly AccompanyingPeriodWorkRepository $workRepository, private readonly Registry $registry, private readonly TranslatorInterface $translator) {} + public function __construct( + private readonly ValidatorInterface $validator, + private readonly AccompanyingPeriodWorkRepository $workRepository, + private readonly Registry $registry, + private readonly TranslatorInterface $translator, + private readonly Security $security, + private readonly PersonRepository $personRepository, + ) {} /** * @Route("/{_locale}/parcours/{accompanying_period_id}/close", name="chill_person_accompanying_course_close") @@ -223,26 +232,29 @@ class AccompanyingCourseController extends \Symfony\Bundle\FrameworkBundle\Contr */ public function newAction(Request $request): Response { + $user = $this->security->getUser(); + + if (!$user instanceof User) { + throw new AccessDeniedHttpException(); + } + $period = new AccompanyingPeriod(); $em = $this->getDoctrine()->getManager(); - if ($request->query->has('person_id')) { - $personIds = $request->query->get('person_id'); + $personIds = $request->query->all('person_id'); - if (false === \is_array($personIds)) { - throw new BadRequestHttpException('person_id parameter should be an array'); - } + foreach ($personIds as $personId) { + $person = $this->personRepository->find($personId); - foreach ($personIds as $personId) { - $person = $em->getRepository(Person::class)->find($personId); - - if (null !== $person) { - $period->addPerson($person); + if (null !== $person) { + if (!$this->isGranted(PersonVoter::SEE, $person)) { + throw new AccessDeniedHttpException(sprintf('person with id %d cannot be seen', $person->getId())); } + $period->addPerson($person); } } - $userLocation = $this->getUser()->getCurrentLocation(); + $userLocation = $user->getCurrentLocation(); $period->setAdministrativeLocation($userLocation); $this->denyAccessUnlessGranted(AccompanyingPeriodVoter::CREATE, $period); @@ -260,6 +272,12 @@ class AccompanyingCourseController extends \Symfony\Bundle\FrameworkBundle\Contr */ public function newHouseholdParcoursAction(Request $request): Response { + $user = $this->getUser(); + + if (!$user instanceof User || !$this->security->isGranted('ROLE_USER')) { + throw new AccessDeniedHttpException(); + } + $period = new AccompanyingPeriod(); $em = $this->getDoctrine()->getManager(); @@ -276,8 +294,7 @@ class AccompanyingCourseController extends \Symfony\Bundle\FrameworkBundle\Contr } } - $userLocation = $this->getUser()->getCurrentLocation(); - $period->setAdministrativeLocation($userLocation); + $period->setAdministrativeLocation($user->getCurrentLocation()); $this->denyAccessUnlessGranted(AccompanyingPeriodVoter::CREATE, $period); diff --git a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkApiController.php b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkApiController.php index 2a9e4e9da..9999257a3 100644 --- a/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkApiController.php +++ b/src/Bundle/ChillPersonBundle/Controller/AccompanyingCourseWorkApiController.php @@ -12,28 +12,40 @@ declare(strict_types=1); namespace Chill\PersonBundle\Controller; use Chill\MainBundle\CRUD\Controller\ApiController; +use Chill\MainBundle\Entity\User; use Chill\MainBundle\Serializer\Model\Collection; use Chill\MainBundle\Serializer\Model\Counter; use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Security\Core\Security; class AccompanyingCourseWorkApiController extends ApiController { - public function __construct(private readonly AccompanyingPeriodWorkRepository $accompanyingPeriodWorkRepository) {} + public function __construct( + private readonly AccompanyingPeriodWorkRepository $accompanyingPeriodWorkRepository, + private readonly Security $security, + ) {} /** * @Route("/api/1.0/person/accompanying-period/work/my-near-end") */ public function myWorksNearEndDate(Request $request): JsonResponse { + $user = $this->security->getUser(); + + if (!$user instanceof User) { + throw new AccessDeniedHttpException(); + } + $since = (new \DateTimeImmutable('now')) ->sub(new \DateInterval('P'.$request->query->getInt('since', 15).'D')); $until = (new \DateTimeImmutable('now')) ->add(new \DateInterval('P'.$request->query->getInt('since', 15).'D')); $total = $this->accompanyingPeriodWorkRepository - ->countNearEndDateByUser($this->getUser(), $since, $until); + ->countNearEndDateByUser($user, $since, $until); if ($request->query->getBoolean('countOnly', false)) { return $this->json( @@ -46,7 +58,7 @@ class AccompanyingCourseWorkApiController extends ApiController $paginator = $this->getPaginatorFactory()->create($total); $works = $this->accompanyingPeriodWorkRepository - ->findNearEndDateByUser($this->getUser(), $since, $until, $paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber()); + ->findNearEndDateByUser($user, $since, $until, $paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber()); $collection = new Collection($works, $paginator); diff --git a/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php b/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php index 7f895d478..0b7326636 100644 --- a/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php +++ b/src/Bundle/ChillPersonBundle/Controller/HouseholdMemberController.php @@ -14,23 +14,37 @@ namespace Chill\PersonBundle\Controller; use Chill\MainBundle\CRUD\Controller\ApiController; use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Household\HouseholdMember; -use Chill\PersonBundle\Entity\Household\Position; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Form\HouseholdMemberType; use Chill\PersonBundle\Household\MembersEditor; use Chill\PersonBundle\Repository\AccompanyingPeriodRepository; +use Chill\PersonBundle\Repository\Household\HouseholdRepository; +use Chill\PersonBundle\Repository\Household\PositionRepository; +use Chill\PersonBundle\Repository\PersonRepository; +use Chill\PersonBundle\Security\Authorization\HouseholdVoter; use Chill\PersonBundle\Security\Authorization\PersonVoter; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Symfony\Component\Security\Core\Security; use Symfony\Component\Serializer\Exception; use Symfony\Contracts\Translation\TranslatorInterface; class HouseholdMemberController extends ApiController { - public function __construct(private readonly UrlGeneratorInterface $generator, private readonly TranslatorInterface $translator, private readonly AccompanyingPeriodRepository $periodRepository) {} + public function __construct( + private readonly UrlGeneratorInterface $generator, + private readonly TranslatorInterface $translator, + private readonly AccompanyingPeriodRepository $periodRepository, + private readonly PersonRepository $personRepository, + private readonly HouseholdRepository $householdRepository, + private readonly Security $security, + private readonly PositionRepository $positionRepository, + ) {} /** * @Route( @@ -83,43 +97,50 @@ class HouseholdMemberController extends ApiController */ public function editor(Request $request) { - $em = $this->getDoctrine()->getManager(); + $ids = $request->query->all('persons'); - if ($request->query->has('persons')) { - $ids = $request->query->get('persons', []); + if ([] !== $ids) { + $persons = []; - if (0 === \count($ids)) { - throw new BadRequestHttpException('parameters persons in query is not an array or empty'); - } + foreach ($ids as $id) { + if (!is_numeric($id)) { + throw new BadRequestHttpException(sprintf('persons with id %s is not numeric', $id)); + } - $persons = $em->getRepository(Person::class) - ->findById($ids); + $person = $this->personRepository->find((int) $id); + + if (null === $person) { + throw new NotFoundHttpException(sprintf('person with id %d not found', $id)); + } - foreach ($persons as $person) { $this->denyAccessUnlessGranted( PersonVoter::SEE, $person, "You are not allowed to see person with id {$person->getId()}" ); + + $persons[] = $person; } } if ($request->query->has('household')) { $householdId = $request->query->get('household', false); - $household = $em->getRepository(Household::class) + $household = $this->householdRepository ->find($householdId); $allowHouseholdCreate = false; $allowHouseholdSearch = false; $allowLeaveWithoutHousehold = false; if (null === $household) { - throw $this->createNotFoundException('household not found'); + throw new NotFoundHttpException('household not found'); + } + + if (!$this->security->isGranted(HouseholdVoter::EDIT, $household)) { + throw new AccessDeniedHttpException('not allowed to edit this household'); } - // TODO ACL on household } - $positions = $this->getDoctrine()->getManager() - ->getRepository(Position::class) + $positions = $this->positionRepository ->findAll(); $data = [ @@ -140,10 +161,8 @@ class HouseholdMemberController extends ApiController ); if (null === $period) { - throw $this->createNotFoundException('period not found'); + throw new NotFoundHttpException('accompanying period not found'); } - - // TODO add acl on accompanying Course } return $this->render('@ChillPerson/Household/members_editor.html.twig', [ diff --git a/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php b/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php index 3b7188513..7444dce5a 100644 --- a/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php +++ b/src/Bundle/ChillPersonBundle/Controller/PersonDuplicateController.php @@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Controller; use Chill\ActivityBundle\Entity\Activity; use Chill\DocStoreBundle\Entity\PersonDocument; use Chill\EventBundle\Entity\Participation; +use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Actions\Remove\PersonMove; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\PersonNotDuplicate; @@ -24,15 +25,21 @@ use Chill\PersonBundle\Repository\PersonNotDuplicateRepository; use Chill\PersonBundle\Repository\PersonRepository; use Chill\PersonBundle\Search\SimilarPersonMatcher; use Chill\TaskBundle\Entity\SingleTask; -use http\Exception\InvalidArgumentException; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\HttpFoundation\Request; -use Symfony\Contracts\Translation\TranslatorInterface; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\Security\Core\Security; use function count; class PersonDuplicateController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController { - public function __construct(private readonly SimilarPersonMatcher $similarPersonMatcher, private readonly TranslatorInterface $translator, private readonly PersonRepository $personRepository, private readonly PersonMove $personMove, private readonly EventDispatcherInterface $eventDispatcher) {} + public function __construct( + private readonly SimilarPersonMatcher $similarPersonMatcher, + private readonly PersonRepository $personRepository, + private readonly PersonMove $personMove, + private readonly EventDispatcherInterface $eventDispatcher, + private readonly Security $security, + ) {} /** * @\Symfony\Component\Routing\Annotation\Route(path="/{_locale}/person/{person1_id}/duplicate/{person2_id}/confirm", name="chill_person_duplicate_confirm") @@ -40,7 +47,7 @@ class PersonDuplicateController extends \Symfony\Bundle\FrameworkBundle\Controll public function confirmAction(mixed $person1_id, mixed $person2_id, Request $request) { if ($person1_id === $person2_id) { - throw new InvalidArgumentException('Can not merge same person'); + throw new \InvalidArgumentException('Can not merge same person'); } $person1 = $this->_getPerson($person1_id); @@ -152,6 +159,12 @@ class PersonDuplicateController extends \Symfony\Bundle\FrameworkBundle\Controll */ public function notDuplicateAction(mixed $person1_id, mixed $person2_id) { + $user = $this->security->getUser(); + + if (!$user instanceof User) { + throw new AccessDeniedHttpException(); + } + [$person1, $person2] = $this->_getPersonsByPriority($person1_id, $person2_id); $this->denyAccessUnlessGranted( @@ -167,7 +180,7 @@ class PersonDuplicateController extends \Symfony\Bundle\FrameworkBundle\Controll $personNotDuplicate = new PersonNotDuplicate(); $personNotDuplicate->setPerson1($person1); $personNotDuplicate->setPerson2($person2); - $personNotDuplicate->setUser($this->getUser()); + $personNotDuplicate->setUser($user); $this->getDoctrine()->getManager()->persist($personNotDuplicate); $this->getDoctrine()->getManager()->flush(); @@ -259,7 +272,7 @@ class PersonDuplicateController extends \Symfony\Bundle\FrameworkBundle\Controll private function _getPersonsByPriority($person1_id, $person2_id) { if ($person1_id === $person2_id) { - throw new InvalidArgumentException('Can not merge same person'); + throw new \InvalidArgumentException('Can not merge same person'); } if ($person1_id > $person2_id) { diff --git a/src/Bundle/ChillPersonBundle/Form/DataMapper/PersonAltNameDataMapper.php b/src/Bundle/ChillPersonBundle/Form/DataMapper/PersonAltNameDataMapper.php index ab36e3e9b..d2a7aba55 100644 --- a/src/Bundle/ChillPersonBundle/Form/DataMapper/PersonAltNameDataMapper.php +++ b/src/Bundle/ChillPersonBundle/Form/DataMapper/PersonAltNameDataMapper.php @@ -19,7 +19,7 @@ use Symfony\Component\Form\Exception\UnexpectedTypeException; class PersonAltNameDataMapper implements DataMapperInterface { - public function mapDataToForms($viewData, iterable $forms) + public function mapDataToForms($viewData, iterable $forms): void { if (null === $viewData) { return; @@ -43,11 +43,7 @@ class PersonAltNameDataMapper implements DataMapperInterface } } - /** - * @param FormInterface[] $forms - * @param Collection $viewData - */ - public function mapFormsToData(iterable $forms, &$viewData) + public function mapFormsToData(iterable $forms, &$viewData): void { $mapIndexToKey = []; diff --git a/src/Bundle/ChillPersonBundle/Form/Type/PickPersonType.php b/src/Bundle/ChillPersonBundle/Form/Type/PickPersonType.php index d29b4cd41..f8086369f 100644 --- a/src/Bundle/ChillPersonBundle/Form/Type/PickPersonType.php +++ b/src/Bundle/ChillPersonBundle/Form/Type/PickPersonType.php @@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Form\Type; use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\GroupCenter; +use Chill\MainBundle\Entity\User; use Chill\MainBundle\Security\Authorization\AuthorizationHelper; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Form\ChoiceLoader\PersonChoiceLoader; @@ -25,7 +26,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Exception\AccessDeniedException; -use Symfony\Component\Security\Core\Role\Role; use Symfony\Contracts\Translation\TranslatorInterface; /** @@ -41,46 +41,15 @@ use Symfony\Contracts\Translation\TranslatorInterface; * - with the `role` option, only the people belonging to the reachable center for the * given role are displayed. */ -class PickPersonType extends AbstractType +final class PickPersonType extends AbstractType { - /** - * @var AuthorizationHelper - */ - protected $authorizationHelper; - - /** - * @var PersonRepository - */ - protected $personRepository; - - /** - * @var TranslatorInterface - */ - protected $translator; - - /** - * @var UrlGeneratorInterface - */ - protected $urlGenerator; - - /** - * @var \Chill\MainBundle\Entity\User - */ - protected $user; - public function __construct( - PersonRepository $personRepository, - TokenStorageInterface $tokenStorage, - AuthorizationHelper $authorizationHelper, - UrlGeneratorInterface $urlGenerator, - TranslatorInterface $translator - ) { - $this->personRepository = $personRepository; - $this->user = $tokenStorage->getToken()->getUser(); - $this->authorizationHelper = $authorizationHelper; - $this->urlGenerator = $urlGenerator; - $this->translator = $translator; - } + private readonly PersonRepository $personRepository, + private readonly TokenStorageInterface $tokenStorage, + private readonly AuthorizationHelper $authorizationHelper, + private readonly UrlGeneratorInterface $urlGenerator, + private readonly TranslatorInterface $translator + ) {} public function buildView(\Symfony\Component\Form\FormView $view, \Symfony\Component\Form\FormInterface $form, array $options) { @@ -130,11 +99,16 @@ class PickPersonType extends AbstractType protected function filterCentersfom(Options $options) { + $user = $this->tokenStorage->getToken()->getUser(); + if (!$user instanceof User) { + throw new \UnexpectedValueException('user should be an instance of '.User::class); + } + if (null === $options['role']) { - $centers = array_map(static fn (GroupCenter $g) => $g->getCenter(), $this->user->getGroupCenters()->toArray()); + $centers = array_map(static fn (GroupCenter $g) => $g->getCenter(), $user->getGroupCenters()->toArray()); } else { $centers = $this->authorizationHelper - ->getReachableCenters($this->user, $options['role']->getRole()); + ->getReachableCenters($user, $options['role']->getRole()); } if (null === $options['centers']) { diff --git a/src/Bundle/ChillPersonBundle/Privacy/PrivacyEventSubscriber.php b/src/Bundle/ChillPersonBundle/Privacy/PrivacyEventSubscriber.php index 88eb2b172..00ffa47f5 100644 --- a/src/Bundle/ChillPersonBundle/Privacy/PrivacyEventSubscriber.php +++ b/src/Bundle/ChillPersonBundle/Privacy/PrivacyEventSubscriber.php @@ -31,31 +31,21 @@ namespace Chill\PersonBundle\Privacy; * along with this program. If not, see . */ +use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\Person; use Psr\Log\LoggerInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -class PrivacyEventSubscriber implements EventSubscriberInterface +final readonly class PrivacyEventSubscriber implements EventSubscriberInterface { - /** - * @var LoggerInterface - */ - protected $logger; - - /** - * @var TokenStorageInterface - */ - protected $token; - /** * PrivacyEventSubscriber constructor. */ - public function __construct(LoggerInterface $logger, TokenStorageInterface $token) - { - $this->logger = $logger; - $this->token = $token; - } + public function __construct( + private LoggerInterface $logger, + private TokenStorageInterface $token + ) {} public static function getSubscribedEvents() { @@ -109,11 +99,20 @@ class PrivacyEventSubscriber implements EventSubscriberInterface ); } - protected function getInvolved(): array + private function getInvolved(): array { + $user = $this->token->getToken()->getUser(); + + if ($user instanceof User) { + return [ + 'by_user' => $user->getUserIdentifier(), + 'by_user_id' => $user->getId(), + ]; + } + return [ - 'by_user' => $this->token->getToken()->getUser()->getUsername(), - 'by_user_id' => $this->token->getToken()->getUser()->getId(), + 'by_user' => $user->getUsername(), + 'by_user_id' => $user->getUserIdentifier(), ]; } } diff --git a/src/Bundle/ChillPersonBundle/config/services/controller.yaml b/src/Bundle/ChillPersonBundle/config/services/controller.yaml index 434d1ea08..9691db298 100644 --- a/src/Bundle/ChillPersonBundle/config/services/controller.yaml +++ b/src/Bundle/ChillPersonBundle/config/services/controller.yaml @@ -26,12 +26,6 @@ services: Chill\PersonBundle\Controller\AdminController: ~ Chill\PersonBundle\Controller\PersonDuplicateController: - arguments: - $similarPersonMatcher: '@Chill\PersonBundle\Search\SimilarPersonMatcher' - $translator: '@Symfony\Contracts\Translation\TranslatorInterface' - $personRepository: '@Chill\PersonBundle\Repository\PersonRepository' - $personMove: '@Chill\PersonBundle\Actions\Remove\PersonMove' - $eventDispatcher: '@Symfony\Contracts\EventDispatcher\EventDispatcherInterface' tags: ['controller.service_arguments'] Chill\PersonBundle\Controller\AccompanyingCourseController: diff --git a/src/Bundle/ChillReportBundle/Form/ReportType.php b/src/Bundle/ChillReportBundle/Form/ReportType.php index 8d6551443..9d979458a 100644 --- a/src/Bundle/ChillReportBundle/Form/ReportType.php +++ b/src/Bundle/ChillReportBundle/Form/ReportType.php @@ -12,6 +12,7 @@ declare(strict_types=1); namespace Chill\ReportBundle\Form; use Chill\CustomFieldsBundle\Form\Type\CustomFieldType; +use Chill\MainBundle\Entity\User; use Chill\MainBundle\Form\Type\AppendScopeChoiceTypeTrait; use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Security\Authorization\AuthorizationHelper; @@ -22,41 +23,16 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; -class ReportType extends AbstractType +final class ReportType extends AbstractType { use AppendScopeChoiceTypeTrait; - /** - * @var AuthorizationHelper - */ - protected $authorizationHelper; - - /** - * @var \Doctrine\Persistence\ObjectManager - */ - protected $om; - - /** - * @var TranslatableStringHelper - */ - protected $translatableStringHelper; - - /** - * @var \Chill\MainBundle\Entity\User - */ - protected $user; - public function __construct( - AuthorizationHelper $helper, - TokenStorageInterface $tokenStorage, - TranslatableStringHelper $translatableStringHelper, - ObjectManager $om - ) { - $this->authorizationHelper = $helper; - $this->user = $tokenStorage->getToken()->getUser(); - $this->translatableStringHelper = $translatableStringHelper; - $this->om = $om; - } + private readonly AuthorizationHelper $authorizationHelper, + private readonly TokenStorageInterface $tokenStorage, + private readonly TranslatableStringHelper $translatableStringHelper, + private readonly ObjectManager $om + ) {} public function buildForm(FormBuilderInterface $builder, array $options) { @@ -74,11 +50,17 @@ class ReportType extends AbstractType 'group' => $options['cFGroup'], ] ); + $user = $this->tokenStorage->getToken()->getUser(); + + if (!$user instanceof User) { + throw new \RuntimeException('user must be a regular user'); + } + $this->appendScopeChoices( $builder, $options['role'], $options['center'], - $this->user, + $user, $this->authorizationHelper, $this->translatableStringHelper, $this->om diff --git a/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php b/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php index 16c520c75..4c1687b5f 100644 --- a/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php +++ b/src/Bundle/ChillTaskBundle/Controller/SingleTaskController.php @@ -11,6 +11,7 @@ declare(strict_types=1); namespace Chill\TaskBundle\Controller; +use Chill\MainBundle\Entity\User; use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface; use Chill\MainBundle\Serializer\Model\Collection; @@ -38,8 +39,10 @@ use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Security\Core\Security; use Symfony\Contracts\Translation\TranslatorInterface; final class SingleTaskController extends AbstractController @@ -55,6 +58,7 @@ final class SingleTaskController extends AbstractController private readonly FilterOrderHelperFactoryInterface $filterOrderHelperFactory, private readonly SingleTaskStateRepository $singleTaskStateRepository, private readonly SingleTaskRepository $singleTaskRepository, + private readonly Security $security, ) {} /** @@ -487,8 +491,14 @@ final class SingleTaskController extends AbstractController */ public function newAction(Request $request) { + $user = $this->security->getUser(); + + if (!$user instanceof User) { + throw new AccessDeniedHttpException(); + } + $task = (new SingleTask()) - ->setAssignee($this->getUser()) + ->setAssignee($user) ->setType('task_default'); $entityType = $this->getEntityContext($request); diff --git a/src/Bundle/ChillTaskBundle/Controller/TaskController.php b/src/Bundle/ChillTaskBundle/Controller/TaskController.php index e5d060de7..5ffc202de 100644 --- a/src/Bundle/ChillTaskBundle/Controller/TaskController.php +++ b/src/Bundle/ChillTaskBundle/Controller/TaskController.php @@ -66,7 +66,7 @@ class TaskController extends AbstractController 'chill_task_single_task_show', [ 'id' => $task->getId(), - 'list_params' => $request->query->get('list_params', []), + 'list_params' => $request->query->all('list_params'), ] ); null === $task->getCourse() ? $defaultTemplate = '@ChillTask/SingleTask/Person/transition.html.twig' : $defaultTemplate = '@ChillTask/SingleTask/AccompanyingCourse/transition.html.twig'; @@ -134,8 +134,6 @@ class TaskController extends AbstractController } /** - * @param \Chill\TaskBundle\Controller\AbstractTask $task - * * @return \Symfony\Component\Form\FormInterface */ protected function createTransitionForm(AbstractTask $task) diff --git a/src/Bundle/ChillTaskBundle/Menu/UserMenuBuilder.php b/src/Bundle/ChillTaskBundle/Menu/UserMenuBuilder.php index e744ddb24..7f1f8fde8 100644 --- a/src/Bundle/ChillTaskBundle/Menu/UserMenuBuilder.php +++ b/src/Bundle/ChillTaskBundle/Menu/UserMenuBuilder.php @@ -26,8 +26,7 @@ final readonly class UserMenuBuilder implements LocalMenuBuilderInterface private TokenStorageInterface $tokenStorage, private TranslatorInterface $translator, private AuthorizationCheckerInterface $authorizationChecker - ) { - } + ) {} public function buildMenu($menuId, MenuItem $menu, array $parameters) {