diff --git a/src/pretix/base/models/event.py b/src/pretix/base/models/event.py index 5e374ecb01..ca04bfd60b 100644 --- a/src/pretix/base/models/event.py +++ b/src/pretix/base/models/event.py @@ -3,6 +3,8 @@ from datetime import datetime from django.conf import settings from django.core.exceptions import ValidationError +from django.core.mail import get_connection +from django.core.mail.backends.smtp import EmailBackend from django.core.validators import RegexValidator from django.db import models from django.template.defaultfilters import date as _date @@ -181,6 +183,18 @@ class Event(LoggedModel): return locking.LockManager(self) + def get_mail_backend(self, force_custom=False): + if self.settings.smtp_use_custom or force_custom: + return EmailBackend(host=self.settings.smtp_host, + port=self.settings.smtp_port, + username=self.settings.smtp_username, + password=self.settings.smtp_password, + use_tls=self.settings.smtp_use_tls, + use_ssl=self.settings.smtp_use_ssl, + fail_silently=False) + else: + return get_connection(fail_silently=False) + class EventPermission(models.Model): """ diff --git a/src/pretix/base/services/mail.py b/src/pretix/base/services/mail.py index 68a061dc1e..d485af5e3d 100644 --- a/src/pretix/base/services/mail.py +++ b/src/pretix/base/services/mail.py @@ -65,16 +65,18 @@ def mail(email: str, subject: str, template: str, ) body += "\r\n" try: - return mail_send([email], subject, body, sender) + return mail_send([email], subject, body, sender, event.id) finally: translation.activate(_lng) -def mail_send(to: str, subject: str, body: str, sender: str) -> bool: +def mail_send(to: str, subject: str, body: str, sender: str, event: int) -> bool: email = EmailMessage(subject, body, sender, to=to) + event = Event.objects.get(id=event) + backend = event.get_mail_backend() try: - email.send(fail_silently=False) + backend.send_messages([email]) return True except Exception: logger.exception('Error sending e-mail') diff --git a/src/pretix/base/settings.py b/src/pretix/base/settings.py index c176c681a0..97d3f29186 100644 --- a/src/pretix/base/settings.py +++ b/src/pretix/base/settings.py @@ -123,7 +123,35 @@ You can change your order details and view the status of your order at Best regards, Your {event} team""")) - } + }, + 'smtp_use_custom': { + 'default': 'False', + 'type': bool + }, + 'smtp_host': { + 'default': '', + 'type': str + }, + 'smtp_port': { + 'default': 587, + 'type': int + }, + 'smtp_username': { + 'default': '', + 'type': str + }, + 'smtp_password': { + 'default': '', + 'type': str + }, + 'smtp_use_tls': { + 'default': 'True', + 'type': bool + }, + 'smtp_use_ssl': { + 'default': 'False', + 'type': bool + }, } diff --git a/src/pretix/control/forms/event.py b/src/pretix/control/forms/event.py index 658af8dc01..b22501e0dc 100644 --- a/src/pretix/control/forms/event.py +++ b/src/pretix/control/forms/event.py @@ -212,6 +212,38 @@ class MailSettingsForm(SettingsForm): widget=I18nTextarea, help_text=_("Available placeholders: {event}, {url}") ) + smtp_use_custom = forms.BooleanField( + label=_("Use custom SMTP server"), + help_text=_("All mail related to your event will be sent over the smtp server specified by you."), + required=False + ) + smtp_host = forms.CharField( + label=_("Hostname"), + required=False + ) + smtp_port = forms.IntegerField( + label=_("Port"), + required=False + ) + smtp_username = forms.CharField( + label=_("Username"), + required=False + ) + smtp_password = forms.CharField( + label=_("Password"), + required=False, + widget=forms.PasswordInput + ) + smtp_use_tls = forms.BooleanField( + label=_("Use STARTTLS"), + help_text=_("Commonly enabled on port 587."), + required=False + ) + smtp_use_ssl = forms.BooleanField( + label=_("Use SSL"), + help_text=_("Commonly enabled on port 465."), + required=False + ) class TicketSettingsForm(SettingsForm): diff --git a/src/pretix/control/templates/pretixcontrol/event/mail.html b/src/pretix/control/templates/pretixcontrol/event/mail.html index 6b44a3e616..680d8b7d1e 100644 --- a/src/pretix/control/templates/pretixcontrol/event/mail.html +++ b/src/pretix/control/templates/pretixcontrol/event/mail.html @@ -15,10 +15,23 @@ {% bootstrap_field form.mail_text_order_placed layout="horizontal" %} {% bootstrap_field form.mail_text_order_paid layout="horizontal" %} +
+ {% trans "SMTP settings" %} + {% bootstrap_field form.smtp_use_custom layout="horizontal" %} + {% bootstrap_field form.smtp_host layout="horizontal" %} + {% bootstrap_field form.smtp_port layout="horizontal" %} + {% bootstrap_field form.smtp_username layout="horizontal" %} + {% bootstrap_field form.smtp_password layout="horizontal" %} + {% bootstrap_field form.smtp_use_tls layout="horizontal" %} + {% bootstrap_field form.smtp_use_ssl layout="horizontal" %} +
+
{% endblock %} diff --git a/src/pretix/control/views/event.py b/src/pretix/control/views/event.py index 706f8f4ed0..a5071cb3e0 100644 --- a/src/pretix/control/views/event.py +++ b/src/pretix/control/views/event.py @@ -235,7 +235,20 @@ class MailSettings(EventPermissionRequiredMixin, FormView): k: form.cleaned_data.get(k) for k in form.changed_data } ) - messages.success(self.request, _('Your changes have been saved.')) + + if request.POST.get('test', '0').strip() == '1': + backend = self.request.event.get_mail_backend(force_custom=True) + try: + backend.open() + except Exception as e: + messages.warning(self.request, _('An error occured while contacting the SMTP server: %s') % str(e)) + else: + messages.success(self.request, _('Your changes have been saved and the connection attempt to ' + 'your SMTP server was successful.')) + finally: + backend.close() + else: + messages.success(self.request, _('Your changes have been saved.')) return redirect(self.get_success_url()) else: return self.get(request) diff --git a/src/pretix/plugins/sendmail/views.py b/src/pretix/plugins/sendmail/views.py index 72e5ec282f..5ded39d3c6 100644 --- a/src/pretix/plugins/sendmail/views.py +++ b/src/pretix/plugins/sendmail/views.py @@ -28,14 +28,14 @@ class SenderView(EventPermissionRequiredMixin, FormView): orders = Order.objects.filter( event=self.request.event, status__in=form.cleaned_data['sendto'] ) - mails = set([o.email for o in orders]) + mails = set([(o.email, o.locale) for o in orders]) self.request.event.log_action('pretix.plugins.sendmail.sent', user=self.request.user, data=dict( form.cleaned_data)) - for m in mails: + for m, l in mails: mail(m, form.cleaned_data['subject'], form.cleaned_data['message'], - None, self.request.event, locale=m.locale) + None, self.request.event, locale=l) messages.success(self.request, _('Your message will be sent to the selected users.'))