Sujet : Hoa_Acl et Base de donnée

(Re)Bonjour,

Hé oui ! Encore une question smile Quoique ici ça s'apparente plus à des précisions/imprécisions sur le package Hoa_Acl.

Je ne connaissais pas la gestion des droits de cette manière et c'est d'ailleurs un des éléments qui m'a beaucoup séduit chez Hoa. Cependant je n'aurais pas résonner de cette manière et c'est peut-être pour cela que j'ai quelques difficultés à mettre ce système parfaitement en place.

Reprenons l'exemple décrit dans le manuel que je réexplique brièvement car c'est là que se situe mon problème. Le groupe admin est indépendant ainsi que le groupe staff. Ce dernier à quant à lui 3 sous-groupes. Editor, adman et editorSpec. EditorSpec est lui-meme un sous-groupe de adman.

Si on traduit ça, ça donne: "Editor et adman sont des personnes du staff et que editorSpec est une personne du staff et c'est également un éditeur spécial".

Si on ajoute des droits aux différents groupes on peut retraduire cette phrase ainsi: "Editor et Adman sont des membres du staff et hérite des droits de ce dernier groupe. EditorSpec hérite des droits du staff ainsi que ceux de adman ".

Ce qui me pose problème c'est que on attribue les droits aux groupes principaux et qu'on en enlève au sous-groupe. Enfin, c'est la philosophie que j'ai cru comprendre. Moi, j'aurai plutôt fait ça dans un autre sens. On déclare d'abord des permissions globale et ensuite on en rajoute en fonction du groupe. Prenons un exemple ce sera peut-être(sans doute !) plus concret !

Le staff est composé chez moi des Newsers, Validateurs et Modérateur. Et on a un groupe qui correspond aux utilisateurs.

Les utilisateurs on accès au forum. Le staff à accès au forum et à son propre forum, le forum staff afin de pouvoir communiquer entre-eux. Le groupe modérateur peut modérer le forum, le groupe des validateurs peut valider les tutoriels et le groupe des newsers peut valider des news et en écrire. Donc si on suit mon raisonnement on attribue les droits généraux au groupe staff où chacun des sous-groupes va hériter de ces droits. Hors le staff est avant tout constitués de membres et ont donc les mêmes droits qu'eux. Les newsers sont des membres mais font partie du staff et on des droits supplémentaires sur les news. Et ainsi de suite pour les validateurs et modo.

Ca c'était l'exemple théorique... Voici l'exemple pratique:

J'ai crée une base de donnée composée d'utilisateurs, groupes et permissions. (Je simplifie au max)

user_id
user_login
user_pwd
user_groupe
groupe_id
groupe_label
groupe_parents
permission_id
permission_groupe
permission_label

L'utilisateur fait donc bien partie d'un groupe ou de plusieurs groupes et les permissions sont attribuées à un groupe ou plusieurs groupes également.

Si je suis le raisonnement de base mon administrateur a toutes les permissions et le staff hérite des permissions de l'administrateur moins les permissions qu'on veut pas lui donner à savoir supprimer le site pour prendre un exemple extrême:D Ca devient difficile de mettre en place se genre de hiérarchie avec une base de données non ? (Enfin il me semble roll )

Si on prend mon exemple ca ne fonctionne pas non plus car selon moi l'administrateur est en bas puisqu'il "hérite" des droits de tout le monde ! Donc normalement je suis censé déclarer les droits de mes autres groupes avant ce qui ne pause pas de soucis et l'administrateur héritera de ces droits. Le problème c'est que quand je vais rajouter un groupe je vais devoir dire que l'administrateur hérite de ces droits... problème c'est pas automatique ! Et je ne parle pas du fait que l'administrateur doit être le dernier groupe qui sors de la base de données pour hrité des groupes précédents !

Donc bref je me suis embrouillé plus que tout je sais ps comment faire et je suis un peu perdu ! J'espère que vous ne vous êtes pas perdu non plus dans mes explications plus que farfelues :s

