Étape 1 sur 2 · environ 45 min

Lisez les droits d'accès sans les confondre avec un filtre

Le Jour 2 a ouvert les notes et les catégories aux utilisateurs internes. Relisez maintenant chaque colonne du fichier : elle autorise une opération sur un modèle, mais elle ne choisit pas encore les enregistrements accessibles.

1. Retrouvez les deux lignes du Jour 2

Ouvrez le fichier ci-dessous. Il doit toujours contenir son en-tête et exactement deux lignes de droits : une pour training.note, l'autre pour training.note.category. Ne les modifiez pas dans cette étape.

custom_addons/training_hello/security/ir.model.access.csv
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_training_note_user,training.note user,model_training_note,base.group_user,1,1,1,1
access_training_note_category_user,training.note.category user,model_training_note_category,base.group_user,1,1,1,1

Chaque ligne crée un droit d'accès Odoo pour un modèle. Les quatre dernières valeurs correspondent aux opérations CRUD : créer, lire, modifier et supprimer. Elles ne décrivent pas une note ou une catégorie particulière.

2. Lisez chaque colonne avec ses valeurs exactes

Une ligne contient huit colonnes. Lisez-les de gauche à droite : d'abord l'identité du droit, puis le modèle et le groupe concernés, enfin les quatre opérations autorisées.

2.1 id

  1. Valeur : elle donne un identifiant externe stable au droit. Lors d'une mise à niveau, Odoo retrouve ainsi le même enregistrement ir.model.access. Ce n'est pas l'identifiant entier d'une ligne PostgreSQL.
  2. Syntaxe : écrivez un nom technique unique, sans espace. Dans ce fichier, utilisez des lettres minuscules, des chiffres et des tirets bas.
  3. Notes : la ligne des notes utilise access_training_note_user.

2.2 name

  1. Valeur : elle donne un nom lisible à ce droit dans l'administration d'Odoo. Elle aide à le reconnaître, mais ne décide aucune autorisation.
  2. Syntaxe : écrivez un libellé court. Si votre texte contient une virgule, placez-le entre guillemets doubles pour conserver une seule colonne CSV.
  3. Notes : la ligne des notes affiche training.note user.

2.3 model_id:id

  1. Valeur : elle désigne le modèle auquel le droit s'applique. Le suffixe :id demande à Odoo de résoudre une référence vers un enregistrement ir.model.
  2. Syntaxe : indiquez l'identifiant externe du modèle. Dans un fichier chargé par le même module, vous pouvez omettre le préfixe du module.
  3. Notes : les notes utilisent model_training_note, la référence du modèle Python training.note.

2.4 group_id:id

  1. Valeur : elle désigne le groupe qui reçoit ce droit. Ici, il s'agit des utilisateurs internes d'Odoo.
  2. Syntaxe : indiquez l'identifiant externe du groupe. Gardez son préfixe lorsque le groupe appartient à un autre module ; une valeur vide rendrait le droit applicable à tous les utilisateurs.
  3. Notes : les notes utilisent base.group_user, le groupe interne fourni par le module base.
Bon à savoir — pourquoi base. ?

Le groupe est fourni par le module base : son identifiant complet est donc base.group_user. Les deux modèles sont fournis par training_hello, le module qui charge ce fichier ; c'est pourquoi leurs références peuvent rester courtes ici.

Bon à savoir — la convention 1 et 0

Dans chacune des quatre colonnes d'autorisation, 1 accorde l'opération dans cette ligne et 0 ne l'accorde pas. Les quatre sous-sections suivantes utilisent cette même convention.

2.5 perm_read

  1. Valeur : elle autorise la recherche et la lecture des enregistrements du modèle.
  2. Syntaxe : utilisez la convention 1/0 ci-dessus ; ici, la valeur est 1.
  3. Notes : 1 permet à un utilisateur interne de retrouver et lire les notes.

2.6 perm_write

  1. Valeur : elle autorise la modification d'un enregistrement déjà créé.
  2. Syntaxe : utilisez la convention 1/0 ci-dessus ; ici, la valeur est 1.
  3. Notes : 1 permet à un utilisateur interne de modifier le titre ou le contenu d'une note accessible.

2.7 perm_create

  1. Valeur : elle autorise la création d'un nouvel enregistrement du modèle.
  2. Syntaxe : utilisez la convention 1/0 ci-dessus ; ici, la valeur est 1.
  3. Notes : 1 permet à un utilisateur interne de créer une nouvelle training.note.

