mirror of
https://github.com/mail-in-a-box/mailinabox.git
synced 2025-04-03 00:07:05 +00:00
140 lines
4.8 KiB
Python
140 lines
4.8 KiB
Python
#####
|
|
##### 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.
|
|
#####
|
|
|
|
|
|
#
|
|
# This hooks management's dns_update and web_update for the
|
|
# remote-nextcloud setup mod.
|
|
#
|
|
# dns_update: When management/dns_update.py creates a new zone, this mod will
|
|
# change _caldavs._tcp and _carddavs._tcp to point to the remote
|
|
# nextcloud.
|
|
#
|
|
# web_update: When management/web_update.py creates a new nginx
|
|
# configuration file "/etc/nginx/conf.d/local.conf", this mod will
|
|
# ensure that .well-known/caldav and .well-known/carddav urls are
|
|
# redirected to the remote nextcloud.
|
|
#
|
|
# The hook is enabled by placing the file in directory
|
|
# LOCAL_MODS_DIR/managment_hooks_d.
|
|
#
|
|
|
|
import os
|
|
import logging
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
def do_hook(hook_name, hook_data, mods_env):
|
|
if 'NC_HOST' not in mods_env or mods_env['NC_HOST'].strip() == '':
|
|
# not configured for a remote nextcloud
|
|
log.debug('hook - not configured for a remote nextcloud')
|
|
return False
|
|
|
|
if hook_name == 'web_update':
|
|
return do_hook_web_update(hook_name, hook_data, mods_env)
|
|
|
|
elif hook_name == 'dns_update':
|
|
return do_hook_dns_update(hook_name, hook_data, mods_env)
|
|
|
|
else:
|
|
log.debug('hook - ignoring hook %s', hook_name)
|
|
return False
|
|
|
|
|
|
def do_hook_dns_update(hook_name, hook_data, mods_env):
|
|
if hook_data['op'] != 'build_zone_end':
|
|
log.debug('hook - ignoring hook op %s:%s', hook_name, hook_data['op'])
|
|
return False
|
|
changed = False
|
|
records = hook_data['records']
|
|
for idx in range(len(records)):
|
|
# record format (name, record-type, record-value, "help-text" or False)
|
|
record = records[idx]
|
|
rname = record[0]
|
|
rtype = record[1]
|
|
if rtype=='SRV' and rname in ('_caldavs._tcp', '_carddavs._tcp'):
|
|
newrec = list(record)
|
|
newrec[2] = '10 10 %s %s.' % (
|
|
mods_env['NC_PORT'],
|
|
mods_env['NC_HOST']
|
|
)
|
|
records[idx] = tuple(newrec)
|
|
changed = True
|
|
return changed
|
|
|
|
|
|
def get_nc_url(mods_env):
|
|
# return the remote nextcloud url - ensures no tailing /
|
|
nc_url = "%s://%s:%s%s" % (
|
|
mods_env['NC_PROTO'],
|
|
mods_env['NC_HOST'],
|
|
mods_env['NC_PORT'],
|
|
mods_env['NC_PREFIX'][0:-1] if mods_env['NC_PREFIX'].endswith('/') else mods_env['NC_PREFIX']
|
|
)
|
|
return nc_url
|
|
|
|
|
|
def do_hook_web_update(hook_name, hook_data, mods_env):
|
|
if hook_data['op'] != 'pre-save':
|
|
log.debug('hook - ignoring hook op %s:%s', hook_name, hook_data['op'])
|
|
return False
|
|
|
|
nc_url = get_nc_url(mods_env)
|
|
|
|
# find start and end of Nextcloud configuration section
|
|
|
|
str = hook_data['nginx_conf']
|
|
start = str.find('# Nextcloud configuration.')
|
|
if start==-1:
|
|
log.error("no Nextcloud configuration found in nginx conf")
|
|
return False
|
|
|
|
end = str.find('\n\t# ssl files ', start)
|
|
if end==0:
|
|
log.error("couldn't determine end of Nextcloud configuration")
|
|
return False
|
|
|
|
# ensure we're not eliminating lines that are not nextcloud
|
|
# related in the event that the conf/nginx-* templates change
|
|
#
|
|
# check that every main directive in the proposed section
|
|
# (excluding block directives) should contains the text "cloud",
|
|
# "carddav", or "caldav"
|
|
|
|
for line in str[start:end].split('\n'):
|
|
if line.startswith("\t\t"): continue
|
|
line_stripped = line.strip()
|
|
if line_stripped == "" or \
|
|
line_stripped.startswith("#") or \
|
|
line_stripped.startswith("}"):
|
|
continue
|
|
if line_stripped.find('cloud')==-1 and \
|
|
line_stripped.find('carddav')==-1 and \
|
|
line_stripped.find('caldav')==-1:
|
|
log.error("nextcloud replacement block directive did not contain 'cloud', 'carddav' or 'caldav'. line=%s", line_stripped)
|
|
return False
|
|
|
|
|
|
# ok, do the replacement
|
|
|
|
template = """# Nextcloud configuration.
|
|
rewrite ^/cloud$ /cloud/ redirect;
|
|
rewrite ^/cloud/(contacts|calendar|files)$ {nc_url}/index.php/apps/$1/ redirect;
|
|
rewrite ^/cloud/(.*)$ {nc_url}/$1 redirect;
|
|
|
|
rewrite ^/.well-known/carddav {nc_url}/remote.php/dav/ redirect;
|
|
rewrite ^/.well-known/caldav {nc_url}/remote.php/dav/ redirect;
|
|
rewrite ^/.well-known/webfinger {nc_url}/index.php/.well-known/webfinger redirect;
|
|
rewrite ^/.well-known/nodeinfo {nc_url}/index.php/.well-known/nodeinfo redirect;
|
|
"""
|
|
|
|
hook_data['nginx_conf'] = str[0:start] + template.format(nc_url=nc_url) + str[end:]
|
|
return True
|