From 5466a50fbfee2536fd8e9686636742d8c8bdb480 Mon Sep 17 00:00:00 2001 From: imperosol Date: Sat, 30 Nov 2024 22:47:47 +0100 Subject: [PATCH] update docs --- docs/tutorial/groups.md | 194 +++++++++++++++++++++++++++++++--------- docs/tutorial/perms.md | 2 +- 2 files changed, 153 insertions(+), 43 deletions(-) diff --git a/docs/tutorial/groups.md b/docs/tutorial/groups.md index b8603d16..1b3677a5 100644 --- a/docs/tutorial/groups.md +++ b/docs/tutorial/groups.md @@ -1,54 +1,157 @@ -Il existe deux types de groupes sur le site AE : +## Un peu d'histoire + +Par défaut, Django met à disposition un modèle `Group`, +lié par clef étrangère au modèle `User`. +Pour créer un système de gestion des groupes qui semblait plus +approprié aux développeurs initiaux, un nouveau +modèle [core.models.Group][] +a été crée, et la relation de clef étrangère a été modifiée +pour lier [core.models.User][] à ce dernier. + +L'ancien modèle `Group` était implicitement +divisé en deux catégories : + +- les *méta-groupes* : groupes liés aux clubs et créés à la volée. + Ces groupes n'étaient liés par clef étrangère à aucun utilisateur. + Ils étaient récupérés à partir de leur nom uniquement + et étaient plus une indirection pour désigner l'appartenance à un club + que des groupes à proprement parler. +- les *groupes réels* : groupes créés à la main + et souvent hardcodés dans la configuration. + +Cependant, ce nouveau système s'éloignait trop du cadre de Django +et a fini par devenir une gêne. +La vérification des droits lors des opérations est devenue +une opération complexe et coûteuse en temps. + +La gestion des groupes a donc été modifiée pour recoller un +peu plus au cadre de Django. +Toutefois, il n'a pas été tenté de revenir à 100% +sur l'architecture prônée par Django. + +D'une part, cela représentait un risque pour le succès de l'application +de la migration sur la base de données de production. + +D'autre part, si une autre architecture a été tentée au début, +ce n'était pas sans raison : +ce que nous voulons modéliser sur le site AE n'est pas +complètement modélisable avec ce qu'offre Django. +Il faut donc bien garder une surcouche au-dessus de l'authentification +de Django. +Tout le défi est de réussir à maintenir cette surcouche aussi fine +que possible sans limiter ce que nous voulons faire. + +## Représentation en base de données + +Le modèle [core.models.Group][] a donc été légèrement remanié +et la distinction entre groupes méta et groupes réels a été plus ou moins +supprimée. +La liaison de clef étrangère se fait toujours entre [core.models.User][] +et [core.models.Group][]. + +Cependant, il y a une subtilité. +Depuis le début, le modèle `Group` de django n'a jamais disparu. +En effet, lorsqu'un modèle hérite d'un modèle qui n'est pas +abstrait, Django garde les deux tables et les lie +par une clef étrangère unique de clef primaire à clef primaire +(pour plus de détail, lire +[la doc de django sur l'héritage de modèle](https://docs.djangoproject.com/fr/stable/topics/db/models/#model-inheritance)) + +L'organisation réelle de notre système de groupes +est donc la suivante : + + +```mermaid +--- +title: Représentation des groupes +--- +erDiagram + core_user }o..o{ core_group: core_user_groups + auth_group }o..o{ auth_permission: auth_group_permissions + core_group ||--|| auth_group: "" + core_user }o..o{ auth_permission :"core_user_user_permissions" + + core_user { + int id PK + string username + string email + string first_name + etc etc + } + core_group { + int group_ptr_id PK,FK + string description + bool is_manually_manageable + } + auth_group { + int id PK + name string + } + auth_permission { + int id PK + string name + } +``` + +Cette organisation, rajoute une certaine complexité, +mais celle-ci est presque entièrement gérée par django, +ce qui fait que la gestion n'est pas tellement plus compliquée +du point de vue du développeur. + +Chaque fois qu'un queryset implique notre `Group` +ou le `Group` de django, l'autre modèle est automatiquement +ajouté à la requête par jointure. +De cette façon, on peut manipuler l'un ou l'autre, +sans même se rendre que les tables sont dans des tables séparées. + +Par exemple : + +=== "python" + + ```python + from core.models import Group + + Group.objects.all() + ``` + +=== "SQL généré" + + ```sql + SELECT "auth_group"."id", + "auth_group"."name", + "core_group"."group_ptr_id", + "core_group"."is_manually_manageable", + "core_group"."description" + FROM "core_group" + INNER JOIN "auth_group" ON ("core_group"."group_ptr_id" = "auth_group"."id") + ``` -- l'un se base sur des groupes enregistrés en base de données pendant le développement, - c'est le système de groupes réels. -- L'autre est plus dynamique et comprend tous les groupes générés - pendant l'exécution et l'utilisation du programme. - Cela correspond généralement aux groupes liés aux clubs. - Ce sont les méta-groupes. ## La définition d'un groupe -Les deux types de groupes sont stockés dans la même table -en base de données, et ne sont différenciés que par un attribut `is_meta`. +Un groupe est constitué des informations suivantes : -### Les groupes réels +- son nom : `name` +- sa description : `description` (optionnelle) +- si on autorise sa gestion par les utilisateurs du site : `is_manually_manageable` -Pour plus différencier l'utilisation de ces deux types de groupe, -il a été créé une classe proxy -(c'est-à-dire qu'elle ne correspond pas à une vraie table en base de donnée) -qui encapsule leur utilisation. -`RealGroup` peut être utilisé pour créer des groupes réels dans le code -et pour faire une recherche sur ceux-ci -(dans le cadre d'une vérification de permissions par exemple). +Si un groupe est gérable manuellement, alors les administrateurs du site +auront le droit d'assigner des utilisateurs à ce groupe depuis l'interface dédiée. -### Les méta-groupes +S'il n'est pas gérable manuellement, on cache aux utilisateurs du site +la gestion des membres de ce groupe. +La gestion se fait alors uniquement "sous le capot", +de manière automatique lors de certains évènements. +Par exemple, lorsqu'un utilisateur rejoint un club, +il est automatiquement ajouté au groupe des membres +du club. +Lorsqu'il quitte le club, il est retiré du groupe. -Les méta-groupes, comme expliqué précédemment, -sont utilisés dans les contextes où il est nécessaire de créer un groupe dynamiquement. -Les objets `MetaGroup`, bien que dynamiques, doivent tout de même s'enregistrer -en base de données comme des vrais groupes afin de pouvoir être affectés -dans les permissions d'autres objets, comme un forum ou une page de wiki par exemple. -C'est principalement utilisé au travers des clubs, -qui génèrent automatiquement deux groupes à leur création : +## Les principaux groupes utilisés -- club-bureau : contient tous les membres d'un club **au dessus** - du grade défini dans `settings.SITH_MAXIMUM_FREE_ROLE`. -- club-membres : contient tous les membres d'un club - **en dessous** du grade défini dans `settings.SITH_MAXIMUM_FREE_ROLE`. - - -## Les groupes réels utilisés - -Les groupes réels que l'on utilise dans le site sont les suivants : - -Groupes gérés automatiquement par le site : - -- `Public` : tous les utilisateurs du site -- `Subscribers` : tous les cotisants du site -- `Old subscribers` : tous les anciens cotisants - -Groupes gérés par les administrateurs (à appliquer à la main sur un utilisateur) : +Les groupes les plus notables gérables par les administrateurs du site sont : - `Root` : administrateur global du site - `Accounting admin` : les administrateurs de la comptabilité @@ -62,3 +165,10 @@ Groupes gérés par les administrateurs (à appliquer à la main sur un utilisat - `Banned to subscribe` : les utilisateurs interdits de cotisation +En plus de ces groupes, on peut noter : + +- `Public` : tous les utilisateurs du site +- `Subscribers` : tous les cotisants du site +- `Old subscribers` : tous les anciens cotisants + + diff --git a/docs/tutorial/perms.md b/docs/tutorial/perms.md index 3377b808..c78292ab 100644 --- a/docs/tutorial/perms.md +++ b/docs/tutorial/perms.md @@ -4,7 +4,7 @@ Le fonctionnement de l'AE ne permet pas d'utiliser le système de permissions intégré à Django tel quel. Lors de la conception du Sith, ce qui paraissait le plus simple à l'époque était de concevoir un système maison afin de se calquer -sur ce que faisais l'ancien site. +sur ce que faisait l'ancien site. ### Protéger un modèle