# # This is a web_update management hook for the remote-nextcloud setup # mod. # # When management/web_update.py creates a new nginx configuration file # "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 hook_name != 'web_update': # we only care about hooking web_update log.debug('hook - ignoring hook %s', hook_name) return False if hook_data['op'] != 'pre-save': log.debug('hook - ignoring hook op %s:%s', hook_name, hook_data['op']) return False 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 # get the remote nextcloud url and ensure 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'] ) # 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# ', start) # this should match comment "# ssl files sha1:...", which is dynamically added by web_update.py:make_domain_config() if end==0: log.error("couldn't determine end of Nextcloud configuration") return False if str[end+4:end+4+9] != 'ssl files': log.error("expected end replacement block comment to start with 'ssl files', but got '%s'", str[end+4:end+4+9]) 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; """ hook_data['nginx_conf'] = str[0:start] + template.format(nc_url=nc_url) + str[end:] return True