From 71b5ffd79c27879af8f883c9cff2af7ba3d98ce4 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi <fme@odoo.com> Date: Mon, 12 Jun 2023 15:43:35 +0200 Subject: [PATCH] [ADD] base: add support for custom functions in imbus & cron_trigger notify This patch provides the possibility to implement a custom security layer on top of Odoo's bus notification system (and cron live triggering system) which both use postgresql's NOTIFY command. The key addition is the `ODOO_NOTIFY_FUNCTION` environment variable (opt-in), which can now define a postgresql function to be called instead of the NOTIFY command. This allows for greater flexibility and control over the notification and triggering mechanisms within Odoo. closes odoo/odoo#130370 Signed-off-by: Fabien Meghazi (fme) <fme@odoo.com> --- addons/bus/models/bus.py | 12 ++++++++++-- odoo/addons/base/models/ir_cron.py | 11 ++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/addons/bus/models/bus.py b/addons/bus/models/bus.py index e94c8f37969a..31f5d91a7096 100644 --- a/addons/bus/models/bus.py +++ b/addons/bus/models/bus.py @@ -2,11 +2,12 @@ import datetime import json import logging +import os import random import select import threading import time -from psycopg2 import InterfaceError +from psycopg2 import InterfaceError, sql import odoo import odoo.service.server as servermod @@ -19,6 +20,9 @@ _logger = logging.getLogger(__name__) # longpolling timeout connection TIMEOUT = 50 +# custom function to call instead of NOTIFY postgresql command (opt-in) +ODOO_NOTIFY_FUNCTION = os.environ.get('ODOO_NOTIFY_FUNCTION') + #---------------------------------------------------------- # Bus #---------------------------------------------------------- @@ -77,7 +81,11 @@ class ImBus(models.Model): @self.env.cr.postcommit.add def notify(): with odoo.sql_db.db_connect('postgres').cursor() as cr: - cr.execute("notify imbus, %s", (json_dump(list(channels)),)) + if ODOO_NOTIFY_FUNCTION: + query = sql.SQL("SELECT {}('imbus', %s)").format(sql.Identifier(ODOO_NOTIFY_FUNCTION)) + else: + query = "NOTIFY imbus, %s" + cr.execute(query, (json_dump(list(channels)), )) @api.model def _sendone(self, channel, notification_type, message): diff --git a/odoo/addons/base/models/ir_cron.py b/odoo/addons/base/models/ir_cron.py index 1345021fc211..46d6f0451f17 100644 --- a/odoo/addons/base/models/ir_cron.py +++ b/odoo/addons/base/models/ir_cron.py @@ -12,11 +12,16 @@ import odoo from odoo import api, fields, models, _ from odoo.exceptions import UserError +from psycopg2 import sql + _logger = logging.getLogger(__name__) BASE_VERSION = odoo.modules.load_information_from_description_file('base')['version'] MAX_FAIL_TIME = timedelta(hours=5) # chosen with a fair roll of the dice +# custom function to call instead of NOTIFY postgresql command (opt-in) +ODOO_NOTIFY_FUNCTION = os.environ.get('ODOO_NOTIFY_FUNCTION') + class BadVersion(Exception): pass @@ -504,7 +509,11 @@ class ir_cron(models.Model): ir_cron modification and on trigger creation (regardless of call_at) """ with odoo.sql_db.db_connect('postgres').cursor() as cr: - cr.execute('NOTIFY cron_trigger, %s', [self.env.cr.dbname]) + if ODOO_NOTIFY_FUNCTION: + query = sql.SQL("SELECT {}('cron_trigger', %s)").format(sql.Identifier(ODOO_NOTIFY_FUNCTION)) + else: + query = "NOTIFY cron_trigger, %s" + cr.execute(query, [self.env.cr.dbname]) _logger.debug("cron workers notified") -- GitLab