Skip to content

Commit

Permalink
[#1635] Improve CKAN's SMTP support
Browse files Browse the repository at this point in the history
Rename config option smtp_server -> smtp.server, add options smtp.starttls,
smtp.user and smtp.password, refactor the email-sending code in
mailer.py to (optionally) support STARTTLS and user and password
authentication. This means CKAN can now send emails using gmail's SMTP
server with a gmail username and password, for example. Sending mail
using a local sendmail process with no STARTTLS, username, or password
should still work as before.
  • Loading branch information
Sean Hammond committed Dec 4, 2012
1 parent 7f9c235 commit 794d61b
Showing 1 changed file with 43 additions and 7 deletions.
50 changes: 43 additions & 7 deletions ckan/lib/mailer.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,53 @@ def _mail_recipient(recipient_name, recipient_email,
msg['To'] = Header(recipient, 'utf-8')
msg['Date'] = Utils.formatdate(time())
msg['X-Mailer'] = "CKAN %s" % __version__

# Send the email using Python's smtplib.
smtp_connection = smtplib.SMTP()
if 'test_smtp_server' in config:
# If 'test_smtp_server' is configured we assume we're running tests,
# and don't use the smtp.server, starttls, user, password etc. options.
smtp_server = config['test_smtp_server']
smtp_starttls = False
smtp_user = None
smtp_password = None
else:
smtp_server = config.get('smtp.server', 'localhost')
smtp_starttls = config.get('smtp.starttls')
smtp_user = config.get('smtp.user')
smtp_password = config.get('smtp.password')
smtp_connection.connect(smtp_server)
try:
server = smtplib.SMTP(
config.get('test_smtp_server',
config.get('smtp_server', 'localhost')))
#server.set_debuglevel(1)
server.sendmail(mail_from, [recipient_email], msg.as_string())
server.quit()
except Exception, e:
#smtp_connection.set_debuglevel(True)

# Identify ourselves and prompt the server for supported features.
smtp_connection.ehlo()

# If 'smtp.starttls' is on in CKAN config, try to put the SMTP
# connection into TLS mode.
if smtp_starttls:
if smtp_connection.has_extn('STARTTLS'):
smtp_connection.starttls()
# Re-identify ourselves over TLS connection.
smtp_connection.ehlo()
else:
raise MailerException("SMTP server does not support STARTTLS")

# If 'smtp.user' is in CKAN config, try to login to SMTP server.
if smtp_user:
assert smtp_password, ("If smtp.user is configured then "
"smtp.password must be configured as well.")
smtp_connection.login(smtp_user, smtp_password)

smtp_connection.sendmail(mail_from, [recipient_email], msg.as_string())
log.info("Sent email to {0}".format(recipient_email))

except smtplib.SMTPException, e:
msg = '%r' % e
log.exception(msg)
raise MailerException(msg)
finally:
smtp_connection.quit()

def mail_recipient(recipient_name, recipient_email, subject,
body, headers={}):
Expand Down

0 comments on commit 794d61b

Please sign in to comment.