# We store the raw MIME message, so if there are any attachments or
# anything, we just push them right in there!
fullmsg = models.TextField(null=False, blank=False)
+ # Flag if the message is "user generated", so we can treat those
+ # separately from an antispam and delivery perspective.
+ usergenerated = models.BooleanField(null=False, blank=False, default=False)
def __unicode__(self):
return "%s: %s -> %s" % (self.pk, self.sender, self.receiver)
from models import QueuedMail
-def send_simple_mail(sender, receiver, subject, msgtxt, attachments=None):
+def send_simple_mail(sender, receiver, subject, msgtxt, attachments=None, usergenerated=False):
# attachment format, each is a tuple of (name, mimetype,contents)
# content should be *binary* and not base64 encoded, since we need to
# use the base64 routines from the email library to get a properly
# Just write it to the queue, so it will be transactionally rolled back
- QueuedMail(sender=sender, receiver=receiver, fullmsg=msg.as_string()).save()
+ QueuedMail(sender=sender, receiver=receiver, fullmsg=msg.as_string(), usergenerated=usergenerated).save()
-def send_mail(sender, receiver, fullmsg):
+def send_mail(sender, receiver, fullmsg, usergenerated=False):
# Send an email, prepared as the full MIME encoded mail already
- QueuedMail(sender=sender, receiver=receiver, fullmsg=fullmsg).save()
+ QueuedMail(sender=sender, receiver=receiver, fullmsg=fullmsg, usergenerated=False).save()
{
'bugid': bugid,
'bug': form.cleaned_data,
- }
+ },
+ usergenerated=True
)
return render_to_response('misc/bug_completed.html', {
VARNISH_PURGERS=() # Extra servers that can do varnish purges through our queue
VARNISH_QUEUE_ID=1 # pgq queue id used for varnish purging
ARCHIVES_SEARCH_SERVER="archives.postgresql.org" # Where to post REST request for archives search
+FRONTEND_SMTP_RELAY="magus.postgresql.org" # Where to relay user generated email
# Load local settings overrides
from settings_local import *
from pgweb.mailqueue.util import send_simple_mail
from pgweb.util.helpers import template_to_string
-def send_template_mail(sender, receiver, subject, templatename, templateattr={}):
+def send_template_mail(sender, receiver, subject, templatename, templateattr={}, usergenerated=False):
send_simple_mail(sender, receiver, subject,
- template_to_string(templatename, templateattr))
+ template_to_string(templatename, templateattr),
+ usergenerated=usergenerated)
def is_behind_cache(request):
"""
# Yes, we do a new connection for each run. Just because we can.
# If it fails we'll throw an exception and just come back on the
# next cron job. And local delivery should never fail...
- smtp = smtplib.SMTP("localhost")
- smtp.sendmail(m.sender, m.receiver, m.fullmsg.encode('utf-8'))
+ if m.usergenerated:
+ # User generated email gets relayed directly over a frontend
+ smtphost = settings.FRONTEND_SMTP_RELAY
+ else:
+ smtphost = 'localhost'
+ smtp = smtplib.SMTP(smtphost)
+ try:
+ smtp.sendmail(m.sender, m.receiver, m.fullmsg.encode('utf-8'))
+ except (smtplib.SMTPSenderRefused, smtplib.SMTPRecipientsRefused, smtplib.SMTPDataError):
+ # If this was user generated, this indicates the antispam
+ # kicking in, so we just ignore it. If it's anything else,
+ # we want to let the exception through.
+ if not m.usergenerated:
+ raise
smtp.close()
m.delete()
transaction.commit()