mirror of
https://gitlab.crans.org/bde/nk20
synced 2025-02-06 15:23:00 +00:00
Create Droits
parent
09abedcd64
commit
9119d740b3
84
Droits.md
Normal file
84
Droits.md
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
# Droits
|
||||||
|
|
||||||
|
Un système de droits basé sur les rôles dans les clubs est géré. Pour chaque adhésion dans un club, l'utilisateur se voit attribué un certain nombre de droits, globaux ou sur le club en question.
|
||||||
|
|
||||||
|
## Permission
|
||||||
|
|
||||||
|
Une permission est, intuitivement, une formule logique indiquant si un utilisateur a le droit d'intéragir avec un modèle ou non. Cela peut concerner uniquement un champ d'un modèle.
|
||||||
|
|
||||||
|
Les différents types d'interaction sont : voir (`view`), modifier (`change`), ajouter (`add`) et supprimer (`delete`).
|
||||||
|
|
||||||
|
Pour savoir si un utilisateur a le droit sur un modèle ou non, la requête est compilée (voir ci-dessous) en un fitre de requête dans la base de données, un objet de la classe `Q`. Ensuite, il suffit d'appliquer ce filtre sur une requête à la base de données du modèle considéré, et voir si l'objet recherché est trouvé ou non.
|
||||||
|
|
||||||
|
Exception faite sur l'ajout d'objets : l'objet n'existant pas encore en base de données, il est ajouté puis supprimé à la volée, en prenant soin de désactiver les signaux.
|
||||||
|
|
||||||
|
## Compilation de la requête
|
||||||
|
|
||||||
|
La requête est enregistrée sous un format JSON, puis est traduite en requête `Q` récursivement en appliquant certains paramètres (on note `about` la fonction de traduction) :
|
||||||
|
|
||||||
|
```
|
||||||
|
* [] | {} -> Q(pk=F("pk")) # Une liste ou un objet vide représente tous les objets
|
||||||
|
* ["AND", query, …] -> about(query) & … # Conjonction de requêtes
|
||||||
|
* ["OR", query, …] -> about(query) | … # Disjonction de requêtes
|
||||||
|
* ["NOT", query] -> ~about(query) # Négation d'une requête
|
||||||
|
* {key: value, …} -> Q(key=value, …) # Liste de champs et de valeurs dans un objet Q
|
||||||
|
* `key` est une chaîne de caractères,représentant le nom du champ
|
||||||
|
* `value` peut être de plusieurs natures :
|
||||||
|
* Un nombre, une chaîne de caractères, un booléen, `null` pour représenter des valeurs littérales
|
||||||
|
* Si c'est une liste, c'est interprété comme un paramètre
|
||||||
|
* Le premier argument de la liste représente le nom du paramètre. Ce peut être l'objet utilisateur `user`, l'objet club `club` ou des objets de classe (`Note`, ...).
|
||||||
|
* S'il y a des arguments suivants dans la liste, ils vont être interprétés comme des sous-attributs du paramètre initial.
|
||||||
|
* Si un argument est une liste, alors c'est interprété comme une fonction à appeler, dont les arguments sont donnés par les autres éléments de la liste. Si cette liste contient un dictionnaire, le dictionnaire est passé en argument à la fonction sous la forme de kwargs.
|
||||||
|
* Les exemples seront plus clairs.
|
||||||
|
* Si c'est un dictionnaire de la forme {"F": oper}, alors c'est interprété comme un objet `F`.
|
||||||
|
* Si `oper` est un littéral, il est interprété tel quel.
|
||||||
|
* Si `oper` = ["ADD", oper1, oper2, …], le résultat est la somme des objets `F` calculés d'après le reste de la liste.
|
||||||
|
* Si `oper` = ["SUB", oper1, oper2,], le résultat est la différence des deux objets `F`.
|
||||||
|
* Si `oper` = ["MUL", oper1, oper2, …], le résultat est le produit des objets `F` calculés d'après le reste de la liste.
|
||||||
|
* Si `oper` = ["F", name], le résultat est F(name).
|
||||||
|
* Dans les autres cas, `oper` est un paramètre calculé comme précédemment.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Exemples
|
||||||
|
|
||||||
|
Cette définition n'étant pas claire, voici quelques exemples facilitant la compréhension :
|
||||||
|
|
||||||
|
```js
|
||||||
|
Modèle : User
|
||||||
|
Q(is_superuser=True) := {"is_superuser": true}
|
||||||
|
Permission accordée si l'utilisateur cible est un super utilisateur.
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
Modèle : Note
|
||||||
|
Q(pk=user.note.pk) := {"pk": ["user", "note", "pk"]}
|
||||||
|
Permission accordée si l'identifiant de la note cible est l'identifiant de l'utilisateur dont on regarde la permission.
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
Modèle : Transaction
|
||||||
|
["AND", {"source": ["user", "note"]}, {"amount__lte": ["user", "note", "balance"]}]
|
||||||
|
Permission accordée si la source est la note de l'utilisateur et si le montant est inférieur à son solde.
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
Modèle : Alias
|
||||||
|
["OR", {"note__in": ["NoteUser", "objects", ["filter", {"user__membership__club__name": "Kfet"}], ["all"]]}, {"note__in": ["NoteClub", "objects", ["all"]]}]
|
||||||
|
Permission accordée si l'alias appartient à une note de club ou s'il appartient à la note d'un utilisateur membre du club Kfet.
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
Modèle : Transaction
|
||||||
|
["AND", {"destination": ["club", "note"]}, {"amount__lte": {"F": ["ADD", ["F", "source__balance"], 5000]}}]
|
||||||
|
Permission accordée si la destination est la note du club dont on est membre et si le montant est inférieur au solde de la source + 50 €, autrement dit le solde final est au-dessus de -50 €.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Masques de permissions
|
||||||
|
|
||||||
|
Chaque permission est associée à un masque. À la connexion, l'utilisateur choisit le masque de droits avec lequel il souhaite se connecter. Les masques sont ordonnés totalement, et l'utilisateur aura effectivement une permission s'il est en droit d'avoir la permission et si son masque est suffisamment haut.
|
||||||
|
|
||||||
|
Par exemple, si la permission de voir toutes les transactions est associée au masque "Droits note uniquement", se connecter avec le masque "Droits basiques" n'octroiera pas cette permission tandis que le masque "Tous mes droits" oui.
|
||||||
|
|
||||||
|
## Signaux
|
||||||
|
|
||||||
|
À chaque fois qu'un modèle est modifié, ajouté ou supprimé, les droits sont contrôlés. Si les droits ne sont pas suffisants, une erreur est lancée. Pour ce qui est de la modification, on ne contrôle que les champs réellement modifiés en comparant l'ancienne et la nouvele instance.
|
Loading…
x
Reference in New Issue
Block a user