diff --git a/plinth/modules/email_server/audit/domain.py b/plinth/modules/email_server/audit/domain.py index da8c77ea6..74f5b6e72 100644 --- a/plinth/modules/email_server/audit/domain.py +++ b/plinth/modules/email_server/audit/domain.py @@ -4,12 +4,12 @@ import io import json import os +import pathlib import re import select import subprocess import sys import time -from types import SimpleNamespace from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ @@ -181,22 +181,11 @@ def _apply_domain_changes(conf_dict): def get_domain_config(): - fields = [] - - # Special keys - mailname = SimpleNamespace(key='_mailname', name='/etc/mailname') - with open('/etc/mailname', 'r') as fd: - mailname.value = fd.readline().strip() - fields.append(mailname) - - # Postconf keys - postconf_keys = [k for k in managed_keys if not k.startswith('_')] - result_dict = postconf.get_many(postconf_keys) - for key, value in result_dict.items(): - field = SimpleNamespace(key=key, value=value, name='$' + key) - fields.append(field) - - return fields + """Return the current domain configuration.""" + postconf_keys = [key for key in managed_keys if not key.startswith('_')] + config = postconf.get_many(postconf_keys) + config['_mailname'] = pathlib.Path('/etc/mailname').read_text().strip() + return config def set_keys(raw): diff --git a/plinth/modules/email_server/forms.py b/plinth/modules/email_server/forms.py index b7fbbddc4..5b48a3d71 100644 --- a/plinth/modules/email_server/forms.py +++ b/plinth/modules/email_server/forms.py @@ -18,6 +18,13 @@ class EmailServerForm(forms.Form): super().__init__(*args, **kwargs) +class DomainsForm(forms.Form): + _mailname = forms.CharField(required=True, strip=True) + mydomain = forms.CharField(required=True, strip=True) + myhostname = forms.CharField(required=True, strip=True) + mydestination = forms.CharField(required=True, strip=True) + + class AliasCreateForm(forms.Form): """Form to create a new alias.""" alias = forms.CharField(label=_('New alias (without @domain)'), diff --git a/plinth/modules/email_server/templates/email_domains.html b/plinth/modules/email_server/templates/email_domains.html deleted file mode 100644 index 6bb763e5b..000000000 --- a/plinth/modules/email_server/templates/email_domains.html +++ /dev/null @@ -1,37 +0,0 @@ -{# SPDX-License-Identifier: AGPL-3.0-or-later #} -{% extends "email_form_base.html" %} -{% load bootstrap %} -{% load i18n %} - -{% block content %} - - {{ block.super }} - -

{% trans "Domains" %}

- -
- - {% for data in fields %} -
-
- {{ data.name }} = {{ data.value }} -
-
- -
- -
-
-
- {% endfor %} - - {% csrf_token %} - -
- - -{% endblock %} diff --git a/plinth/modules/email_server/templates/email_form_base.html b/plinth/modules/email_server/templates/email_form_base.html deleted file mode 100644 index 390c0936b..000000000 --- a/plinth/modules/email_server/templates/email_form_base.html +++ /dev/null @@ -1,19 +0,0 @@ -{# SPDX-License-Identifier: AGPL-3.0-or-later #} -{% extends "base.html" %} - -{% load i18n %} - -{% block content %} - {{ tabs|safe }} - {{ block.super }} - {% if error %} - - {% endif %} -{% endblock %} diff --git a/plinth/modules/email_server/urls.py b/plinth/modules/email_server/urls.py index b7b0c9e43..3c29b382a 100644 --- a/plinth/modules/email_server/urls.py +++ b/plinth/modules/email_server/urls.py @@ -8,7 +8,7 @@ from . import views urlpatterns = [ path('apps/email_server/', views.EmailServerView.as_view(), name='index'), - path('apps/email_server/domains', views.DomainView.as_view(), + path('apps/email_server/domains', views.DomainsView.as_view(), name='domains'), path('apps/email_server/my_mail', non_admin_view(views.MyMailView.as_view()), name='my_mail'), diff --git a/plinth/modules/email_server/views.py b/plinth/modules/email_server/views.py index 89a06a2b6..e10955c14 100644 --- a/plinth/modules/email_server/views.py +++ b/plinth/modules/email_server/views.py @@ -4,6 +4,7 @@ Views for the email app. """ import pwd +from django.contrib import messages from django.core.exceptions import ValidationError from django.http import HttpResponseBadRequest from django.shortcuts import redirect @@ -197,30 +198,45 @@ class AliasView(FormView): aliases_module.put(self._get_uid(), form.cleaned_data['alias']) -class DomainView(ExceptionsMixin, TemplateView): - template_name = 'email_domains.html' +class DomainsView(FormView): + """View to allow editing domain related settings.""" + template_name = 'form.html' + form_class = forms.DomainsForm + prefix = 'domain' + success_url = reverse_lazy('email_server:domains') - def get_context_data(self, *args, **kwargs): - context = super().get_context_data(*args, **kwargs) - fields = audit.domain.get_domain_config() - # If having post data, display the posted values - for field in fields: - field.new_value = self.request.POST.get(field.key, '') - context['fields'] = fields + def get_initial(self): + """Return the initial values to populate in the form.""" + initial = super().get_initial() + initial.update(audit.domain.get_domain_config()) + return initial + + def get_context_data(self, **kwargs): + """Add the title to the document.""" + context = super().get_context_data(**kwargs) + context['title'] = _('Domains') return context - def post(self, request): - return self.catch_exceptions(self._post, request) + def form_valid(self, form): + """Update the settings for changed domain values.""" + old_data = form.initial + new_data = form.cleaned_data + config = {} + for key in form.initial: + if old_data[key] != new_data[key]: + config[key] = new_data[key] - def _post(self, request): - changed = {} - # Skip blank fields - for key, value in request.POST.items(): - value = value.strip() - if value: - changed[key] = value - audit.domain.set_keys(changed) - return self.render_to_response(self.get_context_data()) + if config: + try: + audit.domain.set_keys(config) + messages.success(self.request, _('Configuration updated')) + except Exception: + messages.success(self.request, + _('Error updating configuration')) + else: + messages.info(self.request, _('Setting unchanged')) + + return super().form_valid(form) class XmlView(TemplateView):