2.8 perm_unlink

  1. Valeur : elle autorise la suppression d'un enregistrement. Dans l'ORM, cette opération s'appelle unlink().
  2. Syntaxe : utilisez la convention 1/0 ci-dessus ; ici, la valeur est 1.
  3. Notes : 1 permet à un utilisateur interne de supprimer une note accessible.

La première ligne accorde donc les quatre opérations sur training.note. La seconde accorde séparément les mêmes opérations sur training.note.category. Le droit sur les notes n'accorde pas automatiquement le droit sur les catégories, même si category_id relie les deux modèles.

Bon à savoir — les ACL s'additionnent

Un 0 ne retire pas un droit accordé par une autre ACL, via un autre groupe de l'utilisateur. S'il n'existe aucune ACL qui accorde l'opération, Odoo la refuse.

3. Distinguez l'ACL de la règle sur les enregistrements

CoucheQuestion posée
ACLQuelles opérations un groupe peut-il demander sur le modèle ?
Règle sur les enregistrementsQuels enregistrements cet utilisateur peut-il atteindre ?

L'ACL autorise donc une opération sur le modèle ; la règle sur les enregistrements limite ensuite les lignes accessibles. L'API du Jour 4, comme les autres routes du parcours, passe par les mêmes contrôles de l'ORM Odoo.

Point de contrôle — inspectez le CSV

Dans security/ir.model.access.csv, vérifiez l'en-tête puis les deux lignes de données affichées plus haut. Chaque ligne de données contient huit valeurs : la référence du bon modèle, base.group_user, puis quatre valeurs 1. Confirmez aussi qu'aucune colonne ne contient un domaine ou un identifiant de propriétaire : ce filtrage n'appartient pas à l'ACL.

4. Testez ce que perm_read=0 bloque réellement

Ce test est temporaire. Il montre que le même droit d'accès est vérifié avant l'affichage, quelle que soit l'interface qui demande les notes.

  1. Dans la ligne access_training_note_user, remplacez seulement la première des quatre permissions par 0 : ...,base.group_user,0,1,1,1.
  2. Dans Applications, mettez Hello Odoo à niveau. Cette opération recharge le CSV dans la base ; un simple redémarrage d'Odoo ne suffit pas. Comme aucun code Python ne change ici, ne redémarrez pas le serveur.
  3. Avec le même utilisateur interne connecté, essayez les trois chemins déjà créés au Jour 2 : Notes de formation → Notes, la page /training/notes et le menu Notes Owl.

À observer : les trois chemins refusent la lecture des notes. La vue standard, le contrôleur QWeb et le composant Owl ont des présentations différentes, mais tous appellent training.note dans l'environnement de l'utilisateur connecté. L'ORM constate alors qu'aucune ACL de cet utilisateur n'accorde la lecture.

base.group_user n'est pas un compte système

Ce groupe représente les utilisateurs internes d'Odoo. C'est le groupe de votre compte d'exercice connecté, pas l'utilisateur public d'une route auth="public", et pas le superutilisateur. Une route anonyme utilise l'utilisateur public, qui n'hérite pas de cette ligne. Le superutilisateur, ou du code qui utilise sudo(), peut contourner les ACL : ce test ne démontre donc pas qu'un « compte système » est bloqué.

4.1 Retirez aussi sudo() de la route publique

La première route API du Jour 4 est une démonstration locale avec auth="public". La capture montre son état de départ : sudo() demande explicitement à l'ORM de ne pas appliquer les droits de l'utilisateur de la requête.

Extrait de notes_api.py : la route GET /training/api/notes utilise auth=public et l'appel search_read est précédé de sudo().
État de départ de la démonstration locale : le sudo() visible ici explique pourquoi la route pouvait lire les notes sans session.

Dans custom_addons/training_hello/controllers/notes_api.py, retirez seulement .sudo() de la lecture, afin d'obtenir request.env["training.note"].search_read(...). Redémarrez Odoo, car le contrôleur est du code Python.

4.2 Identifiez l'utilisateur public

Lorsqu'une personne non connectée appelle une route auth="public", Odoo exécute la route avec son utilisateur public partagé. Cet utilisateur appartient au groupe base.group_public. Il est différent de votre utilisateur interne et ne reçoit pas les ACL de base.group_user.

À observer : après avoir retiré sudo(), l'appel anonyme à /training/api/notes est refusé. C'est le comportement attendu pour le journal : l'utilisateur public ne possède aucune ACL de lecture sur training.note.

