From 1c3a06c08a04698f7ddf900f7b659128e5cf27d3 Mon Sep 17 00:00:00 2001 From: richard Date: Thu, 24 Apr 2003 07:20:00 +0000 Subject: [PATCH] SMTP login and TLS support added (sf bug 710853 with extras ;) git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1680 57a73879-2fb5-44c3-a270-3262357dd7e2 --- CHANGES.txt | 1 + roundup/cgi/client.py | 6 +++--- roundup/mailgw.py | 37 +++++++++++++++++++++++++++++++++---- roundup/roundupdb.py | 7 ++++--- scripts/roundup-reminder | 5 +++-- templates/classic/config.py | 16 +++++++++++++++- templates/minimal/config.py | 16 +++++++++++++++- 7 files changed, 74 insertions(+), 14 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 7b05998..3c3664c 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -64,6 +64,7 @@ Feature: - Roundup templates are now distributed much more sanely, allowing for 3rd-party templates. - extended date syntax to make range searches even more useful +- SMTP login and TLS support added (sf bug 710853 with extras ;) Fixed: - applied unicode patch. All data is stored in utf-8. Incoming messages diff --git a/roundup/cgi/client.py b/roundup/cgi/client.py index 3c59776..007d7a0 100644 --- a/roundup/cgi/client.py +++ b/roundup/cgi/client.py @@ -1,4 +1,4 @@ -# $Id: client.py,v 1.113 2003-04-10 05:12:41 richard Exp $ +# $Id: client.py,v 1.114 2003-04-24 07:19:59 richard Exp $ __doc__ = """ WWW request handler (also used in the stand-alone server). @@ -14,7 +14,7 @@ from roundup.cgi.templating import Templates, HTMLRequest, NoTemplate from roundup.cgi import cgitb from roundup.cgi.PageTemplates import PageTemplate from roundup.rfc2822 import encode_header -from roundup.mailgw import uidFromAddress +from roundup.mailgw import uidFromAddress, openSMTPConnection class HTTPException(Exception): pass @@ -787,7 +787,7 @@ please visit the following URL: try: # send the message as admin so bounces are sent there # instead of to roundup - smtp = smtplib.SMTP(self.db.config.MAILHOST) + smtp = openSMTPConnection(self.db.config) smtp.sendmail(self.db.config.ADMIN_EMAIL, [to], message.getvalue()) except socket.error, value: diff --git a/roundup/mailgw.py b/roundup/mailgw.py index 75dd779..89dd29f 100644 --- a/roundup/mailgw.py +++ b/roundup/mailgw.py @@ -73,7 +73,7 @@ are calling the create() method to create a new node). If an auditor raises an exception, the original message is bounced back to the sender with the explanatory message given in the exception. -$Id: mailgw.py,v 1.117 2003-04-23 12:09:20 richard Exp $ +$Id: mailgw.py,v 1.118 2003-04-24 07:19:58 richard Exp $ ''' import string, re, os, mimetools, cStringIO, smtplib, socket, binascii, quopri @@ -132,6 +132,35 @@ def getparam(str, param): return rfc822.unquote(f[i+1:].strip()) return None +def openSMTPConnection(config): + ''' Open an SMTP connection to the mailhost specified in the config + ''' + smtp = smtplib.SMTP(config.MAILHOST) + + # use TLS? + use_tls = getattr(config, 'MAILHOST_TLS', 'no') + if use_tls == 'yes' + # do we have key files too? + keyfile = getattr(config, 'MAILHOST_TLS_KEYFILE', None) + if keyfile is not None: + certfile = getattr(config, 'MAILHOST_TLS_CERTFILE', None) + if certfile is not None: + args = (keyfile, certfile) + else: + args = (keyfile, ) + else: + args = () + # start the TLS + smtp.starttls(*args) + + # ok, now do we also need to log in? + mailuser = getattr(config, 'MAILUSER', None) + if mailuser: + smtp.login(*config.MAILUSER) + + # that's it, a fully-configured SMTP connection ready to go + return smtp + class Message(mimetools.Message): ''' subclass mimetools.Message so we can retrieve the parts of the message... @@ -345,7 +374,7 @@ class MailGW: m.getvalue())) else: try: - smtp = smtplib.SMTP(self.instance.config.MAILHOST) + smtp = openSMTPConnection(self.instance.config) smtp.sendmail(self.instance.config.ADMIN_EMAIL, sendto, m.getvalue()) except socket.error, value: @@ -820,12 +849,12 @@ not find a text/plain part to use. # attach the files to the issue if nodeid: # extend the existing files list - fileprop = cl.get(nodeid, 'file') + fileprop = cl.get(nodeid, 'files') fileprop.extend(files) props['files'] = fileprop else: # pre-load the files list - props['files'] = fileprop + props['files'] = files # diff --git a/roundup/roundupdb.py b/roundup/roundupdb.py index 1294c80..56176a9 100644 --- a/roundup/roundupdb.py +++ b/roundup/roundupdb.py @@ -15,7 +15,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -# $Id: roundupdb.py,v 1.84 2003-04-14 06:24:01 richard Exp $ +# $Id: roundupdb.py,v 1.85 2003-04-24 07:19:58 richard Exp $ __doc__ = """ Extending hyperdb with types specific to issue-tracking. @@ -43,7 +43,8 @@ except ImportError : return '%s%s%s <%s>' % (quotes, name, quotes, address) return address -import hyperdb +from roundup import hyperdb +from roundup.mailgw import openSMTPConnection # set to indicate to roundup not to actually _send_ email # this var must contain a file to write the mail to @@ -333,7 +334,7 @@ class IssueClass: try: # send the message as admin so bounces are sent there # instead of to roundup - smtp = smtplib.SMTP(self.db.config.MAILHOST) + smtp = openSMTPConnection(self.db.config) smtp.sendmail(self.db.config.ADMIN_EMAIL, sendto, message.getvalue()) except socket.error, value: diff --git a/scripts/roundup-reminder b/scripts/roundup-reminder index 733d233..922fe62 100755 --- a/scripts/roundup-reminder +++ b/scripts/roundup-reminder @@ -19,7 +19,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -# $Id: roundup-reminder,v 1.5 2003-02-06 05:43:49 richard Exp $ +# $Id: roundup-reminder,v 1.6 2003-04-24 07:19:59 richard Exp $ ''' Simple script that emails all users of a tracker with the issues that @@ -34,6 +34,7 @@ Note: The instance that this script was designed for has a modified schema! import sys, cStringIO, MimeWriter, smtplib from roundup import instance, date +from roundup.mailgw import openSMTPConnection # open the instance if len(sys.argv) != 2: @@ -147,7 +148,7 @@ and click on "My Issues". Do NOT respond to this message. writer.lastpart() # all done, send! - smtp = smtplib.SMTP(db.config.MAILHOST) + smtp = openSMTPConnection(db.config) smtp.sendmail(db.config.ADMIN_EMAIL, address, message.getvalue()) # vim: set filetype=python ts=4 sw=4 et si diff --git a/templates/classic/config.py b/templates/classic/config.py index d507ba9..8f9057d 100644 --- a/templates/classic/config.py +++ b/templates/classic/config.py @@ -15,7 +15,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -# $Id: config.py,v 1.2 2003-04-23 11:59:36 richard Exp $ +# $Id: config.py,v 1.3 2003-04-24 07:19:59 richard Exp $ import os @@ -25,6 +25,20 @@ TRACKER_HOME=os.path.split(__file__)[0] # The SMTP mail host that roundup will use to send mail MAILHOST = 'localhost' +# If your SMTP mail host requires a username and password for access, then +# specify them here. +# eg. MAILUSER = ('username', 'password') +MAILUSER = () + +# If your SMTP mail host provides or requires TLS (Transport Layer +# Security) then set MAILHOST_TLS = 'yes' +# Optionallly, you may also set MAILHOST_TLS_KEYFILE to the name of a PEM +# formatted file that contains your private key, and MAILHOST_TLS_CERTFILE +# to the name of a PEM formatted certificate chain file. +MAILHOST_TLS = 'no' +MAILHOST_TLS_KEYFILE = '' +MAILHOST_TLS_CERTFILE = '' + # The domain name used for email addresses. MAIL_DOMAIN = 'your.tracker.email.domain.example' diff --git a/templates/minimal/config.py b/templates/minimal/config.py index e5e40f2..f2d3f67 100644 --- a/templates/minimal/config.py +++ b/templates/minimal/config.py @@ -15,7 +15,7 @@ # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # -# $Id: config.py,v 1.1 2003-04-17 03:27:27 richard Exp $ +# $Id: config.py,v 1.2 2003-04-24 07:20:00 richard Exp $ import os @@ -25,6 +25,20 @@ TRACKER_HOME=os.path.split(__file__)[0] # The SMTP mail host that roundup will use to send mail MAILHOST = 'localhost' +# If your SMTP mail host requires a username and password for access, then +# specify them here. +# eg. MAILUSER = ('username', 'password') +MAILUSER = () + +# If your SMTP mail host provides or requires TLS (Transport Layer +# Security) then set MAILHOST_TLS = 'yes' +# Optionallly, you may also set MAILHOST_TLS_KEYFILE to the name of a PEM +# formatted file that contains your private key, and MAILHOST_TLS_CERTFILE +# to the name of a PEM formatted certificate chain file. +MAILHOST_TLS = 'no' +MAILHOST_TLS_KEYFILE = '' +MAILHOST_TLS_CERTFILE = '' + # The domain name used for email addresses. MAIL_DOMAIN = 'your.tracker.email.domain.example' -- 2.30.2