Fix phpstan issues

This commit is contained in:
Julien Fastré 2023-12-12 22:34:26 +01:00
parent af663cf27c
commit da997badd9
Signed by: julienfastre
GPG Key ID: BDE2190974723FCB
26 changed files with 275 additions and 261 deletions

View File

@ -24,6 +24,7 @@ use Chill\MainBundle\Entity\UserJob;
use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Repository\LocationRepository; use Chill\MainBundle\Repository\LocationRepository;
use Chill\MainBundle\Repository\UserRepositoryInterface; use Chill\MainBundle\Repository\UserRepositoryInterface;
use Chill\MainBundle\Security\ChillSecurity;
use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface; use Chill\MainBundle\Security\Resolver\CenterResolverManagerInterface;
use Chill\MainBundle\Templating\Listing\FilterOrderHelper; use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactoryInterface; use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactoryInterface;
@ -67,6 +68,7 @@ final class ActivityController extends AbstractController
private readonly FilterOrderHelperFactoryInterface $filterOrderHelperFactory, private readonly FilterOrderHelperFactoryInterface $filterOrderHelperFactory,
private readonly TranslatableStringHelperInterface $translatableStringHelper, private readonly TranslatableStringHelperInterface $translatableStringHelper,
private readonly PaginatorFactory $paginatorFactory, private readonly PaginatorFactory $paginatorFactory,
private readonly ChillSecurity $security
) {} ) {}
/** /**
@ -384,7 +386,7 @@ final class ActivityController extends AbstractController
} }
$entity = new Activity(); $entity = new Activity();
$entity->setUser($this->getUser()); $entity->setUser($this->security->getUser());
if ($person instanceof Person) { if ($person instanceof Person) {
$entity->setPerson($person); $entity->setPerson($person);
@ -399,7 +401,7 @@ final class ActivityController extends AbstractController
$entity->setDate(new \DateTime('now')); $entity->setDate(new \DateTime('now'));
if ($request->query->has('activityData')) { if ($request->query->has('activityData')) {
$activityData = $request->query->get('activityData'); $activityData = $request->query->all('activityData');
if (\array_key_exists('durationTime', $activityData) && $activityType->getDurationTimeVisible() > 0) { if (\array_key_exists('durationTime', $activityData) && $activityType->getDurationTimeVisible() > 0) {
$durationTimeInMinutes = $activityData['durationTime']; $durationTimeInMinutes = $activityData['durationTime'];
@ -452,7 +454,7 @@ final class ActivityController extends AbstractController
if (\array_key_exists('comment', $activityData) && $activityType->getCommentVisible() > 0) { if (\array_key_exists('comment', $activityData) && $activityType->getCommentVisible() > 0) {
$comment = new CommentEmbeddable(); $comment = new CommentEmbeddable();
$comment->setComment($activityData['comment']); $comment->setComment($activityData['comment']);
$comment->setUserId($this->getUser()->getid()); $comment->setUserId($this->security->getUser()->getId());
$comment->setDate(new \DateTime('now')); $comment->setDate(new \DateTime('now'));
$entity->setComment($comment); $entity->setComment($comment);
} }
@ -513,7 +515,7 @@ final class ActivityController extends AbstractController
$activity_array = $this->serializer->normalize($entity, 'json', ['groups' => 'read']); $activity_array = $this->serializer->normalize($entity, 'json', ['groups' => 'read']);
$defaultLocation = $this->getUser()->getCurrentLocation(); $defaultLocation = $this->security->getUser()->getCurrentLocation();
return $this->render($view, [ return $this->render($view, [
'person' => $person, 'person' => $person,
@ -568,7 +570,7 @@ final class ActivityController extends AbstractController
'person' => $person, 'person' => $person,
'accompanyingCourse' => $accompanyingPeriod, 'accompanyingCourse' => $accompanyingPeriod,
'data' => $data, 'data' => $data,
'activityData' => $request->query->get('activityData', []), 'activityData' => $request->query->all('activityData'),
]); ]);
} }

View File

@ -64,7 +64,7 @@ class LoadActivity extends AbstractFixture implements OrderedFixtureInterface
->setPerson($person) ->setPerson($person)
->setDate($this->faker->dateTimeThisYear()) ->setDate($this->faker->dateTimeThisYear())
->setDurationTime($this->faker->dateTime(36000)) ->setDurationTime($this->faker->dateTime(36000))
->setType($this->getRandomActivityType()) ->setActivityType($this->getRandomActivityType())
->setScope($this->getRandomScope()); ->setScope($this->getRandomScope());
// ->setAttendee($this->faker->boolean()) // ->setAttendee($this->faker->boolean())

View File

@ -15,19 +15,25 @@ use Chill\AsideActivityBundle\Entity\AsideActivity;
use Chill\AsideActivityBundle\Repository\AsideActivityCategoryRepository; use Chill\AsideActivityBundle\Repository\AsideActivityCategoryRepository;
use Chill\MainBundle\CRUD\Controller\CRUDController; use Chill\MainBundle\CRUD\Controller\CRUDController;
use Chill\MainBundle\Pagination\PaginatorInterface; use Chill\MainBundle\Pagination\PaginatorInterface;
use Chill\MainBundle\Security\ChillSecurity;
use Chill\MainBundle\Templating\Listing\FilterOrderHelper; use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
final class AsideActivityController extends CRUDController 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 public function createEntity(string $action, Request $request): object
{ {
if (!$this->security->isGranted('ROLE_USER')) {
throw new AccessDeniedHttpException();
}
$asideActivity = new AsideActivity(); $asideActivity = new AsideActivity();
$asideActivity->setAgent($this->getUser()); $asideActivity->setAgent($this->security->getUser());
$asideActivity->setLocation($this->getUser()->getCurrentLocation()); $asideActivity->setLocation($this->security->getUser()->getCurrentLocation());
$duration = $request->query->get('duration', '300'); $duration = $request->query->get('duration', '300');
$duration = \DateTime::createFromFormat('U', $duration); $duration = \DateTime::createFromFormat('U', $duration);

View File

@ -29,7 +29,7 @@ class ListenToActivityCreate
} }
if ($request->query->has('activityData')) { if ($request->query->has('activityData')) {
$activityData = $request->query->get('activityData'); $activityData = $request->query->all('activityData');
if (\array_key_exists('calendarId', $activityData)) { if (\array_key_exists('calendarId', $activityData)) {
$calendarId = $activityData['calendarId']; $calendarId = $activityData['calendarId'];

View File

@ -20,6 +20,7 @@ use Chill\DocGeneratorBundle\Service\Generator\GeneratorInterface;
use Chill\DocGeneratorBundle\Service\Messenger\RequestGenerationMessage; use Chill\DocGeneratorBundle\Service\Messenger\RequestGenerationMessage;
use Chill\DocStoreBundle\Entity\StoredObject; use Chill\DocStoreBundle\Entity\StoredObject;
use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Security\ChillSecurity;
use Chill\MainBundle\Serializer\Model\Collection; use Chill\MainBundle\Serializer\Model\Collection;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@ -37,7 +38,15 @@ use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
final class DocGeneratorTemplateController extends AbstractController 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( * @Route(
@ -217,7 +226,7 @@ final class DocGeneratorTemplateController extends AbstractController
: []; : [];
// if is test, render the data or generate the doc // 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', [ return $this->render('@ChillDocGenerator/Generator/debug_value.html.twig', [
'datas' => json_encode($context->getData($template, $entity, $contextGenerationData), \JSON_PRETTY_PRINT), 'datas' => json_encode($context->getData($template, $entity, $contextGenerationData), \JSON_PRETTY_PRINT),
]); ]);
@ -265,7 +274,7 @@ final class DocGeneratorTemplateController extends AbstractController
$this->messageBus->dispatch( $this->messageBus->dispatch(
new RequestGenerationMessage( new RequestGenerationMessage(
$this->getUser(), $this->security->getUser(),
$template, $template,
$entityId, $entityId,
$storedObject, $storedObject,

View File

@ -12,12 +12,15 @@ declare(strict_types=1);
namespace Chill\MainBundle\Controller; namespace Chill\MainBundle\Controller;
use Chill\MainBundle\Form\AbsenceType; use Chill\MainBundle\Form\AbsenceType;
use Chill\MainBundle\Security\ChillSecurity;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
class AbsenceController extends AbstractController class AbsenceController extends AbstractController
{ {
public function __construct(private readonly ChillSecurity $security) {}
/** /**
* @Route( * @Route(
* "/{_locale}/absence", * "/{_locale}/absence",
@ -27,7 +30,7 @@ class AbsenceController extends AbstractController
*/ */
public function setAbsence(Request $request) public function setAbsence(Request $request)
{ {
$user = $this->getUser(); $user = $this->security->getUser();
$form = $this->createForm(AbsenceType::class, $user); $form = $this->createForm(AbsenceType::class, $user);
$form->handleRequest($request); $form->handleRequest($request);
@ -54,7 +57,7 @@ class AbsenceController extends AbstractController
*/ */
public function unsetAbsence(Request $request) public function unsetAbsence(Request $request)
{ {
$user = $this->getUser(); $user = $this->security->getUser();
$user->setAbsenceStart(null); $user->setAbsenceStart(null);
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();

View File

@ -13,7 +13,6 @@ namespace Chill\MainBundle\Controller;
use Chill\MainBundle\Entity\Notification; use Chill\MainBundle\Entity\Notification;
use Chill\MainBundle\Entity\NotificationComment; use Chill\MainBundle\Entity\NotificationComment;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Form\NotificationCommentType; use Chill\MainBundle\Form\NotificationCommentType;
use Chill\MainBundle\Form\NotificationType; use Chill\MainBundle\Form\NotificationType;
use Chill\MainBundle\Notification\Exception\NotificationHandlerNotFound; use Chill\MainBundle\Notification\Exception\NotificationHandlerNotFound;
@ -22,6 +21,7 @@ use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Repository\NotificationRepository; use Chill\MainBundle\Repository\NotificationRepository;
use Chill\MainBundle\Repository\UserRepository; use Chill\MainBundle\Repository\UserRepository;
use Chill\MainBundle\Security\Authorization\NotificationVoter; use Chill\MainBundle\Security\Authorization\NotificationVoter;
use Chill\MainBundle\Security\ChillSecurity;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; 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\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
use function in_array; use function in_array;
@ -41,7 +40,7 @@ use function in_array;
*/ */
class NotificationController extends AbstractController 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") * @Route("/create", name="chill_main_notification_create")
@ -50,10 +49,6 @@ class NotificationController extends AbstractController
{ {
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); $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')) { if (!$request->query->has('entityClass')) {
throw new BadRequestHttpException('Missing entityClass parameter'); throw new BadRequestHttpException('Missing entityClass parameter');
} }
@ -68,13 +63,13 @@ class NotificationController extends AbstractController
->setRelatedEntityId($request->query->getInt('entityId')) ->setRelatedEntityId($request->query->getInt('entityId'))
->setSender($this->security->getUser()); ->setSender($this->security->getUser());
if ($request->query->has('tos')) { $tos = $request->query->all('tos');
foreach ($request->query->get('tos') as $toId) {
if (null === $to = $this->userRepository->find($toId)) { foreach ($tos as $toId) {
throw new NotFoundHttpException("user with id {$toId} is not found"); if (null === $to = $this->userRepository->find($toId)) {
} throw new NotFoundHttpException("user with id {$toId} is not found");
$notification->addAddressee($to);
} }
$notification->addAddressee($to);
} }
try { try {
@ -144,10 +139,6 @@ class NotificationController extends AbstractController
{ {
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); $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) { foreach (['accessKey'/* , 'email' */] as $param) {
if (!$request->query->has($param)) { if (!$request->query->has($param)) {
throw new BadRequestHttpException("Missing {$param} parameter"); 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 // we mark the notification as read after having computed the response
if ($this->getUser() instanceof User && !$notification->isReadBy($this->getUser())) { if (!$notification->isReadBy($this->security->getUser())) {
$notification->markAsReadBy($this->getUser()); $notification->markAsReadBy($this->security->getUser());
$this->em->flush(); $this->em->flush();
} }

View File

@ -13,6 +13,7 @@ namespace Chill\MainBundle\Controller;
use Chill\MainBundle\Entity\User; use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Form\UserPasswordType; use Chill\MainBundle\Form\UserPasswordType;
use Chill\MainBundle\Security\ChillSecurity;
use Chill\MainBundle\Security\PasswordRecover\PasswordRecoverEvent; use Chill\MainBundle\Security\PasswordRecover\PasswordRecoverEvent;
use Chill\MainBundle\Security\PasswordRecover\PasswordRecoverVoter; use Chill\MainBundle\Security\PasswordRecover\PasswordRecoverVoter;
use Chill\MainBundle\Security\PasswordRecover\RecoverPasswordHelper; 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\Form\Extension\Core\Type\TextType;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Validator\Constraints\Callback; use Symfony\Component\Validator\Constraints\Callback;
@ -33,56 +35,12 @@ use Symfony\Contracts\Translation\TranslatorInterface;
/** /**
* Class PasswordController. * 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. * PasswordController constructor.
*/ */
public function __construct( 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) {}
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;
}
/** /**
* @return Response * @return Response
@ -250,8 +208,11 @@ class PasswordController extends AbstractController
*/ */
public function UserPasswordAction(Request $request) public function UserPasswordAction(Request $request)
{ {
if (!$this->security->isGranted('ROLE_USER')) {
throw new AccessDeniedHttpException();
}
// get authentified user // get authentified user
$user = $this->getUser(); $user = $this->security->getUser();
// create a form for password_encoder // create a form for password_encoder
$form = $this->passwordForm($user); $form = $this->passwordForm($user);
@ -269,7 +230,7 @@ class PasswordController extends AbstractController
'update password for an user', 'update password for an user',
[ [
'method' => $request->getMethod(), 'method' => $request->getMethod(),
'user' => $user->getUsername(), 'user' => $user->getUserIdentifier(),
] ]
); );

View File

@ -199,7 +199,7 @@ class SearchController extends AbstractController
{ {
// TODO this is an incomplete implementation // TODO this is an incomplete implementation
$query = $request->query->get('q', ''); $query = $request->query->get('q', '');
$types = $request->query->get('type', []); $types = $request->query->all('type');
if (0 === \count($types)) { if (0 === \count($types)) {
throw new BadRequestHttpException('The request must contains at one type'); throw new BadRequestHttpException('The request must contains at one type');

View File

@ -13,13 +13,17 @@ namespace Chill\MainBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController; use Chill\MainBundle\CRUD\Controller\ApiController;
use Chill\MainBundle\Pagination\PaginatorInterface; use Chill\MainBundle\Pagination\PaginatorInterface;
use Chill\MainBundle\Security\ChillSecurity;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
class UserApiController extends ApiController class UserApiController extends ApiController
{ {
public function __construct(private readonly ChillSecurity $security) {}
/** /**
* @Route( * @Route(
* "/api/1.0/main/user-current-location.{_format}", * "/api/1.0/main/user-current-location.{_format}",
@ -31,8 +35,12 @@ class UserApiController extends ApiController
*/ */
public function currentLocation(mixed $_format): JsonResponse public function currentLocation(mixed $_format): JsonResponse
{ {
if (!$this->isGranted('ROLE_USER')) {
throw new AccessDeniedHttpException();
}
return $this->json( return $this->json(
$this->getUser()->getCurrentLocation(), $this->security->getUser()->getCurrentLocation(),
JsonResponse::HTTP_OK, JsonResponse::HTTP_OK,
[], [],
['groups' => ['read']] ['groups' => ['read']]

View File

@ -20,6 +20,7 @@ use Chill\MainBundle\Form\UserPasswordType;
use Chill\MainBundle\Form\UserType; use Chill\MainBundle\Form\UserType;
use Chill\MainBundle\Pagination\PaginatorInterface; use Chill\MainBundle\Pagination\PaginatorInterface;
use Chill\MainBundle\Repository\UserRepository; use Chill\MainBundle\Repository\UserRepository;
use Chill\MainBundle\Security\ChillSecurity;
use Chill\MainBundle\Templating\Listing\FilterOrderHelper; use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
@ -38,7 +39,15 @@ class UserController extends CRUDController
{ {
final public const FORM_GROUP_CENTER_COMPOSED = 'composed_groupcenter'; 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", * @Route("/{_locale}/admin/main/user/{uid}/add_link_groupcenter",
@ -197,7 +206,7 @@ class UserController extends CRUDController
*/ */
public function editCurrentLocationAction(Request $request) public function editCurrentLocationAction(Request $request)
{ {
$user = $this->getUser(); $user = $this->security->getUser();
$form = $this->createForm(UserCurrentLocationType::class, $user) $form = $this->createForm(UserCurrentLocationType::class, $user)
->add('submit', SubmitType::class, ['label' => 'Save']) ->add('submit', SubmitType::class, ['label' => 'Save'])
->handleRequest($request); ->handleRequest($request);

View File

@ -12,18 +12,21 @@ declare(strict_types=1);
namespace Chill\MainBundle\Controller; namespace Chill\MainBundle\Controller;
use Chill\MainBundle\Form\UserPhonenumberType; use Chill\MainBundle\Form\UserPhonenumberType;
use Chill\MainBundle\Security\ChillSecurity;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
class UserProfileController extends AbstractController final class UserProfileController extends AbstractController
{ {
public function __construct( public function __construct(
private readonly TranslatorInterface $translator, private readonly TranslatorInterface $translator,
private readonly ChillSecurity $security,
) {} ) {}
/** /**
@ -33,7 +36,11 @@ class UserProfileController extends AbstractController
*/ */
public function __invoke(Request $request) 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 = $this->createPhonenumberEditForm($user);
$editForm->handleRequest($request); $editForm->handleRequest($request);

View File

@ -20,6 +20,7 @@ use Chill\MainBundle\Form\WorkflowStepType;
use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository; use Chill\MainBundle\Repository\Workflow\EntityWorkflowRepository;
use Chill\MainBundle\Security\Authorization\EntityWorkflowVoter; use Chill\MainBundle\Security\Authorization\EntityWorkflowVoter;
use Chill\MainBundle\Security\ChillSecurity;
use Chill\MainBundle\Workflow\EntityWorkflowManager; use Chill\MainBundle\Workflow\EntityWorkflowManager;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; 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\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Annotation\Route; 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\Validator\Validator\ValidatorInterface;
use Symfony\Component\Workflow\Registry; use Symfony\Component\Workflow\Registry;
use Symfony\Component\Workflow\TransitionBlocker; use Symfony\Component\Workflow\TransitionBlocker;
@ -38,7 +38,7 @@ use Symfony\Contracts\Translation\TranslatorInterface;
class WorkflowController extends AbstractController 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") * @Route("/{_locale}/main/workflow/create", name="chill_main_workflow_create")
@ -62,7 +62,7 @@ class WorkflowController extends AbstractController
->setRelatedEntityClass($request->query->get('entityClass')) ->setRelatedEntityClass($request->query->get('entityClass'))
->setRelatedEntityId($request->query->getInt('entityId')) ->setRelatedEntityId($request->query->getInt('entityId'))
->setWorkflowName($request->query->get('workflow')) ->setWorkflowName($request->query->get('workflow'))
->addSubscriberToFinal($this->getUser()); ->addSubscriberToFinal($this->security->getUser());
$errors = $this->validator->validate($entityWorkflow, null, ['creation']); $errors = $this->validator->validate($entityWorkflow, null, ['creation']);
@ -123,17 +123,17 @@ class WorkflowController extends AbstractController
} }
if (!$this->getUser() instanceof User) { if (!$this->getUser() instanceof User) {
throw new AccessDeniedException('Not a valid user'); throw new AccessDeniedHttpException('Not a valid user');
} }
if ($entityWorkflowStep->getAccessKey() !== $accessKey) { if ($entityWorkflowStep->getAccessKey() !== $accessKey) {
throw new AccessDeniedException('Access key is invalid'); throw new AccessDeniedHttpException('Access key is invalid');
} }
if (!$entityWorkflowStep->isWaitingForTransition()) { if (!$entityWorkflowStep->isWaitingForTransition()) {
$this->addFlash('error', $this->translator->trans('workflow.Steps is not waiting for transition. Maybe someone apply the transition before you ?')); $this->addFlash('error', $this->translator->trans('workflow.Steps is not waiting for transition. Maybe someone apply the transition before you ?'));
} else { } else {
$entityWorkflowStep->addDestUserByAccessKey($this->getUser()); $entityWorkflowStep->addDestUserByAccessKey($this->security->getUser());
$this->entityManager->flush(); $this->entityManager->flush();
$this->addFlash('success', $this->translator->trans('workflow.You get access to this step')); $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'); $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED');
$total = $this->entityWorkflowRepository->countByPreviousTransitionned($this->getUser()); $total = $this->entityWorkflowRepository->countByPreviousTransitionned($this->security->getUser());
$paginator = $this->paginatorFactory->create($total); $paginator = $this->paginatorFactory->create($total);
$workflows = $this->entityWorkflowRepository->findByPreviousTransitionned( $workflows = $this->entityWorkflowRepository->findByPreviousTransitionned(
$this->getUser(), $this->security->getUser(),
['createdAt' => 'DESC'], ['createdAt' => 'DESC'],
$paginator->getItemsPerPage(), $paginator->getItemsPerPage(),
$paginator->getCurrentPageFirstItemNumber() $paginator->getCurrentPageFirstItemNumber()
@ -180,11 +180,11 @@ class WorkflowController extends AbstractController
{ {
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED');
$total = $this->entityWorkflowRepository->countByPreviousDestWithoutReaction($this->getUser()); $total = $this->entityWorkflowRepository->countByPreviousDestWithoutReaction($this->security->getUser());
$paginator = $this->paginatorFactory->create($total); $paginator = $this->paginatorFactory->create($total);
$workflows = $this->entityWorkflowRepository->findByPreviousDestWithoutReaction( $workflows = $this->entityWorkflowRepository->findByPreviousDestWithoutReaction(
$this->getUser(), $this->security->getUser(),
['createdAt' => 'DESC'], ['createdAt' => 'DESC'],
$paginator->getItemsPerPage(), $paginator->getItemsPerPage(),
$paginator->getCurrentPageFirstItemNumber() $paginator->getCurrentPageFirstItemNumber()
@ -208,11 +208,11 @@ class WorkflowController extends AbstractController
{ {
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED');
$total = $this->entityWorkflowRepository->countByDest($this->getUser()); $total = $this->entityWorkflowRepository->countByDest($this->security->getUser());
$paginator = $this->paginatorFactory->create($total); $paginator = $this->paginatorFactory->create($total);
$workflows = $this->entityWorkflowRepository->findByCc( $workflows = $this->entityWorkflowRepository->findByCc(
$this->getUser(), $this->security->getUser(),
['createdAt' => 'DESC'], ['createdAt' => 'DESC'],
$paginator->getItemsPerPage(), $paginator->getItemsPerPage(),
$paginator->getCurrentPageFirstItemNumber() $paginator->getCurrentPageFirstItemNumber()
@ -235,11 +235,11 @@ class WorkflowController extends AbstractController
{ {
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED');
$total = $this->entityWorkflowRepository->countByDest($this->getUser()); $total = $this->entityWorkflowRepository->countByDest($this->security->getUser());
$paginator = $this->paginatorFactory->create($total); $paginator = $this->paginatorFactory->create($total);
$workflows = $this->entityWorkflowRepository->findByDest( $workflows = $this->entityWorkflowRepository->findByDest(
$this->getUser(), $this->security->getUser(),
['createdAt' => 'DESC'], ['createdAt' => 'DESC'],
$paginator->getItemsPerPage(), $paginator->getItemsPerPage(),
$paginator->getCurrentPageFirstItemNumber() $paginator->getCurrentPageFirstItemNumber()
@ -262,11 +262,11 @@ class WorkflowController extends AbstractController
{ {
$this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED');
$total = $this->entityWorkflowRepository->countBySubscriber($this->getUser()); $total = $this->entityWorkflowRepository->countBySubscriber($this->security->getUser());
$paginator = $this->paginatorFactory->create($total); $paginator = $this->paginatorFactory->create($total);
$workflows = $this->entityWorkflowRepository->findBySubscriber( $workflows = $this->entityWorkflowRepository->findBySubscriber(
$this->getUser(), $this->security->getUser(),
['createdAt' => 'DESC'], ['createdAt' => 'DESC'],
$paginator->getItemsPerPage(), $paginator->getItemsPerPage(),
$paginator->getCurrentPageFirstItemNumber() $paginator->getCurrentPageFirstItemNumber()

View File

@ -364,6 +364,11 @@ class User implements UserInterface, \Stringable, PasswordAuthenticatedUserInter
return $this->username; return $this->username;
} }
public function getUserIdentifier(): string
{
return $this->username;
}
/** /**
* @return string * @return string
*/ */

View File

@ -12,32 +12,41 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Controller; namespace Chill\PersonBundle\Controller;
use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\Activity;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Entity\AccompanyingPeriod; use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Form\AccompanyingCourseType; use Chill\PersonBundle\Form\AccompanyingCourseType;
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository; use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
use Chill\PersonBundle\Repository\PersonRepository;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; 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\Routing\Annotation\Route;
use Symfony\Component\Serializer\SerializerInterface; use Symfony\Component\Security\Core\Security;
use Symfony\Component\Validator\ConstraintViolationInterface; use Symfony\Component\Validator\ConstraintViolationInterface;
use Symfony\Component\Validator\ConstraintViolationListInterface; use Symfony\Component\Validator\ConstraintViolationListInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Component\Workflow\Registry; use Symfony\Component\Workflow\Registry;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
/** /**
* Class AccompanyingCourseController. * 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") * @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 public function newAction(Request $request): Response
{ {
$user = $this->security->getUser();
if (!$user instanceof User) {
throw new AccessDeniedHttpException();
}
$period = new AccompanyingPeriod(); $period = new AccompanyingPeriod();
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
if ($request->query->has('person_id')) { $personIds = $request->query->all('person_id');
$personIds = $request->query->get('person_id');
if (false === \is_array($personIds)) { foreach ($personIds as $personId) {
throw new BadRequestHttpException('person_id parameter should be an array'); $person = $this->personRepository->find($personId);
}
foreach ($personIds as $personId) { if (null !== $person) {
$person = $em->getRepository(Person::class)->find($personId); if (!$this->isGranted(PersonVoter::SEE, $person)) {
throw new AccessDeniedHttpException(sprintf('person with id %d cannot be seen', $person->getId()));
if (null !== $person) {
$period->addPerson($person);
} }
$period->addPerson($person);
} }
} }
$userLocation = $this->getUser()->getCurrentLocation(); $userLocation = $user->getCurrentLocation();
$period->setAdministrativeLocation($userLocation); $period->setAdministrativeLocation($userLocation);
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::CREATE, $period); $this->denyAccessUnlessGranted(AccompanyingPeriodVoter::CREATE, $period);
@ -260,6 +272,12 @@ class AccompanyingCourseController extends \Symfony\Bundle\FrameworkBundle\Contr
*/ */
public function newHouseholdParcoursAction(Request $request): Response public function newHouseholdParcoursAction(Request $request): Response
{ {
$user = $this->getUser();
if (!$user instanceof User || !$this->security->isGranted('ROLE_USER')) {
throw new AccessDeniedHttpException();
}
$period = new AccompanyingPeriod(); $period = new AccompanyingPeriod();
$em = $this->getDoctrine()->getManager(); $em = $this->getDoctrine()->getManager();
@ -276,8 +294,7 @@ class AccompanyingCourseController extends \Symfony\Bundle\FrameworkBundle\Contr
} }
} }
$userLocation = $this->getUser()->getCurrentLocation(); $period->setAdministrativeLocation($user->getCurrentLocation());
$period->setAdministrativeLocation($userLocation);
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::CREATE, $period); $this->denyAccessUnlessGranted(AccompanyingPeriodVoter::CREATE, $period);

View File

@ -12,28 +12,40 @@ declare(strict_types=1);
namespace Chill\PersonBundle\Controller; namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController; use Chill\MainBundle\CRUD\Controller\ApiController;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Serializer\Model\Collection; use Chill\MainBundle\Serializer\Model\Collection;
use Chill\MainBundle\Serializer\Model\Counter; use Chill\MainBundle\Serializer\Model\Counter;
use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository; use Chill\PersonBundle\Repository\AccompanyingPeriod\AccompanyingPeriodWorkRepository;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
class AccompanyingCourseWorkApiController extends ApiController 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") * @Route("/api/1.0/person/accompanying-period/work/my-near-end")
*/ */
public function myWorksNearEndDate(Request $request): JsonResponse public function myWorksNearEndDate(Request $request): JsonResponse
{ {
$user = $this->security->getUser();
if (!$user instanceof User) {
throw new AccessDeniedHttpException();
}
$since = (new \DateTimeImmutable('now')) $since = (new \DateTimeImmutable('now'))
->sub(new \DateInterval('P'.$request->query->getInt('since', 15).'D')); ->sub(new \DateInterval('P'.$request->query->getInt('since', 15).'D'));
$until = (new \DateTimeImmutable('now')) $until = (new \DateTimeImmutable('now'))
->add(new \DateInterval('P'.$request->query->getInt('since', 15).'D')); ->add(new \DateInterval('P'.$request->query->getInt('since', 15).'D'));
$total = $this->accompanyingPeriodWorkRepository $total = $this->accompanyingPeriodWorkRepository
->countNearEndDateByUser($this->getUser(), $since, $until); ->countNearEndDateByUser($user, $since, $until);
if ($request->query->getBoolean('countOnly', false)) { if ($request->query->getBoolean('countOnly', false)) {
return $this->json( return $this->json(
@ -46,7 +58,7 @@ class AccompanyingCourseWorkApiController extends ApiController
$paginator = $this->getPaginatorFactory()->create($total); $paginator = $this->getPaginatorFactory()->create($total);
$works = $this->accompanyingPeriodWorkRepository $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); $collection = new Collection($works, $paginator);

View File

@ -14,23 +14,37 @@ namespace Chill\PersonBundle\Controller;
use Chill\MainBundle\CRUD\Controller\ApiController; use Chill\MainBundle\CRUD\Controller\ApiController;
use Chill\PersonBundle\Entity\Household\Household; use Chill\PersonBundle\Entity\Household\Household;
use Chill\PersonBundle\Entity\Household\HouseholdMember; use Chill\PersonBundle\Entity\Household\HouseholdMember;
use Chill\PersonBundle\Entity\Household\Position;
use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Form\HouseholdMemberType; use Chill\PersonBundle\Form\HouseholdMemberType;
use Chill\PersonBundle\Household\MembersEditor; use Chill\PersonBundle\Household\MembersEditor;
use Chill\PersonBundle\Repository\AccompanyingPeriodRepository; 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 Chill\PersonBundle\Security\Authorization\PersonVoter;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Serializer\Exception; use Symfony\Component\Serializer\Exception;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
class HouseholdMemberController extends ApiController 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( * @Route(
@ -83,43 +97,50 @@ class HouseholdMemberController extends ApiController
*/ */
public function editor(Request $request) public function editor(Request $request)
{ {
$em = $this->getDoctrine()->getManager(); $ids = $request->query->all('persons');
if ($request->query->has('persons')) { if ([] !== $ids) {
$ids = $request->query->get('persons', []); $persons = [];
if (0 === \count($ids)) { foreach ($ids as $id) {
throw new BadRequestHttpException('parameters persons in query is not an array or empty'); if (!is_numeric($id)) {
} throw new BadRequestHttpException(sprintf('persons with id %s is not numeric', $id));
}
$persons = $em->getRepository(Person::class) $person = $this->personRepository->find((int) $id);
->findById($ids);
if (null === $person) {
throw new NotFoundHttpException(sprintf('person with id %d not found', $id));
}
foreach ($persons as $person) {
$this->denyAccessUnlessGranted( $this->denyAccessUnlessGranted(
PersonVoter::SEE, PersonVoter::SEE,
$person, $person,
"You are not allowed to see person with id {$person->getId()}" "You are not allowed to see person with id {$person->getId()}"
); );
$persons[] = $person;
} }
} }
if ($request->query->has('household')) { if ($request->query->has('household')) {
$householdId = $request->query->get('household', false); $householdId = $request->query->get('household', false);
$household = $em->getRepository(Household::class) $household = $this->householdRepository
->find($householdId); ->find($householdId);
$allowHouseholdCreate = false; $allowHouseholdCreate = false;
$allowHouseholdSearch = false; $allowHouseholdSearch = false;
$allowLeaveWithoutHousehold = false; $allowLeaveWithoutHousehold = false;
if (null === $household) { 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() $positions = $this->positionRepository
->getRepository(Position::class)
->findAll(); ->findAll();
$data = [ $data = [
@ -140,10 +161,8 @@ class HouseholdMemberController extends ApiController
); );
if (null === $period) { 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', [ return $this->render('@ChillPerson/Household/members_editor.html.twig', [

View File

@ -14,6 +14,7 @@ namespace Chill\PersonBundle\Controller;
use Chill\ActivityBundle\Entity\Activity; use Chill\ActivityBundle\Entity\Activity;
use Chill\DocStoreBundle\Entity\PersonDocument; use Chill\DocStoreBundle\Entity\PersonDocument;
use Chill\EventBundle\Entity\Participation; use Chill\EventBundle\Entity\Participation;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Actions\Remove\PersonMove; use Chill\PersonBundle\Actions\Remove\PersonMove;
use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Entity\PersonNotDuplicate; use Chill\PersonBundle\Entity\PersonNotDuplicate;
@ -24,15 +25,21 @@ use Chill\PersonBundle\Repository\PersonNotDuplicateRepository;
use Chill\PersonBundle\Repository\PersonRepository; use Chill\PersonBundle\Repository\PersonRepository;
use Chill\PersonBundle\Search\SimilarPersonMatcher; use Chill\PersonBundle\Search\SimilarPersonMatcher;
use Chill\TaskBundle\Entity\SingleTask; use Chill\TaskBundle\Entity\SingleTask;
use http\Exception\InvalidArgumentException;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request; 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; use function count;
class PersonDuplicateController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController 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") * @\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) public function confirmAction(mixed $person1_id, mixed $person2_id, Request $request)
{ {
if ($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');
} }
$person1 = $this->_getPerson($person1_id); $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) 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); [$person1, $person2] = $this->_getPersonsByPriority($person1_id, $person2_id);
$this->denyAccessUnlessGranted( $this->denyAccessUnlessGranted(
@ -167,7 +180,7 @@ class PersonDuplicateController extends \Symfony\Bundle\FrameworkBundle\Controll
$personNotDuplicate = new PersonNotDuplicate(); $personNotDuplicate = new PersonNotDuplicate();
$personNotDuplicate->setPerson1($person1); $personNotDuplicate->setPerson1($person1);
$personNotDuplicate->setPerson2($person2); $personNotDuplicate->setPerson2($person2);
$personNotDuplicate->setUser($this->getUser()); $personNotDuplicate->setUser($user);
$this->getDoctrine()->getManager()->persist($personNotDuplicate); $this->getDoctrine()->getManager()->persist($personNotDuplicate);
$this->getDoctrine()->getManager()->flush(); $this->getDoctrine()->getManager()->flush();
@ -259,7 +272,7 @@ class PersonDuplicateController extends \Symfony\Bundle\FrameworkBundle\Controll
private function _getPersonsByPriority($person1_id, $person2_id) private function _getPersonsByPriority($person1_id, $person2_id)
{ {
if ($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) { if ($person1_id > $person2_id) {

View File

@ -19,7 +19,7 @@ use Symfony\Component\Form\Exception\UnexpectedTypeException;
class PersonAltNameDataMapper implements DataMapperInterface class PersonAltNameDataMapper implements DataMapperInterface
{ {
public function mapDataToForms($viewData, iterable $forms) public function mapDataToForms($viewData, iterable $forms): void
{ {
if (null === $viewData) { if (null === $viewData) {
return; return;
@ -43,11 +43,7 @@ class PersonAltNameDataMapper implements DataMapperInterface
} }
} }
/** public function mapFormsToData(iterable $forms, &$viewData): void
* @param FormInterface[] $forms
* @param Collection $viewData
*/
public function mapFormsToData(iterable $forms, &$viewData)
{ {
$mapIndexToKey = []; $mapIndexToKey = [];

View File

@ -13,6 +13,7 @@ namespace Chill\PersonBundle\Form\Type;
use Chill\MainBundle\Entity\Center; use Chill\MainBundle\Entity\Center;
use Chill\MainBundle\Entity\GroupCenter; use Chill\MainBundle\Entity\GroupCenter;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper; use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Form\ChoiceLoader\PersonChoiceLoader; use Chill\PersonBundle\Form\ChoiceLoader\PersonChoiceLoader;
@ -25,7 +26,6 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException; use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\Role\Role;
use Symfony\Contracts\Translation\TranslatorInterface; 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 * - with the `role` option, only the people belonging to the reachable center for the
* given role are displayed. * 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( public function __construct(
PersonRepository $personRepository, private readonly PersonRepository $personRepository,
TokenStorageInterface $tokenStorage, private readonly TokenStorageInterface $tokenStorage,
AuthorizationHelper $authorizationHelper, private readonly AuthorizationHelper $authorizationHelper,
UrlGeneratorInterface $urlGenerator, private readonly UrlGeneratorInterface $urlGenerator,
TranslatorInterface $translator private readonly TranslatorInterface $translator
) { ) {}
$this->personRepository = $personRepository;
$this->user = $tokenStorage->getToken()->getUser();
$this->authorizationHelper = $authorizationHelper;
$this->urlGenerator = $urlGenerator;
$this->translator = $translator;
}
public function buildView(\Symfony\Component\Form\FormView $view, \Symfony\Component\Form\FormInterface $form, array $options) 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) 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']) { 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 { } else {
$centers = $this->authorizationHelper $centers = $this->authorizationHelper
->getReachableCenters($this->user, $options['role']->getRole()); ->getReachableCenters($user, $options['role']->getRole());
} }
if (null === $options['centers']) { if (null === $options['centers']) {

View File

@ -31,31 +31,21 @@ namespace Chill\PersonBundle\Privacy;
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Entity\Person;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 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. * PrivacyEventSubscriber constructor.
*/ */
public function __construct(LoggerInterface $logger, TokenStorageInterface $token) public function __construct(
{ private LoggerInterface $logger,
$this->logger = $logger; private TokenStorageInterface $token
$this->token = $token; ) {}
}
public static function getSubscribedEvents() 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 [ return [
'by_user' => $this->token->getToken()->getUser()->getUsername(), 'by_user' => $user->getUsername(),
'by_user_id' => $this->token->getToken()->getUser()->getId(), 'by_user_id' => $user->getUserIdentifier(),
]; ];
} }
} }

View File

@ -26,12 +26,6 @@ services:
Chill\PersonBundle\Controller\AdminController: ~ Chill\PersonBundle\Controller\AdminController: ~
Chill\PersonBundle\Controller\PersonDuplicateController: 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'] tags: ['controller.service_arguments']
Chill\PersonBundle\Controller\AccompanyingCourseController: Chill\PersonBundle\Controller\AccompanyingCourseController:

View File

@ -12,6 +12,7 @@ declare(strict_types=1);
namespace Chill\ReportBundle\Form; namespace Chill\ReportBundle\Form;
use Chill\CustomFieldsBundle\Form\Type\CustomFieldType; use Chill\CustomFieldsBundle\Form\Type\CustomFieldType;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Form\Type\AppendScopeChoiceTypeTrait; use Chill\MainBundle\Form\Type\AppendScopeChoiceTypeTrait;
use Chill\MainBundle\Form\Type\ChillDateType; use Chill\MainBundle\Form\Type\ChillDateType;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper; use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
@ -22,41 +23,16 @@ use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
class ReportType extends AbstractType final class ReportType extends AbstractType
{ {
use AppendScopeChoiceTypeTrait; 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( public function __construct(
AuthorizationHelper $helper, private readonly AuthorizationHelper $authorizationHelper,
TokenStorageInterface $tokenStorage, private readonly TokenStorageInterface $tokenStorage,
TranslatableStringHelper $translatableStringHelper, private readonly TranslatableStringHelper $translatableStringHelper,
ObjectManager $om private readonly ObjectManager $om
) { ) {}
$this->authorizationHelper = $helper;
$this->user = $tokenStorage->getToken()->getUser();
$this->translatableStringHelper = $translatableStringHelper;
$this->om = $om;
}
public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
{ {
@ -74,11 +50,17 @@ class ReportType extends AbstractType
'group' => $options['cFGroup'], ] 'group' => $options['cFGroup'], ]
); );
$user = $this->tokenStorage->getToken()->getUser();
if (!$user instanceof User) {
throw new \RuntimeException('user must be a regular user');
}
$this->appendScopeChoices( $this->appendScopeChoices(
$builder, $builder,
$options['role'], $options['role'],
$options['center'], $options['center'],
$this->user, $user,
$this->authorizationHelper, $this->authorizationHelper,
$this->translatableStringHelper, $this->translatableStringHelper,
$this->om $this->om

View File

@ -11,6 +11,7 @@ declare(strict_types=1);
namespace Chill\TaskBundle\Controller; namespace Chill\TaskBundle\Controller;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface; use Chill\MainBundle\Security\Resolver\CenterResolverDispatcherInterface;
use Chill\MainBundle\Serializer\Model\Collection; use Chill\MainBundle\Serializer\Model\Collection;
@ -38,8 +39,10 @@ use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
final class SingleTaskController extends AbstractController final class SingleTaskController extends AbstractController
@ -55,6 +58,7 @@ final class SingleTaskController extends AbstractController
private readonly FilterOrderHelperFactoryInterface $filterOrderHelperFactory, private readonly FilterOrderHelperFactoryInterface $filterOrderHelperFactory,
private readonly SingleTaskStateRepository $singleTaskStateRepository, private readonly SingleTaskStateRepository $singleTaskStateRepository,
private readonly SingleTaskRepository $singleTaskRepository, private readonly SingleTaskRepository $singleTaskRepository,
private readonly Security $security,
) {} ) {}
/** /**
@ -487,8 +491,14 @@ final class SingleTaskController extends AbstractController
*/ */
public function newAction(Request $request) public function newAction(Request $request)
{ {
$user = $this->security->getUser();
if (!$user instanceof User) {
throw new AccessDeniedHttpException();
}
$task = (new SingleTask()) $task = (new SingleTask())
->setAssignee($this->getUser()) ->setAssignee($user)
->setType('task_default'); ->setType('task_default');
$entityType = $this->getEntityContext($request); $entityType = $this->getEntityContext($request);

View File

@ -66,7 +66,7 @@ class TaskController extends AbstractController
'chill_task_single_task_show', 'chill_task_single_task_show',
[ [
'id' => $task->getId(), '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'; 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 * @return \Symfony\Component\Form\FormInterface
*/ */
protected function createTransitionForm(AbstractTask $task) protected function createTransitionForm(AbstractTask $task)

View File

@ -26,8 +26,7 @@ final readonly class UserMenuBuilder implements LocalMenuBuilderInterface
private TokenStorageInterface $tokenStorage, private TokenStorageInterface $tokenStorage,
private TranslatorInterface $translator, private TranslatorInterface $translator,
private AuthorizationCheckerInterface $authorizationChecker private AuthorizationCheckerInterface $authorizationChecker
) { ) {}
}
public function buildMenu($menuId, MenuItem $menu, array $parameters) public function buildMenu($menuId, MenuItem $menu, array $parameters)
{ {