Attention : vous consultez actuellement la documentation dédiée aux versions 1.x de Moodle. La documentation pour les versions 2.x de Moodle est consultable ici : Comment les permissions sont calculées ?, celle pour les versions 3.x de Moodle est consultable ici : Comment les permissions sont calculées ? et celle pour Moodle 4.x est consultable là : Comment les permissions sont calculées ?.

« Comment les permissions sont calculées ? » : différence entre les versions

De MoodleDocs
Aller à :navigation, rechercher
(Suite de la traduction (3))
Aucun résumé des modifications
Ligne 7 : Ligne 7 :
Cette page est écrite autant pour les non programmeurs que pour les programmeurs. Elle décrit ''ce que'' la fonction fait, pas ''comment''. Le ''comment'' est compliqué, alors que le ''quoi'' est relativement simple !
Cette page est écrite autant pour les non programmeurs que pour les programmeurs. Elle décrit ''ce que'' la fonction fait, pas ''comment''. Le ''comment'' est compliqué, alors que le ''quoi'' est relativement simple !


Remarquez que la fonction ''n'essaie pas''  de répondre à la grande question posée dans la première phrase de cette page. Elle répond plutôt à la petite question "Un utilisateur peut-il faire ''CAP'' ici ?", où ''CAP'' est une capacité spécifique. Moodle ne calcule jamais la totalité des permissions d'un utilisateur. Une telle opération serait très coûteuse et et n'apporterait pas grand chose, puisque la plupart des permissions ne seraient jamais testées. Moodle calcule donc les permissions à la demande. Moodle ne place pas en cache les permissions calculées, mais les recalcule chaque fois qu'il est nécessaire de les tester. C'est la raison pour laquelle les attributions de rôles et les dérogations prennent effet immédiatement, et que ce n'était pas le cas dans Moodle 1.7.
Remarquez que la fonction ''n'essaie pas''  de répondre à la grande question posée dans la première phrase de cette page. Elle répond plutôt à la petite question "Un utilisateur peut-il faire l'action correspondant à la capacité ''CAP'' ici ?". Moodle ne calcule jamais la totalité des permissions d'un utilisateur. Une telle opération serait très coûteuse et et n'apporterait pas grand chose, puisque la plupart des permissions ne seraient jamais testées. Moodle calcule donc les permissions à la demande. Moodle ne place pas en cache les permissions calculées, mais les recalcule chaque fois qu'il est nécessaire de les tester. C'est la raison pour laquelle les attributions de rôles et les dérogations prennent effet immédiatement, et que ce n'était pas le cas dans Moodle 1.7.
 
== Le calcul ==


La fonction est appelée ainsi :
La fonction est appelée ainsi :


     has_capability(CAPABILITY,CONTEXT,USER);
     has_capability(CAP,CONTEXTE,UTILISATEUR);
 
* CAP est la capacité testée (par exemple ''mod/quiz:attempt'')
* CONTEXTE est le contexte Système ou tout autre contexte imbriqué de façon arbitraire dans le contexte Système. À l'interne, la fonction utilise une notation analogue à celle des chemins d'accès des fichiers Unix pour représenter les contextes (par exemple, /1/3/4/150). De tels détails ne sont pas nécessaires dans cette discussion.
* UTILISATEUR est l'utilisateur.


Elle retourne un résultat vrai/faux :
La fonction retourne un résultat vrai/faux :


* ''true'' signifie que l'utilisateur est autorisé à effectuer l'action
* ''true'' signifie que l'utilisateur est autorisé à effectuer l'action
* ''false'' signifie que l'utilisateur n'est pas autorisé à effectuer l'action
* ''false'' signifie que l'utilisateur n'est pas autorisé à effectuer l'action


Le CONTEXT peut être le contexte Système ou tout autre contexte imbriqué de façon arbitraire dans le contexte Système. À l'interne, la fonction utilise une notation analogue à celle des chemins d'accès des fichiers Unix pour représenter les contextes (par exemple, /1/3/4/150). De tels détails ne sont pas nécessaires dans cette discussion.
===Données utilisées par la fonction===


Supposons qu'un utilisateur soit sur le point de tenter un test (capacité ''mod/quiz:attempt'') dans le contexte d'un module imbriqué quatre niveaux au-dessous du contexte Système.
Supposons que l'utilisateur UTILISATEUR soit sur le point de tenter un test (CAP = ''mod/quiz:attempt'') dans le contexte d'un module imbriqué quatre niveaux au-dessous du contexte Système.


       Système
       Système
Ligne 30 : Ligne 36 :
       Cours
       Cours
         |
         |
        Test  <--- l'utilisateur est ici
      Test  <--- l'utilisateur est ici


