Skip to content

Commit

Permalink
revamp fileVoter #2649
Browse files Browse the repository at this point in the history
  • Loading branch information
numew committed Jun 14, 2024
1 parent 82d237c commit b982a05
Show file tree
Hide file tree
Showing 12 changed files with 44 additions and 152 deletions.
2 changes: 1 addition & 1 deletion src/Controller/Back/SignalementController.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ public function viewSignalement(
): Response {
/** @var User $user */
$user = $this->getUser();
$this->denyAccessUnlessGranted('SIGN_VIEW', $signalement);
if (Signalement::STATUS_ARCHIVED === $signalement->getStatut()) {
$this->addFlash('error', "Ce signalement a été archivé et n'est pas consultable.");

return $this->redirectToRoute('back_index');
}
$this->denyAccessUnlessGranted('SIGN_VIEW', $signalement);

$eventDispatcher->dispatch(
new SignalementViewedEvent($signalement, $user),
Expand Down
9 changes: 2 additions & 7 deletions src/Controller/Back/SignalementFileController.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,6 @@ public function generatePdfSignalement(
MessageBusInterface $messageBus
): Response {
$this->denyAccessUnlessGranted('SIGN_VIEW', $signalement);
if (Signalement::STATUS_ARCHIVED === $signalement->getStatut()) {
$this->addFlash('error', "Ce signalement a été archivé et n'est pas consultable.");

return $this->redirectToRoute('back_index');
}
/** @var User $user */
$user = $this->getUser();

Expand Down Expand Up @@ -64,7 +59,7 @@ public function addFileSignalement(
EntityManagerInterface $entityManager,
SignalementFileProcessor $signalementFileProcessor
): Response {
$this->denyAccessUnlessGranted('FILE_CREATE', $signalement);
$this->denyAccessUnlessGranted('SIGN_EDIT', $signalement);
if (!$this->isCsrfTokenValid('signalement_add_file_'.$signalement->getId(), $request->get('_token')) || !$files = $request->files->get('signalement-add-file')) {
if ($request->isXmlHttpRequest()) {
return $this->json(['response' => 'Token CSRF invalide ou paramètre manquant, veuillez rechargez la page'], Response::HTTP_BAD_REQUEST);
Expand Down Expand Up @@ -113,7 +108,7 @@ public function fileWaitingSuiviSignalement(
EntityManagerInterface $entityManager,
SuiviManager $suiviManager,
): JsonResponse {
$this->denyAccessUnlessGranted('FILE_CREATE', $signalement);
$this->denyAccessUnlessGranted('SIGN_EDIT', $signalement);
$fileRepository = $entityManager->getRepository(File::class);
$files = $fileRepository->findBy(['signalement' => $signalement, 'isWaitingSuivi' => true]);
if (!\count($files)) {
Expand Down
25 changes: 9 additions & 16 deletions src/Controller/Back/SignalementVisitesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,6 @@ class SignalementVisitesController extends AbstractController

private function getSecurityRedirect(Signalement $signalement, Request $request, string $tokenName): ?Response
{
$this->denyAccessUnlessGranted('SIGN_VIEW', $signalement);
if (Signalement::STATUS_ARCHIVED === $signalement->getStatut()) {
$this->addFlash('error', "Ce signalement a été archivé et n'est pas consultable.");

return $this->redirectToRoute('back_index');
}

if (!$this->isCsrfTokenValid($tokenName, $request->get('_token'))) {
$this->addFlash('error', "Erreur de sécurisation de l'envoi de données.");

Expand Down Expand Up @@ -136,13 +129,13 @@ public function cancelVisiteFromSignalement(
): Response {
$requestData = $request->get('visite-cancel');

$intervention = $interventionRepository->findOneBy(['id' => $requestData['intervention']]);
$intervention = $interventionRepository->findOneBy(['id' => $requestData['intervention'], 'signalement' => $signalement]);
if (!$intervention) {
$this->addFlash('error', "Cette visite n'existe pas.");

return $this->redirectToRoute('back_index');
}
$this->denyAccessUnlessGranted('INTERVENTION_EDIT_VISITE', $intervention);
$this->denyAccessUnlessGranted('SIGN_ADD_VISITE', $signalement);

$errorRedirect = $this->getSecurityRedirect(
$signalement,
Expand Down Expand Up @@ -180,13 +173,13 @@ public function rescheduleVisiteFromSignalement(
): Response {
$requestRescheduleData = $request->get('visite-reschedule');

$intervention = $interventionRepository->findOneBy(['id' => $requestRescheduleData['intervention']]);
$intervention = $interventionRepository->findOneBy(['id' => $requestRescheduleData['intervention'], 'signalement' => $signalement]);
if (!$intervention) {
$this->addFlash('error', "Cette visite n'existe pas.");

return $this->redirectToRoute('back_index');
}
$this->denyAccessUnlessGranted('INTERVENTION_EDIT_VISITE', $intervention);
$this->denyAccessUnlessGranted('SIGN_ADD_VISITE', $signalement);

$errorRedirect = $this->getSecurityRedirect(
$signalement,
Expand Down Expand Up @@ -244,13 +237,13 @@ public function confirmVisiteFromSignalement(
): Response {
$requestData = $request->get('visite-confirm');

$intervention = $interventionRepository->findOneBy(['id' => $requestData['intervention']]);
$intervention = $interventionRepository->findOneBy(['id' => $requestData['intervention'], 'signalement' => $signalement]);
if (!$intervention) {
$this->addFlash('error', "Cette visite n'existe pas.");

return $this->redirectToRoute('back_index');
}
$this->denyAccessUnlessGranted('INTERVENTION_EDIT_VISITE', $intervention);
$this->denyAccessUnlessGranted('SIGN_ADD_VISITE', $signalement);

$errorRedirect = $this->getSecurityRedirect(
$signalement,
Expand Down Expand Up @@ -294,13 +287,13 @@ public function editVisiteFromSignalement(
): Response {
$requestData = $request->get('visite-edit');

$intervention = $interventionRepository->findOneBy(['id' => $requestData['intervention']]);
$intervention = $interventionRepository->findOneBy(['id' => $requestData['intervention'], 'signalement' => $signalement]);
if (!$intervention) {
$this->addFlash('error', "Cette visite n'existe pas.");

return $this->redirectToRoute('back_index');
}
$this->denyAccessUnlessGranted('INTERVENTION_EDIT_VISITE', $intervention);
$this->denyAccessUnlessGranted('SIGN_ADD_VISITE', $signalement);

$errorRedirect = $this->getSecurityRedirect(
$signalement,
Expand Down Expand Up @@ -341,7 +334,7 @@ public function deleteRapportVisiteFromSignalement(
EntityManagerInterface $entityManager,
UploadHandlerService $uploadHandlerService,
): Response {
$this->denyAccessUnlessGranted('INTERVENTION_EDIT_VISITE', $intervention);
$this->denyAccessUnlessGranted('SIGN_ADD_VISITE', $intervention->getSignalement());
if (!$this->isCsrfTokenValid('delete_rapport', $request->get('_token')) || $intervention->getSignalement()->getId() !== $signalement->getId() || $intervention->getFiles()->isEmpty()) {
return $this->redirectToRoute('back_signalement_view', ['uuid' => $signalement->getUuid()]);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Controller/Security/SecurityController.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function showUploadedFile(
): BinaryFileResponse|RedirectResponse {
$request = Request::createFromGlobals();

if (!$this->isCsrfTokenValid('suivi_signalement_ext_file_view', $request->get('t')) && !$this->isGranted('FILE_VIEW', $signalement)) {
if (!$this->isCsrfTokenValid('suivi_signalement_ext_file_view', $request->get('t')) && !$this->isGranted('SIGN_VIEW', $signalement)) {
throw $this->createNotFoundException();
}
try {
Expand Down
77 changes: 18 additions & 59 deletions src/Security/Voter/FileVoter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,17 @@
use App\Entity\File;
use App\Entity\Signalement;
use App\Entity\User;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;

class FileVoter extends Voter
{
public const DELETE = 'FILE_DELETE';
public const VIEW = 'FILE_VIEW';
public const CREATE = 'FILE_CREATE';
public const EDIT = 'FILE_EDIT';

public function __construct(private ParameterBagInterface $parameterBag)
{
}

protected function supports(string $attribute, $subject): bool
{
return \in_array($attribute, [self::DELETE, self::VIEW, self::CREATE, self::EDIT]) && ($subject instanceof Signalement || $subject instanceof File);
return \in_array($attribute, [self::DELETE, self::EDIT]) && $subject instanceof File;
}

protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
Expand All @@ -34,39 +27,32 @@ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $
return false;
}

if (!$subject instanceof Signalement && !$subject instanceof File) {
return false;
}
if (self::DELETE !== $attribute &&
self::EDIT !== $attribute &&
$this->isAdminOrRTonHisTerritory($subject, $user)
) {
return true;
}

return match ($attribute) {
self::DELETE => $this->canDelete($subject, $user),
self::VIEW => $this->canView($subject, $user),
self::CREATE => $this->canCreate($subject, $user),
self::EDIT => $this->canEdit($subject, $user),
default => false,
};
}

private function canCreate(Signalement $signalement, User $user): bool
private function canCreate(File $file, User $user): bool
{
return Signalement::STATUS_ACTIVE === $signalement->getStatut()
&& $this->checkSignalementPermission($signalement, $user);
}
if (Signalement::STATUS_ACTIVE !== $file->getSignalement()->getStatut()) {
return false;
}
if ($this->isAdminOrRTonHisTerritory($file, $user)) {
return true;
}

private function canView(Signalement $subject, User $user = null): bool
{
return $this->checkSignalementPermission($subject, $user);
return $file->getSignalement()->getAffectations()->filter(
function (Affectation $affectation) use ($user) {
return $affectation->getPartner()->getId() === $user->getPartner()->getId();
}
)->count() > 0;
}

private function canEdit(File $file, User $user): bool
{
return $this->canCreate($file->getSignalement(), $user)
return $this->canCreate($file, $user)
&& (
$this->isFileUploadedByUser($file, $user)
||
Expand All @@ -76,7 +62,7 @@ private function canEdit(File $file, User $user): bool

private function canDelete(File $file, User $user): bool
{
return $this->canCreate($file->getSignalement(), $user)
return $this->canCreate($file, $user)
&& (
$this->isFileUploadedByUser($file, $user)
||
Expand All @@ -94,39 +80,12 @@ private function isFileUploadedByUser(File $file, User $user): bool
return null !== $file->getUploadedBy() && $file->getUploadedBy() === $user;
}

private function isAdminOrRTonHisTerritory(File|Signalement $subject, User $user): bool
{
return $user->isSuperAdmin() ||
($user->isTerritoryAdmin() && $this->isOnUserTerritory($subject, $user));
}

private function checkSignalementPermission(Signalement $signalement, ?User $user = null): bool
private function isAdminOrRTonHisTerritory(File $subject, User $user): bool
{
if (null === $user) {
return false;
}
if ($this->isAdminOrRTonHisTerritory($signalement, $user)) {
if ($user->isSuperAdmin()) {
return true;
}

return $signalement->getAffectations()->filter(
function (Affectation $affectation) use ($user) {
return $affectation->getPartner()->getId() === $user->getPartner()->getId();
}
)->count() > 0;
}

private function isOnUserTerritory(File|Signalement $subject, User $user): bool
{
if (
(
$subject instanceof Signalement && $subject->getTerritory() === $user->getTerritory()
)
||
(
$subject instanceof File && $subject->getSignalement()->getTerritory() === $user->getTerritory()
)
) {
if ($user->isTerritoryAdmin() && $subject->getSignalement()->getTerritory() === $user->getTerritory()) {
return true;
}

Expand Down
59 changes: 0 additions & 59 deletions src/Security/Voter/InterventionVoter.php

This file was deleted.

6 changes: 5 additions & 1 deletion src/Security/Voter/SignalementVoter.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,18 @@ private function canEdit(Signalement $signalement, User $user): bool

private function canView(Signalement $signalement, User $user): bool
{
if (Signalement::STATUS_ARCHIVED === $signalement->getStatut()) {
return false;
}

return $signalement->getAffectations()->filter(function (Affectation $affectation) use ($user) {
return $affectation->getPartner()->getId() === $user->getPartner()->getId();
})->count() > 0 || $user->isTerritoryAdmin() && $user->getTerritory() === $signalement->getTerritory();
}

public function canAddVisite(Signalement $signalement, User $user): bool
{
if (Signalement::STATUS_ACTIVE !== $signalement->getStatut() && Signalement::STATUS_NEED_PARTNER_RESPONSE !== $signalement->getStatut()) {
if (!\in_array($signalement->getStatut(), [Signalement::STATUS_ACTIVE, Signalement::STATUS_NEED_PARTNER_RESPONSE])) {
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion templates/back/signalement/view.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
{% if canEditNDE %}
{% include '_partials/_modal_edit_nde.html.twig' %}
{% endif %}
{% if is_granted('FILE_CREATE', signalement) %}
{% if is_granted('SIGN_EDIT', signalement) %}
{% include '_partials/_modal_upload_files.html.twig' %}
{% endif %}
{% if is_granted('ROLE_ADMIN') %}
Expand Down
2 changes: 1 addition & 1 deletion templates/back/signalement/view/photos-documents.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<h3 class="fr-h5">{{ zonetitle }}</h3>
</div>
<div class="fr-col-3 fr-col-md-6 fr-text--right">
{% if (is_granted('FILE_CREATE', signalement)) %}
{% if (is_granted('SIGN_EDIT', signalement)) %}
<ul class="fr-btns-group fr-btns-group--inline fr-btns-group--sm fr-btns-group--right fr-btns-group--icon-left">
<li>
<button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
{% include 'back/signalement/view/visites/modals/visites-modal-reschedule.html.twig' %}
{% elseif intervention.status is same as constant('App\\Entity\\Intervention::STATUS_DONE') %}
{% include 'back/signalement/view/visites/modals/visites-modal-edit.html.twig' %}
{% if is_granted('FILE_CREATE', signalement) %}
{% if is_granted('SIGN_EDIT', signalement) %}
{% include 'back/signalement/view/visites/modals/visites-modal-upload-files.html.twig' %}
{% endif %}
{% endif %}
Expand Down
Loading

0 comments on commit b982a05

Please sign in to comment.