email_server: domains: Use Django forms and views

- Eliminate error-prone custom code and styling.

Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2021-10-15 19:43:59 -07:00 committed by James Valleroy
parent b62dd2442c
commit e85001f01f
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
6 changed files with 50 additions and 94 deletions

View File

@ -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):

View File

@ -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)'),

View File

@ -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 }}
<h2>{% trans "Domains" %}</h2>
<form action="{{ request.path }}" method="post">
{% for data in fields %}
<div class="form-group">
<div class="form-text">
<strong>{{ data.name }}</strong> = {{ data.value }}
</div> <!-- end form-text -->
<div class="row">
<label for="text_{{ data.key }}" class="col-sm-2 col-form-label">
{% trans "New value" %}
</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="text_{{ data.key }}"
name="{{ data.key }}" value="{{ data.new_value }}">
</div>
</div> <!-- end row -->
</div> <!-- end form-group -->
{% endfor %}
{% csrf_token %}
<input class="btn btn-primary" type="submit" name="btn_update"
value="{% trans 'Update' %}">
</form>
{% endblock %}

View File

@ -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 %}
<div class="alert alert-danger" role="alert">
<p>
{% trans "There was a problem with your request. Please try again." %}
</p>
{% for message in error %}
<p>{{ message }}</p>
{% endfor %}
</div>
{% endif %}
{% endblock %}

View File

@ -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'),

View File

@ -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):