1 new changeset in galaxy-central: http://bitbucket.org/galaxy/galaxy-central/changeset/b6582a3018f5/ changeset: b6582a3018f5 branches: user: natefoo date: 2011-06-03 17:25:02 summary: SMTP Authentication support for all places where Galaxy sends mail. Use STARTTLS where available, too. affected #: 7 files (3.8 KB) --- a/lib/galaxy/config.py Fri Jun 03 10:16:20 2011 -0400 +++ b/lib/galaxy/config.py Fri Jun 03 11:25:02 2011 -0400 @@ -76,6 +76,8 @@ self.mailing_join_addr = kwargs.get('mailing_join_addr',"galaxy-user-join@bx.psu.edu") self.error_email_to = kwargs.get( 'error_email_to', None ) self.smtp_server = kwargs.get( 'smtp_server', None ) + self.smtp_username = kwargs.get( 'smtp_username', None ) + self.smtp_password = kwargs.get( 'smtp_password', None ) self.start_job_runners = kwargs.get( 'start_job_runners', None ) # External Service types used in sample tracking self.external_service_type_config_file = resolve_path( kwargs.get( 'external_service_type_config_file', 'external_service_types_conf.xml' ), self.root ) --- a/lib/galaxy/jobs/actions/post.py Fri Jun 03 10:16:20 2011 -0400 +++ b/lib/galaxy/jobs/actions/post.py Fri Jun 03 11:25:02 2011 -0400 @@ -1,5 +1,5 @@ -import logging, datetime, smtplib -from email.MIMEText import MIMEText +import logging, datetime +from galaxy.util import send_mail from galaxy.util.json import to_json_string log = logging.getLogger( __name__ ) @@ -58,35 +58,17 @@ @classmethod def execute(cls, app, sa_session, action, job, replacement_dict): - smtp_server = app.config.smtp_server if action.action_arguments and action.action_arguments.has_key('host'): host = action.action_arguments['host'] else: host = 'usegalaxy.org' - if smtp_server is None: - log.error("Mail is not configured for this galaxy instance. Workflow action aborting after logging mail to info.") - frm = 'galaxy-noreply@%s' % host - to = job.user.email - outdata = ', '.join(ds.dataset.display_name() for ds in job.output_datasets) - msg = MIMEText( "Your Galaxy job generating dataset '%s' is complete as of %s." % (outdata, datetime.datetime.now().strftime( "%I:%M" ))) - msg[ 'To' ] = to - msg[ 'From' ] = frm - msg[ 'Subject' ] = "Galaxy notification regarding history '%s'" % (job.history.name) - log.info(msg) - return - # Build the email message frm = 'galaxy-noreply@%s' % host to = job.user.email + subject = "Galaxy workflow step notification '%s'" % (job.history.name) outdata = ', '.join(ds.dataset.display_name() for ds in job.output_datasets) - msg = MIMEText( "Your Galaxy job generating dataset '%s' is complete as of %s." % (outdata, datetime.datetime.now().strftime( "%I:%M" ))) - msg[ 'To' ] = to - msg[ 'From' ] = frm - msg[ 'Subject' ] = "Galaxy workflow step notification '%s'" % (job.history.name) + body = "Your Galaxy job generating dataset '%s' is complete as of %s." % (outdata, datetime.datetime.now().strftime( "%I:%M" )) try: - s = smtplib.SMTP() - s.connect( smtp_server ) - s.sendmail( frm, [ to ], msg.as_string() ) - s.close() + send_mail( frm, to, subject, body, app.config ) except Exception, e: log.error("EmailAction PJA Failed, exception: %s" % e) --- a/lib/galaxy/model/__init__.py Fri Jun 03 10:16:20 2011 -0400 +++ b/lib/galaxy/model/__init__.py Fri Jun 03 11:25:02 2011 -0400 @@ -15,7 +15,7 @@ from galaxy.web.form_builder import * from galaxy.model.item_attrs import UsesAnnotations, APIItem from sqlalchemy.orm import object_session -import os.path, os, errno, codecs, operator, smtplib, socket, pexpect, logging, time +import os.path, os, errno, codecs, operator, socket, pexpect, logging, time log = logging.getLogger( __name__ ) @@ -1803,12 +1803,8 @@ to = self.notification['email'] frm = 'galaxy-no-reply@' + host subject = "Galaxy Sample Tracking notification: '%s' sequencing request" % self.name - message = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s" % ( frm, ", ".join( to ), subject, body ) try: - s = smtplib.SMTP() - s.connect( trans.app.config.smtp_server ) - s.sendmail( frm, to, message ) - s.quit() + util.send_mail( frm, to, subject, body, trans.app.config ) comments = "Email notification sent to %s." % ", ".join( to ).strip().strip( ',' ) except Exception,e: comments = "Email notification failed. (%s)" % str(e) --- a/lib/galaxy/util/__init__.py Fri Jun 03 10:16:20 2011 -0400 +++ b/lib/galaxy/util/__init__.py Fri Jun 03 11:25:02 2011 -0400 @@ -2,7 +2,8 @@ Utility functions used systemwide. """ -import logging, threading, random, string, re, binascii, pickle, time, datetime, math, re, os, sys, tempfile, stat, grp +import logging, threading, random, string, re, binascii, pickle, time, datetime, math, re, os, sys, tempfile, stat, grp, smtplib +from email.MIMEText import MIMEText # Older py compatibility try: @@ -540,6 +541,51 @@ return "%.1f %s" % (size, word) return '??? bytes' +def send_mail( frm, to, subject, body, config ): + """ + Sends an email. + """ + msg = MIMEText( body ) + msg[ 'To' ] = to + msg[ 'From' ] = frm + msg[ 'Subject' ] = subject + if config.smtp_server is None: + log.error( "Mail is not configured for this Galaxy instance." ) + log.info( msg ) + return + s = smtplib.SMTP() + s.connect( config.smtp_server ) + try: + s.starttls() + log.debug( 'Initiated SSL/TLS connection to SMTP server: %s' % config.smtp_server ) + except RuntimeError, e: + log.warning( 'SSL/TLS support is not available to your Python interpreter: %s' % e ) + except smtplib.SMTPHeloError, e: + log.error( "The server didn't reply properly to the HELO greeting: %s" % e ) + s.close() + raise + except smtplib.SMTPException, e: + log.warning( 'The server does not support the STARTTLS extension: %s' % e ) + if config.smtp_username and config.smtp_password: + try: + s.login( config.smtp_username, config.smtp_password ) + except smtplib.SMTPHeloError, e: + log.error( "The server didn't reply properly to the HELO greeting: %s" % e ) + s.close() + raise + except smtplib.SMTPAuthenticationError, e: + log.error( "The server didn't accept the username/password combination: %s" % e ) + s.close() + raise + except smtplib.SMTPError, e: + log.error( "No suitable authentication method was found: %s" % e ) + s.close() + raise + if isinstance( to, basestring ): + to = [ to ] + s.sendmail( frm, to, msg.as_string() ) + s.quit() + galaxy_root_path = os.path.join(__path__[0], "..","..","..") # The dbnames list is used in edit attributes and the upload tool dbnames = read_dbnames( os.path.join( galaxy_root_path, "tool-data", "shared", "ucsc", "builds.txt" ) ) --- a/lib/galaxy/web/controllers/dataset.py Fri Jun 03 10:16:20 2011 -0400 +++ b/lib/galaxy/web/controllers/dataset.py Fri Jun 03 11:25:02 2011 -0400 @@ -1,4 +1,4 @@ -import logging, os, string, shutil, re, socket, mimetypes, smtplib, urllib, tempfile, zipfile, glob, sys +import logging, os, string, shutil, re, socket, mimetypes, urllib, tempfile, zipfile, glob, sys from galaxy.web.base.controller import * from galaxy.web.framework.helpers import time_ago, iff, grids @@ -10,7 +10,6 @@ from galaxy.model.item_attrs import * from galaxy.model import LibraryDatasetDatasetAssociation, HistoryDatasetAssociation -from email.MIMEText import MIMEText import pkg_resources; pkg_resources.require( "Paste" ) import paste.httpexceptions @@ -174,7 +173,7 @@ host = trans.request.host history_view_link = "%s/history/view?id=%s" % ( str( host ), trans.security.encode_id( hda.history_id ) ) # Build the email message - msg = MIMEText( string.Template( error_report_template ) + body = string.Template( error_report_template ) \ .safe_substitute( host=host, dataset_id=hda.dataset_id, history_id=hda.history_id, @@ -189,7 +188,7 @@ job_info=job.info, job_traceback=job.traceback, email=email, - message=message ) ) + message=message ) frm = to_address # Check email a bit email = email.strip() @@ -198,15 +197,10 @@ to = to_address + ", " + email else: to = to_address - msg[ 'To' ] = to - msg[ 'From' ] = frm - msg[ 'Subject' ] = "Galaxy tool error report from " + email + subject = "Galaxy tool error report from " + email # Send it try: - s = smtplib.SMTP() - s.connect( smtp_server ) - s.sendmail( frm, [ to ], msg.as_string() ) - s.close() + util.send_mail( frm, to, subject, body, trans.app.config ) return trans.show_ok_message( "Your error report has been sent" ) except Exception, e: return trans.show_error_message( "An error occurred sending the report by email: %s" % str( e ) ) --- a/lib/galaxy/web/controllers/user.py Fri Jun 03 10:16:20 2011 -0400 +++ b/lib/galaxy/web/controllers/user.py Fri Jun 03 11:25:02 2011 -0400 @@ -5,9 +5,8 @@ from galaxy.web.base.controller import * from galaxy.model.orm import * from galaxy import util, model -import logging, os, string, re, smtplib, socket, glob +import logging, os, string, re, socket, glob from random import choice -from email.MIMEText import MIMEText from galaxy.web.form_builder import * from galaxy.util.json import from_json_string, to_json_string from galaxy.web.framework.helpers import iff @@ -560,15 +559,12 @@ if trans.app.config.smtp_server is None: error = "Now logged in as " + user.email + ". However, subscribing to the mailing list has failed because mail is not configured for this Galaxy instance." else: - msg = MIMEText( 'Join Mailing list.\n' ) - to = msg[ 'To' ] = trans.app.config.mailing_join_addr - frm = msg[ 'From' ] = email - msg[ 'Subject' ] = 'Join Mailing List' + body = 'Join Mailing list.\n' + to = trans.app.config.mailing_join_addr + frm = email + subject = 'Join Mailing List' try: - s = smtplib.SMTP() - s.connect( trans.app.config.smtp_server ) - s.sendmail( frm, [ to ], msg.as_string() ) - s.close() + util.send_mail( frm, to, subject, body, trans.app.config ) except: error = "Now logged in as " + user.email + ". However, subscribing to the mailing list has failed." if not error and not is_admin: @@ -888,15 +884,12 @@ host = trans.request.host.split(':')[0] if host == 'localhost': host = socket.getfqdn() - msg = MIMEText( 'Your password on %s has been reset to:\n\n %s\n' % ( host, new_pass ) ) - to = msg[ 'To' ] = email - frm = msg[ 'From' ] = 'galaxy-no-reply@' + host - msg[ 'Subject' ] = 'Galaxy Password Reset' + body = 'Your password on %s has been reset to:\n\n %s\n' % ( host, new_pass ) + to = email + frm = 'galaxy-no-reply@' + host + subject = 'Galaxy Password Reset' try: - s = smtplib.SMTP() - s.connect( trans.app.config.smtp_server ) - s.sendmail( frm, [ to ], msg.as_string() ) - s.close() + util.send_mail( frm, to, subject, body, trans.app.config ) reset_user.set_password_cleartext( new_pass ) trans.sa_session.add( reset_user ) trans.sa_session.flush() --- a/universe_wsgi.ini.sample Fri Jun 03 10:16:20 2011 -0400 +++ b/universe_wsgi.ini.sample Fri Jun 03 11:25:02 2011 -0400 @@ -161,9 +161,16 @@ # Galaxy sends mail for various things: Subscribing users to the mailing list # if they request it, emailing password resets, notification from the Galaxy # Sample Tracking system, and reporting dataset errors. To do this, it needs -# to send mail through an SMTP server, which you may define here. +# to send mail through an SMTP server, which you may define here (host:port). +# Galaxy will automatically try STARTTLS but will continue upon failure. #smtp_server = None +# If your SMTP server requires a username and password, you can provide them +# here (password in cleartext here, but if your server supports STARTTLS it +# will be sent over the network encrypted). +#smtp_username = None +#smtp_password = None + # On the user registration form, users may choose to join the mailing list. # This is the address of the list they'll be subscribed to. #mailing_join_addr = galaxy-user-join@bx.psu.edu Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.