From 1b175e48d42ff78709373c2bddca2cdb264ab2d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C5=82osz?= Date: Sun, 29 Oct 2023 09:36:16 +0000 Subject: [PATCH 01/11] testing: Add "download zonefile" button --- core/admin/mailu/ui/views/domains.py | 16 ++++++++++++++++ towncrier/newsfragments/3008.feature | 1 + 2 files changed, 17 insertions(+) create mode 100644 towncrier/newsfragments/3008.feature diff --git a/core/admin/mailu/ui/views/domains.py b/core/admin/mailu/ui/views/domains.py index 4cdd830a..fcbe70a2 100644 --- a/core/admin/mailu/ui/views/domains.py +++ b/core/admin/mailu/ui/views/domains.py @@ -70,6 +70,22 @@ 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//downzonefile', methods=['GET']) +@access.domain_admin(models.Domain, 'domain_name') +def domain_details(domain_name): + domain = models.Domain.query.get(domain_name) or flask.abort(404) + final = domain.dns_mx+"\n" + final = final + domain.dns_spf+"\n" + if domain.dkim_publickey: + final = final + domain.dkim_publickey+"\n" + final = final + domain.dns_dkim+"\n" + final = final + domain.dns_dmarc+"\n" + if domain.dns_tlsa: + final = final + domain.dns_tlsa + for i in domain.dns_autoconfig: + final = final + i+"\n" + return flask.Response(final,content_type="text/plain") + @ui.route('/domain/genkeys/', methods=['GET', 'POST']) @access.domain_admin(models.Domain, 'domain_name') diff --git a/towncrier/newsfragments/3008.feature b/towncrier/newsfragments/3008.feature new file mode 100644 index 00000000..1bda6ca6 --- /dev/null +++ b/towncrier/newsfragments/3008.feature @@ -0,0 +1 @@ +Add "download zonefile" button to domain configuration \ No newline at end of file From 43dc61f4158b613e0283571eff6e995403adceba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C5=82osz=20Thiede?= Date: Sun, 29 Oct 2023 11:23:22 +0100 Subject: [PATCH 02/11] switch "downzonefile" to "zonefile" --- core/admin/mailu/ui/views/domains.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/admin/mailu/ui/views/domains.py b/core/admin/mailu/ui/views/domains.py index fcbe70a2..3dc0fcdb 100644 --- a/core/admin/mailu/ui/views/domains.py +++ b/core/admin/mailu/ui/views/domains.py @@ -70,9 +70,9 @@ 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//downzonefile', methods=['GET']) +@ui.route('/domain/details//zonefile', methods=['GET']) @access.domain_admin(models.Domain, 'domain_name') -def domain_details(domain_name): +def domain_download_zonefile(domain_name): domain = models.Domain.query.get(domain_name) or flask.abort(404) final = domain.dns_mx+"\n" final = final + domain.dns_spf+"\n" From 0718edcba9124f4f90dc2270c66409b6e292fac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C5=82osz=20Thiede?= Date: Sun, 29 Oct 2023 11:24:37 +0100 Subject: [PATCH 03/11] Create the button for zonefile downloading --- core/admin/mailu/ui/templates/domain/details.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/admin/mailu/ui/templates/domain/details.html b/core/admin/mailu/ui/templates/domain/details.html index 28f3f570..34405ac7 100644 --- a/core/admin/mailu/ui/templates/domain/details.html +++ b/core/admin/mailu/ui/templates/domain/details.html @@ -17,6 +17,9 @@ {% trans %}Generate keys{% endtrans %} {%- endif %} + + {% trans %}Download zonefile{% endtrans %} + {%- endif %} {%- endblock %} From 83f3b7722c91448804ce4fffcb22340663010251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C5=82osz=20Thiede?= Date: Sun, 29 Oct 2023 11:30:06 +0100 Subject: [PATCH 04/11] add a button to download zonefile --- core/admin/mailu/translations/en/LC_MESSAGES/messages.po | 4 ++++ core/admin/mailu/ui/templates/domain/details.html | 5 +---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/admin/mailu/translations/en/LC_MESSAGES/messages.po b/core/admin/mailu/translations/en/LC_MESSAGES/messages.po index 4ec33e05..f19e191f 100644 --- a/core/admin/mailu/translations/en/LC_MESSAGES/messages.po +++ b/core/admin/mailu/translations/en/LC_MESSAGES/messages.po @@ -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 "" diff --git a/core/admin/mailu/ui/templates/domain/details.html b/core/admin/mailu/ui/templates/domain/details.html index 34405ac7..92f7e288 100644 --- a/core/admin/mailu/ui/templates/domain/details.html +++ b/core/admin/mailu/ui/templates/domain/details.html @@ -16,10 +16,7 @@ {%- else %} {% trans %}Generate keys{% endtrans %} {%- endif %} - - - {% trans %}Download zonefile{% endtrans %} - + {% trans %}Download zonefile{% endtrans %} {%- endif %} {%- endblock %} From 150448367775a1131bd3340b5e5535be1bfbd6fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C5=82osz=20Thiede?= Date: Sun, 29 Oct 2023 11:50:36 +0100 Subject: [PATCH 05/11] make it save as a file, name {domain}-zonefile.txt --- core/admin/mailu/ui/views/domains.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/admin/mailu/ui/views/domains.py b/core/admin/mailu/ui/views/domains.py index 3dc0fcdb..b03b96b0 100644 --- a/core/admin/mailu/ui/views/domains.py +++ b/core/admin/mailu/ui/views/domains.py @@ -84,7 +84,7 @@ def domain_download_zonefile(domain_name): final = final + domain.dns_tlsa for i in domain.dns_autoconfig: final = final + i+"\n" - return flask.Response(final,content_type="text/plain") + return flask.Response(final,content_type="text/plain",headers={'Content-disposition': 'attachment; filename='+domain.name+'-zonefile.txt'}) @ui.route('/domain/genkeys/', methods=['GET', 'POST']) From 9905806c971e7291eab9c31a6d91f4073c2ae379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C5=82osz=20Thiede?= Date: Sun, 29 Oct 2023 11:50:43 +0100 Subject: [PATCH 06/11] create a button --- core/admin/mailu/ui/templates/domain/details.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/admin/mailu/ui/templates/domain/details.html b/core/admin/mailu/ui/templates/domain/details.html index 92f7e288..a58c4477 100644 --- a/core/admin/mailu/ui/templates/domain/details.html +++ b/core/admin/mailu/ui/templates/domain/details.html @@ -10,13 +10,13 @@ {%- block main_action %} {%- if current_user.global_admin %} - + {%- if domain.dkim_publickey %} {% trans %}Regenerate keys{% endtrans %} {%- else %} {% trans %}Generate keys{% endtrans %} {%- endif %} - {% trans %}Download zonefile{% endtrans %} + {% trans %}Download zonefile{% endtrans %} {%- endif %} {%- endblock %} From a27845b2136200db22e7db1307e9b412549e8f20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C5=82osz=20Thiede?= Date: Sun, 29 Oct 2023 11:53:31 +0100 Subject: [PATCH 07/11] update docs --- docs/webadministration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/webadministration.rst b/docs/webadministration.rst index 802ce43b..3ce53fe8 100644 --- a/docs/webadministration.rst +++ b/docs/webadministration.rst @@ -280,7 +280,7 @@ On the `Mail domains` page all the domains served by Mailu are configured. Via t Details ``````` -This page is also accessible for domain managers. On the details page all DNS settings are displayed for configuring your DNS server. It contains information on what to configure as MX record and SPF record. On this page it is also possible to (re-)generate the keys for DKIM and DMARC. The option for generating keys for DKIM and DMARC is only available for global administrators. After generating the keys for DKIM and DMARC, this page will also show the DNS records for configuring the DKIM/DMARC records on the DNS server. +This page is also accessible for domain managers. On the details page all DNS settings are displayed for configuring your DNS server. It contains information on what to configure as MX record and SPF record. On this page it is also possible to (re-)generate the keys for DKIM and DMARC. The option for generating keys for DKIM and DMARC is only available for global administrators. After generating the keys for DKIM and DMARC, this page will also show the DNS records for configuring the DKIM/DMARC records on the DNS server. You can also download a zonefile for easy upload to your nameserver. Edit From 16af54b15d76acef6dd33c134a5dfd569cfb5f81 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Mon, 30 Oct 2023 16:00:43 +0100 Subject: [PATCH 08/11] Only use split key in zonefile, not in gui/api/export --- core/admin/mailu/models.py | 4 +--- .../mailu/ui/templates/domain/details.html | 4 ---- core/admin/mailu/ui/views/domains.py | 23 +++++++++++-------- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/core/admin/mailu/models.py b/core/admin/mailu/models.py index 926ef2fc..45ec457c 100644 --- a/core/admin/mailu/models.py +++ b/core/admin/mailu/models.py @@ -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): diff --git a/core/admin/mailu/ui/templates/domain/details.html b/core/admin/mailu/ui/templates/domain/details.html index a58c4477..74657c28 100644 --- a/core/admin/mailu/ui/templates/domain/details.html +++ b/core/admin/mailu/ui/templates/domain/details.html @@ -36,10 +36,6 @@ {%- if domain.dkim_publickey %} - - {% trans %}DKIM public key{% endtrans %} - {{ macros.clip("dkim_key") }}
{{ domain.dkim_publickey }}
- {% trans %}DNS DKIM entry{% endtrans %} {{ macros.clip("dns_dkim") }}
{{ domain.dns_dkim }}
diff --git a/core/admin/mailu/ui/views/domains.py b/core/admin/mailu/ui/views/domains.py index b03b96b0..6fb4410b 100644 --- a/core/admin/mailu/ui/views/domains.py +++ b/core/admin/mailu/ui/views/domains.py @@ -74,17 +74,22 @@ def domain_details(domain_name): @access.domain_admin(models.Domain, 'domain_name') def domain_download_zonefile(domain_name): domain = models.Domain.query.get(domain_name) or flask.abort(404) - final = domain.dns_mx+"\n" - final = final + domain.dns_spf+"\n" + res = [domain.dns_mx, domain.dns_spf] if domain.dkim_publickey: - final = final + domain.dkim_publickey+"\n" - final = final + domain.dns_dkim+"\n" - final = final + domain.dns_dmarc+"\n" + 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: - final = final + domain.dns_tlsa - for i in domain.dns_autoconfig: - final = final + i+"\n" - return flask.Response(final,content_type="text/plain",headers={'Content-disposition': 'attachment; filename='+domain.name+'-zonefile.txt'}) + 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/', methods=['GET', 'POST']) From e77b3f0a36dcb9a09c906181f8d0b47ac16d8f36 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 1 Nov 2023 18:01:39 +0100 Subject: [PATCH 09/11] Update newsfragment --- towncrier/newsfragments/3008.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/towncrier/newsfragments/3008.feature b/towncrier/newsfragments/3008.feature index 1bda6ca6..1bc39cb1 100644 --- a/towncrier/newsfragments/3008.feature +++ b/towncrier/newsfragments/3008.feature @@ -1 +1 @@ -Add "download zonefile" button to domain configuration \ No newline at end of file +Add "download zonefile" button to domain configuration and un-split dkim key in dns table From fa8e8f4f7313634efd1737b36c72b0771939d87a Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Wed, 1 Nov 2023 18:02:40 +0100 Subject: [PATCH 10/11] Rename 3008.feature to 3023.feature --- towncrier/newsfragments/{3008.feature => 3023.feature} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename towncrier/newsfragments/{3008.feature => 3023.feature} (100%) diff --git a/towncrier/newsfragments/3008.feature b/towncrier/newsfragments/3023.feature similarity index 100% rename from towncrier/newsfragments/3008.feature rename to towncrier/newsfragments/3023.feature From 901e4a772dbec86faaf3a2be34e98f3eff64e025 Mon Sep 17 00:00:00 2001 From: Alexander Graf Date: Thu, 2 Nov 2023 15:58:15 +0100 Subject: [PATCH 11/11] Remove surplus double quote --- core/admin/mailu/ui/views/domains.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/admin/mailu/ui/views/domains.py b/core/admin/mailu/ui/views/domains.py index 6fb4410b..dcd1aedd 100644 --- a/core/admin/mailu/ui/views/domains.py +++ b/core/admin/mailu/ui/views/domains.py @@ -79,7 +79,7 @@ def domain_download_zonefile(domain_name): 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(f'{record} {txt}') res.append(domain.dns_dmarc) if domain.dns_tlsa: res.append(domain.dns_tlsa)