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:
@@ -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
88
management/hooks.py
Normal 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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user