mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-08-26 12:46:08 +00:00
email: dns: Show table for desired DNS entries
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
1af9a6b114
commit
bc5de46eb2
68
plinth/modules/email/dns.py
Normal file
68
plinth/modules/email/dns.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
"""
|
||||||
|
Manage DNS entries needed for an email server.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
|
from plinth.errors import ActionError
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Entry: # pylint: disable=too-many-instance-attributes
|
||||||
|
"""A DNS entry."""
|
||||||
|
type_: str
|
||||||
|
value: str
|
||||||
|
domain: Union[str, None] = None
|
||||||
|
class_: str = 'IN'
|
||||||
|
ttl: int = 60
|
||||||
|
priority: int = 10
|
||||||
|
weight: Union[int, None] = None
|
||||||
|
port: Union[int, None] = None
|
||||||
|
|
||||||
|
def get_split_value(self):
|
||||||
|
"""If the record is TXT and value > 255, split it."""
|
||||||
|
if len(self.value) <= 255:
|
||||||
|
return self.value
|
||||||
|
|
||||||
|
pieces = []
|
||||||
|
value = self.value
|
||||||
|
while value:
|
||||||
|
pieces.append(f'"{value[:255]}"')
|
||||||
|
value = value[255:]
|
||||||
|
|
||||||
|
return ' '.join(pieces)
|
||||||
|
|
||||||
|
|
||||||
|
def get_entries():
|
||||||
|
"""Return the list of DNS entries to make."""
|
||||||
|
from . import audit
|
||||||
|
|
||||||
|
domain = audit.domain.get_domains()['primary_domain']
|
||||||
|
mx_spam_entries = [
|
||||||
|
Entry(type_='MX', value=f'{domain}.'),
|
||||||
|
Entry(type_='TXT', value='v=spf1 mx a ~all'),
|
||||||
|
Entry(
|
||||||
|
domain='_dmarc', type_='TXT',
|
||||||
|
value='v=DMARC1; p=none; sp=quarantine; '
|
||||||
|
f'rua=mailto:postmaster@{domain}; ')
|
||||||
|
]
|
||||||
|
try:
|
||||||
|
dkim_public_key = audit.dkim.get_public_key(domain)
|
||||||
|
dkim_entries = [
|
||||||
|
Entry(domain='dkim._domainkey', type_='TXT',
|
||||||
|
value=f'v=DKIM1; k=rsa; p={dkim_public_key}')
|
||||||
|
]
|
||||||
|
except ActionError:
|
||||||
|
dkim_entries = []
|
||||||
|
|
||||||
|
autoconfig_entries = [
|
||||||
|
Entry(domain='_submission._tcp', type_='SRV', weight=10, port=587,
|
||||||
|
value=f'{domain}.'),
|
||||||
|
Entry(domain='_imaps._tcp', type_='SRV', weight=10, port=993,
|
||||||
|
value=f'{domain}.'),
|
||||||
|
Entry(domain='_pop3s._tcp', type_='SRV', priority=20, weight=10,
|
||||||
|
port=995, value=f'{domain}.'),
|
||||||
|
]
|
||||||
|
return mx_spam_entries + dkim_entries + autoconfig_entries
|
||||||
@ -15,3 +15,47 @@
|
|||||||
{% trans "Manage Aliases" %}
|
{% trans "Manage Aliases" %}
|
||||||
</a>
|
</a>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_content %}
|
||||||
|
{{ block.super }}
|
||||||
|
|
||||||
|
<h3>{% trans "DNS Records" %}</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{% blocktrans trimmed %}
|
||||||
|
The following DNS records must be added manually on your primary domain
|
||||||
|
for the mail server to work properly.
|
||||||
|
{% endblocktrans %}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table table-sm">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{% trans "Domain" %}</th>
|
||||||
|
<th>{% trans "TTL" %}</th>
|
||||||
|
<th>{% trans "Class" %}</th>
|
||||||
|
<th>{% trans "Type" %}</th>
|
||||||
|
<th>{% trans "Priority" %}</th>
|
||||||
|
<th>{% trans "Weight" %}</th>
|
||||||
|
<th>{% trans "Port" %}</th>
|
||||||
|
<th>{% trans "Host/Target/Value" %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for dns_entry in dns_entries %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ dns_entry.domain|default_if_none:"" }}</td>
|
||||||
|
<td>{{ dns_entry.ttl }}</td>
|
||||||
|
<td>{{ dns_entry.class_ }}</td>
|
||||||
|
<td>{{ dns_entry.type_ }}</td>
|
||||||
|
<td>{{ dns_entry.priority }}</td>
|
||||||
|
<td>{{ dns_entry.weight|default_if_none:"" }}</td>
|
||||||
|
<td>{{ dns_entry.port|default_if_none:"" }}</td>
|
||||||
|
<td class="text-break">{{ dns_entry.get_split_value }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|||||||
@ -9,6 +9,7 @@ from django.utils.translation import gettext_lazy as _
|
|||||||
from django.views.generic.base import TemplateView
|
from django.views.generic.base import TemplateView
|
||||||
from django.views.generic.edit import FormView
|
from django.views.generic.edit import FormView
|
||||||
|
|
||||||
|
from plinth.modules.email import dns
|
||||||
from plinth.views import AppView
|
from plinth.views import AppView
|
||||||
|
|
||||||
from . import aliases as aliases_module
|
from . import aliases as aliases_module
|
||||||
@ -21,6 +22,12 @@ class EmailAppView(AppView):
|
|||||||
form_class = forms.DomainForm
|
form_class = forms.DomainForm
|
||||||
template_name = 'email.html'
|
template_name = 'email.html'
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
"""Add additional context data for rendering the template."""
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context['dns_entries'] = dns.get_entries()
|
||||||
|
return context
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
"""Return the initial values to populate in the form."""
|
"""Return the initial values to populate in the form."""
|
||||||
initial = super().get_initial()
|
initial = super().get_initial()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user