smtp-handling #3

Open
PeterSurda wants to merge 3 commits from cis-kuldeep/influx-smtp-gateway:smtp-handling into master
1 changed files with 57 additions and 25 deletions

82
main.py
View File

@ -13,16 +13,45 @@ from email.mime.text import MIMEText
import cherrypy import cherrypy
import logging import logging
import threading
logging.basicConfig(stream=sys.stdout, logging.basicConfig(stream=sys.stdout,
format='%(name)s - %(levelname)s - %(message)s') format='%(name)s - %(levelname)s - %(message)s')
def soft_return(msg):
time.sleep(0.2)
return(msg)
class SMTPWebhookApp: class SMTPWebhookApp:
""" """
SMTP webhook server SMTP webhook server
""" """
def create_new_client(self, response):
Review

needs to return a value (e.g. boolean)

needs to return a value (e.g. boolean)
try:
mythread.client = smtplib.SMTP(host=SMTP_SERVER_HOST,
port=SMTP_SERVER_PORT)
mythread.client.starttls()
return True
except (smtplib.SMTPException, TimeoutError) as e:
soft_return("can't connect")
response = {"status": 500, # noqa:F841
"message": "some error: {}".format(e)}
return False
def smtp_login(self, response, msg):
Review

needs to return a value

needs to return a value
try:
mythread.client.login(msg["From"], FROM_MAIL_PASSWORD)
return True
except smtplib.SMTPException as e:
soft_return(e)
response = {"status": 500, # noqa:F841
"message": "some error: {}".format(e)}
return False
def _send_mail(self): def _send_mail(self):
if not cherrypy.request.headers.get('Content-Length'): if not cherrypy.request.headers.get('Content-Length'):
@ -49,33 +78,36 @@ class SMTPWebhookApp:
body = req_body['body'] body = req_body['body']
to_mail = req_body['to_mail'] to_mail = req_body['to_mail']
try:
client = smtplib.SMTP(host=SMTP_SERVER_HOST, port=SMTP_SERVER_PORT)
except (smtplib.SMTPConnectionError, TimeoutError) as e:
time.sleep(0.2)
logging.error("To: {}, error: {}".format(to_mail, e))
return {"status": 400, "message": "SMTP client error: {}.".format(
e)}
msg = MIMEText(body, 'plain', 'utf-8') msg = MIMEText(body, 'plain', 'utf-8')
msg['Subject'] = Header(subject, 'utf-8') msg['Subject'] = Header(subject, 'utf-8')
msg['From'] = FROM_MAIL msg['From'] = FROM_MAIL
msg['To'] = to_mail msg['To'] = to_mail
try:
client.ehlo() c = 0
client.starttls() response = {}
client.ehlo() while (c < 2):
client.login(msg["From"], FROM_MAIL_PASSWORD) try:
client.sendmail(msg['From'], msg['To'], msg.as_string()) mythread.client.sendmail(msg['From'],
response = {"status": 200, "message": "mail sent successfully"} msg['To'], msg.as_string())
logging.info("To: {}, mail sent successfully".format(to_mail)) response = {"status": 200, "message": "mail sent successfully"}
except smtplib.SMTPException as e: except (AttributeError, ValueError,
time.sleep(0.2) smtplib.SMTPServerDisconnected):
logging.error("To: {}, error: {}".format(to_mail, e)) if (c == 1):
response = {"status": 500, "message": "some error: {}".format(e)} soft_return("can't connect")
finally:
Review

need to check for return value and skip login if connect fails

need to check for return value and skip `login` if `connect` fails
client.quit() if not self.create_new_client(response):
return response break
if not self.smtp_login(response, msg):
break
except smtplib.SMTPException as e:
soft_return("can't send for some reason")
response = {"status": 500,
"message": "some error: {}".format(e)}
finally:
c += 1
return response
@cherrypy.expose @cherrypy.expose
def send_mail(self): def send_mail(self):
@ -89,7 +121,6 @@ class SMTPWebhookApp:
ROOT = SMTPWebhookApp() ROOT = SMTPWebhookApp()
SMTP_SERVER_PORT = 587 SMTP_SERVER_PORT = 587
CHERRYPY_SERVER_HOST = "0.0.0.0" CHERRYPY_SERVER_HOST = "0.0.0.0"
CHERRYPY_SERVER_PORT = 8081 CHERRYPY_SERVER_PORT = 8081
@ -109,7 +140,8 @@ if __name__ == "__main__":
ENGINE = cherrypy.engine ENGINE = cherrypy.engine
cherrypy.tree.mount(ROOT, config={}) cherrypy.tree.mount(ROOT, config={})
mythread = threading.local()
mythread.client = None
if hasattr(ENGINE, "signal_handler"): if hasattr(ENGINE, "signal_handler"):
ENGINE.signal_handler.subscribe() ENGINE.signal_handler.subscribe()
if hasattr(ENGINE, "console_control_handler"): if hasattr(ENGINE, "console_control_handler"):