Y-a-t'il une autre démarche ? Ou plus simplement, comment mettre un système de droits avec base de données en place ?

Merci d'avance

2

Re : Hoa_Acl et Base de donnée

Bonjour,

Je suis intéressé sur ce sujet, je vais bientot me plonger dans les ACL avec Hoa
Cela reste encore flou pour moi sur la manière d'organiser la base.
Je donnerai mes idées après d'autres réponse le temps de réfléchir un peu a ça.

A bientot

Le code c'est comme le paic citron, quand il y en a plus... il y en a encore !

3

Re : Hoa_Acl et Base de donnée

Hey smile,

Merci pour les compliments, c'est gentil, et bienvenu à toi !

Alors, j'avoue ne pas avoir vraiment tout compris, je tente une réponse.
Tout d'abord, tu as fait une petite faute :

Malian a écrit:

Si on traduit ça, ça donne: "Editor et adman sont des personnes du staff et que editorSpec est une personne du staff et c'est également un éditeur spécial".

Faux. editorSpec est une personne du staff mais également de adman.

Le fait de donner un droit à un groupe de personnes va naturellement le donner à ses enfants, puisque c'est un héritage ! Si par la suite on veut restreindre les accès, alors oui, il faut le dire aux enfants.
Tu peux raisonner dans l'autre sens où on aurait un « arbre » (c'est un graphe en fait) construit à l'envers. On aurait editorSpec qui aurait deux enfants (au lieu de deux parents) : adman et staff. Si tu donnes des droits à editorSpec, ses enfants (ou ses parents dans le premier modèle) l'auront également. Il te suffira d'ajouter des droits à adman et staff pour que ça ne perturbe/touche pas editorSpec. Mais si on réfléchit bien, ça revient au même … Quoi que, ça peut être plus simple dans certain cas, car on peut ajouter peu ou supprimer beaucoup, ça dépend de notre graphe d'héritage.

Disons que cette technique d'ajouter ou de retirer des droits est propre aux ACL. Si tu as fait un peu de réseau, tu as du étudier les ACL pour les routeurs. C'est le même principe. On autorise ou on refuse une IP. C'est le même principe ici, sauf qu'on a un héritage. Note, tu n'es pas obligé d'utiliser l'héritage hein. C'est un plus car le système est basé sur les graphes, ce qui permet un héritage multiple des droits, mais rien ne t'oblige à l'utiliser.

Pour ton exemple, tu as cinq groupes : user, staff, newser, moderator et validator. Il y a un seul héritage (selon ton explication), entre user et staffstaff hérite des droits de user car il a les même et en ajoute. staff est donc un enfant de user (pour donner la direction de l'héritage).
Ensuite, les groupes newser, moderator et validator sont indépendants, i.e. ils n'héritent de rien.
Par la suite, un membre du forum appartient à un ou plusieurs groupes, mais il n'est pas un groupe, attention à faire la différence.
Rappelles-toi, dans le manuel de référence, on travaille en trois étapes (plus une optionnelle) : groupes et héritages multiples, permissions et utilisateurs. Pour l'instant, on travaille sur les groupes et les héritages multiples. Les membres du forum font partis de l'étape utilisateurs.

Utiliser une base de données relationnelle pour exprimer un graphe est très compliqué. On peut le faire avec une base de données objet car on trouve les notions de listes, de sacs, d'ensembles et de tableaux. Car il faudrait faire quoi ? Dire : pour tel groupe, on hérite de tels autres groupes. Seulement, tu auras remarqué le pluriel à « tels autres groupes ». Comment représenter ça avec une base relationnelle ? Tu pourrais, mais tu aurais une redondance d'informations :

Group ( id*, refId*, label*, inherits* )

Avec une clé primaire qui est un quadruplet, on peut s'en sortir. Un exemple :

Group:
  0, 0, admin, null,
  1, 1, staff, null,
  2, 2, editor, 1
  3, 3, adman, 1
  4, 4, editorSpec, 1
  5, 4, editorSpec, 3

Comment ça marche ? id représente l'identifiant de notre quadruplet, il s'auto-incrémente et n'intervient pas dans notre raisonnement, refId représente l'identifiant du groupe, label est le nom du groupe et inherits représente le parent du groupe. Si on veut tous les parents d'un groupe :

SELECT inherits FROM Group WHERE label = 'editorSpec'

Cela devrait nous retourner 1 et 3, soit le groupe staff et adman.

C'est une solution possible. Je n'ai jamais réfléchit au problème et on doit peut-être pouvoir représenter des graphes plus efficacement, à voir. On peut d'ores et déjà factoriser les labels des groupes dans une autre table (lié par l'attribut refId). C'est une idée, on aura une table déjà moins lourde.

