Salut,
J'ai tout lu (sisi, véridique). J'ai même tout compris, enfin je pense. J'ai pas réfléchi en détails, mais l'idée ne me parait pas mauvaise.
Ta question, tu dois pouvoir y répondre tout seul, si tu fais un peu l'analyse de ce dont tu as besoin au départ : les fonctionnalités à implémenter, comment décrire chaque objet (user en l'occurrence).
Tel que je vois tes tables, un utilisateur peut faire partie au maximum d'un groupe. Personnellement, j'ai tendance à toujours permettre qu'un utilisateur soit dans plusieurs groupes. Ca donne une relation n,n entre les tables users et groups, il faut donc une table supplémentaire qui matérialise cette relation conceptuelle.
Tu donnes des noms différents à tes clé étrangères en les préfixant avec fk_ : c'est, d'un point de vue conceptuel, mauvais. Une clé étrangère n'est que la manifestation de la relation entre deux tables, par une donnée. Cette donnée est la même dans les deux tables. Il FAUT donc l'appeler toujours pareil. Par contre, il faut TOUJOURS utiliser des noms différents pour des données différentes. Par exemple, je vois souvent des bases de données avec plusieurs données qui portent le nom "name", ou "address" : un coup il s'agit du nom d'un utilisateur, un coup du nom d'un film, une autre fois de celui d'un animal de comapgnie, ...
Par contre id_rule et fk_id_rule sont strictement la même donnée, il faut donc nommer les champs de manière identique.
Je sais : ça ne change pas le fonctionnement. Mais conceptuellement, ce n'est pas du tout la même chose. Quand on établi un dictionnaire de données, chaque donnée est identifiée par son nom : la retrouver plusieurs fois avec plusieurs noms est une erreur. De même, ne trouver qu'un nom pour représenter plusieurs données différentes est aussi une erreur.
Ta manière de gérer les permissions simple utilisateur et admin me paraît limitative. Si je comprends bien, tu utilises la permission d'écriture comme identifiant un admin, donc autorisant l'accès en lecture. Ca ne te laisse pas beaucoup de marge de manoeuvre si tu souhaites changer la hiérarchie des groupes ou des permissions.
La gestion des permissions est une problèmatique cruciale sur un site, d'autant plus s'il s'agit d'un site communautaire ou basé sur l'UGC (User Generated Content, comme un wiki, un blog collectif, etc). Il est possible de gérer cette problématique de plusieurs manières, mais il n'est pas forcément bon de les mélanger : si on y gagne en souplesse dans la théorie, dans l'utilisation, on peut vite s'emmêler les pinceaux (comme avec les permissions de phpBB2, c'était un grand n'importe quoi).
Ma manière de voir est d'utiliser des groupes, et uniquement des groupes. Si on souhaite donner des permissions très précises à un utilisateur en particulier, il suffit de lui dédier un groupe. On peut donc avoir au maximum autant de groupes que d'utilisateurs + les groupes "normaux". Il est donc important, dans cette optique, de permettre à un utilisateur de faire partie de plusieurs groupes, sachant que si l'appartenance à un groupe donne la permission, alors l'utilisateur a la permission. Pour les cas des utilisateurs punis, il suffit de les enlever des groupes auxquels ils appartiennent et de les ranger dans un groupe spécifique, avec des permissions limitées. On peut aussi, si on ne souhaite pas effacer les groupes (et donc les permissions) actuelles, gérer spécifiquement les permissions de ce groupe limité (alors, on ne tient compte que des permissions de ce groupe).
Ceci étant dit, voici comment j'implémenterais ça :
table users (user_id, user_login, user_password, etc)
table groups (group_id, group_name, etc)
table users_groups (user_id, group_id)
table rules (rule_id, rule_name)
table permissions (group_id, rule_id)
Pour les tables users et groups, pas besoin d'explications... La table users_groups permet à la relation n,n entre les tables users et groups d'exister.
La table rules liste les permissions que tu souhaites octroyer sur ton site : lecture, création, modification, suppression, bannir un membre, etc. Rien de plus.
La table acl définit les permissions qui sont DONNEES à un groupe. Si la relation group-rule n'existe pas, alors le groupe n'a pas la permission d'exécuter cette action.
Pour les membres punis qui feraient partie d'un groupe limité, il conviendrait alors de ne vérifier les permissions QUE pour ce groupe, pas pour les autres.
Concrètement, pour connaître les permissions d'un utilisateur :
Code :
SELECT r.rule_name
FROM rules r
LEFT JOIN permissions p ON p.rule_id = r.rule_id
LEFT JOIN users_groups ug ON ug.group_id=p.group_id
LEFT JOIN groups g ON ug.group_id = g.group_id
WHERE ug.user_id = 2
Question optimisation, je n'ai aucune idée de ce que ça donne, par contre ^^ Ca s'exécute rapidement chez moi, mais comme j'ai mis que 2 groupes, 2 utilisateurs, 4 permissions...
Par contre, c'est ce que je vois de mieux en terme de flexibilité. En plus, là, c'est MySQL qui calcule tout seul si l'utilisateur a la permissions ou pas. Si la permission sort sur une ligne, c'est que oui, sinon, non. Un simple isset() sur un tableau associatif permet de connaître la permission.
Je sais pas si ça répond à ta question, mais c'est quand même ce que je réponds ^^
--
Neige
Souvent la réponse à votre question se trouve dans la
doc. Commencez par là ;)