diff --git a/assets/app.js b/assets/app.js
index cbcfb63..0706665 100644
--- a/assets/app.js
+++ b/assets/app.js
@@ -47,17 +47,21 @@ if (! location.pathname.includes('login')) {
const userMenu = document.querySelector('.dropdown-trigger');
const userCaret = document.querySelector('#user-caret');
- document.querySelector('#for-vocabs').addEventListener('click', function () {
- vocabs.classList.toggle('is-hidden');
+ const forVocabs = document.querySelector('#for-vocabs')
+
+ if (forVocabs) {
+ forVocabs.addEventListener('click', function () {
+ vocabs.classList.toggle('is-hidden');
- if (this.firstElementChild.classList.contains('fa-angle-right')) {
- this.firstElementChild.classList.remove('fa-angle-right');
- this.firstElementChild.classList.add('fa-angle-down');
- } else {
- this.firstElementChild.classList.remove('fa-angle-down');
- this.firstElementChild.classList.add('fa-angle-right');
- }
- });
+ if (this.firstElementChild.classList.contains('fa-angle-right')) {
+ this.firstElementChild.classList.remove('fa-angle-right');
+ this.firstElementChild.classList.add('fa-angle-down');
+ } else {
+ this.firstElementChild.classList.remove('fa-angle-down');
+ this.firstElementChild.classList.add('fa-angle-right');
+ }
+ });
+ }
userMenu.addEventListener('click', function () {
document.querySelector('.dropdown').classList.toggle('is-active');
diff --git a/src/Controller/VocabFuncContextController.php b/src/Controller/VocabFuncContextController.php
index cde3520..b323c2c 100644
--- a/src/Controller/VocabFuncContextController.php
+++ b/src/Controller/VocabFuncContextController.php
@@ -3,12 +3,14 @@
namespace App\Controller;
use App\Entity\VocabFuncContext;
-use App\Repository\VocabFuncContextRepository;
+use App\Security\Voter\VocabVoter;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
+use Symfony\Component\Security\Core\Exception\AccessDeniedException;
+use Symfony\Component\Security\Http\Attribute\IsGranted;
class VocabFuncContextController extends AbstractController
{
@@ -17,10 +19,8 @@ class VocabFuncContextController extends AbstractController
{
$roles = $this->getUser()->getRoles();
- if (! in_array('ROLE_REVISOR', $roles)
- && ! in_array('ROLE_ADMIN', $roles)
- ) {
- $this->addFlash('warning', 'Only revisors and administrators can edit vocabularies');
+ if (in_array('ROLE_READER', $roles)) {
+ $this->addFlash('warning', 'Only editors, revisors and administrators can view vocabularies');
return $this->redirectToRoute('app_home');
}
@@ -35,9 +35,16 @@ class VocabFuncContextController extends AbstractController
#[Route('/vocabs/functional_context/add', name: 'app_vocab_func_context_add')]
public function addTerm(Request $request, EntityManagerInterface $em): Response
{
- $term = $request->getPayload()->get('_term');
-
$vocab = new VocabFuncContext;
+ try {
+ $this->denyAccessUnlessGranted(VocabVoter::EDIT, $vocab);
+ }
+ catch (AccessDeniedException) {
+ $this->addFlash('warning', 'Only revisors and administrators can edit vocabularies');
+ return $this->redirectToRoute('app_home');
+ }
+
+ $term = $request->getPayload()->get('_term');
$vocab->setTerm($term);
$em->persist($vocab);
$em->flush();
diff --git a/src/Entity/VocabFuncContext.php b/src/Entity/VocabFuncContext.php
index 710809f..2baf29a 100644
--- a/src/Entity/VocabFuncContext.php
+++ b/src/Entity/VocabFuncContext.php
@@ -7,7 +7,7 @@ use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity()]
#[ORM\Table(name: 'lis_contesto_funz')]
-class VocabFuncContext
+class VocabFuncContext implements \App\VocabInterface
{
#[ORM\Id]
#[ORM\GeneratedValue]
diff --git a/src/Security/Voter/VocabVoter.php b/src/Security/Voter/VocabVoter.php
new file mode 100644
index 0000000..3fa3537
--- /dev/null
+++ b/src/Security/Voter/VocabVoter.php
@@ -0,0 +1,49 @@
+getUser();
+
+ // if the user is anonymous, do not grant access
+ if (!$user instanceof UserInterface) {
+ return false;
+ }
+
+ $roles = $user->getRoles();
+
+ // TODO: Better way to check roles?
+ switch ($attribute) {
+ case self::EDIT:
+ case self::DELETE:
+ return in_array('ROLE_ADMIN', $roles)
+ || in_array('ROLE_REVISOR', $roles);
+ break;
+
+ case self::VIEW:
+ return ! in_array('ROLE_READER', $roles);
+ break;
+ }
+
+ return false;
+ }
+}
diff --git a/src/VocabInterface.php b/src/VocabInterface.php
new file mode 100644
index 0000000..6f0782c
--- /dev/null
+++ b/src/VocabInterface.php
@@ -0,0 +1,7 @@
+
Profile
- {% if 'ROLE_ADMIN' in app.user.roles %}
+ {% if is_granted('ROLE_ADMIN') %}
@@ -57,6 +57,7 @@