Le module test fera appel à la fonction ''has_capability'' pour voir s'il doit permettre à l'utilisateur d'effectuer cette action.
Le module test fera appel à la fonction ''has_capability()'' pour déterminer s'il doit permettre à l'utilisateur d'effectuer cette action.


La fonction considère les données de permissions suivantes :
La fonction considère les données de permissions suivantes :
Ligne 42 : Ligne 48 :
Il est à remarquer qu'il peut y avoir plusieurs rôles attribués et/ou plusieurs dérogations définies dans un seul contexte.   
Il est à remarquer qu'il peut y avoir plusieurs rôles attribués et/ou plusieurs dérogations définies dans un seul contexte.   


La permision pour l'utilisateur de tenter le test ou non dépend des données ci-dessus, ainsi que de l'emplacement de ces données dans la chaîne des contextes.
La permission pour l'utilisateur de tenter le test ou non dépend des données ci-dessus, ainsi que de l'emplacement de ces données dans la chaîne des contextes.


La fonction ignore toutes les données n'étant pas utilisées dans le calcul des permissions. Elle ignore notamment :
La fonction ''has_capability()'' considère tous les rôles et toutes les dérogations ayant un impact sur UTILISATEUR dans CONTEXTE, mais elle ignore toutes les capacités autres que CAP. Elle ignore notamment :


* les rôles qui ne sont pas attribués à l'utilisateur,
* les rôles qui ne sont pas attribués à l'utilisateur,
Ligne 50 : Ligne 56 :
* les permissions qui ne sont pas définies.   
* les permissions qui ne sont pas définies.   


Après avoir ignoré ces données, il nous reste une très simple "tranche de données" consistant uniquement des permissions liées à la capacité que nous testons, et pour lesquelles les valeurs sont soit Autoriser (A), Empêcher (P), ou Interdire (X). Ces données peuvent être représentées sous la forme d'un joli tableau, ressemblant à une simple addition en colonne. Dans l'exemple de notre test, admettons que nous ayons le tableau
Après avoir ignoré ces données, il nous reste une très simple "tranche de données" consistant uniquement des permissions liées à la capacité que nous testons, et pour lesquelles les valeurs sont soit Autoriser (A), Empêcher (P), ou Interdire (X). Ces données peuvent être représentées sous la forme d'un joli tableau, ressemblant à une simple addition en colonne.
 
=== Un exemple ===
 
Dans l'exemple de notre test, admettons que nous ayons le tableau


     P  A  P
     P  A  P
Ligne 70 : Ligne 80 :


Nous allons "combiner" les permissions et écrire le résultat au-dessous de la ligne horizontale. Le résultat, que nous appellerons la ''permission calculée'', sera soit ''A'', soit ''P'', soit ''X''. La fonction retournera ''true'' (vrai) ou ''false'' (faux) sur la base de la permission calculée.
Nous allons "combiner" les permissions et écrire le résultat au-dessous de la ligne horizontale. Le résultat, que nous appellerons la ''permission calculée'', sera soit ''A'', soit ''P'', soit ''X''. La fonction retournera ''true'' (vrai) ou ''false'' (faux) sur la base de la permission calculée.
=== L'algorithme ===


Avant d'effectuer notre "addition," nous vérifions si les données contiennent un ''X'' (Interdire) quelque part. Si c'est le cas, nous avons terminé : la permission calculée est alors ''X''. Dans notre exemple :
Avant d'effectuer notre "addition," nous vérifions si les données contiennent un ''X'' (Interdire) quelque part. Si c'est le cas, nous avons terminé : la permission calculée est alors ''X''. Dans notre exemple :
Ligne 93 : Ligne 105 :
#S'il n'y a qu'une seule permission sur la ligne, la permission calculée est la valeur de cette permssion ; STOP.
#S'il n'y a qu'une seule permission sur la ligne, la permission calculée est la valeur de cette permssion ; STOP.
#S'il y a deux ou plus de permissions sur la ligne, les additionner en prenant les valeurs numériques suivantes : A = +1, P = -1.
#S'il y a deux ou plus de permissions sur la ligne, les additionner en prenant les valeurs numériques suivantes : A = +1, P = -1.
##Si la somme est positive, la permission calculée est ''A'' ; STOP.
#*Si la somme est positive, la permission calculée est ''A'' ; STOP.
##Si la somme est négative, la permission calculée est ''P'' ; STOP.
#*Si la somme est négative, la permission calculée est ''P'' ; STOP.
##Si la somme est nulle, le calcul ne permet pas de conclure. Si nous sommes déjà sur la ligne du haut, la permission calculée est ''P''; STOP.  Sinon, passer à la ligne supérieure et aller à l'étape 2.
#*Si la somme est nulle, le calcul ne permet pas de conclure. Si nous sommes déjà sur la ligne du haut, la permission calculée est ''P''; STOP.  Sinon, passer à la ligne supérieure et aller à l'étape 2.


