Skip to content

Droits par rôle ​

Une fois qu'on sait qui appelle (Authentification), reste à savoir ce qu'il a le droit de faire. Toutes ces décisions sont prises à un seul endroit : lib/timemanager/authorization.ex.

Les trois rôles ​

RôleEn une phrase
Employé (employee)pointe, voit ses heures, demande des corrections
Manager (manager)en plus, gère ses équipes : les heures, absences et semaines de ses membres
General Manager (general_manager)en plus, gère les comptes et voit toutes les équipes, comme s'il en était le manager

« Ses gens », pour un manager, ce sont les membres des équipes qu'il manage (Teams.manages?/2).

Le principe : une seule fonction, refus par défaut ​

Un contrôleur ne réécrit jamais une règle. Il pose la question :

elixir
Authorization.authorize(current_user, :edit_working_times, user_id)
# => :ok  ou  {:error, :forbidden}  (réponse 403)

Chaque règle est une clause de la fonction privée allowed?/3. La dernière clause refuse tout :

elixir
defp allowed?(_current_user, _action, _subject), do: false

Une action oubliée est donc refusée, jamais permise par erreur. C'est le principe du refus par défaut.

L'ordre des clauses compte

Elixir essaie les clauses de haut en bas et prend la première qui correspond. Exemple :

elixir
defp allowed?(%User{id: id}, :edit_working_times, id), do: false        # 1. soi-même : non
defp allowed?(%User{role: "general_manager"}, :edit_working_times, _), do: true  # 2. le GM : oui

Pour le General Manager qui veut modifier ses propres heures, la clause 1 correspond d'abord : refusé. Inverser les deux lignes lui donnerait ce droit. Toucher à l'ordre de ce fichier demande donc de relancer authorization_test.exs.

Le tableau complet ​

Action (authorize)EmployéManagerGeneral Manager
:view_data_of voir les heures, pointages, tableau de bordles siennesles siennes + ses genstout le monde
:clock pointer, prendre une pausesoisoisoi
:edit_working_times modifier des heures, absences, valider une semaine✗ses gens, jamais soitout le monde, jamais soi
:request_correction demander une correctionsoisoisoi
:review_correction accepter ou refuser une demande✗celles de ses gens, jamais la siennetoutes, la sienne comprise
:reopen_week rouvrir une semaine validée✗celles qu'il a validéestoutes
:list_users lister les comptes✗les comptes actifstous
:invite_user inviter une personne✗✗✓
:change_role promouvoir, retirer les droits✗✗les autres, jamais soi
:delete_account supprimer un comptele sienle sienles autres, jamais le sien
:update_profile nom, langue, thèmele sienle sienle sien
:update_email changer d'e-mail✗✗le sien (en deux temps)
:change_password changer de mot de passele sienle sienle sien
:export_data « Mes données »les siennesles siennesles siennes
:view_team, :view_team_averages, :manage_team✗les équipes qu'il managetoutes
:create_team créer une équipe✗dont il est le managerpour n'importe quel manager
:assign_team_manager changer le manager d'une équipe✗✗✓

Les règles qui protègent les employés ​

Le sujet demande de protéger les employés contre un usage non éthique de l'application. Plusieurs règles servent exactement à ça :

RègleCe qu'elle empêche
Personne ne pointe pour un autre (:clock, soi seulement)un manager qui « arrange » une arrivée
Personne ne modifie ses propres heures (:edit_working_times, jamais soi)un manager ou le GM qui s'ajoute des heures ; l'employé passe par une demande de correction, motivée et examinée
Toute modification est journaliséeune heure changée en silence : la personne la voit dans « Mes modifications » et reçoit une notification
« Mes données » à la personne seule (:export_data)même le GM ne peut pas télécharger le dossier complet de quelqu'un
Un manager ne voit que ses gensla surveillance de personnes qui ne sont pas dans ses équipes

Le General Manager examine ses propres demandes

Personne n'est au-dessus de lui : ses demandes de correction ne pourraient être examinées par personne d'autre. Il les examine donc lui-même, mais il ne modifie toujours jamais ses heures directement : sa correction passe par une demande, motivée et journalisée comme les autres.

Ce que les listes renvoient ​

Certaines routes n'ont pas besoin de authorize : elles ne renvoient que ce que l'appelant a le droit de voir.

RouteContenu
GET /api/teamsles équipes qu'on manage (manager), toutes (GM), une liste vide (employé)
GET /api/correctionsses propres demandes, plus celles qu'on peut examiner
GET /api/notificationsles siennes, toujours

Les mêmes règles côté web ​

Le site web cache les pages et les boutons interdits (meta.roles dans son routeur, canViewDataOf dans utils/permissions.js), pour le confort : on ne propose pas une action qui serait refusée. Mais seule l'API décide : un bouton affiché par erreur donnerait un 403, jamais une action interdite.