Ai-je correctement et suffisamment répondu à tes questions smile ?

« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

4

Re : Hoa_Acl et Base de donnée

Je vais essayer de ne pas m'embarquer dans de grandes explications mais faire simple.

Alors dans mon exemple, le groupe modérateurs, newsers et validateurs font partie du staff et il hérite des droits de ce dernier. Ce qui me semble logique puisque j'accorde au groupe staff le droit d'accéder au forum du staff, donc j'aimerais aussi que les modérateurs, newsers et validateurs aient "directement" les mêmes droits. Voilà pour clarifier mon explication vaseuses big_smile

La technique que tu proposes est celle que j'avais envisagé mais dans ma tête c'était mal vu et ta technique règle le problème qui je m'étais posé.

Je vais tenter d'appliquer ça et faire différents tests pour voir ce que cela donne.

Encore une fois merci smile

5

Re : Hoa_Acl et Base de donnée

Pour ton héritage, la solution est la même. Considère ma réponse comme un exemple, tu n'as qu'à poursuivre le raisonnement wink.

En attente de tes prochains tests smile.

« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

6

Re : Hoa_Acl et Base de donnée

C'est parti ! Les tests sur Acl et les bases de données en commencer. Voici mes démarches, observations et conclusion :

Premièrement j'ai créé mes bases de données avec plus ou moins la même structure que celle que tu as proposé dans ce même post. Jusque là aucun problème, je me suis juste un peu embrouillé, ça doit être la fatigue ^^

Maintenance place au code. Tout d'abord avec des jointures je récupère toutes les informations dont j'ai besoin en les regroupant à savoir :

  • L'id du groupe (nom)

  • La description (label)

  • Les parents du groupe

  • Les permissions du groupe (nom et description)

C'est ici que commence les premiers problèmes ! Je passe tout ce schmilblick dans une boucle et je me rend compte qu'on ne peut pas déclarer deux fois un groupe ! C'est tout à fais normal selon moi alors pourquoi ai-je une erreur ? C'est simple on a plusieurs fois le même groupe parce que dans la table chaque entrée du même groupe correspond à un parent différent ! (Comme dans ton exemple). Problème vite réglé il suffit de vérifier si le groupe n'existe pas déjà. Si c'est le cas on ne le recrée pas !

Ca c'est fait, bon j'ai les permissions à rajouter à mon groupe puisque je les prends directement, aucun soucis ! Un petit addPermission et c'est réglé !

Mais ce serait trop facile ! Ben oui ! Quand on rajoute un groupe on est bien obligé de lui dire si il y a des parents ou non ! Et cela doit être fait à l'ajout ! Donc on ne peut pas directement crée le groupe dans l'Acl puisque je dois rajouter tous les parents en un coup ! Bon ben on va changer la structure de l'application, on va crée un tableau un chaque entrée correspond à l'id du groupe, il suffit ainsi de regarder si l'id existe déjà pour ne pas rencontrer le même problème qu'au premier point. Cette entrée sera elle même un tableau où on stockera une référence à l'objet, et les parents. Il suffira ensuite de reparcourir ce même tableau puisque là on aura assimiler un groupe et tous ces parents. Là les ajoute à l'Acl !

