diff --git a/actions/matrixsynapse b/actions/matrixsynapse index ded88b33c..6bf35cd0f 100755 --- a/actions/matrixsynapse +++ b/actions/matrixsynapse @@ -32,13 +32,10 @@ def parse_arguments(): parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(dest='subcommand', help='Sub command') - post_install = subparsers.add_parser( - 'post-install', - help="Perform post install steps") - + subparsers.add_parser('post-install', help='Perform post install steps') subparsers.add_parser('enable', help='Enable matrix-synapse service') subparsers.add_parser('disable', help='Disable matrix-synapse service') - setup = subparsers.add_parser('setup', help='Set Domain name for Matrix') + setup = subparsers.add_parser('setup', help='Set domain name for Matrix') setup.add_argument( '--domain-name', help='The domain name that will be used by Matrix Synapse') @@ -47,37 +44,39 @@ def parse_arguments(): def subcommand_post_install(_): - file_path = "/etc/matrix-synapse/homeserver.yaml" - + """Perform post installation configuration.""" + file_path = '/etc/matrix-synapse/homeserver.yaml' with open(file_path) as config_file: config = round_trip_load(config_file) - config["listeners"][0]["bind_address"] = "0.0.0.0" - config["listeners"][1]["bind_address"] = "127.0.0.1" - config["max_upload_size"] = "100M" - config["enable_registration"] = True + config['max_upload_size'] = '100M' + config['enable_registration'] = True + for listener in config['listeners']: + if listener['port'] == 8448: + listener['bind_address'] = '0.0.0.0' - with open(file_path, "w") as config_file: + with open(file_path, 'w') as config_file: round_trip_dump(config, config_file) def subcommand_setup(arguments): + """Configure the domain name for matrix-synapse package.""" domain_name = arguments.domain_name action_utils.dpkg_reconfigure('matrix-synapse', {'server-name': domain_name}) - action_utils.webserver_enable('matrixsynapse') + subcommand_enable(arguments) def subcommand_enable(_): - """Enable service""" - action_utils.webserver_enable('matrixsynapse') + """Enable service.""" action_utils.service_enable('matrix-synapse') + action_utils.webserver_enable('matrix-synapse-plinth') def subcommand_disable(_): - """Disable service""" + """Disable service.""" + action_utils.webserver_disable('matrix-synapse-plinth') action_utils.service_disable('matrix-synapse') - action_utils.webserver_disable('matrixsynapse') def main(): diff --git a/data/etc/apache2/conf-available/matrix-synapse-plinth.conf b/data/etc/apache2/conf-available/matrix-synapse-plinth.conf new file mode 100644 index 000000000..64217ece9 --- /dev/null +++ b/data/etc/apache2/conf-available/matrix-synapse-plinth.conf @@ -0,0 +1,8 @@ +## +## On all sites, provide Matrix Synapse on a default path: /_matrix. This is +## only useful for clients to login without specifying a server port. This is +## not useful for federation which requires SRV record or listening on port +## 8448. Further, federation requires same TLS public key to be provided to +## Apache and Matrix Synapse server. +## +ProxyPass /_matrix http://localhost:8008/_matrix diff --git a/data/etc/apache2/conf-available/matrixsynapse.conf b/data/etc/apache2/conf-available/matrixsynapse.conf deleted file mode 100644 index 143da7633..000000000 --- a/data/etc/apache2/conf-available/matrixsynapse.conf +++ /dev/null @@ -1 +0,0 @@ -ProxyPass /_matrix http://localhost:8008/_matrix diff --git a/data/etc/plinth/modules-enabled/matrixsynapse b/data/etc/plinth/modules-enabled/matrixsynapse new file mode 100644 index 000000000..2d77c1313 --- /dev/null +++ b/data/etc/plinth/modules-enabled/matrixsynapse @@ -0,0 +1 @@ +plinth.modules.matrixsynapse diff --git a/data/usr/lib/firewalld/services/matrix-synapse-plinth.xml b/data/usr/lib/firewalld/services/matrix-synapse-plinth.xml index da5c8b83f..a5279a2f4 100644 --- a/data/usr/lib/firewalld/services/matrix-synapse-plinth.xml +++ b/data/usr/lib/firewalld/services/matrix-synapse-plinth.xml @@ -1,6 +1,6 @@ Matrix Synapse - Matrix is a Federated IM, VoIP and Video server + Matrix is a Federated IM, VoIP and Video server. In Matrix, every user runs one or more Matrix clients, which connect through to a Matrix homeserver. The homeserver stores all their personal chat history and user account information, much as a mail client connects through to an IMAP/SMTP server. Enable this if you are running a Matrix Synapse homeserver to create local Matrix accounts that can federate with accounts on other servers. diff --git a/plinth/modules/matrixsynapse/__init__.py b/plinth/modules/matrixsynapse/__init__.py index 6b7b3286f..21edc1936 100644 --- a/plinth/modules/matrixsynapse/__init__.py +++ b/plinth/modules/matrixsynapse/__init__.py @@ -16,7 +16,7 @@ # """ -Plinth module to configure matrix-synapse server +Plinth module to configure matrix-synapse server. """ import logging @@ -41,17 +41,21 @@ managed_services = ['matrix-synapse'] managed_packages = ['matrix-synapse'] -title = _('Federated IM, VoIP and Video server \n (matrix-synapse)') +title = _('Chat Server \n (Matrix Synapse)') description = [ - _('Matrix is an new ecosystem for open federated Instant Messaging ' - 'and VoIP. Synapse is a reference Matrix server implementation.'), + _('Matrix is an new ' + 'ecosystem for open, federated instant messaging and VoIP. Synapse is a ' + 'server implementing the Matrix protocol. It provides chat groups, ' + 'audio/video calls, end-to-end encryption, multiple device ' + 'synchronization and does not require phone numbers to work. Users on a ' + 'given Matrix server can converse with users on all other Matrix servers ' + 'via federation.'), _('To communicate, you can use the ' - 'Riot client.'), - - _('Changing the FreedomBox domain name needs a reinstall of ' - 'Matrix-Synapse and you WILL LOSE DATA.') + 'available clients ' + 'for mobile, desktop and the web. Riot ' + 'client is recommended.') ] service = None @@ -62,7 +66,7 @@ SERVER_NAME_PATH = "/etc/matrix-synapse/conf.d/server_name.yaml" def init(): - """Initialize the matrix-synapse module""" + """Initialize the matrix-synapse module.""" menu = cfg.main_menu.get('apps:index') menu.add_urlname(title, 'glyphicon-comment', 'matrixsynapse:index') @@ -71,7 +75,7 @@ def init(): if setup_helper.get_state() != 'needs-setup': service = service_module.Service( 'matrix-synapse', title, - ports=['matrix-synapse'], + ports=['matrix-synapse-plinth'], is_external=True, is_enabled=is_enabled, enable=enable, disable=disable) if is_enabled(): @@ -88,6 +92,7 @@ def setup(helper, old_version=None): ports=['matrix-synapse-plinth'], is_external=True, is_enabled=is_enabled, enable=enable, disable=disable) + helper.call('post', actions.superuser_run, 'matrixsynapse', ['post-install']) helper.call('post', service.notify_enabled, None, True) @@ -95,12 +100,14 @@ def setup(helper, old_version=None): def add_shortcut(): + """Add a shortcut to the frontpage.""" frontpage.add_shortcut('matrixsynapse', title, details=description, configure_url=reverse_lazy('matrixsynapse:index'), login_required=True) def is_setup(): + """Return whether the Matrix Synapse server is setup.""" return os.path.exists(SERVER_NAME_PATH) @@ -109,29 +116,6 @@ def is_enabled(): return action_utils.service_is_enabled('matrix-synapse') -def get_domain_names(): - """Return the domain name(s)""" - results = [] - - for domain_type, domains in names.domains.items(): - if domain_type == 'hiddenservice': - continue - for domain in domains: - results.append((domain, domain)) - - return results - - -def get_configured_domain_name(): - if not is_setup(): - return "" - - with open(SERVER_NAME_PATH) as config_file: - config, _, _ = load_yaml_guess_indent(config_file) - - return config["server_name"] - - def enable(): """Enable the module.""" actions.superuser_run('matrixsynapse', ['enable']) @@ -146,4 +130,36 @@ def disable(): def diagnose(): """Run diagnostics and return the results.""" - return [action_utils.diagnose_port_listening(8008, 'tcp4')] + results = [] + + results.append(action_utils.diagnose_port_listening(8008, 'tcp4')) + results.append(action_utils.diagnose_port_listening(8448, 'tcp4')) + results.extend(action_utils.diagnose_url_on_all( + 'https://{host}/_matrix', check_certificate=False)) + + return results + + +def get_domain_names(): + """Return the domain name(s).""" + results = [] + + for domain_type, domains in names.domains.items(): + if domain_type == 'hiddenservice': + continue + + for domain in domains: + results.append((domain, domain)) + + return results + + +def get_configured_domain_name(): + """Return the currently configured domain name.""" + if not is_setup(): + return None + + with open(SERVER_NAME_PATH) as config_file: + config, _, _ = load_yaml_guess_indent(config_file) + + return config['server_name'] diff --git a/plinth/modules/matrixsynapse/forms.py b/plinth/modules/matrixsynapse/forms.py index 6bb382fd3..18872c524 100644 --- a/plinth/modules/matrixsynapse/forms.py +++ b/plinth/modules/matrixsynapse/forms.py @@ -16,7 +16,7 @@ # """ -Forms for configuring matrix-synapse +Forms for configuring matrix-synapse. """ from django import forms @@ -26,12 +26,13 @@ from plinth.modules import matrixsynapse class MatrixSynapseForm(forms.Form): - """Form to do initial configuration of matrix-synapse""" + """Form to do initial configuration of matrix-synapse.""" domain_name = forms.ChoiceField( - label=_('Select the domain name to be used for Matrix'), + label=_('Select the domain name'), choices=[] ) def __init__(self, *args, **kwargs): + """Initialize the form object.""" super().__init__(*args, **kwargs) self.fields['domain_name'].choices = matrixsynapse.get_domain_names() diff --git a/plinth/modules/matrixsynapse/templates/matrix-pre-setup.html b/plinth/modules/matrixsynapse/templates/matrix-pre-setup.html deleted file mode 100644 index a7037a1dc..000000000 --- a/plinth/modules/matrixsynapse/templates/matrix-pre-setup.html +++ /dev/null @@ -1,62 +0,0 @@ -{% extends "base.html" %} -{% comment %} -# -# This file is part of Plinth. -# -# This program is free software: you can redistribute it and/or modify -# it 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. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -{% endcomment %} - -{% load bootstrap %} -{% load i18n %} - -{% block content %} - {% block pagetitle %} -

