Définitions

Rôles

La gestion des droits dans Scenari est basée sur le concept de rôles. Par rôle, nous entendons une fonction assumée par les acteurs d'un système. Exemples : rédacteur, éditeur, correcteur, traducteur, documentaliste...

Dans les conceptions classiques d'un contrôle d'accès par rôles, ceux-ci consistent en un regroupement d'utilisateurs sur une partie d'un système (worskpace/espace dans notre cas) par son critère d'accès (le chemin). Les rôles dans Scenari peuvent être définis par d'autres critères que le chemin, tel que le type de l'objet dans le sens d'un modèle documentaire, pour par exemple restreindre l'édition d'items dédiés à l'indexation à un rôle documentaliste.

Outre cet enjeu fonctionnel, l'introduction des rôles permet :

  • de définir les classes d'acteurs en amont de l'instance de l'application, lors du développement du modèle documentaire,

  • de définir des rôles implicites sur les objets tel que créateur, pour par exemple restreindre l'initiation d'un workflow sur un objet à son créateur,

  • avoir une interface utilisateur réactive s'adaptant finement aux droits alloués à l'utilisateur, sans que le client n'ait besoin d'interroger le serveur ou d'avoir une vue complète sur le système.

Définition des rôles d'un utilisateur pour un objet

getRoles(object, user) -> role[]

avec :

  • user : utilisateur connecté (incluant son profil, ses appartenance à des groupes, etc),

  • object : objet sur lequel l'utilisateur joue un ou plusieurs rôles. Aujourd'hui, les objets sont des items, des espaces, des ateliers, le serveur (mais ce pourrait être d'autres objets : les publications, les documents-dossiers[1], les workflow, les annotations...),

  • role[] : ensemble de rôles assumés par un utilisateur sur un objet donné,

  • getRoles() : fonction qui doit fournir la liste des rôles pour un couple (objet, utilisateur) donné.

Permissions

Une permission représente une opération possible sur un objet. Il se caractérise par un verbe (read, write, etc...). L'ensemble des permissions est défini en dur dans le code de l'application, par une hiérarchie représentant la spécialisation de l'opération. Cette spécialisation se veut très fine, allant jusqu'à décrire la visibilité des opérations dans l'interface graphique.

Droits systèmes

La gestion de droits par rôles est complémentaire d'une gestion de droits dit "système", représentant des contraintes extérieurs indépendantes des rôles joués par chaque utilisateur sur les objets. Par exemple, sans modifier les rôles de chaque utilisateur sur un item, ce dernier peut-être verrouillé en écriture car :

  • il est en cours d'édition par un auteur

  • il est impliqué dans un processus de workflow qui impose de ne pas modifier cet item pendant la durée de ce workflow

  • l'item n'est pas un item appartenant à l'atelier mais un item externe (cf liens inter-ateliers)

  • un mécanisme de backup impose de verrouiller tout accès en écriture pendant une heure chaque nuit

  • etc.

Exemples d'un ensemble de permissions avec son arbre de spécialisation

La permission do est la racine de toutes les permissions.

Les permissions de 2ème niveau correspondent à des grandes classes d'actions (lire, écrire, administrer...).

Les permissions de niveaux suivants correspondent à des actions sur des types d'objets précis.

Les permissions de dernier niveau sont des permissions spécifiques à chaque élément d'interface graphiques (comme les views..). Une même action peut ainsi être autorisée au travers d'une certaine interface graphique, mais pas une une autre.

Les permissions systèmes sont précisées entre parenthèses.

  • do

    • read (READ)

    • write (WRITE)

      • item.write

        • item.create

          • view.wspnav.item.create

        • item.delete

          • view.wspnav.item.delete

        • item.update

          • view.wspnav.item.update

          • view.mainview.item.update

        • item-version.restore

          • view.versions.restore

      • item-version.create

        • view.versions.create

    • admin (ALL)

      • wsp.create

        • view.wspManager.wsp.create

      • server.create

      • server.installPack

Caractéristiques des rôles

  • Priorité : les différents rôles définis pour un utilisateur sur un objet peuvent entraîner des permissions contradictoires. Les rôles sont donc caractérisés par une priorité influençant l'ordre de contrôle des permissions.

  • Extension : une notion d'extension de rôle est introduite pour faciliter la définition des autorisations : un auteur est un contributeur qui dispose en plus des permissions X et en moins les permissions Y.

  • Groupe : les rôles peuvent être groupé pour déterminer une relation d'exclusivité entre les rôles. Cette contrainte n'est pas forcément forte : elle sert avant tout à présenter une interface graphique de sélection du rôle adaptée à l'environnement métier.

Autorisations

Les rôles jouant le rôle d'indirection par rapport à l'association objet / utilisateur, le test effectif déterminant si une action est permise ou non se résume à une relation entre les permissions et les rôles. Elle peut être définie en amont de l'instance applicative, sous la forme d'un ensemble de triplets (role, permission, allowed).

Exemple de paramétrage

  • (superAdmin, do, allow) : un utilisateur qui a le rôle superAdmin peut tout faire.

  • (contributor, do, deny) : un utilisateur qui a le rôle contributor ne peut rien faire par défaut. Les permissions lui seront autorisées plus localement.

Définition des autorisations

isAllowed(permission, role[], systemRights) -> boolean

avec :

  • permission : permission à tester,

  • role[] : liste de rôles issus de la formule getRoles(object, user),

  • systemRights : droits systèmes associés à l'objet,

  • isAllowed() : fonction qui détermine si au moins un des rôles passés en paramètre dispose d'une permission.

L'algorithme de isAllowed() est :

  1. tri des rôles selon leur priorité ;

  2. si des droits systèmes sont associés à la permission, contrôle que les droits systèmes de l'objet passé en paramètre inclus les droits requis par la permission, sinon retourne faux.

  3. pour chaque rôle :

    1. recherche d'un triplet avec la permission. si un triplet est trouvé, la fonction retourne vrai si allow, faux si deny ;

    2. si aucun triplet trouvé, on recommence avec le rôle qu'il étend;

  4. si aucun triplet trouvé, on recommence l'étape 2 avec la permission parente ;

  5. si aucun trouvé, on retourne faux (mais c'est alors une erreur de paramétrage à moins que la liste des rôles ne soit vide).