Miracle ça fonctionne ! Commençons les test !
Je dois avouer que au début j'y ai cru ^^ Mais alors vraiment ! Jusqu'au moment ou j'ai décidé de rajouter un groupe et d'en modifier un autre pour qu'il hérite de ce groupe. Action qu'on peut facilement concevoir dans un projet, petit exemple au cas ou on ne me comprend pas.

Groupe 1
------ Groupe 2
------------- Groupe 3

Le groupe 3 hérite du groupe 2 qui lui même hérite du groupe 1. J'aimerais maintenant rajouter un palier entre 1 et 2 ainsi:

Groupe 1
------ Groupe 4
------------Groupe 2
--------------------Groupe 3

Et là c'est la catastrophe sad Ben oui forcément puisque mon groupe 4 c'est le groupe 4 dans la liste ! Pas le groupe 2 donc on va d'abord créer les autres groupes et on va demander au groupe 2 d'être l'enfant d'un groupe qui n'existe pas ! On a droit a une jolie exception du package graph qui nous dis effectivement que le groupe 4 n'existe pas !

J'ai réfléchi, pas longtemps je l'avoue parce qu'il se fait tard, et je me suis dis que une solution serait de pouvoir rajouter des parents quand on le souhaite à l'enfant mais je suis bien d'accord que ça se conçoit moyennement dans la réalité (quoique ^^) alors dans un code.

En effet si on peut rajouter quand on veut des parents nous n'aurions plus ce soucis.

Maintenant une fois encore peut-être que je m'y prend mal ^^

Au dodo maintenant !

Merci smile

7

Re : Hoa_Acl et Base de donnée

Hmm, tu devrais un œil à la section Notion de boucle sur les graphes smile.

« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

8

Re : Hoa_Acl et Base de donnée

Enfin fini !

Alors tout d'abord, j'avais déjà regarder cette partie du manuel sans trop vraiment la comprendre je l'avoue. Là j'ai bien analyser la chose tout en testant et en ayant le code à coté de moi pour bien voir ce que ça faisais et ça a effectivement pu régler quelques problèmes.

Cependant (si si big_smile) j'ai quelques remarque à faire, je suis là pour ça tout de même !

J'ai gardé la même technique que précédemment. Je vais essayé quand même de clarifier tout ça pour de futur lecteur ...

Première étape:

Initialisation de Acl. Ne pas oublié d'autoriser les boucles sur les graphes sinon on aura des erreurs.

Première remarque ici. J'ai vu dans le package Graph qu'il y avais moyen de modifier la constance au moyen de la fonction allowLoop de ce même package. Mais il me semble qu'il n'est pas possible d'activer cette fonction si on provient du package Acl l'instance de graph est contenue dans la variable groups du package Acl et que on ne peut y accéder de l'extérieur, fonction getGroups en protected. Ai-je mal vu ? A changer ? A toi de voir. Personnellement pour mes test j'ai directement modifier la valeur dans le package c'est mal !

Deuxième étape

Récupération de toutes les données en provenance de la base de données. Ici ça n'a rien à voir avec Hoa sauf peut-être pour ceux qui utilise le package Hoa_Database_Dal mais aucun problème de mon côté.

Troisième étape
J'initialise une variable, $var = array(), dans laquelle je vais stocker toutes les données provenant de la boucle qui va servir à lire les données de la base de données. Dans cette boucle il faut:

  • Vérifier qu'on ai pas déjà créer le groupe

  • Si le groupe n'est pas encore créer on le créer et on le stock dans $var['groupe_id']['instance']. Si le groupe existe on ne fait rien

  • Récupérer les parents de ce groupe. On le stockera dans la variable $var['groupe_id']['inherits'][]

  • On fait de même pour les permissions associées à ce groupe dans une variable du même style

Pourquoi je stock toutes ces données dans un autres tableau et pourquoi je ne les rajoutes pas directement à l'intance d'acl ?

  • Comme cité dans un post plus haut, il faut récupérer tous les parents avant de rajouter un groupe !

  • On ne peut pas se permettre de rajouter directement les permissions à l'instance du groupe au moyen de addPermission car cette fonction n'est pas récursive et ne tiendra compte que du groupe en cours

