Merge branch 'main' into renovate/major-node-majeur
This commit is contained in:
commit
7b87aef501
@ -11,7 +11,7 @@ jobs:
|
|||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Run PHP CS Fixer
|
- name: Run PHP CS Fixer
|
||||||
uses: docker://oskarstark/php-cs-fixer-ga@sha256:6fbe82f34cafde58e7dc2a48ccf5854135edd456f5ee2c53a6199a706727cd1f
|
uses: docker://oskarstark/php-cs-fixer-ga@sha256:223e25a1681d3e5309f207022e17a980fe45a30b1eff3f32930cb9167e3caef9
|
||||||
with:
|
with:
|
||||||
args: --diff --dry-run
|
args: --diff --dry-run
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM dunglas/frankenphp@sha256:18a14f07c085a83e0c7d6c833f64d8733a78e656c0f2911400f9c6bc99ac3fd0
|
FROM dunglas/frankenphp@sha256:7a45fd0a4114256cc49da94503e6c60c88e491f2ef74fee983887bfd0a271af2
|
||||||
|
|
||||||
ENV SERVER_NAME=":80"
|
ENV SERVER_NAME=":80"
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
"ext-iconv": "*",
|
"ext-iconv": "*",
|
||||||
"doctrine/dbal": "^4.2.2",
|
"doctrine/dbal": "^4.2.2",
|
||||||
"doctrine/doctrine-bundle": "^2.13.2",
|
"doctrine/doctrine-bundle": "^2.13.2",
|
||||||
"doctrine/doctrine-migrations-bundle": "^3.4.0",
|
"doctrine/doctrine-migrations-bundle": "^3.4.1",
|
||||||
"doctrine/orm": "^3.3.1",
|
"doctrine/orm": "^3.3.2",
|
||||||
"league/flysystem": "^3.29.1",
|
"league/flysystem": "^3.29.1",
|
||||||
"oneup/flysystem-bundle": "^4.12.4",
|
"oneup/flysystem-bundle": "^4.12.4",
|
||||||
"phpdocumentor/reflection-docblock": "^5.6.1",
|
"phpdocumentor/reflection-docblock": "^5.6.1",
|
||||||
@ -51,10 +51,10 @@
|
|||||||
"symfony/web-link": "7.2.*",
|
"symfony/web-link": "7.2.*",
|
||||||
"symfony/yaml": "7.2.*",
|
"symfony/yaml": "7.2.*",
|
||||||
"symfonycasts/reset-password-bundle": "^1.23.1",
|
"symfonycasts/reset-password-bundle": "^1.23.1",
|
||||||
"symfonycasts/tailwind-bundle": "^0.7.0",
|
"symfonycasts/tailwind-bundle": "^0.7.1",
|
||||||
"tales-from-a-dev/flowbite-bundle": "^0.7.1",
|
"tales-from-a-dev/flowbite-bundle": "^0.7.1",
|
||||||
"twig/extra-bundle": "^2.12|^3.18",
|
"twig/extra-bundle": "^2.12|^3.19",
|
||||||
"twig/twig": "^2.12|^3.18"
|
"twig/twig": "^2.12|^3.19"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"allow-plugins": {
|
"allow-plugins": {
|
||||||
@ -109,11 +109,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"friendsofphp/php-cs-fixer": "^3.68.1",
|
"friendsofphp/php-cs-fixer": "^3.68.5",
|
||||||
"phpstan/extension-installer": "^1.4.3",
|
"phpstan/extension-installer": "^1.4.3",
|
||||||
"phpstan/phpstan-strict-rules": "^2.0.3",
|
"phpstan/phpstan-strict-rules": "^2.0.3",
|
||||||
"phpstan/phpstan-symfony": "^2.0.2",
|
"phpstan/phpstan-symfony": "^2.0.2",
|
||||||
"phpunit/phpunit": "^11.5.3",
|
"phpunit/phpunit": "^11.5.6",
|
||||||
"rector/rector": "^2.0.7",
|
"rector/rector": "^2.0.7",
|
||||||
"symfony/browser-kit": "7.2.*",
|
"symfony/browser-kit": "7.2.*",
|
||||||
"symfony/css-selector": "7.2.*",
|
"symfony/css-selector": "7.2.*",
|
||||||
|
447
composer.lock
generated
447
composer.lock
generated
File diff suppressed because it is too large
Load Diff
32
migrations/Version20250126120344.php
Normal file
32
migrations/Version20250126120344.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20250126120344 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('CREATE TABLE parent_directory_permission (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, role VARCHAR(255) NOT NULL, read BOOLEAN NOT NULL, write BOOLEAN NOT NULL, parent_directory_id INTEGER NOT NULL, CONSTRAINT FK_F93986627CFA5BB1 FOREIGN KEY (parent_directory_id) REFERENCES parent_directory (id) NOT DEFERRABLE INITIALLY IMMEDIATE)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_F93986627CFA5BB1 ON parent_directory_permission (parent_directory_id)');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('DROP TABLE parent_directory_permission');
|
||||||
|
}
|
||||||
|
}
|
@ -38,7 +38,7 @@ class CreateUserCommand extends Command
|
|||||||
$email = $io->ask('Email de l\'utilisateur');
|
$email = $io->ask('Email de l\'utilisateur');
|
||||||
$password = $io->askHidden('Mot de passe de l\'utilisateur');
|
$password = $io->askHidden('Mot de passe de l\'utilisateur');
|
||||||
$isAdmin = $io->confirm('Est-ce un administrateur ?');
|
$isAdmin = $io->confirm('Est-ce un administrateur ?');
|
||||||
$folderRole = $io->choice('Rôle du dossier', array_map(static fn ($role) => $role->value, RoleEnum::cases()), RoleEnum::VISITEUR->value);
|
$folderRole = $io->choice('Groupe', array_map(static fn ($role) => $role->value, RoleEnum::cases()), RoleEnum::VISITEUR->value);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$user = $this->userRepository->findOneBy(['email' => $email]);
|
$user = $this->userRepository->findOneBy(['email' => $email]);
|
||||||
|
@ -8,12 +8,14 @@ use App\Entity\ParentDirectory;
|
|||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use App\Enum\RoleEnum;
|
use App\Enum\RoleEnum;
|
||||||
use App\Form\CreateDirectoryType;
|
use App\Form\CreateDirectoryType;
|
||||||
|
use App\Form\FilePermissionType;
|
||||||
use App\Form\RenameType;
|
use App\Form\RenameType;
|
||||||
use App\Form\UploadType;
|
use App\Form\UploadType;
|
||||||
use App\Repository\ParentDirectoryRepository;
|
use App\Repository\ParentDirectoryRepository;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use League\Flysystem\Filesystem;
|
use League\Flysystem\Filesystem;
|
||||||
use League\Flysystem\FilesystemException;
|
use League\Flysystem\FilesystemException;
|
||||||
|
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||||
use Symfony\Component\HttpFoundation\HeaderUtils;
|
use Symfony\Component\HttpFoundation\HeaderUtils;
|
||||||
@ -43,21 +45,17 @@ class FilesController extends AbstractController
|
|||||||
public function index(Filesystem $defaultAdapter, UrlGeneratorInterface $urlGenerator, #[MapQueryParameter('path')] string $path = ''): Response
|
public function index(Filesystem $defaultAdapter, UrlGeneratorInterface $urlGenerator, #[MapQueryParameter('path')] string $path = ''): Response
|
||||||
{
|
{
|
||||||
$path = $this->normalizePath($path);
|
$path = $this->normalizePath($path);
|
||||||
/**
|
$this->getUser();
|
||||||
* @var User $user
|
|
||||||
*/
|
|
||||||
$user = $this->getUser();
|
|
||||||
|
|
||||||
if ('' !== $path) {
|
if ('' !== $path) {
|
||||||
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $path]);
|
$pathExploded = explode('/', $path);
|
||||||
|
|
||||||
|
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $pathExploded[0]]);
|
||||||
|
|
||||||
if (null === $parentDir || !$defaultAdapter->directoryExists($path)) {
|
if (null === $parentDir || !$defaultAdapter->directoryExists($path)) {
|
||||||
throw $this->createNotFoundException("Ce dossier n'existe pas !");
|
throw $this->createNotFoundException("Ce dossier n'existe pas !");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!$this->isGranted('file_read', $parentDir)) {
|
||||||
|
|
||||||
if (!$this->isGranted('file', $parentDir)) {
|
|
||||||
throw $this->createNotFoundException("Vous n'avez pas le droit d'accéder à ce dossier !");
|
throw $this->createNotFoundException("Vous n'avez pas le droit d'accéder à ce dossier !");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -72,15 +70,15 @@ class FilesController extends AbstractController
|
|||||||
// On vérifie si l'utilisateur a le droit d'accéder au fichier (vérifier que owner_role du parentDirectory correspondant est bien le folderRole de l'utilisateur)
|
// On vérifie si l'utilisateur a le droit d'accéder au fichier (vérifier que owner_role du parentDirectory correspondant est bien le folderRole de l'utilisateur)
|
||||||
$pathFile = explode('/', (string) $file['path']);
|
$pathFile = explode('/', (string) $file['path']);
|
||||||
if ('' !== $path) {
|
if ('' !== $path) {
|
||||||
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $pathFile[0]]);
|
$parentDirectory = $this->parentDirectoryRepository->findOneBy(['name' => $pathFile[0]]);
|
||||||
|
|
||||||
if (null === $parentDir || !$this->isGranted('file', $parentDir)) {
|
if (null === $parentDirectory || !$this->isGranted('file_read', $parentDirectory)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} elseif ('file' !== $file['type']) {
|
} elseif ('file' !== $file['type']) {
|
||||||
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $filename]);
|
$parentDirectory = $this->parentDirectoryRepository->findOneBy(['name' => $filename]);
|
||||||
|
|
||||||
if (null === $parentDir || !$this->isGranted('file', $parentDir)) {
|
if (null === $parentDirectory || !$this->isGranted('file_read', $parentDirectory)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,6 +106,7 @@ class FilesController extends AbstractController
|
|||||||
return $this->render('files/index.html.twig', [
|
return $this->render('files/index.html.twig', [
|
||||||
'files' => $realFiles,
|
'files' => $realFiles,
|
||||||
'path' => $path,
|
'path' => $path,
|
||||||
|
'parentDir' => $parentDir ?? null,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,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é
|
// Si l'owner role sur le parent est visiteur, on peut accéder au fichier sans être connecté
|
||||||
if (RoleEnum::VISITEUR !== $parentDir->getOwnerRole()) {
|
if (!$this->isGranted('file_read', $parentDir)) {
|
||||||
$this->denyAccessUnlessGranted('ROLE_USER');
|
throw $this->createNotFoundException("Vous n'avez pas le droit d'accéder à ce fichier !");
|
||||||
|
|
||||||
/**
|
|
||||||
* @var User $user
|
|
||||||
*/
|
|
||||||
$user = $this->getUser();
|
|
||||||
|
|
||||||
if (!$this->isGranted('file', $parentDir)) {
|
|
||||||
throw $this->createNotFoundException("Vous n'avez pas le droit d'accéder à ce fichier !");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$mimetype = $defaultAdapter->mimeType($file);
|
$mimetype = $defaultAdapter->mimeType($file);
|
||||||
@ -167,18 +157,16 @@ class FilesController extends AbstractController
|
|||||||
#[IsGranted('ROLE_USER')]
|
#[IsGranted('ROLE_USER')]
|
||||||
public function fileDelete(Filesystem $defaultAdapter, #[MapQueryParameter('filename')] string $filename): RedirectResponse
|
public function fileDelete(Filesystem $defaultAdapter, #[MapQueryParameter('filename')] string $filename): RedirectResponse
|
||||||
{
|
{
|
||||||
/**
|
$this->getUser();
|
||||||
* @var User $user
|
|
||||||
*/
|
|
||||||
$user = $this->getUser();
|
|
||||||
$file = $this->normalizePath($filename);
|
$file = $this->normalizePath($filename);
|
||||||
|
|
||||||
$realPath = explode('/', $file);
|
$realPath = explode('/', $file);
|
||||||
|
$parentDir = null;
|
||||||
|
|
||||||
if (count($realPath) > 1) {
|
if (count($realPath) > 1) {
|
||||||
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $realPath[0]]);
|
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $realPath[0]]);
|
||||||
|
|
||||||
if (null === $parentDir || !$this->isGranted('file', $parentDir)) {
|
if (null === $parentDir || !$this->isGranted('file_write', $parentDir)) {
|
||||||
throw $this->createNotFoundException("Vous n'avez pas le droit de supprimer ce fichier !");
|
throw $this->createNotFoundException("Vous n'avez pas le droit de supprimer ce fichier !");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,28 +192,35 @@ class FilesController extends AbstractController
|
|||||||
public function directoryDelete(Filesystem $defaultAdapter, #[MapQueryParameter('path')] string $path): RedirectResponse
|
public function directoryDelete(Filesystem $defaultAdapter, #[MapQueryParameter('path')] string $path): RedirectResponse
|
||||||
{
|
{
|
||||||
$path = $this->normalizePath($path);
|
$path = $this->normalizePath($path);
|
||||||
/**
|
$this->getUser();
|
||||||
* @var User $user
|
|
||||||
*/
|
|
||||||
$user = $this->getUser();
|
|
||||||
|
|
||||||
$realPath = explode('/', $path);
|
$realPath = explode('/', $path);
|
||||||
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $realPath[0]]);
|
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $realPath[0]]);
|
||||||
|
|
||||||
if (null === $parentDir || !$this->isGranted('file', $parentDir)) {
|
if (null === $parentDir || !$this->isGranted('file_write', $parentDir)) {
|
||||||
throw $this->createNotFoundException("Vous n'avez pas le droit de supprimer ce dossier !");
|
throw $this->createNotFoundException("Vous n'avez pas le droit de supprimer ce dossier !");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('' !== $path && !str_starts_with($path, '.') && $defaultAdapter->directoryExists($path)) {
|
if ('' !== $path && !str_starts_with($path, '.') && $defaultAdapter->directoryExists($path)) {
|
||||||
$defaultAdapter->deleteDirectory($path);
|
$defaultAdapter->deleteDirectory($path);
|
||||||
|
if ($parentDir->getName() === $path) {
|
||||||
|
$this->entityManager->remove($parentDir);
|
||||||
|
$this->entityManager->flush();
|
||||||
|
}
|
||||||
|
|
||||||
$this->addFlash('success', 'Le dossier a bien été supprimé.');
|
$this->addFlash('success', 'Le dossier a bien été supprimé.');
|
||||||
} else {
|
} else {
|
||||||
$this->addFlash('error', 'Le dossier n\'existe pas.');
|
$this->addFlash('error', 'Le dossier n\'existe pas.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$newPath = dirname($path);
|
||||||
|
|
||||||
|
if ('.' === $newPath) {
|
||||||
|
$newPath = '';
|
||||||
|
}
|
||||||
|
|
||||||
return $this->redirectToRoute('app_files_index', [
|
return $this->redirectToRoute('app_files_index', [
|
||||||
'path' => dirname($path),
|
'path' => $newPath,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,10 +232,7 @@ class FilesController extends AbstractController
|
|||||||
public function rename(#[MapQueryParameter('path')] string $filepath, Request $request, Filesystem $defaultAdapter): Response
|
public function rename(#[MapQueryParameter('path')] string $filepath, Request $request, Filesystem $defaultAdapter): Response
|
||||||
{
|
{
|
||||||
$filepath = $this->normalizePath($filepath);
|
$filepath = $this->normalizePath($filepath);
|
||||||
/**
|
$this->getUser();
|
||||||
* @var User $user
|
|
||||||
*/
|
|
||||||
$user = $this->getUser();
|
|
||||||
|
|
||||||
if ('' === $filepath || str_starts_with($filepath, '.') || !$defaultAdapter->fileExists($filepath)) {
|
if ('' === $filepath || str_starts_with($filepath, '.') || !$defaultAdapter->fileExists($filepath)) {
|
||||||
throw $this->createNotFoundException("Ce fichier n'existe pas !");
|
throw $this->createNotFoundException("Ce fichier n'existe pas !");
|
||||||
@ -251,7 +243,7 @@ class FilesController extends AbstractController
|
|||||||
if (count($realPath) > 1) {
|
if (count($realPath) > 1) {
|
||||||
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $realPath[0]]);
|
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $realPath[0]]);
|
||||||
|
|
||||||
if (null === $parentDir || !$this->isGranted('file', $parentDir)) {
|
if (null === $parentDir || !$this->isGranted('file_write', $parentDir)) {
|
||||||
throw $this->createNotFoundException("Vous n'avez pas le droit de renommer ce fichier !");
|
throw $this->createNotFoundException("Vous n'avez pas le droit de renommer ce fichier !");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -302,7 +294,7 @@ class FilesController extends AbstractController
|
|||||||
|
|
||||||
if (count($realPath) > 1) {
|
if (count($realPath) > 1) {
|
||||||
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $realPath[0]]);
|
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $realPath[0]]);
|
||||||
if (null === $parentDir || !$this->isGranted('file', $parentDir)) {
|
if (null === $parentDir || !$this->isGranted('file_write', $parentDir)) {
|
||||||
throw $this->createNotFoundException("Vous n'avez pas le droit de créer de sous-dossier dans ce dossier !");
|
throw $this->createNotFoundException("Vous n'avez pas le droit de créer de sous-dossier dans ce dossier !");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -368,15 +360,12 @@ class FilesController extends AbstractController
|
|||||||
public function renameDirectory(#[MapQueryParameter('path')] string $filepath, Request $request, Filesystem $defaultAdapter): Response
|
public function renameDirectory(#[MapQueryParameter('path')] string $filepath, Request $request, Filesystem $defaultAdapter): Response
|
||||||
{
|
{
|
||||||
$filepath = $this->normalizePath($filepath);
|
$filepath = $this->normalizePath($filepath);
|
||||||
/**
|
$this->getUser();
|
||||||
* @var User $user
|
|
||||||
*/
|
|
||||||
$user = $this->getUser();
|
|
||||||
|
|
||||||
$realPath = explode('/', $filepath);
|
$realPath = explode('/', $filepath);
|
||||||
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $realPath[0]]);
|
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $realPath[0]]);
|
||||||
|
|
||||||
if (null === $parentDir || !$this->isGranted('file', $parentDir)) {
|
if (null === $parentDir || !$this->isGranted('file_write', $parentDir)) {
|
||||||
throw $this->createNotFoundException("Vous n'avez pas le droit de renommer ce dossier !");
|
throw $this->createNotFoundException("Vous n'avez pas le droit de renommer ce dossier !");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,10 +412,7 @@ class FilesController extends AbstractController
|
|||||||
{
|
{
|
||||||
$path = $this->normalizePath($path);
|
$path = $this->normalizePath($path);
|
||||||
|
|
||||||
/**
|
$this->getUser();
|
||||||
* @var User $user
|
|
||||||
*/
|
|
||||||
$user = $this->getUser();
|
|
||||||
|
|
||||||
if ('' === $path) {
|
if ('' === $path) {
|
||||||
throw $this->createNotFoundException("Vous ne pouvez pas uploader de fichier à la racine !");
|
throw $this->createNotFoundException("Vous ne pouvez pas uploader de fichier à la racine !");
|
||||||
@ -435,7 +421,7 @@ class FilesController extends AbstractController
|
|||||||
$realPath = explode('/', $path);
|
$realPath = explode('/', $path);
|
||||||
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $realPath[0]]);
|
$parentDir = $this->parentDirectoryRepository->findOneBy(['name' => $realPath[0]]);
|
||||||
|
|
||||||
if (null === $parentDir || !$this->isGranted('file', $parentDir)) {
|
if (null === $parentDir || !$this->isGranted('file_write', $parentDir)) {
|
||||||
throw $this->createNotFoundException("Vous n'avez pas le droit d'uploader des fichiers dans ce dossier !");
|
throw $this->createNotFoundException("Vous n'avez pas le droit d'uploader des fichiers dans ce dossier !");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -478,7 +464,55 @@ class FilesController extends AbstractController
|
|||||||
$path = trim($path, '/');
|
$path = trim($path, '/');
|
||||||
// On retire les chemins relatifs
|
// On retire les chemins relatifs
|
||||||
$path = str_replace('..', '', $path);
|
$path = str_replace('..', '', $path);
|
||||||
|
// On retire les . qui sont seul dans la chaîne, en vérifiant qu'il n'y a pas de lettre avant ou après
|
||||||
|
$path = preg_replace('/(?<!\w)\.(?!\w)/', '', $path);
|
||||||
|
|
||||||
return str_replace('//', '/', $path);
|
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(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,8 @@ namespace App\Entity;
|
|||||||
|
|
||||||
use App\Enum\RoleEnum;
|
use App\Enum\RoleEnum;
|
||||||
use App\Repository\ParentDirectoryRepository;
|
use App\Repository\ParentDirectoryRepository;
|
||||||
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
|
use Doctrine\Common\Collections\Collection;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
#[ORM\Entity(repositoryClass: ParentDirectoryRepository::class)]
|
#[ORM\Entity(repositoryClass: ParentDirectoryRepository::class)]
|
||||||
@ -29,6 +31,17 @@ class ParentDirectory
|
|||||||
#[ORM\Column]
|
#[ORM\Column]
|
||||||
private ?bool $isPublic = null;
|
private ?bool $isPublic = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Collection<int, ParentDirectoryPermission>
|
||||||
|
*/
|
||||||
|
#[ORM\OneToMany(targetEntity: ParentDirectoryPermission::class, mappedBy: 'parentDirectory', orphanRemoval: true)]
|
||||||
|
private Collection $parentDirectoryPermissions;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->parentDirectoryPermissions = new ArrayCollection();
|
||||||
|
}
|
||||||
|
|
||||||
public function getId(): ?int
|
public function getId(): ?int
|
||||||
{
|
{
|
||||||
return $this->id;
|
return $this->id;
|
||||||
@ -81,4 +94,32 @@ class ParentDirectory
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<int, ParentDirectoryPermission>
|
||||||
|
*/
|
||||||
|
public function getParentDirectoryPermissions(): Collection
|
||||||
|
{
|
||||||
|
return $this->parentDirectoryPermissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addParentDirectoryPermission(ParentDirectoryPermission $parentDirectoryPermission): static
|
||||||
|
{
|
||||||
|
if (!$this->parentDirectoryPermissions->contains($parentDirectoryPermission)) {
|
||||||
|
$this->parentDirectoryPermissions->add($parentDirectoryPermission);
|
||||||
|
$parentDirectoryPermission->setParentDirectory($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeParentDirectoryPermission(ParentDirectoryPermission $parentDirectoryPermission): static
|
||||||
|
{
|
||||||
|
// set the owning side to null (unless already changed)
|
||||||
|
if ($this->parentDirectoryPermissions->removeElement($parentDirectoryPermission) && $parentDirectoryPermission->getParentDirectory() === $this) {
|
||||||
|
$parentDirectoryPermission->setParentDirectory(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
84
src/Entity/ParentDirectoryPermission.php
Normal file
84
src/Entity/ParentDirectoryPermission.php
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Entity;
|
||||||
|
|
||||||
|
use App\Enum\RoleEnum;
|
||||||
|
use App\Repository\ParentDirectoryPermissionRepository;
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
#[ORM\Entity(repositoryClass: ParentDirectoryPermissionRepository::class)]
|
||||||
|
class ParentDirectoryPermission
|
||||||
|
{
|
||||||
|
#[ORM\Id]
|
||||||
|
#[ORM\GeneratedValue]
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?int $id = null;
|
||||||
|
|
||||||
|
#[ORM\Column(enumType: RoleEnum::class)]
|
||||||
|
private ?RoleEnum $role = null;
|
||||||
|
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?bool $read = null;
|
||||||
|
|
||||||
|
#[ORM\Column]
|
||||||
|
private ?bool $write = null;
|
||||||
|
|
||||||
|
#[ORM\ManyToOne(inversedBy: 'parentDirectoryPermissions')]
|
||||||
|
#[ORM\JoinColumn(nullable: false)]
|
||||||
|
private ?ParentDirectory $parentDirectory = null;
|
||||||
|
|
||||||
|
public function getId(): ?int
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRole(): ?RoleEnum
|
||||||
|
{
|
||||||
|
return $this->role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setRole(RoleEnum $role): static
|
||||||
|
{
|
||||||
|
$this->role = $role;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isRead(): ?bool
|
||||||
|
{
|
||||||
|
return $this->read;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setRead(bool $read): static
|
||||||
|
{
|
||||||
|
$this->read = $read;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isWrite(): ?bool
|
||||||
|
{
|
||||||
|
return $this->write;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setWrite(bool $write): static
|
||||||
|
{
|
||||||
|
$this->write = $write;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParentDirectory(): ?ParentDirectory
|
||||||
|
{
|
||||||
|
return $this->parentDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setParentDirectory(?ParentDirectory $parentDirectory): static
|
||||||
|
{
|
||||||
|
$this->parentDirectory = $parentDirectory;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
@ -32,4 +32,22 @@ enum RoleEnum: string
|
|||||||
|
|
||||||
return $roles;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
51
src/Form/FilePermissionType.php
Normal file
51
src/Form/FilePermissionType.php
Normal 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,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
42
src/Form/ParentDirectoryPermissionType.php
Normal file
42
src/Form/ParentDirectoryPermissionType.php
Normal 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,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -5,9 +5,11 @@ declare(strict_types=1);
|
|||||||
namespace App\Form;
|
namespace App\Form;
|
||||||
|
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
|
use App\Enum\RoleEnum;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
use Symfony\Component\Form\Extension\Core\Type\EmailType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\EnumType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
|
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
@ -18,9 +20,16 @@ class UserAdminType extends AbstractType
|
|||||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||||
{
|
{
|
||||||
$builder
|
$builder
|
||||||
|
->add('fullname', null, [
|
||||||
|
'label' => 'Nom complet',
|
||||||
|
])
|
||||||
->add('email', EmailType::class, [
|
->add('email', EmailType::class, [
|
||||||
'label' => 'Adresse email',
|
'label' => 'Adresse email',
|
||||||
])
|
])
|
||||||
|
->add('folderRole', EnumType::class, [
|
||||||
|
'label' => 'Groupe',
|
||||||
|
'class' => RoleEnum::class,
|
||||||
|
])
|
||||||
->add('role', ChoiceType::class, [
|
->add('role', ChoiceType::class, [
|
||||||
'label' => 'Rôle',
|
'label' => 'Rôle',
|
||||||
'choices' => [
|
'choices' => [
|
||||||
|
45
src/Repository/ParentDirectoryPermissionRepository.php
Normal file
45
src/Repository/ParentDirectoryPermissionRepository.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Repository;
|
||||||
|
|
||||||
|
use App\Entity\ParentDirectoryPermission;
|
||||||
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends ServiceEntityRepository<ParentDirectoryPermission>
|
||||||
|
*/
|
||||||
|
class ParentDirectoryPermissionRepository extends ServiceEntityRepository
|
||||||
|
{
|
||||||
|
public function __construct(ManagerRegistry $registry)
|
||||||
|
{
|
||||||
|
parent::__construct($registry, ParentDirectoryPermission::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * @return ParentDirectoryPermission[] Returns an array of ParentDirectoryPermission objects
|
||||||
|
// */
|
||||||
|
// public function findByExampleField($value): array
|
||||||
|
// {
|
||||||
|
// return $this->createQueryBuilder('p')
|
||||||
|
// ->andWhere('p.exampleField = :val')
|
||||||
|
// ->setParameter('val', $value)
|
||||||
|
// ->orderBy('p.id', 'ASC')
|
||||||
|
// ->setMaxResults(10)
|
||||||
|
// ->getQuery()
|
||||||
|
// ->getResult()
|
||||||
|
// ;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public function findOneBySomeField($value): ?ParentDirectoryPermission
|
||||||
|
// {
|
||||||
|
// return $this->createQueryBuilder('p')
|
||||||
|
// ->andWhere('p.exampleField = :val')
|
||||||
|
// ->setParameter('val', $value)
|
||||||
|
// ->getQuery()
|
||||||
|
// ->getOneOrNullResult()
|
||||||
|
// ;
|
||||||
|
// }
|
||||||
|
}
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace App\Security\Voter;
|
namespace App\Security\Voter;
|
||||||
|
|
||||||
use App\Entity\ParentDirectory;
|
use App\Entity\ParentDirectory;
|
||||||
|
use App\Entity\ParentDirectoryPermission;
|
||||||
use App\Entity\User;
|
use App\Entity\User;
|
||||||
use App\Enum\RoleEnum;
|
use App\Enum\RoleEnum;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
@ -25,13 +26,33 @@ final class FileVoter extends Voter
|
|||||||
*/
|
*/
|
||||||
$realSubject = $subject;
|
$realSubject = $subject;
|
||||||
$user = $token->getUser();
|
$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) {
|
if (!$user instanceof User) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
$parentDirectoryPermissions = array_filter($realSubject->getParentDirectoryPermissions()->toArray(), static fn (ParentDirectoryPermission $parentDirectoryPermission) => $parentDirectoryPermission->getRole() === $user->getFolderRole());
|
||||||
|
|
||||||
|
$parentDirectoryPermission = null;
|
||||||
|
|
||||||
|
if ([] !== $parentDirectoryPermissions) {
|
||||||
|
$parentDirectoryPermission = array_values($parentDirectoryPermissions)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
$checkNeeded = false;
|
||||||
|
|
||||||
|
if (null !== $parentDirectoryPermission) {
|
||||||
|
$checkNeeded = 'file_read' === $attribute ? $parentDirectoryPermission->isRead() : $parentDirectoryPermission->isWrite();
|
||||||
|
}
|
||||||
|
|
||||||
if ($realSubject->getUserCreated() === $user) {
|
if ($realSubject->getUserCreated() === $user) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return $realSubject->isPublic() && ($realSubject->getOwnerRole() === $user->getFolderRole() || in_array($user->getFolderRole(), $realSubject->getOwnerRole()->getHigherRoles(), true));
|
return $realSubject->isPublic() && ($checkNeeded || $realSubject->getOwnerRole() === $user->getFolderRole() || in_array($user->getFolderRole(), $realSubject->getOwnerRole()->getHigherRoles(), true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
20
src/Twig/Extension/EntityExtension.php
Normal file
20
src/Twig/Extension/EntityExtension.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Twig\Extension;
|
||||||
|
|
||||||
|
use App\Twig\Runtime\EntityExtensionRuntime;
|
||||||
|
use Twig\Extension\AbstractExtension;
|
||||||
|
use Twig\TwigFilter;
|
||||||
|
use Twig\TwigFunction;
|
||||||
|
|
||||||
|
class EntityExtension extends AbstractExtension
|
||||||
|
{
|
||||||
|
public function getFunctions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new TwigFunction('get_parent_dir', [EntityExtensionRuntime::class, 'getParentDir']),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
22
src/Twig/Runtime/EntityExtensionRuntime.php
Normal file
22
src/Twig/Runtime/EntityExtensionRuntime.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Twig\Runtime;
|
||||||
|
|
||||||
|
use App\Entity\ParentDirectory;
|
||||||
|
use App\Repository\ParentDirectoryRepository;
|
||||||
|
use Twig\Extension\RuntimeExtensionInterface;
|
||||||
|
|
||||||
|
class EntityExtensionRuntime implements RuntimeExtensionInterface
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly ParentDirectoryRepository $parentDirectoryRepository
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParentDir(string $value): ParentDirectory
|
||||||
|
{
|
||||||
|
return $this->parentDirectoryRepository->findOneBy(['name' => $value]);
|
||||||
|
}
|
||||||
|
}
|
37
templates/files/file_edit.html.twig
Normal file
37
templates/files/file_edit.html.twig
Normal 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 %}
|
@ -8,6 +8,7 @@
|
|||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
{{ include('partials/alerts.html.twig') }}
|
{{ include('partials/alerts.html.twig') }}
|
||||||
</div>
|
</div>
|
||||||
|
{% if parentDir == null or (parentDir != null and is_granted('file_write', parentDir)) %}
|
||||||
<div class="flex justify-end">
|
<div class="flex justify-end">
|
||||||
<a href="{{ path('app_files_create_directory', {
|
<a href="{{ path('app_files_create_directory', {
|
||||||
base: path
|
base: path
|
||||||
@ -18,6 +19,7 @@
|
|||||||
}) }}" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800">Ajouter des fichiers</a>
|
}) }}" class="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800">Ajouter des fichiers</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
{% include 'partials/breadbrumb.html.twig' %}
|
{% include 'partials/breadbrumb.html.twig' %}
|
||||||
</div>
|
</div>
|
||||||
@ -62,6 +64,7 @@
|
|||||||
<td class="px-6 py-4 flex gap-2 light:text-black">
|
<td class="px-6 py-4 flex gap-2 light:text-black">
|
||||||
{% if file.type == 'file' %}
|
{% if file.type == 'file' %}
|
||||||
<a title="Permet de télécharger le fichier" href="{{ file.url }}" class="hover:text-blue-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:download" /></a>
|
<a title="Permet de télécharger le fichier" href="{{ file.url }}" class="hover:text-blue-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:download" /></a>
|
||||||
|
{% if is_granted('file_write', parentDir) %}
|
||||||
<a title="Permet de renommer le fichier" href="{{ path('app_files_rename', {
|
<a title="Permet de renommer le fichier" href="{{ path('app_files_rename', {
|
||||||
path: file.path
|
path: file.path
|
||||||
}) }}" class="hover:text-blue-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:pencil" /></a>
|
}) }}" class="hover:text-blue-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:pencil" /></a>
|
||||||
@ -70,13 +73,27 @@
|
|||||||
filename: file.path
|
filename: file.path
|
||||||
})
|
})
|
||||||
}}" class="hover:text-red-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:trash-can" /></a>
|
}}" class="hover:text-red-700 duration-300"><twig:ux:icon class="w-6 h-6" name="fa6-solid:trash-can" /></a>
|
||||||
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
{% if parentDir == null %}
|
||||||
|
{% set parentDirectory = get_parent_dir(file.path) %}
|
||||||
|
{% 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', {
|
<a href="{{ path('app_files_rename-directory', {
|
||||||
path: file.path
|
path: file.path
|
||||||
}) }}" class="hover:text-blue-700 duration-300" title="Permet de renommer le dossier"><twig:ux:icon class="w-6 h-6" name="fa6-solid:pencil" /></a>
|
}) }}" class="hover:text-blue-700 duration-300" title="Permet de renommer le dossier"><twig:ux:icon class="w-6 h-6" name="fa6-solid:pencil" /></a>
|
||||||
<a href="{{ path('app_files_delete_directory', {
|
<a href="{{ path('app_files_delete_directory', {
|
||||||
path: file.path
|
path: file.path
|
||||||
}) }}" class="hover:text-red-700 duration-300" title="Permet de supprimer le dossier"><twig:ux:icon class="w-6 h-6" name="fa6-solid:trash-can" /></a>
|
}) }}" class="hover:text-red-700 duration-300" title="Permet de supprimer le dossier"><twig:ux:icon class="w-6 h-6" name="fa6-solid:trash-can" /></a>
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user