1
0
mirror of https://github.com/Mailu/Mailu.git synced 2025-08-10 22:31:47 +02:00
3023: Add zonefile download r=mergify[bot] a=MajliTech

## What type of PR?

Feature

## What does this PR do?
On /admin/domain/details/{domain}, adds a button to redirect to /admin/domain/details/{domain}/zonefile, which downloads a zonefile for this domain.

closes #2618

## Prerequisites
Before we can consider review and merge, please make sure the following list is done and checked.
If an entry in not applicable, you can check it or remove it from the list.

- [X] In case of feature or enhancement: documentation updated accordingly
- [X] Unless it's docs or a minor change: add [changelog](https://mailu.io/master/contributors/workflow.html#changelog) entry file.


Co-authored-by: Miłosz <hello@majlitech.pl>
Co-authored-by: Miłosz Thiede <git@majlitech.pl>
Co-authored-by: Alexander Graf <ghostwheel42@users.noreply.github.com>
This commit is contained in:
bors[bot]
2023-11-02 16:01:03 +00:00
committed by GitHub
6 changed files with 30 additions and 10 deletions

View File

@@ -232,9 +232,7 @@ class Domain(Base):
""" return DKIM record for domain """
if self.dkim_key:
selector = app.config['DKIM_SELECTOR']
txt = f'v=DKIM1; k=rsa; p={self.dkim_publickey}'
record = ' '.join(f'"{txt[p:p+250]}"' for p in range(0, len(txt), 250))
return f'{selector}._domainkey.{self.name}. 600 IN TXT {record}'
return f'{selector}._domainkey.{self.name}. 600 IN TXT "v=DKIM1; k=rsa; p={self.dkim_publickey}"'
@cached_property
def dns_dmarc(self):

View File

@@ -511,6 +511,10 @@ msgstr ""
msgid "Generate keys"
msgstr ""
#: mailu/ui/templates/domain/details.html:19
msgid "Download zonefile"
msgstr ""
#: mailu/ui/templates/domain/details.html:30
msgid "DNS MX entry"
msgstr ""

View File

@@ -10,13 +10,13 @@
{%- block main_action %}
{%- if current_user.global_admin %}
<a class="btn btn-primary float-right" href="{{ url_for(".domain_genkeys", domain_name=domain.name) }}">
<a class="btn btn-primary btn-group float-right" href="{{ url_for(".domain_genkeys", domain_name=domain.name) }}">
{%- if domain.dkim_publickey %}
{% trans %}Regenerate keys{% endtrans %}
{%- else %}
{% trans %}Generate keys{% endtrans %}
{%- endif %}
</a>
</a><a style="margin-right: 5px;" class="btn btn-primary btn-group float-right" href="{{ url_for(".domain_download_zonefile", domain_name=domain.name) }}"> {% trans %}Download zonefile{% endtrans %}</a>
{%- endif %}
{%- endblock %}
@@ -36,10 +36,6 @@
</td>
</tr>
{%- if domain.dkim_publickey %}
<tr>
<th>{% trans %}DKIM public key{% endtrans %}</th>
<td>{{ macros.clip("dkim_key") }}<pre id="dkim_key" class="pre-config border bg-light">{{ domain.dkim_publickey }}</pre></td>
</tr>
<tr>
<th>{% trans %}DNS DKIM entry{% endtrans %}</th>
<td>{{ macros.clip("dns_dkim") }}<pre id="dns_dkim" class="pre-config border bg-light">{{ domain.dns_dkim }}</pre></td>

View File

@@ -70,6 +70,27 @@ def domain_details(domain_name):
domain = models.Domain.query.get(domain_name) or flask.abort(404)
return flask.render_template('domain/details.html', domain=domain)
@ui.route('/domain/details/<domain_name>/zonefile', methods=['GET'])
@access.domain_admin(models.Domain, 'domain_name')
def domain_download_zonefile(domain_name):
domain = models.Domain.query.get(domain_name) or flask.abort(404)
res = [domain.dns_mx, domain.dns_spf]
if domain.dkim_publickey:
record = domain.dns_dkim.split('"', 1)[0].strip()
txt = f'v=DKIM1; k=rsa; p={domain.dkim_publickey}'
txt = ' '.join(f'"{txt[p:p+250]}"' for p in range(0, len(txt), 250))
res.append(f'{record} {txt}')
res.append(domain.dns_dmarc)
if domain.dns_tlsa:
res.append(domain.dns_tlsa)
res.extend(domain.dns_autoconfig)
res.append("")
return flask.Response(
"\n".join(res),
content_type="text/plain",
headers={"Content-disposition": f"attachment; filename={domain.name}-zonefile.txt"}
)
@ui.route('/domain/genkeys/<domain_name>', methods=['GET', 'POST'])
@access.domain_admin(models.Domain, 'domain_name')