# Abilities

### Principe de base

La gestion des droits se base sur la librairie [@casl/ability](https://casl.js.org/v6/en/) et génère un ensemble de
droits (abilities), par exemple le droit d'afficher une page.

Ces droits dépendent de deux choses :

- Les modules du logiciel possédés par l'organisation
- Les rôles de l'utilisateur dans cette organisation (y compris d'éventuels droits personnalisés)

Par la suite, on pourra tester les droits d'un utilisateur à effectuer une action en faisant par exemple :

      if(!ability.can('display', 'subscription_page')) {
          throw new Error('Forbidden')
      }

### Fonctionnement

#### Les rôles de l'utilisateur

Les rôles de l'utilisateur sont récupérés auprès de l'API. Ils peuvent être de deux natures :

- rôle en tant que fonction (`ROLE_CA`, `ROLE_MEMBER`, ...)
- rôle lié à un droit particulier (`ROLE_GENERAL_CONFIG`, `ROLE_USERS`, ...)

#### Les fichiers de configuration

L'ensemble des droits est défini dans les fichiers de configuration `./config/abilities`

Chaque entrée est constituée :

- d'un nom
- d'une action associée (`display` ou `manage`)
- et éventuellement d'une ou plusieurs conditions

Exemple :

    adherent_list_page:
        action: 'display'
        conditions:
        - { function: organizationHasAnyModule, parameters: ['Users'] }
        - { function: organizationIsShowAdherentList }
        - { function: accessHasAnyProfile, parameters: ['member'] }

#### Le plugin ability.ts

Le plugin `plugins/ability.ts` :

1. récupère les profils de l'access et de l'organisation
2. instancie le service AbilityBuilder
3. lui injecte les deux profils récupérés plus haut
4. puis créé un listener qui appellera la méthode `buildAbilities` de ce service à chaque mise à jour du profil de l'organisation

#### Le service AbilityBuilder

Ce service fait appel tour à tour à deux méthodes `buildAbilitiesFromRoles` et `buildAbilitiesFromConfig`

La première fait appel à son tour au service `RoleUtils` pour convertir tous les rôles (hors rôles liés à une fonction,
par ex "Membre du CA") en droits. Ainsi un rôle `ROLE_EXAMENS` deviendra un droit `{subject: 'examen', action: 'manage'}`
et un rôle deviendra un droits `{subject: 'billing_administration', action: 'display'}`

La seconde construit les droits à partir des fichiers de configuration qui définissent les conditions d'accès aux
différents droits (voir plus haut). Ces conditions sont testées de diverses manières selon leur nature. Par exemple,
la condition `accessIsAdminAccount` deviendra un test sur `accessProfile.isAdminAccount`.

Une fois construit, ces droits sont passés au service MongoAbility de la librairie Casl.

#### Utilisation

A partir de là, on pourra tester les droits d'un utilisateur dans une page ou un composable à l'aide de la commande
`ability.can(action, subject)`.

Cette méthode sera ainsi appelée en en-tête de la section script de chaque page, et pour chaque entrée des menus.
