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" %}
-
-
-
-
-{% 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 %}
-
-
- {% trans "There was a problem with your request. Please try again." %}
-
- {% for message in error %}
-
{{ message }}
- {% endfor %}
-
- {% 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):