Notice that the algorithm stops when either (1) a conclusive result is obtained, or (2) the top line is reached without obtaining a conclusive result.
Notice that the algorithm stops when either (1) a conclusive result is obtained, or (2) the top line is reached without obtaining a conclusive result.
=== Application de l'algorithme à notre exemple ===


Let's take our original example, replacing the ''X'' by ''P'' to make it more interesting:
Let's take our original example, replacing the ''X'' by ''P'' to make it more interesting:
Ligne 131 : Ligne 145 :


         final result = has_capability(moodle/site:doanything, CONTEXT, USER);
         final result = has_capability(moodle/site:doanything, CONTEXT, USER);


==Voir aussi ==
==Voir aussi ==

Version du 26 février 2008 à 21:33

Remarque : la traduction de cet article n'est pas terminée. N'hésitez pas à traduire tout ou partie de cette page ou à la compléter. Vous pouvez aussi utiliser la page de discussion pour vos recommandations et suggestions d'améliorations.


Une des questions posées très fréquemment est : Quelles permissions possède un utilisateur pour un contexte donné ?

Cette page explique la fonction principale de Moodle utilisée pour répondre à cette question. Cette fonction est has_capability(). Elle se trouve dans le fichier lib/accesslib.php. Cette fonction implémente les règles pour calculer la "somme" des permissions de multiples rôles et dérogations. Pour un utilisateur donné, une capacité, et un contexte, la fonction renvoi true (vrai) si l'utilisateur est autorisé à effectuer l'action contrôlée par la capacité dans le contexte donné, et false (faux) sinon.

Cette page est écrite autant pour les non programmeurs que pour les programmeurs. Elle décrit ce que la fonction fait, pas comment. Le comment est compliqué, alors que le quoi est relativement simple !

Remarquez que la fonction n'essaie pas de répondre à la grande question posée dans la première phrase de cette page. Elle répond plutôt à la petite question "Un utilisateur peut-il faire l'action correspondant à la capacité CAP ici ?". Moodle ne calcule jamais la totalité des permissions d'un utilisateur. Une telle opération serait très coûteuse et et n'apporterait pas grand chose, puisque la plupart des permissions ne seraient jamais testées. Moodle calcule donc les permissions à la demande. Moodle ne place pas en cache les permissions calculées, mais les recalcule chaque fois qu'il est nécessaire de les tester. C'est la raison pour laquelle les attributions de rôles et les dérogations prennent effet immédiatement, et que ce n'était pas le cas dans Moodle 1.7.

Le calcul

La fonction est appelée ainsi :

   has_capability(CAP,CONTEXTE,UTILISATEUR);
  • CAP est la capacité testée (par exemple mod/quiz:attempt)
  • CONTEXTE est le contexte Système ou tout autre contexte imbriqué de façon arbitraire dans le contexte Système. À l'interne, la fonction utilise une notation analogue à celle des chemins d'accès des fichiers Unix pour représenter les contextes (par exemple, /1/3/4/150). De tels détails ne sont pas nécessaires dans cette discussion.
  • UTILISATEUR est l'utilisateur.

La fonction retourne un résultat vrai/faux :

  • true signifie que l'utilisateur est autorisé à effectuer l'action
  • false signifie que l'utilisateur n'est pas autorisé à effectuer l'action

Données utilisées par la fonction

Supposons que l'utilisateur UTILISATEUR soit sur le point de tenter un test (CAP = mod/quiz:attempt) dans le contexte d'un module imbriqué quatre niveaux au-dessous du contexte Système.

     Système
        |
    Catégorie A
        |					      
   Sous-catégorie B
        |
      Cours
        |
      Test  <--- l'utilisateur est ici

Le module test fera appel à la fonction has_capability() pour déterminer s'il doit permettre à l'utilisateur d'effectuer cette action.

La fonction considère les données de permissions suivantes :

  • la définition des rôles (situées dans le contexte Système),
  • les attributions de rôles qui ont été effectuées dans n'importe lequel des cinq contextes concernés,
  • les dérogations aux rôles ayant été définies dans n'importe lequel des contextes, sauf le contexte Système (il n'y a pas de dérogation de rôles possible dans le contexte Système).

Il est à remarquer qu'il peut y avoir plusieurs rôles attribués et/ou plusieurs dérogations définies dans un seul contexte.