Quatrième étape

On a maintenant un tableau à notre disposition qui pour chaque entrée contient:

  • Une référence à l'instance du groupe

  • Tous les parents du groupe

  • Toutes les permissions du groupes et donc de ses enfants puisque ceux-ci héritent des permissions des parents

Il nous faut parcourir se tableau afin d'ajouter chaque groupe à l'Acl. Je procède de cette manière.

$acl->addGroup($val['instance'], $val['inherits']);

Maintenant il faut parcourir ce même tableau pour ajouter les permissions du groupe à son groupe et donc à ses enfants.

Pourquoi reparcourir le tableau une seconde fois et ne pas directement ajouter les permissions au groupe ?

Si on ne fait pas ainsi les groupes enfants n'existerons pas encore et l'héritage des permissions ne se fera pas!

Voilà ma démarche. Je comptais pas faire ça sous forme de tutoriel, ni de manière si bâclée je m'en excuse mais j'ai essayé d'être le plus complet possible en expliquant bien la démarche et les raisons de ces démarches.

Je note aussi que dans le fichier Graph/Node/AdjacencyList.php à la ligne 139 tu réinitialises à chaque fois la variable $this->nodes[$node->getNodeId()] ce qui à pour effet de supprimer les référence au enfant (oui au enfant ici non au parent j'ai mis un peu de temps à comprendre ^^) En effet si on active les boucles il se peut que on fasse référence à un enfant qui n'existe pas encore mais le script php à la ligne 156 va quand même créer une variable destinée à accueillir ce futur enfant. Si maintenant quand le groupe est créer on réinitialise la variable on perd les infos précédemment entrées. J'ai réglé ce problème en remplaçant par ceci:

    $this->nodes[$node->getNodeId()][self::NODE_VALUE] = $node;

        if(!isset($this->nodes[$node->getNodeId()][self::NODE_CHILD]))
            $this->nodes[$node->getNodeId()][self::NODE_CHILD] = array();

Conclusion
Alors en conclusion j'ai bidouillé ! Et j'en suis pas fière d'ailleurs big_smile J'aimerais savoir ce que tu penses de ma démarche et savoir surtout si ma modification de ton code est justifée ou si (encore) j'ai tapé vraiment à coté smile

Merci d'avance

EDIT: Je précise que maintenant tout fonctionne parfaitement. Je suis sûr qu'il y a moyen d'améliorer ça mais la j'ai plus le courage ^^

Dernière fois dit par Malian (29 May. 2009 15:31)

9

Re : Hoa_Acl et Base de donnée

Hey smile,

C'est effectivement une façon de faire. Représenter un héritage multiple sous forme relationnelle linéaire n'est jamais très simple de toute façon. Tu peux sûrement optimiser tes requêtes SQL mais je te laisse gérer ça wink.


Mise à jour du code

Hoa_Acl permet maintenant d'autoriser ou non les boucles dans le graphe sous-jacent. Pour cela, il suffit d'utiliser les constantes ALLOW_LOOP et DISALLOW_LOOP (par défaut) de la classe Hoa_Graph, en premier paramètre de la méthode getInstance de la classe Hoa_Acl. La classe est à jour, ainsi que la documentation (voir la section Mise en place de l'héritage des groupes, le dernier paragraphe).
Pour le code, il faut se rapporter à la révision 351.

Hoa_Graph ne détruit plus les enfants des nœuds lors d'une redéfinition du nœud si les boucles sont autorisées. Le correctif est la révision 352.

Tu peux générer deux patches et les appliquer. Je te laisse gérer ça (car SVN est réparé ! Je vais écrire dessus juste après cette réponse).

Encore des questions que j'aurais oublié smile ?

« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

10

Re : Hoa_Acl et Base de donnée

Pour le moment c'est parfait smile
Je vais m'attaquer aus sessions maintenant ^^ Changement de sujet total

Grand merci à toi pour ces modifications rapide et bon courage pour la suite de Hoa smile