diff --git a/plinth/modules/apache/__init__.py b/plinth/modules/apache/__init__.py index 3e2ccd7d2..a73483c76 100644 --- a/plinth/modules/apache/__init__.py +++ b/plinth/modules/apache/__init__.py @@ -12,6 +12,7 @@ from plinth.daemon import Daemon, RelatedDaemon from plinth.modules.firewall.components import Firewall from plinth.modules.letsencrypt.components import LetsEncrypt from plinth.package import Packages +from plinth.signals import domain_added, domain_removed from plinth.utils import format_lazy, is_valid_user_name from . import privileged @@ -64,6 +65,12 @@ class ApacheApp(app_module.App): related_daemon = RelatedDaemon('related-daemon-apache', 'uwsgi') self.add(related_daemon) + @staticmethod + def post_init(): + """Perform post initialization operations.""" + domain_added.connect(_on_domain_added) + domain_removed.connect(_on_domain_removed) + def setup(self, old_version): """Install and configure the app.""" super().setup(old_version) @@ -71,6 +78,19 @@ class ApacheApp(app_module.App): self.enable() +def _on_domain_added(sender, domain_type, name='', description='', + services=None, **kwargs): + """Add site specific configuration for a domain.""" + if name: + privileged.domain_setup(name) + + +def _on_domain_removed(sender, domain_type, name='', **kwargs): + """Remove site specific configuration for a domain.""" + if name: + privileged.domain_remove(name) + + # (U)ser (W)eb (S)ites diff --git a/plinth/modules/apache/privileged.py b/plinth/modules/apache/privileged.py index 1093ae989..2568aa82e 100644 --- a/plinth/modules/apache/privileged.py +++ b/plinth/modules/apache/privileged.py @@ -214,3 +214,36 @@ def uwsgi_enable(name: str): def uwsgi_disable(name: str): """Disable uWSGI configuration and reload.""" action_utils.uwsgi_disable(name) + + +@privileged +def domain_setup(domain: str): + """Add site specific configuration for a domain.""" + if '/' in domain: + raise ValueError('Invalid domain') + + path = pathlib.Path('/etc/apache2/sites-available/') + path = path / (domain + '.conf') + configuration = 'Use FreedomBoxTLSSiteMacro {domain}\n' + if path.is_file(): + return # File already exists. Assume it to be correct one. + + path.write_text(configuration.format(domain=domain)) + + with action_utils.WebserverChange() as webserver: + webserver.enable('freedombox-tls-site-macro', kind='config') + webserver.enable(domain, kind='site') + + +@privileged +def domain_remove(domain: str): + """Remove site specific configuration for a domain.""" + if '/' in domain: + raise ValueError('Invalid domain') + + with action_utils.WebserverChange() as webserver: + webserver.disable(domain, kind='site') + + path = pathlib.Path('/etc/apache2/sites-available/') + path = path / (domain + '.conf') + path.unlink(missing_ok=True) diff --git a/plinth/modules/letsencrypt/privileged.py b/plinth/modules/letsencrypt/privileged.py index e9dff41a0..0993c02d4 100644 --- a/plinth/modules/letsencrypt/privileged.py +++ b/plinth/modules/letsencrypt/privileged.py @@ -2,7 +2,6 @@ """Configure Let's Encrypt.""" import filecmp -import glob import importlib import inspect import os @@ -24,10 +23,6 @@ LE_DIRECTORY = '/etc/letsencrypt/' ETC_SSL_DIRECTORY = '/etc/ssl/' AUTHENTICATOR = 'webroot' WEB_ROOT_PATH = '/var/www/html' -APACHE_PREFIX = '/etc/apache2/sites-available/' -APACHE_CONFIGURATION = ''' -Use FreedomBoxTLSSiteMacro {domain} -''' def _get_certificate_expiry(domain: str) -> str: @@ -139,9 +134,6 @@ def obtain(domain: str): subprocess.run(command, check=True) - with action_utils.WebserverChange() as webserver_change: - _setup_webserver_config(domain, webserver_change) - @privileged def copy_certificate(managing_app: str, source_private_key: str, @@ -259,19 +251,3 @@ def delete(domain: str): command = ['certbot', 'delete', '--non-interactive', '--cert-name', domain] subprocess.run(command, check=True) action_utils.webserver_disable(domain, kind='site') - - -def _setup_webserver_config(domain, webserver_change): - """Create SSL web server configuration for a domain. - - Do so only if there is no configuration existing. - """ - file_name = os.path.join(APACHE_PREFIX, domain + '.conf') - if os.path.isfile(file_name): - os.rename(file_name, file_name + '.fbx-bak') - - with open(file_name, 'w', encoding='utf-8') as file_handle: - file_handle.write(APACHE_CONFIGURATION.format(domain=domain)) - - webserver_change.enable('freedombox-tls-site-macro', kind='config') - webserver_change.enable(domain, kind='site')