mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-11-04 01:12:08 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			152 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			152 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
Droits
 | 
						|
======
 | 
						|
 | 
						|
Le système de droit par défaut de Django n'est pas suffisamment granulaire pour les besoins de la Note Kfet 2020.
 | 
						|
Un système personnalisé a donc été développé.
 | 
						|
 | 
						|
Il permet la création de Permission, qui autorise ou non a faire une action précise sur un ou des objets
 | 
						|
de la base de données.
 | 
						|
 | 
						|
Plusieurs permissions peuvent être regroupé dans un Role.
 | 
						|
Ce Role est relié a la responsabilité/fonction de la personne dans un Club. Ils sont valable au maximum tant que la
 | 
						|
personne est adhérente du Club concerné, mais ce rôle peut être modifié/supprimé avant le terme.
 | 
						|
 | 
						|
Permission
 | 
						|
----------
 | 
						|
 | 
						|
Une permission est un Model Django dont les principaux attributs sont :
 | 
						|
 | 
						|
* ``model`` : Le model sur lequel cette permission va s'appliquer
 | 
						|
* ``type``  : Les différents types d'interaction sont : voir (``view``), modifier (``change``), ajouter (``add``)
 | 
						|
  et supprimer (``delete``).
 | 
						|
* ``query`` : Requête sur la cible, encodé en JSON, traduit en un Q object (cf `Query <#compilation-de-la-query>`_)
 | 
						|
* ``field`` : le champ cible qui pourra être modifié. (tous les champs si vide)
 | 
						|
 | 
						|
Pour savoir si un⋅e utilisateur⋅rice a le droit sur un modèle ou non, la requête est compilée (voir ci-dessous) en un filtre
 | 
						|
de requête dans la base de données, un objet de la classe ``Q`` (En SQL l'objet Q s'interprète comme tout ce qui suit
 | 
						|
un ``WHERE ...`` Ils peuvent être combiné à l'aide d'opérateurs logiques. Plus d'information sur les Q object dans la
 | 
						|
`documentation officielle <https://docs.djangoproject.com/fr/2.2/topics/db/queries/#complex-lookups-with-q-objects>`_.
 | 
						|
 | 
						|
Ce Q object sera donc utilisé pour savoir si l'instance que l'on veut modifier est concernée par notre permission.
 | 
						|
 | 
						|
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 query
 | 
						|
-----------------------
 | 
						|
 | 
						|
La query est enregistrée sous un format JSON, puis est traduite en requête ``Q`` récursivement en appliquant certains paramètres.
 | 
						|
Le fonctionnemente de base des permission peux être décris avec les différents opérations :
 | 
						|
 | 
						|
+----------------+-----------------------------+-------------------------------------+
 | 
						|
| opérations     | JSON                        | Q object                            |
 | 
						|
+================+=============================+=====================================+
 | 
						|
| ALL            | ``[]`` ou ``{}``            | ``.objects.get(Q(pk=F("pk"))``      |
 | 
						|
+----------------+-----------------------------+-------------------------------------+
 | 
						|
| ET             | ``["AND", Q_1, Q_2, ... ]`` | ``.objects.get(Q_1 & Q_2 & ...)``   |
 | 
						|
+----------------+-----------------------------+-------------------------------------+
 | 
						|
| OU             | ``["OR", Q_1, Q_2, ...]``   | ``.objects.get(Q_1 \| Q_2 \| ...)`` |
 | 
						|
+----------------+-----------------------------+-------------------------------------+
 | 
						|
| NON            | ``["NOT", Q_1]``            | ``.objects.get(~Q_1)``              |
 | 
						|
+----------------+-----------------------------+-------------------------------------+
 | 
						|
| key == value   | ``{key: value}``            | ``.objects.get(Q(key = value))``    |
 | 
						|
+----------------+-----------------------------+-------------------------------------+
 | 
						|
 | 
						|
 | 
						|
Vous n'avez rien compris ? Voilà des exemples :
 | 
						|
 | 
						|
Exemples
 | 
						|
--------
 | 
						|
 | 
						|
* Permission sur le model ``User`` avec comme query:
 | 
						|
 | 
						|
  .. code:: js
 | 
						|
 | 
						|
    {"is_superuser": true}
 | 
						|
 | 
						|
  | si l'utilisateur⋅rice cible est un⋅e super utilisateur⋅rice.
 | 
						|
 | 
						|
* sur le model ``Note`` :
 | 
						|
 | 
						|
  .. code:: js
 | 
						|
 | 
						|
    {"pk":
 | 
						|
      ["user","note", "pk"]
 | 
						|
    }
 | 
						|
 | 
						|
  |  si l'identifiant de la note cible est l'identifiant de l'utilisateur⋅rice dont on regarde la permission.
 | 
						|
 | 
						|
* sur le model ``Transaction``:
 | 
						|
 | 
						|
  .. code:: js
 | 
						|
 | 
						|
    ["AND",
 | 
						|
      {"source":
 | 
						|
        ["user", "note"]},
 | 
						|
      {"amount__lte":
 | 
						|
        ["user", "note", "balance"]}
 | 
						|
    ]
 | 
						|
 | 
						|
  | si la source est la note de l'utilisateur⋅rice et si le montant est inférieur à son solde.
 | 
						|
 | 
						|
* Sur le model ``Alias``
 | 
						|
 | 
						|
  .. code:: js
 | 
						|
 | 
						|
    ["OR",
 | 
						|
      {"note__in":
 | 
						|
        ["NoteUser", "objects",[
 | 
						|
          "filter",{
 | 
						|
            "user__membership__club__name": "Kfet"
 | 
						|
          }],
 | 
						|
          ["all"]
 | 
						|
        ]},
 | 
						|
      {"note__in":
 | 
						|
        ["NoteClub", "objects", ["all"]]
 | 
						|
      }
 | 
						|
    ]
 | 
						|
 | 
						|
  | si l'alias appartient à une note de club ou s'il appartient à la note d'un⋅e utilisateur⋅rice membre du club Kfet.
 | 
						|
 | 
						|
* sur le model ``Transaction``
 | 
						|
 | 
						|
  .. code:: js
 | 
						|
 | 
						|
    ["AND",
 | 
						|
      {"destination": ["club", "note"]},
 | 
						|
      {"amount__lte":
 | 
						|
         {"F": [
 | 
						|
           "ADD",
 | 
						|
           ["F", "source__balance"],
 | 
						|
           2000]
 | 
						|
         }
 | 
						|
       }
 | 
						|
    ]
 | 
						|
 | 
						|
  | si la destination est la note du club dont on est membre et si le montant est inférieur au solde de la source + 20 €,
 | 
						|
    autrement dit le solde final est au-dessus de -20 €.
 | 
						|
 | 
						|
 | 
						|
Masques de permissions
 | 
						|
----------------------
 | 
						|
 | 
						|
Chaque permission est associée à un masque. À la connexion, l'utilisateur⋅rice choisit le masque de droits avec lequel iel
 | 
						|
souhaite se connecter. Les masques sont ordonnés totalement, et l'utilisateur⋅rice aura effectivement une permission si iel 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 nouvelle instance.
 | 
						|
 | 
						|
Graphe des modèles
 | 
						|
------------------
 | 
						|
 | 
						|
.. image:: ../_static/img/graphs/permission.svg
 | 
						|
   :alt: Graphe de l'application permission
 |