{{ title }}

- {% endblock %} - - {% block description %} - {% for paragraph in description %} -

{{ paragraph|safe }}

- {% endfor %} - {% endblock %} - -

- {% url 'config:index' as index_url %} - {% if domain_names|length == 0 %} - No domain(s) are set. You can setup your domain on the system at - Configure page. - {% endif %} -

- - {% block status %} - {% endblock %} - - {% block diagnostics %} - {% endblock %} - - {% block configuration %} - {% if domain_names|length > 0 %} -

Configuration

-
- {% csrf_token %} - - {{ form|bootstrap }} - - -
- {% endif %} - {% endblock %} -{% endblock %} diff --git a/plinth/modules/matrixsynapse/templates/matrix-synapse-pre-setup.html b/plinth/modules/matrixsynapse/templates/matrix-synapse-pre-setup.html new file mode 100644 index 000000000..93c212f71 --- /dev/null +++ b/plinth/modules/matrixsynapse/templates/matrix-synapse-pre-setup.html @@ -0,0 +1,66 @@ +{% extends "base.html" %} +{% comment %} +# +# This file is part of Plinth. +# +# This program is free software: you can redistribute it and/or modify +# it 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. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +{% endcomment %} + +{% load bootstrap %} +{% load i18n %} + +{% block content %} +

