From aaa6342f936c1a723ec339359c55b92700a3739a Mon Sep 17 00:00:00 2001 From: fliu <10025-fliu@users.noreply.salsa.debian.org> Date: Sun, 28 Mar 2021 23:40:18 +0000 Subject: [PATCH] email: Basic app to manage an email server - Install postfix and manage the service - Import ugettext - Dummy forms and views - .version (integer) is required [sunil: Disable the app until remaining issues are worked out] Signed-off-by: Sunil Mohan Adapa --- actions/email_server | 0 plinth/modules/email_server/__init__.py | 88 +++++++++++++++++++ .../etc/plinth/modules-enabled/email_server | 1 + plinth/modules/email_server/forms.py | 6 ++ plinth/modules/email_server/manifest.py | 52 +++++++++++ plinth/modules/email_server/tests/__init__.py | 0 plinth/modules/email_server/urls.py | 8 ++ plinth/modules/email_server/views.py | 15 ++++ 8 files changed, 170 insertions(+) create mode 100644 actions/email_server create mode 100644 plinth/modules/email_server/__init__.py create mode 100644 plinth/modules/email_server/data/etc/plinth/modules-enabled/email_server create mode 100644 plinth/modules/email_server/forms.py create mode 100644 plinth/modules/email_server/manifest.py create mode 100644 plinth/modules/email_server/tests/__init__.py create mode 100644 plinth/modules/email_server/urls.py create mode 100644 plinth/modules/email_server/views.py diff --git a/actions/email_server b/actions/email_server new file mode 100644 index 000000000..e69de29bb diff --git a/plinth/modules/email_server/__init__.py b/plinth/modules/email_server/__init__.py new file mode 100644 index 000000000..65211a9c0 --- /dev/null +++ b/plinth/modules/email_server/__init__.py @@ -0,0 +1,88 @@ +"""FreedomBox email server app""" +# SPDX-License-Identifier: AGPL-3.0-or-later + +from django.urls import reverse_lazy +from django.utils.translation import ugettext_lazy as _ + +import plinth.app +import plinth.daemon +import plinth.frontpage +import plinth.menu +from plinth.modules.firewall.components import Firewall + +from . import manifest + +version = 1 +managed_packages = ['postfix', 'dovecot-pop3d', 'dovecot-imapd', + 'dovecot-lmtpd', 'dovecot-ldap', 'dovecot-managesieved'] +managed_services = ['postfix', 'dovecot'] +app = None + + +class EmailServerApp(plinth.app.App): + """FreedomBox email server app""" + app_id = 'email_server' + + def __init__(self): + """The app's constructor""" + super().__init__() + + info = plinth.app.Info( + app_id=self.app_id, + version=version, + name=_('Email Server'), + short_description=_('An email server for FreedomBox'), + manual_page='EmailServer', + clients=manifest.clients, + donation_url='https://freedomboxfoundation.org/donate/' + ) + self.add(info) + + menu_item = plinth.menu.Menu( + 'menu_' + self.app_id, # unique id + info.name, # app display name + info.short_description, # app description + 'roundcube', # icon name in `static/theme/icons/` + 'email_server:index', # view name + parent_url_name='apps' + ) + self.add(menu_item) + + shortcut = plinth.frontpage.Shortcut( + 'shortcut_' + self.app_id, + name=info.name, + short_description=info.short_description, + icon='roundcube', + configure_url=reverse_lazy('email_server'), + clients=manifest.clients, + login_required=True + ) + self.add(shortcut) + + postfix_ports = [] + dovecot_ports = [] + all_firewalld_ports = [] + for port in (25, 465, 587): + postfix_ports.extend([(port, 'tcp4'), (port, 'tcp6')]) + for port in (993, 995): + dovecot_ports.extend([(port, 'tcp4'), (port, 'tcp6')]) + all_firewalld_ports.extend(['smtp', 'smtps', 'smtp-submission']) + all_firewalld_ports.extend(['pop3s', 'imaps']) + + # Manage daemons + postfixd = plinth.daemon.Daemon('daemon-postfix', 'postfix', + listen_ports=postfix_ports) + dovecotd = plinth.daemon.Daemon('daemon-dovecot', 'dovecot', + listen_ports=dovecot_ports) + self.add(postfixd) + self.add(dovecotd) + + # Ports + firewall = Firewall('firewall-email', info.name, + ports=all_firewalld_ports, is_external=True) + self.add(firewall) + + +def setup(helper, old_version=None): + """Installs and configures module""" + helper.install(managed_packages) diff --git a/plinth/modules/email_server/data/etc/plinth/modules-enabled/email_server b/plinth/modules/email_server/data/etc/plinth/modules-enabled/email_server new file mode 100644 index 000000000..fb87084c0 --- /dev/null +++ b/plinth/modules/email_server/data/etc/plinth/modules-enabled/email_server @@ -0,0 +1 @@ +#plinth.modules.email_server diff --git a/plinth/modules/email_server/forms.py b/plinth/modules/email_server/forms.py new file mode 100644 index 000000000..4f6ecdac7 --- /dev/null +++ b/plinth/modules/email_server/forms.py @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +from django import forms + + +class EmailServerForm(forms.Form): + pass diff --git a/plinth/modules/email_server/manifest.py b/plinth/modules/email_server/manifest.py new file mode 100644 index 000000000..3a6bdae77 --- /dev/null +++ b/plinth/modules/email_server/manifest.py @@ -0,0 +1,52 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +from django.utils.translation import ugettext_lazy as _ +from plinth.clients import store_url + +clients = [{ + 'name': _('Roundcube'), + 'platforms': [{ + 'type': 'web', + 'url': '/plinth/apps/roundcube' + }] +}, { + 'name': _('Thunderbird'), + 'platforms': [{ + 'type': 'download', + 'os': 'gnu-linux', + 'url': 'https://www.thunderbird.net/en-US/' + }, { + 'type': 'download', + 'os': 'macos', + 'url': 'https://www.thunderbird.net/en-US/' + }, { + 'type': 'download', + 'os': 'windows', + 'url': 'https://www.thunderbird.net/en-US/' + }] +}, { + 'name': _('K-9 Mail'), + 'platforms': [{ + 'type': 'store', + 'os': 'android', + 'store_name': 'f-droid', + 'url': store_url('f-droid', 'com.fsck.k9') + }, { + 'type': 'store', + 'os': 'android', + 'store_name': 'google-play', + 'url': store_url('google-play', 'com.fsck.k9') + }] +}, { + 'name': _('FairEmail'), + 'platforms': [{ + 'type': 'store', + 'os': 'android', + 'store_name': 'f-droid', + 'url': store_url('f-droid', 'eu.faircode.email') + }, { + 'type': 'store', + 'os': 'android', + 'store_name': 'google-play', + 'url': store_url('google-play', 'eu.faircode.email') + }] +}] diff --git a/plinth/modules/email_server/tests/__init__.py b/plinth/modules/email_server/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/plinth/modules/email_server/urls.py b/plinth/modules/email_server/urls.py new file mode 100644 index 000000000..61d5844af --- /dev/null +++ b/plinth/modules/email_server/urls.py @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +from django.urls import path +from . import views + + +urlpatterns = [ + path('apps/email_server/', views.EmailServerView.as_view(), name='index') +] diff --git a/plinth/modules/email_server/views.py b/plinth/modules/email_server/views.py new file mode 100644 index 000000000..615142512 --- /dev/null +++ b/plinth/modules/email_server/views.py @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +import plinth +from . import forms + + +class EmailServerView(plinth.views.AppView): + """Server configuration page""" + app_id = 'email_server' + form_class = forms.EmailServerForm + + def form_valid(self, form): + # old_settings = form.initial + # new_status = form.cleaned_data + # plinth.actions.superuser_run('email_server', ['--help']) + return super().form_valid(form)