1. Remplacez le contrôleur anonyme
Ouvrez le fichier utilisé à la section 2 et remplacez tout son contenu par cette version. L’URL, la méthode GET et la lecture ORM restent les mêmes. La route POST anonyme disparaît pour le moment ; vous la recréerez proprement dans la section suivante.
from odoo import http
from odoo.http import request
class TrainingNotesApiController(http.Controller):
@http.route(
"/training/api/notes",
type="http",
auth="bearer",
methods=["GET"],
)
def list_notes(self):
notes = request.env["training.note"].search_read(
fields=["id", "title", "body"],
order="id desc",
limit=20,
)
for note in notes:
note["body"] = note["body"] or ""
return request.make_json_response({
"notes": notes,
"count": len(notes),
})auth="bearer" demande à Odoo d’examiner l’en-tête Authorization avant d’appeler list_notes(). Avec une clé valide, Odoo retrouve l’utilisateur propriétaire et place son identité dans request.env, l’environnement de l’ORM pour cette requête.
L’appel request.env["training.note"].search_read(...) applique donc l’ACL et les éventuelles règles sur les enregistrements de cet utilisateur. Il conserve les trois champs et la limite de vingt notes, mais n’utilise plus sudo(). Les règles de propriétaire du jour 5 ne sont pas encore en place ; à ce stade, vous observez les droits réellement définis au jour 2.
Le modèle du Jour 2 définit le contenu ainsi :
body = fields.Text(string="Contenu")Ce champ ne comporte pas required=True et peut donc ne contenir aucun texte. La boucle remplace la valeur vide par "" afin que body reste une chaîne dans le JSON. La réponse garde les deux clés de premier niveau notes et count.
La requête n’envoie ni identifiant utilisateur ni champ d’identité. Elle présente seulement la clé. Odoo détermine son propriétaire, puis l’ORM travaille avec les droits de ce compte.
2. Redémarrez Odoo
Action qui redémarre Odoo : redémarrez votre processus Odoo local, puis attendez que les journaux indiquent que le serveur est de nouveau prêt. Vous avez modifié du Python ; un rechargement du navigateur ne relit pas le contrôleur.
Vous n’avez modifié ni champ, ni XML, ni manifeste. Une mise à niveau du module n’est donc pas nécessaire pour ce seul remplacement.
3. Comparez les trois appels sous Linux ou macOS
Utilisez le même terminal que dans l’étape précédente. --include affiche le statut et les en-têtes HTTP avant le corps. Les trois commandes visent exactement la même route locale.
Clé acceptée
curl --include \
--header "Authorization: Bearer YOUR_API_KEY" \
http://127.0.0.1:8069/training/api/notesRésultat attendu : la première ligne contient 200 OK, le Content-Type est JSON et le corps contient les notes que cet utilisateur peut lire.
{
"notes": [
{
"id": 3,
"title": "Une base d'exercice",
"body": "Nous pouvons y apprendre sans toucher à des données réelles."
},
{
"id": 2,
"title": "Observer avant de modifier",
"body": "La mise à niveau est le moment où Odoo applique les fichiers du module."
},
{
"id": 1,
"title": "Bienvenue",
"body": "Une note est un enregistrement stocké par Odoo."
}
],
"count": 3
}Ne comparez pas les nombres id avec l’exemple : ils dépendent de votre base. Vérifiez plutôt l’ordre décroissant, les trois clés de chaque note et l’égalité entre count et la longueur de notes.
Clé absente
curl --include \
http://127.0.0.1:8069/training/api/notesRésultat attendu : Odoo répond 401 Unauthorized, annonce l’authentification Bearer dans l’en-tête WWW-Authenticate et ne renvoie aucune note.
Clé invalide
curl --include \
--header "Authorization: Bearer YOUR_API_KEYx" \
http://127.0.0.1:8069/training/api/notesRésultat attendu : Odoo répond encore 401 Unauthorized. Le serveur a reçu un secret, mais il ne correspond à aucune clé API active.
4. Exécutez les mêmes cas dans PowerShell
Dans PowerShell, écrivez curl.exe afin d’appeler explicitement le programme cURL. Remplacez YOUR_API_KEY dans chaque commande par votre clé.
curl.exe --include --header "Authorization: Bearer YOUR_API_KEY" http://127.0.0.1:8069/training/api/notescurl.exe --include http://127.0.0.1:8069/training/api/notescurl.exe --include --header "Authorization: Bearer YOUR_API_KEYx" http://127.0.0.1:8069/training/api/notesVous devez observer la même suite : 200 OK avec les notes, puis deux réponses 401 Unauthorized sans données. Dans les deux refus, Odoo arrête la requête avant la lecture de training.note ; le contrôleur ne compare jamais la clé lui-même.
5. Conservez la clé pour les deux sections suivantes
Gardez ce terminal ouvert : la création par l’API, puis le client Vue, utiliseront la même clé temporaire. Ne copiez toujours pas la valeur dans un fichier source. Vous révoquerez la clé et effacerez la variable à la toute fin du Jour 4.
La même URL renvoie les vraies notes avec une clé valide et refuse les appels sans clé ou avec une clé invalide. L’identité vient d’Odoo, puis l’ORM applique les droits de cet utilisateur.