diff --git a/src/Controller/FilesController.php b/src/Controller/FilesController.php index 1d6a90a..66744f0 100755 --- a/src/Controller/FilesController.php +++ b/src/Controller/FilesController.php @@ -8,12 +8,14 @@ use App\Entity\ParentDirectory; use App\Entity\User; use App\Enum\RoleEnum; use App\Form\CreateDirectoryType; +use App\Form\FilePermissionType; use App\Form\RenameType; use App\Form\UploadType; use App\Repository\ParentDirectoryRepository; use Doctrine\ORM\EntityManagerInterface; use League\Flysystem\Filesystem; use League\Flysystem\FilesystemException; +use Symfony\Bridge\Doctrine\Attribute\MapEntity; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\HeaderUtils; @@ -45,7 +47,9 @@ class FilesController extends AbstractController $path = $this->normalizePath($path); $this->getUser(); if ('' !== $path) { - $parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $path]); + $pathExploded = explode('/', $path); + + $parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $pathExploded[0]]); if (null === $parentDir || !$defaultAdapter->directoryExists($path)) { throw $this->createNotFoundException("Ce dossier n'existe pas !"); @@ -121,17 +125,8 @@ class FilesController extends AbstractController } // Si l'owner role sur le parent est visiteur, on peut accéder au fichier sans être connecté - if (RoleEnum::VISITEUR !== $parentDir->getOwnerRole()) { - $this->denyAccessUnlessGranted('ROLE_USER'); - - /** - * @var User $user - */ - $user = $this->getUser(); - - if (!$this->isGranted('file_read', $parentDir)) { - throw $this->createNotFoundException("Vous n'avez pas le droit d'accéder à ce fichier !"); - } + if (!$this->isGranted('file_read', $parentDir)) { + throw $this->createNotFoundException("Vous n'avez pas le droit d'accéder à ce fichier !"); } $mimetype = $defaultAdapter->mimeType($file); @@ -474,4 +469,50 @@ class FilesController extends AbstractController return str_replace('//', '/', $path); } + + #[Route('/file-edit-permission/{parentDir}', name: 'file_edit_permission')] + #[IsGranted('ROLE_USER')] + public function fileRead(#[MapEntity(mapping: ['parentDir' => 'name'])] ParentDirectory $parentDir, Request $request): Response + { + /** + * @var User $user + */ + $user = $this->getUser(); + + // 2 possibilités : soit l'utilisateur est le créateur du dossier, soit le dossier est public et l'utilisateur a le role Conseil d'administration + // Si ce n'est pas le cas, on redirige vers la page d'accueil + if ($parentDir->getUserCreated() !== $user) { + if ($parentDir->isPublic() && RoleEnum::CONSEIL_ADMINISTRATION !== $user->getFolderRole()) { + $this->addFlash('error', 'Vous n\'avez pas le droit de modifier les permissions de ce dossier.'); + return $this->redirectToRoute('app_files_index'); + } elseif (!$parentDir->isPublic()) { + $this->addFlash('error', 'Vous n\'avez pas le droit de modifier les permissions de ce dossier.'); + return $this->redirectToRoute('app_files_index'); + } + } + + $form = $this->createForm(FilePermissionType::class, $parentDir); + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $datas = $form->getData(); + + foreach ($datas->getParentDirectoryPermissions() as $parentPerm) { + $this->entityManager->persist($parentPerm); + } + $this->entityManager->persist($datas); + + $this->entityManager->flush(); + + $this->addFlash('success', 'Les permissions ont bien été modifiées.'); + + return $this->redirectToRoute('app_files_index'); + } + + return $this->render('files/file_edit.html.twig', [ + 'parentDir' => $parentDir, + 'form' => $form->createView(), + ]); + } } diff --git a/src/Enum/RoleEnum.php b/src/Enum/RoleEnum.php index f621c4f..5d674e6 100644 --- a/src/Enum/RoleEnum.php +++ b/src/Enum/RoleEnum.php @@ -32,4 +32,22 @@ enum RoleEnum: string return $roles; } + + public function getInferiorRoles(): array + { + $roles = []; + + $isFound = false; + foreach (RoleEnum::cases() as $role) { + if ($role === $this) { + $isFound = true; + } + + if ($isFound) { + $roles[] = $role; + } + } + + return $roles; + } } diff --git a/src/Form/FilePermissionType.php b/src/Form/FilePermissionType.php new file mode 100644 index 0000000..05e57ab --- /dev/null +++ b/src/Form/FilePermissionType.php @@ -0,0 +1,51 @@ +add('ownerRole', EnumType::class, [ + 'class' => RoleEnum::class, + 'label' => 'Rôle minimum', + ]) + ->add('isPublic', null, [ + 'label' => 'Dossier public', + ]) + ->add('parentDirectoryPermissions', CollectionType::class, [ + 'entry_type' => ParentDirectoryPermissionType::class, + 'entry_options' => [ + 'label' => false, + ], + 'allow_add' => true, + 'allow_delete' => true, + 'by_reference' => false, + ]) + ->add('submit', SubmitType::class, [ + 'label' => 'Enregistrer', + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => ParentDirectory::class, + ]); + } +} diff --git a/src/Form/ParentDirectoryPermissionType.php b/src/Form/ParentDirectoryPermissionType.php new file mode 100644 index 0000000..df63647 --- /dev/null +++ b/src/Form/ParentDirectoryPermissionType.php @@ -0,0 +1,42 @@ +add('role', EnumType::class, [ + 'class' => RoleEnum::class, + 'label' => 'Rôle', + ]) + ->add('read', null, [ + 'label' => 'Lecture', + ]) + ->add('write', null, [ + 'label' => 'Écriture', + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => ParentDirectoryPermission::class, + ]); + } +} diff --git a/src/Security/Voter/FileVoter.php b/src/Security/Voter/FileVoter.php index 6501b39..f520b36 100644 --- a/src/Security/Voter/FileVoter.php +++ b/src/Security/Voter/FileVoter.php @@ -26,10 +26,16 @@ final class FileVoter extends Voter */ $realSubject = $subject; $user = $token->getUser(); + + $parentDirectoryPermissionsVisiteurRead = array_filter($realSubject->getParentDirectoryPermissions()->toArray(), static fn (ParentDirectoryPermission $parentDirectoryPermission) => RoleEnum::VISITEUR === $parentDirectoryPermission->getRole()); + + if ([] !== $parentDirectoryPermissionsVisiteurRead && !($user instanceof User)) { + return 'file_read' === $attribute && array_values($parentDirectoryPermissionsVisiteurRead)[0]->isRead(); + } + if (!$user instanceof User) { return false; } - $parentDirectoryPermissions = array_filter($realSubject->getParentDirectoryPermissions()->toArray(), static fn (ParentDirectoryPermission $parentDirectoryPermission) => $parentDirectoryPermission->getRole() === $user->getFolderRole()); $parentDirectoryPermission = null; diff --git a/templates/files/file_edit.html.twig b/templates/files/file_edit.html.twig new file mode 100644 index 0000000..d333af0 --- /dev/null +++ b/templates/files/file_edit.html.twig @@ -0,0 +1,37 @@ +{% extends 'base.html.twig' %} + +{% block body %} +