From fc541ba6bdb59694113f7fda0dc9e75993524ec1 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Thu, 16 Dec 2021 18:33:56 +0100 Subject: [PATCH] [IMP] mail_broker: Set webhook --- mail_gateway/controllers/__init__.py | 1 - mail_gateway/controllers2/__init__.py | 2 + mail_gateway/controllers2/bot_controller.py | 41 ++++++ .../{controllers => controllers2}/main.py | 0 mail_gateway/models/mail_broker.py | 124 +++++++++++++++++- mail_gateway/models/mail_message.py | 4 +- mail_gateway/models/mail_message_broker.py | 2 +- mail_gateway/views/mail_broker.xml | 31 ++++- mail_gateway/views/mail_broker_channel.xml | 5 +- 9 files changed, 196 insertions(+), 14 deletions(-) delete mode 100644 mail_gateway/controllers/__init__.py create mode 100644 mail_gateway/controllers2/__init__.py create mode 100644 mail_gateway/controllers2/bot_controller.py rename mail_gateway/{controllers => controllers2}/main.py (100%) diff --git a/mail_gateway/controllers/__init__.py b/mail_gateway/controllers/__init__.py deleted file mode 100644 index 12a7e529b..000000000 --- a/mail_gateway/controllers/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import main diff --git a/mail_gateway/controllers2/__init__.py b/mail_gateway/controllers2/__init__.py new file mode 100644 index 000000000..df749a82b --- /dev/null +++ b/mail_gateway/controllers2/__init__.py @@ -0,0 +1,2 @@ +from . import main +from . import bot_controller diff --git a/mail_gateway/controllers2/bot_controller.py b/mail_gateway/controllers2/bot_controller.py new file mode 100644 index 000000000..575833d1c --- /dev/null +++ b/mail_gateway/controllers2/bot_controller.py @@ -0,0 +1,41 @@ +import logging + +from odoo import http +import json +_logger = logging.getLogger(__name__) + + +class BrokerController(http.Controller): + @http.route( + "/broker//update", + type="json", + auth="none", + method=["POST"], + csrf=False, + ) + def post_bot_updates(self, bot_key, **kwargs): + print(kwargs) + json_request = http.request.jsonrequest + bot_id = http.request.env["mail.broker"]._get_broker_id(bot_key, **kwargs) + if not bot_id: + return {} + broker = http.request.env["mail.broker"].browse(bot_id) + broker.with_user(broker.webhook_user_id.id).with_context( + notify_broker=True + )._receive_update(json_request) + return {} + + @http.route( + "/braaoker//update", + type="http", + auth="none", + method=["GET"], + csrf=False, + ) + def get_baaot_updates(self, bot_key, **kwargs): + # This might be used for verification + print(kwargs) + bot_id = http.request.env["mail.broker"]._get_broker_id(bot_key, **kwargs) + if not bot_id: + return "" + return http.request.env["mail.broker"].browse(bot_id)._verify_bot(**kwargs) diff --git a/mail_gateway/controllers/main.py b/mail_gateway/controllers2/main.py similarity index 100% rename from mail_gateway/controllers/main.py rename to mail_gateway/controllers2/main.py diff --git a/mail_gateway/models/mail_broker.py b/mail_gateway/models/mail_broker.py index 7bac6f6d4..4f8368e67 100644 --- a/mail_gateway/models/mail_broker.py +++ b/mail_gateway/models/mail_broker.py @@ -1,7 +1,7 @@ # Copyright 2020 Creu Blanca # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models +from odoo import api, fields, models, tools class MailBroker(models.Model): @@ -10,16 +10,68 @@ class MailBroker(models.Model): name = fields.Char(required=True) token = fields.Char(required=True) - _sql_constraints = [ - ("mail_broker_token", "unique(token)", "Token must be unique"), - ] broker_type = fields.Selection([], required=True) show_on_app = fields.Boolean(default=True) - webhook_url = fields.Char() + webhook_key = fields.Char() + integrated_webhook = fields.Boolean(readonly=True) + can_set_webhook = fields.Boolean(compute="_compute_webhook_checks") + webhook_url = fields.Char(compute="_compute_webhook_url") + has_new_channel_security = fields.Boolean( + help="When checked, channels are not created automatically" + ) webhook_user_id = fields.Many2one( "res.users", default=lambda self: self.env.user.id ) + _sql_constraints = [ + ("mail_broker_token", "unique(token)", "Token must be unique"), + ( + "mail_broker_webhook_key", + "unique(webhook_key)", + "Webhook Key must be unique", + ), + ] + + @api.depends("webhook_key") + def _compute_webhook_url(self): + for record in self: + record.webhook_url = record._get_webhook_url() + + def _get_webhook_url(self): + return "%s/broker/%s/update" % ( + self.webhook_url + or self.env["ir.config_parameter"].get_param("web.base.url"), + self.webhook_key, + ) + + def _can_set_webhook(self): + return self.webhook_key and self.webhook_user_id + + @api.depends("broker_type") + def _compute_webhook_checks(self): + for record in self: + record.can_set_webhook = record._can_set_webhook() + + def set_webhook(self): + self.ensure_one() + if self.can_set_webhook: + self._set_webhook() + + def remove_webhook(self): + self.ensure_one() + self._remove_webhook() + + def update_webhook(self): + self.ensure_one() + self.remove_webhook() + self.set_webhook() + + def _set_webhook(self): + self.integrated_webhook = True + + def _remove_webhook(self): + self.integrated_webhook = False + @api.model def broker_fetch_slot(self): result = [] @@ -46,3 +98,65 @@ class MailBroker(models.Model): if name: domain += [("name", "ilike", "%" + name + "%")] return self.env["mail.broker.channel"].search(domain).read(["name"]) + + def _receive_update(self, update): + return getattr(self, "_receive_update_%s" % self.broker_type)(update) + + def write(self, vals): + res = super(MailBroker, self).write(vals) + if "webhook_key" in vals: + self.clear_caches() + return res + + @api.model_create_single + def create(self, vals): + res = super(MailBroker, self).create(vals) + if "webhook_key" in vals: + self.clear_caches() + return res + + @api.model + @tools.ormcache() + def _get_broker_map(self): + result = {} + for record in self.search([]): + result[record.webhook_key] = record.id + return result + + @api.model + def _get_broker_id(self, key, **kwargs): + # We are using cache in order to avoid an exploit + if not key: + return False + return self._get_broker_map().get(key, False) + + def _get_channel_id(self, chat_token): + return ( + self.env["mail.broker.channel"] + .search( + [("token", "=", str(chat_token)), ("broker_id", "=", self.id)], limit=1 + ) + .id + ) + + def _get_channel(self, token, update, force_create=False): + chat_id = self._get_channel_id(token) + if chat_id: + return self.env["mail.broker.channel"].browse(chat_id) + if not force_create and self.has_new_channel_security: + return False + return self.env["mail.broker.channel"].create( + self._get_channel_vals(token, update) + ) + + def _get_channel_vals(self, token, update): + return { + "token": token, + "broker_id": self.id, + "show_on_app": self.show_on_app, + } + + def _verify_bot(self, **kwargs): + self.ensure_one() + # TODO: PASS IT TO WHATSAPP + return kwargs.get("hub.challenge") diff --git a/mail_gateway/models/mail_message.py b/mail_gateway/models/mail_message.py index 0a561cab1..c00f6985c 100644 --- a/mail_gateway/models/mail_message.py +++ b/mail_gateway/models/mail_message.py @@ -15,7 +15,9 @@ class MailMessage(models.Model): store=True, ) broker_unread = fields.Boolean(default=False) - broker_type = fields.Selection([("telegram", "Telegram")], required=True) + broker_type = fields.Selection( + selection=lambda r: r.env["mail.broker"]._fields["broker_type"].selection + ) broker_notification_ids = fields.One2many( "mail.message.broker", inverse_name="mail_message_id" ) diff --git a/mail_gateway/models/mail_message_broker.py b/mail_gateway/models/mail_message_broker.py index 98fe5de94..ba4a45136 100644 --- a/mail_gateway/models/mail_message_broker.py +++ b/mail_gateway/models/mail_message_broker.py @@ -51,7 +51,7 @@ class MailMessageBroker(models.Model): @api.model_create_multi def create(self, vals_list): messages = super().create(vals_list) - if self.env.context.get("notify_broker", True): + if self.env.context.get("notify_broker", False): notifications = [] for message in messages: notifications.append( diff --git a/mail_gateway/views/mail_broker.xml b/mail_gateway/views/mail_broker.xml index 0cff00f85..30b0a9d33 100644 --- a/mail_gateway/views/mail_broker.xml +++ b/mail_gateway/views/mail_broker.xml @@ -9,17 +9,42 @@
-
+
+
+ + - + + + -
diff --git a/mail_gateway/views/mail_broker_channel.xml b/mail_gateway/views/mail_broker_channel.xml index 7af017caf..6abefe62f 100644 --- a/mail_gateway/views/mail_broker_channel.xml +++ b/mail_gateway/views/mail_broker_channel.xml @@ -31,7 +31,6 @@ - @@ -53,14 +52,14 @@ - Mail Broken Channel + Mail Broker Channel mail.broker.channel tree,form [] {} - Mail Broken Channel + Mail Broker Channel