Skip to content

Commit

Permalink
Fix security attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
ottaviano committed Jan 30, 2025
1 parent e5d2590 commit ab78346
Show file tree
Hide file tree
Showing 36 changed files with 79 additions and 59 deletions.
2 changes: 1 addition & 1 deletion src/Controller/Api/Action/CancelActionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'actions') and (action.getAuthor() == user or user.hasDelegatedFromUser(action.getAuthor(), 'actions'))"))]
#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'actions') and (subject.getAuthor() == user or user.hasDelegatedFromUser(subject.getAuthor(), 'actions'))"), subject: 'action')]
class CancelActionController extends AbstractController
{
public function __invoke(Action $action, EntityManagerInterface $manager, MessageBusInterface $bus): Response
Expand Down
4 changes: 2 additions & 2 deletions src/Controller/Api/AdherentAutocompleteController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

use App\Adherent\AdherentAutocompleteFilter;
use App\Repository\AdherentRepository;
use App\Scope\FeatureEnum;
use App\Scope\ScopeGeneratorResolver;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
Expand All @@ -16,7 +16,7 @@
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;

#[IsGranted('REQUEST_SCOPE_GRANTED', subject: [FeatureEnum::TEAM, FeatureEnum::MY_TEAM, FeatureEnum::COMMITTEE])]
#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', ['team', 'my_team', 'committee'])"))]
#[Route(path: '/v3/adherents/autocomplete', name: 'api_adherent_autocomplete', methods: ['GET'])]
class AdherentAutocompleteController extends AbstractController
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'messages') and (data.getAuthor() == user or user.hasDelegatedFromUser(data.getAuthor(), 'messages'))"))]
#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'messages') and (subject.getAuthor() == user or user.hasDelegatedFromUser(subject.getAuthor(), 'messages'))"), subject: 'data')]
class DuplicateMessageController extends AbstractController
{
public function __construct(private readonly AdherentMessageManager $manager)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Symfony\Component\Serializer\SerializerInterface;

#[IsGranted(new Expression("is_granted('ROLE_USER') and (message.getAuthor() == user or user.hasDelegatedFromUser(message.getAuthor(), 'messages'))"))]
#[IsGranted(new Expression("is_granted('ROLE_USER') and (subject.getAuthor() == user or user.hasDelegatedFromUser(subject.getAuthor(), 'messages'))"), subject: 'message')]
#[Route(path: '/adherent_messages/{uuid}', name: 'app_api_get_adherent_message_status', methods: ['GET'])]
class GetAdherentMessageStatusController extends AbstractController
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'messages') and (message.getAuthor() == user or user.hasDelegatedFromUser(message.getAuthor(), 'messages'))"))]
#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'messages') and (subject.getAuthor() == user or user.hasDelegatedFromUser(subject.getAuthor(), 'messages'))"), subject: 'message')]
class SendAdherentMessageController extends AbstractController
{
public function __construct(private readonly AdherentMessageManager $manager)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'messages') and (message.getAuthor() == user or user.hasDelegatedFromUser(message.getAuthor(), 'messages'))"))]
#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'messages') and (subject.getAuthor() == user or user.hasDelegatedFromUser(subject.getAuthor(), 'messages'))"), subject: 'message')]
class SendTestAdherentMessageController extends AbstractController
{
public function __construct(private readonly AdherentMessageManager $manager)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;

#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'messages') and (data.getAuthor() == user or user.hasDelegatedFromUser(data.getAuthor(), 'messages'))"))]
#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'messages') and (subject.getAuthor() == user or user.hasDelegatedFromUser(subject.getAuthor(), 'messages'))"), subject: 'data')]
class UpdateAdherentMessageFilterController extends AbstractController
{
public function __construct(
Expand Down
2 changes: 1 addition & 1 deletion src/Controller/Api/ElectProfileController.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;

#[IsGranted(new Expression('is_granted(\'ROLE_OAUTH_SCOPE_READ:PROFILE\') and is_granted(\'ongoing_eletected_representative\')'))]
#[IsGranted(new Expression("is_granted('ROLE_OAUTH_SCOPE_READ:PROFILE') and is_granted('ongoing_eletected_representative')"))]
#[Route(path: '/v3/profile', name: 'app_api_user_profile')]
class ElectProfileController extends AbstractController
{
Expand Down
2 changes: 1 addition & 1 deletion src/Controller/Api/Event/CancelEventController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'events') and is_granted('CAN_MANAGE_EVENT', event)"))]
#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'events') and is_granted('CAN_MANAGE_EVENT', subject)"), subject: 'event')]
class CancelEventController extends AbstractController
{
public function __invoke(EventCanceledHandler $handler, Request $request, BaseEvent $event): Response
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'events') and is_granted('MANAGE_ZONEABLE_ITEM__FOR_SCOPE', event)"))]
#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'events') and is_granted('MANAGE_ZONEABLE_ITEM__FOR_SCOPE', subject)"), subject: 'event')]
#[Route(path: '/v3/events/{uuid}/participants.{_format}', name: 'api_events_get_participants', requirements: ['uuid' => '%pattern_uuid%', '_format' => 'json|xlsx'], defaults: ['_format' => 'json'], methods: ['GET'])]
class GetEventParticipantsController extends AbstractController
{
Expand Down
2 changes: 1 addition & 1 deletion src/Controller/Api/Jecoute/GetSurveyRepliesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'survey') and is_granted('SCOPE_CAN_MANAGE', survey)"))]
#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'survey') and is_granted('SCOPE_CAN_MANAGE', subject)"), subject: 'survey')]
#[Route(path: '/v3/surveys/{uuid}/replies.{_format}', name: 'api_survey_get_survey_replies', methods: ['GET'], requirements: ['uuid' => '%pattern_uuid%', '_format' => 'json|csv|xlsx'], defaults: ['_format' => 'json'])]
class GetSurveyRepliesController extends AbstractController
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', ['pap_v2', 'pap']) and is_granted('SCOPE_CAN_MANAGE', campaign)"))]
#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', ['pap_v2', 'pap']) and is_granted('SCOPE_CAN_MANAGE', subject)"), subject: 'campaign')]
#[Route(path: '/v3/pap_campaigns/{uuid}/replies.{_format}', name: 'api_pap_camapign_get_campaign_survey_replies', requirements: ['uuid' => '%pattern_uuid%', '_format' => 'json|csv|xlsx'], defaults: ['_format' => 'json'], methods: ['GET'])]
class GetPapCampaignSurveyRepliesController extends AbstractController
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[IsGranted(new Expression("campaign.isPermanent() or is_granted('ROLE_PHONING_CAMPAIGN_MEMBER')"))]
#[IsGranted(new Expression("subject.isPermanent() or is_granted('ROLE_PHONING_CAMPAIGN_MEMBER')"), subject: 'campaign')]
#[Route(path: '/v3/phoning_campaigns/{uuid}/survey', name: 'api_phoning_camapign_get_campaign_survey', requirements: ['uuid' => '%pattern_uuid%'], methods: ['GET'])]
class GetPhoningCampaignSurveyController extends AbstractController
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
use App\Entity\Phoning\Campaign;
use App\Exporter\PhoningCampaignSurveyRepliesExporter;
use App\Repository\Jecoute\DataSurveyRepository;
use App\Scope\FeatureEnum;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[IsGranted('REQUEST_SCOPE_GRANTED', subject: FeatureEnum::PHONING_CAMPAIGN)]
#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'phoning_campaign')"))]
#[Route(path: '/v3/phoning_campaigns/{uuid}/replies.{_format}', name: 'api_phoning_campaign_get_campaign_survey_replies', requirements: ['uuid' => '%pattern_uuid%', '_format' => 'json|csv|xlsx'], defaults: ['_format' => 'json'], methods: ['GET'])]
class GetPhoningCampaignSurveyRepliesController extends AbstractController
{
Expand Down
2 changes: 1 addition & 1 deletion src/Controller/Api/Team/AddTeamMembersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;

#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'team') and is_granted('SCOPE_CAN_MANAGE', team)"))]
#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'team') and is_granted('SCOPE_CAN_MANAGE', subject)"), subject: 'team')]
#[Route(path: '/v3/teams/{uuid}/add-members', requirements: ['uuid' => '%pattern_uuid%'], name: 'api_team_add_members', methods: ['PUT'])]
class AddTeamMembersController extends AbstractController
{
Expand Down
2 changes: 1 addition & 1 deletion src/Controller/Api/Team/RemoveTeamController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'team') and is_granted('SCOPE_CAN_MANAGE', team)"))]
#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'team') and is_granted('SCOPE_CAN_MANAGE', subject)"), subject: 'team')]
#[Route(path: '/v3/teams/{uuid}', requirements: ['uuid' => '%pattern_uuid%'], name: 'api_team_remove', methods: ['DELETE'])]
class RemoveTeamController extends AbstractController
{
Expand Down
2 changes: 1 addition & 1 deletion src/Controller/Api/Team/RemoveTeamMemberController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'team') and is_granted('SCOPE_CAN_MANAGE', team)"))]
#[IsGranted(new Expression("is_granted('REQUEST_SCOPE_GRANTED', 'team') and is_granted('SCOPE_CAN_MANAGE', subject)"), subject: 'team')]
#[Route(path: '/v3/teams/{uuid}/members/{adherent_uuid}', requirements: ['uuid' => '%pattern_uuid%', 'adherent_uuid' => '%pattern_uuid%'], name: 'api_team_remove_member', methods: ['DELETE'])]
class RemoveTeamMemberController extends AbstractController
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ public function filterMessageAction(
]);
}

#[IsGranted(new Expression("is_granted('IS_AUTHOR_OF', message) and is_granted('USER_CAN_SEND_MESSAGE', message)"))]
#[IsGranted(new Expression("is_granted('IS_AUTHOR_OF', subject) and is_granted('USER_CAN_SEND_MESSAGE', subject)"), subject: 'message')]
#[Route(path: '/{uuid}/send', name: 'send', methods: ['GET'])]
public function sendMessageAction(AbstractAdherentMessage $message, AdherentMessageManager $manager): Response
{
Expand Down Expand Up @@ -235,7 +235,7 @@ public function sendMessageAction(AbstractAdherentMessage $message, AdherentMess
return $this->redirectToMessageRoute('list');
}

#[IsGranted(new Expression("is_granted('IS_AUTHOR_OF', message) and message.isSent()"))]
#[IsGranted(new Expression("is_granted('IS_AUTHOR_OF', subject) and subject.isSent()"), subject: 'message')]
#[Route(path: '/{uuid}/confirmation', name: 'send_success', methods: ['GET'])]
public function sendSuccessAction(AbstractAdherentMessage $message): Response
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[IsGranted(new Expression("is_granted('HOST_COMMITTEE', committee) and committee.isApproved()"))]
#[IsGranted('HOST_COMMITTEE', subject: 'committee')]
#[Route(path: '/espace-animateur/{committee_slug}/messagerie', name: 'app_message_committee_')]
class CommitteeMessageController extends AbstractController
{
Expand Down Expand Up @@ -63,6 +63,7 @@ public function messageListAction(
#[Route(path: '/creer', name: 'create', methods: ['GET', 'POST'])]
public function createMessageAction(
Request $request,
#[MapEntity(mapping: ['committee_slug' => 'slug'])]
Committee $committee,
AdherentMessageManager $manager,
): Response {
Expand Down Expand Up @@ -108,6 +109,7 @@ public function updateMessageAction(
Request $request,
CommitteeAdherentMessage $message,
AdherentMessageManager $manager,
#[MapEntity(mapping: ['committee_slug' => 'slug'])]
Committee $committee,
): Response {
if ($message->isSent()) {
Expand Down Expand Up @@ -145,6 +147,7 @@ public function updateMessageAction(
public function filterMessageAction(
Request $request,
CommitteeAdherentMessage $message,
#[MapEntity(mapping: ['committee_slug' => 'slug'])]
Committee $committee,
AdherentMessageManager $manager,
FilterFormFactory $formFactory,
Expand Down Expand Up @@ -194,8 +197,11 @@ public function filterMessageAction(

#[IsGranted('IS_AUTHOR_OF', subject: 'message')]
#[Route(path: '/{uuid}/visualiser', name: 'preview', methods: ['GET'])]
public function previewMessageAction(CommitteeAdherentMessage $message, Committee $committee): Response
{
public function previewMessageAction(
CommitteeAdherentMessage $message,
#[MapEntity(mapping: ['committee_slug' => 'slug'])]
Committee $committee,
): Response {
if (!$message->isSynchronized()) {
throw new BadRequestHttpException('Message preview is not ready yet.');
}
Expand All @@ -208,6 +214,7 @@ public function previewMessageAction(CommitteeAdherentMessage $message, Committe
public function deleteMessageAction(
CommitteeAdherentMessage $message,
ObjectManager $manager,
#[MapEntity(mapping: ['committee_slug' => 'slug'])]
Committee $committee,
): Response {
$manager->remove($message);
Expand All @@ -223,6 +230,7 @@ public function deleteMessageAction(
public function sendMessageAction(
CommitteeAdherentMessage $message,
AdherentMessageManager $manager,
#[MapEntity(mapping: ['committee_slug' => 'slug'])]
Committee $committee,
): Response {
if (!$message->isSynchronized()) {
Expand All @@ -248,10 +256,13 @@ public function sendMessageAction(
return $this->redirectToRoute('app_message_committee_list', ['committee_slug' => $committee->getSlug()]);
}

#[IsGranted(new Expression("is_granted('IS_AUTHOR_OF', message) and message.isSent()"))]
#[IsGranted(new Expression("is_granted('IS_AUTHOR_OF', subject) and subject.isSent()"), subject: 'message')]
#[Route(path: '/{uuid}/confirmation', name: 'send_success', methods: ['GET'])]
public function sendSuccessAction(AbstractAdherentMessage $message, Committee $committee): Response
{
public function sendSuccessAction(
AbstractAdherentMessage $message,
#[MapEntity(mapping: ['committee_slug' => 'slug'])]
Committee $committee,
): Response {
return $this->renderTemplate('message/send_success/committee.html.twig', $committee, ['message' => $message]);
}

Expand All @@ -260,6 +271,7 @@ public function sendSuccessAction(AbstractAdherentMessage $message, Committee $c
public function sendTestMessageAction(
CommitteeAdherentMessage $message,
Manager $manager,
#[MapEntity(mapping: ['committee_slug' => 'slug'])]
Committee $committee,
): Response {
if (!$message->isSynchronized()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public function __construct(ElectionRepository $electionRepository)
#[Route(path: '', name: '_list', methods: ['GET'])]
public function listDesignationsAction(
Request $request,
#[MapEntity(mapping: ['committee_slug' => 'slug'])]
Committee $committee,
CommitteeElectionRepository $repository,
): Response {
Expand All @@ -44,6 +45,7 @@ public function listDesignationsAction(
#[Route(path: '/{uuid}/{election_round_uuid}', name: '_dashboard', methods: ['GET'], defaults: ['election_round_uuid' => null])]
public function dashboardAction(
Request $request,
#[MapEntity(mapping: ['committee_slug' => 'slug'])]
Committee $committee,
Election $election,
#[MapEntity(mapping: ['election_round_uuid' => 'uuid'])]
Expand All @@ -65,6 +67,7 @@ public function dashboardAction(
#[Route(path: '/{uuid}/liste-emargement/{election_round_uuid}', name: '_voters_list', methods: ['GET'], defaults: ['election_round_uuid' => null])]
public function listVotersAction(
Request $request,
#[MapEntity(mapping: ['committee_slug' => 'slug'])]
Committee $committee,
Election $election,
VoterRepository $voterRepository,
Expand Down Expand Up @@ -92,6 +95,7 @@ public function listVotersAction(
#[Route(path: '/{uuid}/resultats/{election_round_uuid}', name: '_results', methods: ['GET'], defaults: ['election_round_uuid' => null])]
public function showResultsAction(
Request $request,
#[MapEntity(mapping: ['committee_slug' => 'slug'])]
Committee $committee,
Election $election,
#[MapEntity(mapping: ['election_round_uuid' => 'uuid'])]
Expand Down Expand Up @@ -125,6 +129,7 @@ function (ElectionPoolResult $poolResult) use ($poolCode) {
#[Route(path: '/{uuid}/bulletins/{election_round_uuid}', name: '_votes', methods: ['GET'], defaults: ['election_round_uuid' => null])]
public function listVotesAction(
Request $request,
#[MapEntity(mapping: ['committee_slug' => 'slug'])]
Committee $committee,
Election $election,
VoteResultRepository $voteResultRepository,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ public function invitationListAction(
]);
}

#[IsGranted(new Expression('invitation.getMembership() == user.getMembershipFor(committee)'))]
#[IsGranted(new Expression('subject.getMembership() == user.getMembershipFor(committee)'), subject: 'invitation')]
#[Route(path: '/mes-invitations/{uuid}/accepter', name: '_invitation_accept', methods: ['GET', 'POST'])]
public function acceptInvitationAction(
#[MapEntity(mapping: ['slug' => 'slug'])]
Expand Down Expand Up @@ -266,7 +266,7 @@ public function acceptInvitationAction(
]);
}

#[IsGranted(new Expression('invitation.getMembership() == user.getMembershipFor(committee)'))]
#[IsGranted(new Expression('subject.getMembership() == user.getMembershipFor(committee)'), subject: 'invitation')]
#[Route(path: '/mes-invitations/{uuid}/decliner', name: '_invitation_decline', methods: ['GET'])]
public function declineInvitationAction(
#[MapEntity(mapping: ['slug' => 'slug'])]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[IsGranted(new Expression("is_granted('MANAGE_COMMITTEE_DESIGNATIONS', committee) and committee.isApproved()"))]
#[IsGranted(new Expression("is_granted('MANAGE_COMMITTEE_DESIGNATIONS', subject) and subject.isApproved()"), subject: 'committee')]
#[Route(path: '/espace-animateur/{committee_slug}/designations', name: 'app_supervisor_designations')]
class SupervisorDesignationController extends AbstractDesignationController
{
Expand Down
Loading

0 comments on commit ab78346

Please sign in to comment.