NXL Forge.Pendant que le marché rédige — nous livrons
Technique Odoo··4 min de lecture

Odoo 19 : l'opérateur any! ignore les règles d'accès sur le comodèle

Depuis Odoo 17, l'opérateur any traverse une relation avec un domaine imbriqué. Odoo 19 ajoute any!, qui fonctionne pareil mais court-circuite les règles d'accès du comodèle. Pratique dans le cœur, piège de sécurité dans du code métier.

Odoo 19ORMdomainessécuritédéveloppement

Quand vous filtrez des enregistrements liés dans Odoo, deux écritures coexistent depuis plusieurs versions. La notation pointée, du type [('partner_id.country_id.code', '=', 'FR')], reste la plus répandue. Depuis Odoo 17, l'opérateur any propose une autre voie pour traverser une relation avec un domaine imbriqué. Odoo 19 ajoute une variante que beaucoup de développeurs vont croiser sans en mesurer la portée : any!. Le point d'exclamation n'a rien de cosmétique, car il modifie le comportement de sécurité de la requête.

Ce que fait déjà any

L'opérateur any existe dans le cœur depuis Odoo 17. On le retrouve dans le tuple TERM_OPERATORS du fichier odoo/osv/expression.py, aux côtés de not any, en 17.0 comme en 18.0 1. Il sert à interroger un champ relationnel (many2one, one2many, many2many) ou le champ id, avec un domaine imbriqué.

Concrètement, [('order_line', 'any', [('product_id.type', '=', 'consu')])] sélectionne les commandes dont au moins une ligne porte un produit consommable. Le domaine placé en troisième position s'évalue sur le comodèle du champ. La forme not any retourne l'inverse : aucun enregistrement lié ne satisfait la condition. La documentation ORM précise d'ailleurs que la traversée classique par notation pointée revient en interne à un any. Écrire any de façon explicite rend surtout le domaine plus lisible quand la condition imbriquée devient longue, et évite les chaînes de points à rallonge.

Un détail mérite attention dès cette version. Lorsque la valeur est un domaine appliqué à un many2one ou à id, la recherche interne s'exécute avec active_test=False. Autrement dit, la traversée voit aussi les enregistrements archivés du comodèle.

Ce que réorganise Odoo 19

Odoo 19 déplace la logique des domaines. Le code historique de odoo/osv/expression.py migre vers un nouveau module, odoo/orm/domains.py. La liste des opérateurs reconnus s'appelle désormais STANDARD_CONDITION_OPERATORS, et elle contient quatre entrées pour cette famille : any, not any, any! et not any! 2. Les deux dernières sont nouvelles. Si vous migrez un module qui monkey-patchait expression.py, ce changement d'emplacement vous concerne directement.

any! : la traversée qui saute les règles d'accès

La différence tient en une phrase du code source. La docstring de domains.py indique que any! fonctionne comme any, mais qu'il évite d'ajouter les règles d'enregistrement sur le comodèle 3. En clair, la recherche imbriquée ne passe pas par les ir.rule définies sur le modèle lié.

Rappelons l'enjeu. Une règle d'enregistrement restreint les lignes qu'un utilisateur donné a le droit de voir. Avec un any ordinaire, le domaine imbriqué s'évalue en tenant compte de ces règles : un commercial qui ne voit que ses propres commandes ne matchera jamais un parent à travers un enregistrement lié qui lui est masqué. Avec any!, ce filtrage de sécurité est court-circuité. La correspondance du parent se calcule sur l'ensemble des données du comodèle, sans considérer qui interroge.

Le cœur d'Odoo emploie any! dans des cas précis : quand la valeur passée est déjà un objet SQL ou une Query, ou quand le champ porte l'attribut bypass_search_access. Ce sont des situations où le contrôle d'accès est censé avoir été traité en amont. Le problème apparaît quand un développeur reprend any! dans un domaine métier custom sans mesurer la portée. Le filtre semble alors « mieux marcher », puisqu'il remonte davantage de résultats, mais il peut révéler l'existence d'enregistrements qu'un profil ne devrait pas atteindre, ou classer un parent selon des enfants qui lui sont invisibles.

Le cas des enregistrements archivés

Le comportement active_test=False sur les many2one et id reste une source de surprises. Un domaine censé ignorer les partenaires archivés continuera de matcher à travers eux, parce que la traversée relationnelle les inclut. Le sujet est vivant côté dépôt : une correction récente ajuste justement la prise en compte des enregistrements archivés dans la recherche relationnelle par any 4. Pour les champs x2many, la logique diffère légèrement, la recherche s'appuyant sur le contexte du champ plutôt que sur un active_test forcé. Cette asymétrie vaut d'être testée sur vos propres modèles avant mise en production.

Notre lecture

Dans du code custom, any explicite gagne en lisibilité face aux chaînes pointées profondes, et nous le recommandons pour les domaines imbriqués un peu denses. any! relève d'un autre régime. Il ne doit pas servir à faire taire un utilisateur qui se plaint de résultats manquants, car ce résultat absent est peut-être une règle d'enregistrement qui fait son travail. Réservez-le aux cas où vous maîtrisez les données interrogées et où vous assumez de passer à côté des ir.rule. Le réflexe de validation reste le même que pour toute évolution ORM 19 : rejouez vos filtres sous un utilisateur à droits restreints, et vérifiez le comportement sur les enregistrements archivés. Pour le reste des ajustements ORM de cette version, nous détaillons les points qui touchent les modules dans notre panorama des changements ORM d'Odoo 19.

Sources

Footnotes

  1. Tuple TERM_OPERATORS du fichier odoo/osv/expression.py, branches 17.0 et 18.0 du dépôt officiel : présence de any et not any, absence de any!. ↩

  2. Ensemble STANDARD_CONDITION_OPERATORS du fichier odoo/orm/domains.py, branche 19.0 : any, not any, any!, not any!. ↩

  3. Docstring de odoo/orm/domains.py (19.0) : « any! works like any but bypass adding record rules on the comodel ». La même docstring précise le _search avec active_test=False pour un domaine sur many2one ou id. ↩

  4. Pull request de correction sur le dépôt odoo/odoo visant à inclure les enregistrements archivés dans la recherche relationnelle par any. ↩

Sur le même thème

Votre idée mérite un vrai logiciel

Une question, un projet Odoo ?

Modules préconfigurés, intégration, sur-mesure — parlons-en sans engagement.