mirror of
https://github.com/ae-utbm/sith.git
synced 2025-07-12 04:49:25 +00:00
Revert "Cleaned doc folder as it was unused"
This reverts commit 8716f2a01e
.
This commit is contained in:
64
doc/overlay/groups.rst
Normal file
64
doc/overlay/groups.rst
Normal file
@ -0,0 +1,64 @@
|
||||
Le système de groupes
|
||||
=====================
|
||||
|
||||
Il existe deux types de groupes sur le site AE. 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
|
||||
--------------------------
|
||||
|
||||
Comme on peut l'observer, il existe une entrée de groupes dans la base de données. Cette classe implémente à la fois les groupes réels et les méta groupes.
|
||||
|
||||
Ce qui différencie ces deux types de groupes ce sont leur utilisation et leur manière d'être générés. La distinction est faite au travers de la propriété `is_meta`.
|
||||
|
||||
.. autoclass:: core.models.Group
|
||||
:members:
|
||||
|
||||
Les groupes réels
|
||||
-----------------
|
||||
|
||||
Pour simplifier l'utilisation de ces deux types de groupe, il a été crée 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).
|
||||
|
||||
.. autoclass:: core.models.RealGroup
|
||||
:members:
|
||||
|
||||
.. note::
|
||||
|
||||
N'oubliez pas de créer une variable dans les settings contenant le numéro du groupe pour facilement l'utiliser dans le code plus tard. Ces variables sont du type `SITH_GROUP_GROUPE_NAME_ID`.
|
||||
|
||||
Les méta groupes
|
||||
----------------
|
||||
|
||||
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 *on runtime*. Les objets `MetaGroup`, bien que dynamiques, doivent tout de même s'enregistrer en base de donnée 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 :
|
||||
|
||||
* 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.
|
||||
|
||||
.. autoclass:: core.models.MetaGroup
|
||||
:members:
|
||||
|
||||
|
||||
.. _groups-list:
|
||||
|
||||
La liste des groupes réels
|
||||
--------------------------
|
||||
|
||||
Les groupes réels existant par défaut 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) :
|
||||
|
||||
* **Root** -> administrateur global du site
|
||||
* **Accounting admin** -> les administrateurs de la comptabilité
|
||||
* **Communication admin** -> les administrateurs de la communication
|
||||
* **Counter admin** -> les administrateurs des comptoirs (foyer et autre)
|
||||
* **SAS admin** -> les administrateurs du SAS
|
||||
* **Forum admin** -> les administrateurs du forum
|
||||
* **Pedagogy admin** -> les administrateurs de la pédagogie (guide des UVs)
|
||||
* **Banned from buying alcohol** -> les utilisateurs interdits de vente d'alcool (non mineurs)
|
||||
* **Banned from counters** -> les utilisateurs interdits d'utilisation des comptoirs
|
||||
* **Banned to subscribe** -> les utilisateurs interdits de cotisation
|
159
doc/overlay/rights.rst
Normal file
159
doc/overlay/rights.rst
Normal file
@ -0,0 +1,159 @@
|
||||
La gestion des droits
|
||||
=====================
|
||||
|
||||
La gestion des droits dans l'association étant très complexe, le système de permissions intégré dans Django ne suffisait pas, il a donc fallu créer et intégrer le notre.
|
||||
|
||||
La gestion des permissions se fait directement sur un modèle, il existe trois niveaux de permission :
|
||||
|
||||
* Édition des propriétés de l'objet
|
||||
* Édition de certaines valeurs l'objet
|
||||
* Voir l'objet
|
||||
|
||||
Protéger un modèle
|
||||
------------------
|
||||
|
||||
Lors de l'écriture d'un modèle, il est très simple de définir des permissions. Celle-ci peuvent être basées sur des groupes et/ou sur des fonctions personnalisées.
|
||||
|
||||
Nous allons présenter ici les deux techniques. Dans un premier temps nous allons protéger une classe Article par groupes.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from django.db import models
|
||||
from django.conf import settings
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from core.views import *
|
||||
from core.models import User, Group
|
||||
|
||||
# Utilisation de la protection par groupe
|
||||
class Article(models.Model):
|
||||
|
||||
title = models.CharField(_("title"), max_length=100)
|
||||
content = models.TextField(_("content"))
|
||||
|
||||
# Ne peut pas être une liste
|
||||
# Groupe possédant l'objet
|
||||
# Donne les droits d'édition des propriétés de l'objet
|
||||
owner_group = models.ForeignKey(
|
||||
Group, related_name="owned_articles", default=settings.SITH_GROUP_ROOT_ID
|
||||
)
|
||||
|
||||
# Doit être une liste
|
||||
# Tous les groupes qui seront ajouté dans ce champ auront les droits d'édition de l'objet
|
||||
edit_group = models.ManyToManyField(
|
||||
edit_groups = models.ManyToManyField(
|
||||
Group,
|
||||
related_name="editable_articles",
|
||||
verbose_name=_("edit groups"),
|
||||
blank=True,
|
||||
)
|
||||
)
|
||||
|
||||
# Doit être une liste
|
||||
# Tous les groupes qui seront ajouté dans ce champ auront les droits de vue de l'objet
|
||||
view_groups = models.ManyToManyField(
|
||||
Group,
|
||||
related_name="viewable_articles",
|
||||
verbose_name=_("view groups"),
|
||||
blank=True,
|
||||
)
|
||||
|
||||
Voici maintenant comment faire en définissant des fonctions personnalisées. Cette deuxième solution permet, dans le cas où la première n'est pas assez puissante, de créer des permissions complexes et fines. Attention à bien les rendre lisibles et de bien documenter.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from core.views import *
|
||||
from core.models import User, Group
|
||||
|
||||
# Utilisation de la protection par fonctions
|
||||
class Article(models.Model):
|
||||
|
||||
title = models.CharField(_("title"), max_length=100)
|
||||
content = models.TextField(_("content"))
|
||||
|
||||
# Donne ou non les droits d'édition des propriétés de l'objet
|
||||
# Un utilisateur dans le bureau AE aura tous les droits sur cet objet
|
||||
def is_owned_by(self, user):
|
||||
return user.is_board_member
|
||||
|
||||
# Donne ou non les droits d'édition de l'objet
|
||||
# L'objet ne sera modifiable que par un utilisateur cotisant
|
||||
def can_be_edited_by(self, user):
|
||||
return user.is_subscribed
|
||||
|
||||
# Donne ou non les droits de vue de l'objet
|
||||
# Ici, l'objet n'est visible que par un utilisateur connecté
|
||||
def can_be_viewed_by(self, user):
|
||||
return not user.is_anonymous
|
||||
|
||||
.. note::
|
||||
|
||||
Si un utilisateur est autorisé à un niveau plus élevé que celui auquel il est testé, le système le détectera automatiquement et les droits lui seront accordé. Par défaut, les seuls utilisateurs ayant des droits quelconques sont les *superuser* de Django et les membres du bureau AE qui sont définis comme *owner*.
|
||||
|
||||
Appliquer les permissions
|
||||
-------------------------
|
||||
|
||||
Dans un template
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Il existe trois fonctions de base sur lesquelles reposent les vérifications de permission. Elles sont disponibles dans le contexte par défaut du moteur de template et peuvent être utilisées à tout moment.
|
||||
|
||||
Tout d'abord, voici leur documentation et leur prototype.
|
||||
|
||||
.. autofunction:: core.views.can_edit_prop
|
||||
.. autofunction:: core.views.can_edit
|
||||
.. autofunction:: core.views.can_view
|
||||
|
||||
Voici un exemple d'utilisation dans un template :
|
||||
|
||||
.. code-block:: html+jinja
|
||||
|
||||
{# ... #}
|
||||
{% if can_edit(club, user) %}
|
||||
<a href="{{ url('club:tools', club_id=club.id) }}">{{ club }}</a>
|
||||
{% endif %}
|
||||
|
||||
Dans une vue
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Généralement, les vérifications de droits dans les templates se limitent au liens à afficher puisqu'il ne faut pas mettre de logique autre que d'affichage à l'intérieur. C'est donc généralement au niveau des vues que cela a lieu.
|
||||
|
||||
Notre système s'appuie sur un système de mixin à hériter lors de la création d'une vue basée sur une classe. Ces mixins ne sont compatibles qu'avec les classes récupérant un objet ou une liste d'objet. Dans le cas d'un seul objet, une permission refusée est levée lorsque l'utilisateur n'as pas le droit de visionner la page. Dans le d'une liste d'objet, le mixin filtre les objets non autorisés et si aucun ne l'est l'utilisateur recevra une liste vide d'objet.
|
||||
|
||||
Voici un exemple d'utilisation en reprenant l'objet Article crée précédemment :
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from django.views.generic import CreateView, ListView
|
||||
|
||||
from core.views import CanViewMixin, CanCreateMixin
|
||||
|
||||
from .models import Article
|
||||
|
||||
...
|
||||
|
||||
# Il est important de mettre le mixin avant la classe héritée de Django
|
||||
# L'héritage multiple se fait de droite à gauche et les mixins ont besoin
|
||||
# d'une classe de base pour fonctionner correctement.
|
||||
class ArticlesListView(CanViewMixin, ListView):
|
||||
|
||||
model = Article # On base la vue sur le modèle Article
|
||||
...
|
||||
|
||||
# Même chose pour une vue de création de l'objet Article
|
||||
class ArticlesCreateView(CanCreateMixin, CreateView):
|
||||
|
||||
model = Article
|
||||
|
||||
Le système de permissions de propose plusieurs mixins différents, les voici dans leur intégralité.
|
||||
|
||||
.. autoclass:: core.views.CanCreateMixin
|
||||
.. autoclass:: core.views.CanEditPropMixin
|
||||
.. autoclass:: core.views.CanEditMixin
|
||||
.. autoclass:: core.views.CanViewMixin
|
||||
.. autoclass:: core.views.UserIsRootMixin
|
||||
.. autoclass:: core.views.FormerSubscriberMixin
|
||||
.. autoclass:: core.views.UserIsLoggedMixin
|
Reference in New Issue
Block a user