diff --git a/src/pretix/control/views/mailsetup.py b/src/pretix/control/views/mailsetup.py index 97badc4810..1b04f6bf30 100644 --- a/src/pretix/control/views/mailsetup.py +++ b/src/pretix/control/views/mailsetup.py @@ -192,10 +192,15 @@ class MailSettingsSetupView(TemplateView): return super().get(request, *args, **kwargs) session_key = f'sender_mail_verification_code_{self.request.path}_{self.simple_form.cleaned_data.get("mail_from")}' + verify_dns = ( + settings.MAIL_CUSTOM_SENDER_SPF_STRING or + (settings.MAIL_CUSTOM_SENDER_DKIM_CNAME and settings.MAIL_CUSTOM_SENDER_DMARC_REQUIRED) or + settings.MAIL_CUSTOM_SENDER_DMARC_REQUIRED + ) allow_save = ( (not settings.MAIL_CUSTOM_SENDER_VERIFICATION_REQUIRED or ('verification' in self.request.POST and self.request.POST.get('verification', '') == self.request.session.get(session_key, None))) and - (not settings.MAIL_CUSTOM_SENDER_SPF_STRING or self.request.POST.get('state') == 'save') + (not verify_dns or self.request.POST.get('state') == 'save') ) if allow_save: @@ -238,7 +243,7 @@ class MailSettingsSetupView(TemplateView): dkim_hostname = None dkim_cname = None if settings.MAIL_CUSTOM_SENDER_DKIM_CNAME and settings.MAIL_CUSTOM_SENDER_DKIM_SELECTOR: - dkim_hostname = settings.MAIL_CUSTOM_SENDER_DKIM_SELECTOR + '.domainkey.' + hostname + dkim_hostname = settings.MAIL_CUSTOM_SENDER_DKIM_SELECTOR + '._domainkey.' + hostname cname_target = get_cname_record(dkim_hostname) dkim_cname = settings.MAIL_CUSTOM_SENDER_DKIM_CNAME if not dkim_cname.endswith("."): @@ -252,7 +257,7 @@ class MailSettingsSetupView(TemplateView): 'spam. We strongly recommend setting up DKIM through a CNAME record. You can do so through the ' 'DNS settings at the provider you registered your domain with.' ) - elif cname_target != settings.MAIL_CUSTOM_SENDER_DKIM_CNAME: + elif cname_target != dkim_cname: dkim_warning = _( 'We found a CNAME record for a DKIM key, but it is not pointing to the right location. ' 'This means that there is a very high chance most of the emails will be rejected or marked as ' diff --git a/src/tests/control/test_organizer.py b/src/tests/control/test_organizer.py index 5ef89e9001..d822c754ba 100644 --- a/src/tests/control/test_organizer.py +++ b/src/tests/control/test_organizer.py @@ -159,6 +159,22 @@ class OrganizerTest(SoupTest): self.orga1.settings.flush() assert "mail_from" not in self.orga1.settings._cache() + @staticmethod + def _fake_dmarc_record(hostname): + return { + 'test.pretix.dev': 'v=DMARC1; p=quarantine; sp=none; adkim=r; aspf=r;', + 'bad.pretix.dev': 'BLA', + 'none.pretix.dev': None, + }[hostname] + + @staticmethod + def _fake_cname_record(hostname): + return { + 'pretix._domainkey.test.pretix.dev': 'test-pretix-dev.dkim.pretix.eu.', + 'pretix._domainkey.bad.pretix.dev': 'example.org', + 'pretix._domainkey.none.pretix.dev': None, + }[hostname] + @staticmethod def _fake_spf_record(hostname): return { @@ -172,9 +188,17 @@ class OrganizerTest(SoupTest): 'spftest.pretix.dev': None, }[hostname] - @override_settings(MAIL_CUSTOM_SENDER_VERIFICATION_REQUIRED=False, MAIL_CUSTOM_SENDER_SPF_STRING="include:spftest.pretix.dev include:test2.pretix.dev") - def test_email_setup_no_verification_spf_success(self): + @override_settings( + MAIL_CUSTOM_SENDER_VERIFICATION_REQUIRED=False, + MAIL_CUSTOM_SENDER_SPF_STRING="include:spftest.pretix.dev include:test2.pretix.dev", + MAIL_CUSTOM_SENDER_DKIM_SELECTOR="pretix", + MAIL_CUSTOM_SENDER_DKIM_CNAME="dkim.pretix.eu.", + MAIL_CUSTOM_SENDER_DMARC_REQUIRED=True, + ) + def test_email_setup_no_verification_spf_dmarc_dkim_success(self): self.monkeypatch.setattr("pretix.control.views.mailsetup.get_spf_record", OrganizerTest._fake_spf_record) + self.monkeypatch.setattr("pretix.control.views.mailsetup.get_cname_record", OrganizerTest._fake_cname_record) + self.monkeypatch.setattr("pretix.control.views.mailsetup.get_dmarc_record", OrganizerTest._fake_dmarc_record) doc = self.post_doc( '/control/organizer/%s/settings/email/setup' % self.orga1.slug, { @@ -213,6 +237,43 @@ class OrganizerTest(SoupTest): # not yet saved assert "mail_from" not in self.orga1.settings._cache() + @override_settings(MAIL_CUSTOM_SENDER_VERIFICATION_REQUIRED=False, + MAIL_CUSTOM_SENDER_DKIM_SELECTOR="pretix", + MAIL_CUSTOM_SENDER_DKIM_CNAME="dkim.pretix.eu.", + MAIL_CUSTOM_SENDER_SPF_STRING="") + def test_email_setup_no_verification_dkim_warning(self): + self.monkeypatch.setattr("pretix.control.views.mailsetup.get_cname_record", OrganizerTest._fake_cname_record) + doc = self.post_doc( + '/control/organizer/%s/settings/email/setup' % self.orga1.slug, + { + 'mode': 'simple', + 'simple-mail_from': 'test@bad.pretix.dev', + }, + follow=True + ) + assert doc.select('.alert-danger') + self.orga1.settings.flush() + # not yet saved + assert "mail_from" not in self.orga1.settings._cache() + + @override_settings(MAIL_CUSTOM_SENDER_VERIFICATION_REQUIRED=False, + MAIL_CUSTOM_SENDER_DMARC_REQUIRED=True, + MAIL_CUSTOM_SENDER_SPF_STRING="") + def test_email_setup_no_verification_dmarc_warning(self): + self.monkeypatch.setattr("pretix.control.views.mailsetup.get_dmarc_record", OrganizerTest._fake_dmarc_record) + doc = self.post_doc( + '/control/organizer/%s/settings/email/setup' % self.orga1.slug, + { + 'mode': 'simple', + 'simple-mail_from': 'test@bad.pretix.dev', + }, + follow=True + ) + assert doc.select('.alert-danger') + self.orga1.settings.flush() + # not yet saved + assert "mail_from" not in self.orga1.settings._cache() + def test_email_setup_smtp(self): self.monkeypatch.setattr("pretix.base.email.test_custom_smtp_backend", lambda b, a: None) self.monkeypatch.setattr("socket.gethostbyname", lambda h: "8.8.8.8")