{{ title }}

+ + {% for paragraph in description %} +

{{ paragraph|safe }}

+ {% endfor %} + +

{% trans "Configuration" %}

+ +

+ {% blocktrans trimmed %} + Matrix service needs to be configured for a domain. Users on other Matrix + servers will be able to reach users on this server using this domain name. + Matrix user IDs will look like @username:domainname. + {% endblocktrans %} +

+ + + + {% if not domain_names %} + {% url 'config:index' as config_url %} +

+ {% blocktrans trimmed %} + No domain(s) are available. Configure + at least one domain to be able to use Matrix Synapse. + {% endblocktrans %} +

+ {% else %} +
+ {% csrf_token %} + + {{ form|bootstrap }} + + +
+ {% endif %} +{% endblock %} diff --git a/plinth/modules/matrixsynapse/templates/matrix-post-setup.html b/plinth/modules/matrixsynapse/templates/matrix-synapse.html similarity index 66% rename from plinth/modules/matrixsynapse/templates/matrix-post-setup.html rename to plinth/modules/matrixsynapse/templates/matrix-synapse.html index a7cf46d44..775384d11 100644 --- a/plinth/modules/matrixsynapse/templates/matrix-post-setup.html +++ b/plinth/modules/matrixsynapse/templates/matrix-synapse.html @@ -22,18 +22,16 @@ {% load i18n %} {% block description %} + {% for paragraph in description %} +

