fix perm
All checks were successful
Apply PHP CS Fixer / php-cs-fixer (push) Successful in 21s
CI / build-test (push) Successful in 1m34s
rector / Rector (push) Successful in 1m13s

This commit is contained in:
Melaine Gérard 2025-01-26 15:18:22 +01:00
parent 2b52d18da5
commit 9ecc72628c
7 changed files with 214 additions and 13 deletions

View File

@ -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(),
]);
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
namespace App\Form;
use App\Entity\ParentDirectory;
use App\Entity\User;
use App\Enum\RoleEnum;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\EnumType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class FilePermissionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->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,
]);
}
}

View File

@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
namespace App\Form;
use App\Entity\ParentDirectory;
use App\Entity\ParentDirectoryPermission;
use App\Entity\User;
use App\Enum\RoleEnum;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EnumType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ParentDirectoryPermissionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->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,
]);
}
}

View File

@ -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;

View File

@ -0,0 +1,37 @@
{% extends 'base.html.twig' %}
{% block body %}
<div class="container mx-auto px-16 mt-4">
<div class="block p-6 bg-white border border-gray-200 rounded-lg shadow dark:bg-gray-800 dark:border-gray-700">
<h3 class="mb-2 text-2xl font-bold tracking-tight text-gray-900 dark:text-white">Gérer les permissions du dossier {{ parentDir.name }}</h3>
{{ form_start(form) }}
{{ form_row(form.ownerRole) }}
{{ form_row(form.isPublic) }}
{{ form_label(form.parentDirectoryPermissions) }}
{{ form_widget(form.parentDirectoryPermissions) }}
<button type="button" id="add-parentDirectoryPermissions" class="py-2.5 px-5 me-2 mb-2 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-blue-700 focus:z-10 focus:ring-4 focus:ring-gray-100 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700">Ajouter</button>
{{ form_end(form) }}
</div>
</div>
{% endblock %}
{% block title %}
Gérer les permissions du dossier {{ parentDir.name }}
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script>
document.addEventListener('readystatechange', (e) => {
if (document.readyState === "complete") {
document.querySelector('#add-parentDirectoryPermissions').addEventListener('click', function() {
const container = document.querySelector('#file_permission_parentDirectoryPermissions');
const prototype = container.dataset.prototype;
const index = container.children.length;
container.insertAdjacentHTML('beforeend', prototype.replace(/__name__/g, index));
});
}
})
</script>
{% endblock %}

View File

@ -80,6 +80,12 @@
{% else %}
{% set parentDirectory = parentDir %}
{% endif %}
{% if parentDir == null and (parentDirectory.userCreated == app.user or (parentDirectory.isPublic and app.user.folderRole == enum('App\\Enum\\RoleEnum').CONSEIL_ADMINISTRATION)) %}
<a href="{{ path('app_files_file_edit_permission', {
parentDir: parentDirectory.name,
}) }}" class="hover:text-blue-700 duration-300" title="Permet de renommer le dossier"><twig:ux:icon class="w-6 h-6" name="fa6-solid:shield" /></a>
{% endif %}
{% if is_granted('file_write', parentDirectory) %}
<a href="{{ path('app_files_rename-directory', {
path: file.path