1
0
mirror of https://github.com/mail-in-a-box/mailinabox.git synced 2026-03-12 17:07:23 +01:00

Fix url redirection when a remote nextcloud is used so that .well-known/caldav and carddav work properly, as well as the redirecting /cloud to the remote Nextcloud. Since the nginx config is replaced by the management daemon whenever a new domain is added, this change adds a hooking mechanism for setup mods.Fix url redirection when a remote nextcloud is in use. This corrects redirection for /.well-known/caldav, /.well-known/carddav and /cloud to send the client to the remote nextcloud. This requires an nginx configuration change, and since the nginx config is replaced by the management daemon whenever a new domain is added, this change adds a hooking mechanism for setup mods allowing them to intercept and modify the resultant nginx config.

This commit is contained in:
downtownallday
2022-09-21 15:52:47 -04:00
parent dae697e6af
commit 53cbabac75
13 changed files with 282 additions and 5 deletions

View File

@@ -549,6 +549,13 @@ def web_update():
from web_update import do_web_update
return do_web_update(env)
@app.route('/hooks/update', methods=['POST'])
@authorized_personnel_only
def hooks_update():
from hooks import update_hook_handlers
update_hook_handlers()
return "OK"
# System
@app.route('/system/version', methods=["GET"])
@@ -820,6 +827,8 @@ add_ui_common(app)
from daemon_reports import add_reports
add_reports(app, env, authorized_personnel_only)
from hooks import update_hook_handlers
update_hook_handlers()
if __name__ == '__main__':
if "DEBUG" in os.environ:

88
management/hooks.py Normal file
View File

@@ -0,0 +1,88 @@
# -*- indent-tabs-mode: t; tab-width: 4; python-indent-offset: 4; -*-
#####
##### This file is part of Mail-in-a-Box-LDAP which is released under the
##### terms of the GNU Affero General Public License as published by the
##### Free Software Foundation, either version 3 of the License, or (at
##### your option) any later version. See file LICENSE or go to
##### https://github.com/downtownallday/mailinabox-ldap for full license
##### details.
#####
import sys, os, stat, importlib
from threading import Lock
from utils import load_environment, load_env_vars_from_file
import logging
log = logging.getLogger(__name__)
#
# keep a list of hook handlers as a list of dictionaries. see
# update_hook_handlers() for the format
#
mutex = Lock()
handlers = []
mods_env = {} # dict derived from /etc/mailinabox_mods.conf
def update_hook_handlers():
global handlers, mods_env
new_handlers= []
for dir in sys.path:
hooks_dir = os.path.join(dir, "management_hooks_d")
if not os.path.isdir(hooks_dir):
continue
# gather a list of applicable hook handlers
for item in os.listdir(hooks_dir):
item_path = os.path.join(hooks_dir, item)
mode = os.lstat(item_path).st_mode
if item.endswith('.py') and stat.S_ISREG(mode):
new_handlers.append({
'sort_id': item,
'path': "management_hooks_d.%s" % (item[0:-3]),
'type': "py"
})
log.info('hook handler: %s', item_path)
# handlers are sorted alphabetically by file name
new_handlers = sorted(new_handlers, key=lambda path: path['sort_id'])
log.info('%s hook handlers', len(new_handlers))
# load /etc/mailinabox_mods.conf
new_mods_env = load_environment()
if os.path.isfile('/etc/mailinabox_mods.conf'):
load_env_vars_from_file(
'/etc/mailinabox_mods.conf',
strip_quotes=True,
merge_env=new_mods_env
)
# update globals
mutex.acquire()
handlers = new_handlers
mods_env = new_mods_env
mutex.release()
def exec_hooks(hook_name, data):
# `data` is a dictionary containing data from the hook caller, the
# contents of which are specific to the type of hook. Handlers may
# modify the dictionary to return updates to the caller.
mutex.acquire()
cur_handlers = handlers
cur_mods_env = mods_env
mutex.release()
for handler in cur_handlers:
if handler['type'] == 'py':
# load the python code and run the `do_hook` function
log.debug('calling %s hook handler: %s' % (hook_name, handler['path']))
module = importlib.import_module(handler['path'])
do_hook = getattr(module, "do_hook")
do_hook(hook_name, data, cur_mods_env)
else:
log.error('Unknown hook handler type in %s: %s', handler['path'], handler['type'])
return len(cur_handlers)

View File

@@ -18,6 +18,7 @@ from mailconfig import get_mail_domains
from dns_update import get_custom_dns_config, get_dns_zones
from ssl_certificates import get_ssl_certificates, get_domain_ssl_files, check_certificate
from utils import shell, safe_domain_name, sort_domains
import hooks
def get_web_domains(env, include_www_redirects=True, include_auto=True, exclude_dns_elsewhere=True, categories=['mail', 'ssl']):
# What domains should we serve HTTP(S) for?
@@ -114,6 +115,11 @@ def do_web_update(env):
# Add default 'www.' redirect.
nginx_conf += make_domain_config(domain, [template0, template3], ssl_certificates, env)
# execute hooks
hook_data = {'nginx_conf': nginx_conf}
hooks.exec_hooks('web_update', hook_data)
nginx_conf = hook_data['nginx_conf']
# Did the file change? If not, don't bother writing & restarting nginx.
nginx_conf_fn = "/etc/nginx/conf.d/local.conf"
if os.path.exists(nginx_conf_fn):