La permission pour l'utilisateur de tenter le test ou non dépend des données ci-dessus, ainsi que de l'emplacement de ces données dans la chaîne des contextes.

La fonction has_capability() considère tous les rôles et toutes les dérogations ayant un impact sur UTILISATEUR dans CONTEXTE, mais elle ignore toutes les capacités autres que CAP. Elle ignore notamment :

  • les rôles qui ne sont pas attribués à l'utilisateur,
  • les capacités autres que celles que nous testons et
  • les permissions qui ne sont pas définies.

Après avoir ignoré ces données, il nous reste une très simple "tranche de données" consistant uniquement des permissions liées à la capacité que nous testons, et pour lesquelles les valeurs sont soit Autoriser (A), Empêcher (P), ou Interdire (X). Ces données peuvent être représentées sous la forme d'un joli tableau, ressemblant à une simple addition en colonne.

Un exemple

Dans l'exemple de notre test, admettons que nous ayons le tableau

   P  A  P
         A
   P  A  X
   A     P
      P  A
   --------
      ?    

La première rangée représente les permissions indiquées dans les définitions des rôles, une permission pour chacun des rôles que possède l'utilisateur. Dans notre exemple, on observe que trois rôles sont attribués à l'utilisateur. Les rangées suivantes représentent les dérogations. Dans l'exemple, on observe que l'utilisateur

  • une dérogation dans la catégorie A,
  • trois dérogations dans la catégorie B,
  • deux dérogations dans le cours et
  • deux dérogations dans le test proprement dit.

Dans la représentation d'un exemple complexe tel que celui-ci, il est judicieux d'aligner les dérogations de permissions au-dessous du rôle pour lequel la dérogation est définie, mais il n'est pas nécessaire de le faire, car nous n'additionnons pas les permissions en colonne comme nous le faisons avec des nombres.

Nous allons "combiner" les permissions et écrire le résultat au-dessous de la ligne horizontale. Le résultat, que nous appellerons la permission calculée, sera soit A, soit P, soit X. La fonction retournera true (vrai) ou false (faux) sur la base de la permission calculée.

L'algorithme

Avant d'effectuer notre "addition," nous vérifions si les données contiennent un X (Interdire) quelque part. Si c'est le cas, nous avons terminé : la permission calculée est alors X. Dans notre exemple :

   P  A  P
         A
   P  A  X
   A     P
      P  A
   --------
      X    <----- permission calculée


S'il n'y a pas de X, l'algorithme d'addition doit être utilisé. Comme il ne s'agit pas d'une véritable addition, l'algorithme

  • commence à la dernière ligne et remonte ligne par ligne,
  • considère la totalité d'une ligne à la fois (au lieu de travailler en colonnes),
  • peut se terminer avant d'atteindre la ligne du haut.

Voici comment fonctionne l'algorithme :

  1. Commencer sur la dernière ligne.
  2. S'il n'y a qu'une seule permission sur la ligne, la permission calculée est la valeur de cette permssion ; STOP.
  3. S'il y a deux ou plus de permissions sur la ligne, les additionner en prenant les valeurs numériques suivantes : A = +1, P = -1.
    • Si la somme est positive, la permission calculée est A ; STOP.
    • Si la somme est négative, la permission calculée est P ; STOP.
    • Si la somme est nulle, le calcul ne permet pas de conclure. Si nous sommes déjà sur la ligne du haut, la permission calculée est P; STOP. Sinon, passer à la ligne supérieure et aller à l'étape 2.

Notice that the algorithm stops when either (1) a conclusive result is obtained, or (2) the top line is reached without obtaining a conclusive result.

Application de l'algorithme à notre exemple

Let's take our original example, replacing the X by P to make it more interesting:

   P  A  P
         A
   P  A  P
   A     P
      P  A
   --------
      ?   

Now carry out the steps of the algorithm

  • There are two permissions on line 5
  • Since P + A = 0, the result is inconclusive and we must look at line 4.
  • There are two permissions on line 4.
  • Since A + P = 0, the result is inconclusive and we must look at line 3.
  • There are three permissions on line 3.
  • Since A + P + P = -1 we have a conclusive result! The computed permission is P.
   P  A  P
         A
   P  A  P
   A     P
      P  A
   --------
      P       <----- computed permission

If the computed permission had been A, the function would have returned true without further ado, allowing the user to perform the action.

However if the computed permission is P or X, the function does not immediately return false. Rather, it tests if the user has moodle/site:doanything = Allow (since this permission trumps all others). The function does this by calling itself:

       final result = has_capability(moodle/site:doanything, CONTEXT, USER);

Voir aussi