diff --git a/mailcatcher_menu/__init__.py b/mailcatcher_menu/__init__.py index 511a0ca..15668ac 100644 --- a/mailcatcher_menu/__init__.py +++ b/mailcatcher_menu/__init__.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- from . import controllers -from . import models \ No newline at end of file +from . import models +from . import wizard +from .hooks import post_init_hook \ No newline at end of file diff --git a/mailcatcher_menu/__manifest__.py b/mailcatcher_menu/__manifest__.py index 99cdf14..fba7339 100644 --- a/mailcatcher_menu/__manifest__.py +++ b/mailcatcher_menu/__manifest__.py @@ -17,7 +17,10 @@ 'module_type': 'official', 'depends': ['mail','base',], 'data': [ + 'wizard/install_warning_wizard_view.xml', 'views/views.xml', - 'data/data.xml' + 'data/data.xml', + 'security/ir.model.access.csv', ], + 'post_init_hook': 'post_init_hook', } diff --git a/mailcatcher_menu/controllers/controllers.py b/mailcatcher_menu/controllers/controllers.py index bcb2eda..4d06ad4 100644 --- a/mailcatcher_menu/controllers/controllers.py +++ b/mailcatcher_menu/controllers/controllers.py @@ -1,21 +1,55 @@ -# -*- coding: utf-8 -*- -# from odoo import http +# Copyright 2024 Open2Bizz +# License LGPL-3 + +import logging +import requests + +from odoo import http +from odoo.http import request, Response + +_logger = logging.getLogger(__name__) + +MAILHOG_BASE = "http://localhost:8025" -# class TestserverO2b(http.Controller): -# @http.route('/testserver_o2b/testserver_o2b/', auth='public') -# def index(self, **kw): -# return "Hello, world" +class MailcatcherProxy(http.Controller): -# @http.route('/testserver_o2b/testserver_o2b/objects/', auth='public') -# def list(self, **kw): -# return http.request.render('testserver_o2b.listing', { -# 'root': '/testserver_o2b/testserver_o2b', -# 'objects': http.request.env['testserver_o2b.testserver_o2b'].search([]), -# }) + @http.route(['/mailcatcher', '/mailcatcher/'], + type='http', auth='user', website=False, csrf=False) + def mailcatcher_proxy(self, subpath='', **kw): + """Proxy requests to the local MailHog instance.""" + target_url = f"{MAILHOG_BASE}/{subpath}" + if request.httprequest.query_string: + target_url += '?' + request.httprequest.query_string.decode('utf-8') -# @http.route('/testserver_o2b/testserver_o2b/objects//', auth='public') -# def object(self, obj, **kw): -# return http.request.render('testserver_o2b.object', { -# 'object': obj -# }) + try: + headers = { + k: v for k, v in request.httprequest.headers + if k.lower() not in ('host', 'cookie', 'authorization') + } + resp = requests.request( + method=request.httprequest.method, + url=target_url, + headers=headers, + data=request.httprequest.get_data(), + timeout=30, + allow_redirects=False, + ) + except requests.exceptions.ConnectionError: + _logger.warning("Could not connect to MailHog at %s", MAILHOG_BASE) + return Response("MailHog is not available", status=502) + + excluded_headers = { + 'content-encoding', 'content-length', 'transfer-encoding', + 'connection', + } + response_headers = [ + (k, v) for k, v in resp.headers.items() + if k.lower() not in excluded_headers + ] + + return Response( + resp.content, + status=resp.status_code, + headers=response_headers, + ) diff --git a/mailcatcher_menu/data/data.xml b/mailcatcher_menu/data/data.xml index e506423..cb672a8 100644 --- a/mailcatcher_menu/data/data.xml +++ b/mailcatcher_menu/data/data.xml @@ -1,5 +1,4 @@ - diff --git a/mailcatcher_menu/hooks.py b/mailcatcher_menu/hooks.py new file mode 100644 index 0000000..1721890 --- /dev/null +++ b/mailcatcher_menu/hooks.py @@ -0,0 +1,40 @@ +# Copyright 2024 Open2Bizz +# License LGPL-3 + +import logging +import os +import subprocess + +_logger = logging.getLogger(__name__) + + +def post_init_hook(env): + """Install MailHog as a systemd service when the module is installed.""" + script_path = os.path.join( + os.path.dirname(os.path.abspath(__file__)), + 'install_mailhog_as_service.sh', + ) + + if not os.path.isfile(script_path): + _logger.error("MailHog install script not found at %s", script_path) + return + + _logger.info("Running MailHog install script: %s", script_path) + try: + result = subprocess.run( + ['bash', script_path], + capture_output=True, + text=True, + timeout=300, + ) + if result.returncode == 0: + _logger.info("MailHog installed successfully.\n%s", result.stdout) + else: + _logger.error( + "MailHog install script failed (exit %s):\n%s\n%s", + result.returncode, result.stdout, result.stderr, + ) + except subprocess.TimeoutExpired: + _logger.error("MailHog install script timed out after 300 seconds") + except Exception as e: + _logger.error("Failed to run MailHog install script: %s", e) diff --git a/mailcatcher_menu/install_mailhog_as_service.sh b/mailcatcher_menu/install_mailhog_as_service.sh new file mode 100644 index 0000000..c950793 --- /dev/null +++ b/mailcatcher_menu/install_mailhog_as_service.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +set -e # stop bij fouten + +echo "" +echo "===================================" +echo "Update apt..." +echo "===================================" +apt update + +echo "" +echo "===================================" +echo "Install dependencies..." +echo "===================================" +apt-get -y install wget tar + +echo "" +echo "===================================" +echo "Install Go 1.24.3..." +echo "===================================" +GO_VERSION=1.24.3 +wget https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz + +sudo rm -rf /usr/local/go +sudo tar -C /usr/local -xzf go${GO_VERSION}.linux-amd64.tar.gz + +# Go environment correct instellen +export GOROOT=/usr/local/go +export GOPATH=$HOME/go +export PATH=$GOROOT/bin:$GOPATH/bin:$PATH + +echo "Go version:" +go version + +echo "" +echo "===================================" +echo "Installing MailHog..." +echo "===================================" +/usr/local/go/bin/go install github.com/mailhog/MailHog@latest + +if [ -f "$HOME/go/bin/MailHog" ]; then + echo "MailHog installed successfully" +else + echo "ERROR: MailHog binary not found!" + exit 1 +fi + +echo "" +echo "===================================" +echo "Copy MailHog to /usr/local/bin..." +echo "===================================" +sudo cp "$HOME/go/bin/MailHog" /usr/local/bin/MailHog + +echo "" +echo "===================================" +echo "Create MailHog service..." +echo "===================================" +sudo tee /etc/systemd/system/mailhog.service > /dev/null < # License LGPL-3 -from odoo import api, fields, models, _ - -import logging -_logger = logging.getLogger(__name__) - -class IrActionUrl(models.Model): - _inherit = "ir.config_parameter" - - @api.model - #def init(self): - def _mailcatcher_url(self): - parameters = self.env['ir.config_parameter'].search([('key','=', 'web.base.url')]) - if parameters: - parameter = parameters[0] - cont_nr = parameter.value.split("//",1)[1] #Haal https:// van string - cont_nr = cont_nr[0:3] #De eerste 3 karakters is het containernummer - act_url = "https://" + cont_nr + "-mailcatcher.staging.open2bizz.com" - _logger.info('---------- ACT_URL ---------- %s', act_url) - action_id = self.env['ir.model.data']._xmlid_to_res_id('mailcatcher_menu.action_mailcatcher_url') - action = self.env['ir.actions.act_url'].browse(action_id) - if action: - action.write({'url':act_url}) +# MailHog is now accessed via the internal proxy controller at /mailcatcher/ +# so no dynamic URL computation is needed anymore. diff --git a/mailcatcher_menu/security/ir.model.access.csv b/mailcatcher_menu/security/ir.model.access.csv index f1ba01f..1849ee3 100644 --- a/mailcatcher_menu/security/ir.model.access.csv +++ b/mailcatcher_menu/security/ir.model.access.csv @@ -1,2 +1,2 @@ "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" -"access_mailcatcher_menu_mailcatcher_menu","mailcatcher_menu.mailcatcher_menu","model_mailcatcher_menu_mailcatcher_menu","base.group_user",1,1,1,1 +"access_mailcatcher_install_warning_wizard","mailcatcher.install.warning.wizard","model_mailcatcher_install_warning_wizard","base.group_user",1,1,1,1 diff --git a/mailcatcher_menu/views/views.xml b/mailcatcher_menu/views/views.xml index 6b01f38..108f59d 100644 --- a/mailcatcher_menu/views/views.xml +++ b/mailcatcher_menu/views/views.xml @@ -3,7 +3,7 @@ Open Mailcatcher - https://mailcatcher.staging.open2bizz.com + /mailcatcher/ new diff --git a/mailcatcher_menu/wizard/__init__.py b/mailcatcher_menu/wizard/__init__.py new file mode 100644 index 0000000..54c2cdf --- /dev/null +++ b/mailcatcher_menu/wizard/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +from . import install_warning_wizard diff --git a/mailcatcher_menu/wizard/install_warning_wizard.py b/mailcatcher_menu/wizard/install_warning_wizard.py new file mode 100644 index 0000000..505c6cd --- /dev/null +++ b/mailcatcher_menu/wizard/install_warning_wizard.py @@ -0,0 +1,43 @@ +# Copyright 2024 Open2Bizz +# License LGPL-3 + +from odoo import models, fields, api, _ + + +class MailcatcherInstallWarningWizard(models.TransientModel): + _name = 'mailcatcher.install.warning.wizard' + _description = 'MailCatcher Install Warning' + + module_id = fields.Many2one('ir.module.module', string='Module', readonly=True) + + def action_confirm_install(self): + """User confirmed — proceed with the actual module installation.""" + self.ensure_one() + return self.module_id.with_context( + skip_mailcatcher_warning=True + ).button_immediate_install() + + +class IrModuleModule(models.Model): + _inherit = 'ir.module.module' + + def button_immediate_install(self): + """Override to show a warning before installing mailcatcher_menu.""" + if self.env.context.get('skip_mailcatcher_warning'): + return super().button_immediate_install() + + mailcatcher_modules = self.filtered(lambda m: m.name == 'mailcatcher_menu') + if mailcatcher_modules: + wizard = self.env['mailcatcher.install.warning.wizard'].create({ + 'module_id': mailcatcher_modules[0].id, + }) + return { + 'name': _('Install MailCatcher Module'), + 'type': 'ir.actions.act_window', + 'res_model': 'mailcatcher.install.warning.wizard', + 'res_id': wizard.id, + 'view_mode': 'form', + 'target': 'new', + } + + return super().button_immediate_install() diff --git a/mailcatcher_menu/wizard/install_warning_wizard_view.xml b/mailcatcher_menu/wizard/install_warning_wizard_view.xml new file mode 100644 index 0000000..a5f5922 --- /dev/null +++ b/mailcatcher_menu/wizard/install_warning_wizard_view.xml @@ -0,0 +1,28 @@ + + + mailcatcher.install.warning.wizard.form + mailcatcher.install.warning.wizard + +
+ + +
+
+
+