Gestion de droits d'accès

a marqué ce sujet comme résolu.

Bonjour,

J'ai une entité permettant de stocker des droits d'accès :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<?php
/**
 * @ORM\Table(name="PageAccess")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\BaseRepository")
 */
class PageAccess {

// ... champs pas montrés ici ...

/**
*@ORM\Column(type="simple_array", columnDefinition="set('view', 'edit', 'admin')")
*@Assert\Choice(multiple=true, choices={"view", "edit", "admin"})
*/
protected $access;

// ... constructeur et méthodes, pas montrés non plus ...

}

J'ai aussi un formulaire permettant aux super admins de modifier ces droits :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?php
class PageAccessItemType extends AbstractType { 

    public function buildForm(FormBuilderInterface $builder, array $options){
$builder
->add('user', 'FOS\UserBundle\Form\Type\UsernameFormType', array('label'=>'User'))
->add('access', ChoiceType::class, array('label'=>'AccessMode', 'expanded'=>true, 'multiple'=>true, 'choices'=>array('cb_view'=>'view', 'cb_edit'=>'edit', 'cb_admin'=>'admin')));
}

// ... suite ...

Du point de vue fonctionnel tout va bien. J'utilise un voteur pour faire respecter les droits d'accès. Ma question est plutôt d'ordre organisationnelle.

A trois reprises j'énumère les droits existants. D'abord deux fois de suite dans la classe d'entité. Une fois pour la structure de la base, et une fois pour la validation.

1
2
*@ORM\Column(type="simple_array", columnDefinition="set('view', 'edit', 'admin')")
*@Assert\Choice(multiple=true, choices={"view", "edit", "admin"})

ET encore une fois dans la classe du formulaire pour définir les options qu'il est possible de cocher :

1
->add('access', ChoiceType::class, array('label'=>'AccessMode', 'expanded'=>true, 'multiple'=>true, 'choices'=>array('cb_view'=>'view', 'cb_edit'=>'edit', 'cb_admin'=>'admin')));

Ma question: n'y a-t-il pas moyen de définir les différents droits existants qu'une seule et unique fois pour toute, à un seul endroit ? Peut-on par exemple référencer une information d'une annotation dans une autre annotation ? OU bien récupérer les informations provenant des annotations dans le code afin d'éviter les répétitions ?

Bien sûr je pourrais créer une entité supplémentaire, une entité qui représenterait un droit, avec juste son nom et son ID, mais je n'en vois vraiment pas l'intérêt sachant que la table contiendrait tout au plus une dizaine d'entrées, et ne changerait que très très rarement. En plus il me semble que ça complique pas mal la chose lorsqu'il s'agira de vérifier les droits. Car pour le moment avec ma construction, dans le voteur, il suffit de récupérer la ligne correspondant à l'utilisateur et la page en cours, et si elle existe, vérifier si le droit qu'on cherche est dans le tableau. Si oui donner accès, si non ou si la ligne n'existe carrément pas, ne pas donner accès. En passant par une entité représentant un droit, il faut d'abord requêter la table faisant la correspondance nom>ID, et seulement après on peut le chercher dans le tableau. Ca fait une étape idiote en plus je trouve.

Philosophiquement parlant, je pense que la liste des droits existants n'a pas à se trouver dans des tables de base de données vu que c'est quelque chose de relativement immuable, et invariant d'une instance de l'application à l'autre.

En PHP brut, j'aurais fait ça avec des flags, ou avec une colonne de type set comme j'essaie de le faire ici… Quelle est la bonne manière de le faire avec symfony ? Sans être obligé de se répéter 3 fois ?

Merci pour vos réponses.

+0 -0

Je ne crois pas qu'il existe dans Symfony de moyen particulier pour contourner ce problème, d'autant qu'à mon avis le champ columnDefinition de ton annotation @ORM\Column ne peut pas prendre de variable…

Si jamais tu peux renoncer à son champ - après tout tu as déjà la contrainte de validation -, tu peux utiliser un array constant statique dans lequel tu stockes tes clés - et éventuellement le texte associé à ces clés dans le formulaire en tant que valeurs de l'array - et l'appeler dans le formulaire ainsi que dans la contrainte avec le paramètre callback (via une méthode statique donc).

C'est pas super élégant, mais c'est potentiellement mieux que de la duplication de code.

+0 -0

Mouais, ça ne me satisfait que moyennement comme réponse. JE n'ai pas l'impression que ça simplifie grand chose. Dommage. Pour le moment je vais donc rester avec le code que j'ai actuellement.

Merci quand même.

Pas d'autre idée ?

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte