From ed0ab1ab64d818a10b88fc54d40df4920498bdb1 Mon Sep 17 00:00:00 2001
From: Johannes Keyser
Date: Sun, 7 May 2017 15:00:49 +0100
Subject: [PATCH] ejabberd: add option to enable/disable Message Archive
Management
---
actions/ejabberd | 53 +++++++++++++++++++
plinth/modules/ejabberd/forms.py | 40 ++++++++++++++
.../modules/ejabberd/templates/ejabberd.html | 15 ++++++
plinth/modules/ejabberd/views.py | 49 +++++++++++++++++
4 files changed, 157 insertions(+)
create mode 100644 plinth/modules/ejabberd/forms.py
diff --git a/actions/ejabberd b/actions/ejabberd
index e161ab603..42090ae30 100755
--- a/actions/ejabberd
+++ b/actions/ejabberd
@@ -78,6 +78,13 @@ def parse_arguments():
help='Update ejabberd with new domainname')
domainname_change.add_argument('--domainname', help='New domainname')
+ # Switch/check Message Archive Management (MAM) in ejabberd config
+ help_MAM = 'Switch or check Message Archive Management (MAM).'
+ mam = subparsers.add_parser('mam', help=help_MAM)
+ mam.add_argument('command',
+ choices=('enable', 'disable', 'status'),
+ help=help_MAM)
+
subparsers.required = True
return parser.parse_args()
@@ -209,6 +216,52 @@ def subcommand_change_domainname(arguments):
action_utils.service_start('ejabberd')
+def subcommand_mam(argument):
+ """Enable, disable, or get status of Message Archive Management (MAM)."""
+
+ with open(EJABBERD_CONFIG, 'r') as file_handle:
+ conf = ruamel.yaml.round_trip_load(file_handle, preserve_quotes=True)
+
+ if 'modules' not in conf:
+ print('Found no "modules" entry in ejabberd configuration file.')
+ return
+
+ if argument.command == 'status':
+ if 'mod_mam' in conf['modules']:
+ print('enabled')
+ return
+ else:
+ print('disabled')
+ return
+
+ if argument.command == 'enable':
+ # Explicitly set the recommended / default settings for mod_mam,
+ # see https://docs.ejabberd.im/admin/configuration/#mod-mam.
+ settings_mod_mam = {'mod_mam': {
+ 'iqdisc': 'one_queue', # discipline, recommended 'one_queue'
+ 'db_type': 'mnesia', # default is 'mnesia' (w/o set default_db)
+ 'default': 'never', # policy, default 'never'
+ 'request_activates_archiving': False, # default False
+ 'assume_mam_usage': False, # for non-ack'd msgs, default False
+ 'cache_size': 1000, # default is 1000 items
+ 'cache_life_time': 3600 # default is 3600 seconds = 1h
+ }}
+ conf['modules'].update(settings_mod_mam)
+ elif argument.command == 'disable':
+ # disable modules by erasing from config file
+ if 'mod_mam' in conf['modules']:
+ conf['modules'].pop('mod_mam')
+ else:
+ print("Unknown command: %s" % argument.command)
+ return
+
+ with open(EJABBERD_CONFIG, 'w') as file_handle:
+ ruamel.yaml.round_trip_dump(conf, file_handle)
+
+ if action_utils.service_is_running('ejabberd'):
+ action_utils.service_restart('ejabberd')
+
+
def main():
"""Parse arguments and perform all duties"""
arguments = parse_arguments()
diff --git a/plinth/modules/ejabberd/forms.py b/plinth/modules/ejabberd/forms.py
new file mode 100644
index 000000000..ee44540fe
--- /dev/null
+++ b/plinth/modules/ejabberd/forms.py
@@ -0,0 +1,40 @@
+#
+# 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 .
+#
+
+"""
+Forms for configuring Ejabberd.
+"""
+
+from plinth import forms as plinthForms
+from django import forms as djangoForms
+from django.utils.translation import ugettext_lazy as _
+
+from plinth import cfg
+from plinth.utils import format_lazy
+
+
+class EjabberdForm(plinthForms.ServiceForm):
+ """Ejabberd configuration form."""
+ MAM_enabled = djangoForms.BooleanField(
+ label=_('Enable Message Archive Management'),
+ required=False,
+ help_text=format_lazy(_(
+ 'If enabled, your {box_name} will store chat message histories. '
+ 'This allows synchronization of conversations between multiple '
+ 'clients, and reading the history of a multi-user chat room. '
+ 'It depends on the client settings whether the histories are '
+ 'stored as plain text or encrypted.'), box_name=_(cfg.box_name)))
diff --git a/plinth/modules/ejabberd/templates/ejabberd.html b/plinth/modules/ejabberd/templates/ejabberd.html
index 79e525503..3d20cae60 100644
--- a/plinth/modules/ejabberd/templates/ejabberd.html
+++ b/plinth/modules/ejabberd/templates/ejabberd.html
@@ -19,6 +19,7 @@
{% endcomment %}
{% load i18n %}
+{% load bootstrap %}
{% block description %}
@@ -46,3 +47,17 @@
{% trans "Launch web client" %}
{% endblock %}
+
+
+{% block configuration %}
+ {% trans "Configuration" %}
+
+
+{% endblock %}
diff --git a/plinth/modules/ejabberd/views.py b/plinth/modules/ejabberd/views.py
index 778b96ddd..20b1d62e8 100644
--- a/plinth/modules/ejabberd/views.py
+++ b/plinth/modules/ejabberd/views.py
@@ -25,6 +25,10 @@ from stronghold.decorators import public
from plinth.modules import ejabberd
from plinth.views import ServiceView
+from .forms import EjabberdForm
+from plinth import actions
+from django.contrib import messages
+from django.utils.translation import ugettext as _
class EjabberdServiceView(ServiceView):
@@ -33,8 +37,53 @@ class EjabberdServiceView(ServiceView):
template_name = 'ejabberd.html'
description = ejabberd.description
diagnostics_module_name = 'ejabberd'
+ form_class = EjabberdForm
+
+ def get_initial(self):
+ initdict = super().get_initial()
+ initdict.update({'MAM_enabled': self.is_MAM_enabled()})
+ return initdict
def get_context_data(self, *args, **kwargs):
+ """Add service to the context data."""
context = super().get_context_data(*args, **kwargs)
context['domainname'] = ejabberd.get_domainname()
return context
+
+ def form_valid(self, form):
+ """Enable/disable a service and set messages."""
+ old_status = form.initial
+ new_status = form.cleaned_data
+ app_same = old_status['is_enabled'] == new_status['is_enabled']
+ mam_same = old_status['MAM_enabled'] == new_status['MAM_enabled']
+
+ if app_same and mam_same:
+ # TODO: find a more reliable/official way to check whether the
+ # request has messages attached.
+ if not self.request._messages._queued_messages:
+ messages.info(self.request, _('Setting unchanged'))
+ elif not app_same:
+ if new_status['is_enabled']:
+ self.service.enable()
+ messages.success(self.request, _('Application enabled'))
+ else:
+ self.service.disable()
+ messages.success(self.request, _('Application disabled'))
+
+ if not mam_same:
+ # note ejabberd action "enable" or "disable" restarts, if running
+ if new_status['MAM_enabled']:
+ actions.superuser_run('ejabberd', ['mam', 'enable'])
+ messages.success(self.request,
+ _('Message Archive Management enabled'))
+ else:
+ actions.superuser_run('ejabberd', ['mam', 'disable'])
+ messages.success(self.request,
+ _('Message Archive Management disabled'))
+
+ return super(ServiceView, self).form_valid(form)
+
+ def is_MAM_enabled(self):
+ """Return whether Message Archive Management (MAM) is enabled."""
+ output = actions.superuser_run('ejabberd', ['mam', 'status'])
+ return output.strip() == 'enabled'