{{ paragraph|safe }}

+ {% endfor %} -{% for paragraph in description %} -

{{ paragraph|safe }}

-{% endfor %} - -

- {% url 'config:index' as index_url %} - {% blocktrans trimmed with domain_name=domain_name %} - The Matrix server domain is set to {{ domain_name }}. User - IDs will look like @username:{{ domain_name }} - Changing the FreedomBox domain name needs a reinstall of - Matrix-Synapse and you WILL LOSE DATA. +

+ {% blocktrans trimmed %} + The Matrix server domain is set to {{ domain_name }}. User IDs + will look like @username:{{ domain_name }}. Changing the domain + name after the initial setup is currently not supported. {% endblocktrans %} -

+

+

New users can be registered from any client.

{% endblock %} diff --git a/plinth/modules/matrixsynapse/urls.py b/plinth/modules/matrixsynapse/urls.py index 19e41a110..d1f05d672 100644 --- a/plinth/modules/matrixsynapse/urls.py +++ b/plinth/modules/matrixsynapse/urls.py @@ -16,16 +16,14 @@ # """ -URL for the matrix-synapse module +URLs for the matrix-synapse module. """ from django.conf.urls import url -from .views import MatrixSynapseSetupView, MatrixSynapseServiceView +from .views import SetupView, ServiceView urlpatterns = [ - url(r'^apps/matrixsynapse/setup', MatrixSynapseSetupView.as_view(), - name='setup'), - url(r'^apps/matrixsynapse/$', MatrixSynapseServiceView.as_view(), - name='index') + url(r'^apps/matrixsynapse/setup/$', SetupView.as_view(), name='setup'), + url(r'^apps/matrixsynapse/$', ServiceView.as_view(), name='index'), ] diff --git a/plinth/modules/matrixsynapse/views.py b/plinth/modules/matrixsynapse/views.py index 8100d352f..9ad5363f9 100644 --- a/plinth/modules/matrixsynapse/views.py +++ b/plinth/modules/matrixsynapse/views.py @@ -16,27 +16,27 @@ # """ -Views for the Matrix Synapse module +Views for the Matrix Synapse module. """ + from django.shortcuts import redirect from django.urls import reverse_lazy from django.views.generic import FormView from plinth import actions +from plinth import views from plinth.modules import matrixsynapse from plinth.modules.matrixsynapse.forms import MatrixSynapseForm -from plinth.views import ServiceView -class MatrixSynapseSetupView(FormView): +class SetupView(FormView): """Show matrix-synapse setup page.""" - template_name = 'matrix-pre-setup.html' + template_name = 'matrix-synapse-pre-setup.html' form_class = MatrixSynapseForm - description = matrixsynapse.description - title = matrixsynapse.title success_url = reverse_lazy('matrixsynapse:index') def form_valid(self, form): + """Handle valid form submission.""" domain_name = form.cleaned_data['domain_name'] actions.superuser_run('matrixsynapse', ['setup', '--domain-name', domain_name]) @@ -44,28 +44,32 @@ class MatrixSynapseSetupView(FormView): return super().form_valid(form) def get_context_data(self, *args, **kwargs): + """Provide context data to the template.""" context = super().get_context_data(**kwargs) - context['description'] = self.description - context['title'] = self.title + + context['title'] = matrixsynapse.title + context['description'] = matrixsynapse.description context['domain_names'] = matrixsynapse.get_domain_names() return context -class MatrixSynapseServiceView(ServiceView): +class ServiceView(views.ServiceView): """Show matrix-synapse service page.""" service_id = matrixsynapse.managed_services[0] - template_name = 'matrix-post-setup.html' + template_name = 'matrix-synapse.html' + description = matrixsynapse.description diagnostics_module_name = 'matrixsynapse' def dispatch(self, request, *args, **kwargs): + """Redirect to setup page if setup is not done yet.""" if not matrixsynapse.is_setup(): return redirect('matrixsynapse:setup') return super().dispatch(request, *args, **kwargs) def get_context_data(self, *args, **kwargs): + """Add additional context data for template.""" context = super().get_context_data(**kwargs) context['domain_name'] = matrixsynapse.get_configured_domain_name() - return context