Ne donnez pas la lecture publique au journal

Il serait possible de viser base.group_public dans une ACL avec perm_read=1. Nous ne le faisons pas ici : sans une règle sur les enregistrements adaptée, chaque visiteur pourrait lire toutes les notes. Pour de vraies données publiques, créez plutôt un modèle ou un champ de publication explicite, puis ajoutez une ACL et une règle qui limitent strictement les enregistrements publiés.

Un 0 ne constitue pas une interdiction absolue

Dans cette ligne, 0 signifie seulement que base.group_user ne reçoit pas le droit de lire. Si l'utilisateur possède un autre groupe avec une ACL qui accorde perm_read=1, il peut encore lire le modèle. Ici, les trois interfaces échouent parce qu'aucune autre ACL ne rend la lecture disponible à votre utilisateur interne.

  1. Replacez 1 dans perm_read, mettez de nouveau le module à niveau, puis rechargez les trois écrans.
Point de contrôle — restaurez la lecture

Après la seconde mise à niveau, les notes réapparaissent dans la vue standard, sur /training/notes et dans Notes Owl. Vous avez vérifié qu'une ACL autorise une opération sur le modèle, avant que chaque interface ne présente les enregistrements.

5. Exercice — donnez l'accès aux notes à un groupe dédié

Jusqu'ici, l'ACL visait tous les utilisateurs internes avec base.group_user. Créez maintenant un groupe propre au journal et donnez-lui l'accès aux notes. Une ACL vise un groupe, jamais un utilisateur précis : c'est l'appartenance de l'utilisateur au groupe qui lui donne le droit.

5.1 Créez le groupe dans le module

Un groupe déclaré par le module possède un external ID fiable, réutilisable dans le CSV. Créez ce fichier :

custom_addons/training_hello/security/training_note_groups.xml
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
    <record id="group_training_note_user" model="res.groups">
        <field name="name">Training Notes User</field>
    </record>
</odoo>

Dans la liste data de custom_addons/training_hello/__manifest__.py, ajoutez "security/training_note_groups.xml", juste avant "security/ir.model.access.csv",. Mettez ensuite Hello Odoo à niveau dans Applications. Cette mise à niveau crée le groupe dans la base ; aucun redémarrage Python n'est nécessaire.

5.2 Ajoutez le groupe aux deux comptes

Dans Paramètres → Utilisateurs et sociétés → Groupes, retrouvez Training Notes User. Le menu de la capture vous mène à la liste des groupes.

Dans Paramètres, le menu Utilisateurs et sociétés est ouvert et montre l'entrée Groupes.
Ouvrez Groupes pour vérifier que la mise à niveau a créé Training Notes User.
  1. Ouvrez Paramètres → Utilisateurs et sociétés → Utilisateurs et créez un utilisateur interne nommé Sam Formation. Donnez-lui un identifiant de connexion et un mot de passe temporaires réservés à l'exercice.
  2. Dans les droits d'accès de Sam, ajoutez le groupe Training Notes User.
  3. Ajoutez aussi ce groupe à votre propre compte, que la suite appellera Alex. Vous conservez ainsi l'accès aux notes après la modification de l'ACL.
  4. Déconnectez-vous, puis connectez-vous une fois comme Sam. Vous vérifiez ainsi que le nouveau compte peut ouvrir l'interface Odoo.

5.3 Remplacez le groupe de la ligne des notes

Dans custom_addons/training_hello/security/ir.model.access.csv, remplacez uniquement base.group_user par l'external ID du nouveau groupe dans la ligne des notes :

Modification de la ligne des notes dans ir.model.access.csv
access_training_note_user,training.note user,model_training_note,group_training_note_user,1,1,1,1

Ne placez pas l'identifiant de Sam dans cette ligne : le quatrième champ attend l'external ID d'un groupe. Mettez Hello Odoo à niveau pour recharger le CSV. Connecté comme Sam, ouvrez Notes de formation → Notes : l'accès est accordé parce que Sam est membre de Training Notes User. Un utilisateur interne qui ne possède pas ce groupe ne reçoit plus cette ACL sur les notes.

Point de contrôle — vérifiez le nouveau groupe

Alex et Sam ont le groupe Training Notes User. Après la mise à niveau, les deux comptes peuvent ouvrir les notes. Vous avez séparé « utilisateur interne » de « utilisateur autorisé à manipuler le journal » ; la section 4 utilisera ces deux mêmes comptes.